šŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
šŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

React Styling | React Tutorial

Learn about React Styling in this comprehensive React tutorial for frontend web development. Master the className attribute, explore inline styles with JavaScript objects, and learn to organize your styles using CSS Modules for scalable architectures.

⚔ Total XP: 0|šŸ’» react XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

šŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
šŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

React changes how CSS gets applied to markup, from the className attribute to inline style objects and locally scoped CSS Modules. This lesson covers the core styling techniques available in React and when each one makes sense.

1Styling React

Building a React application is only half the job — the other half is making it look good. In traditional HTML, styling means the class attribute plus a separate CSS file, but because JSX compiles down to JavaScript function calls, React handles styling a bit differently.

React supports several distinct approaches to styling, from basic class names to dynamic inline styles and locally scoped CSS Modules, each suited to different situations.

āœ•
—
+
// Styling React Components
localhost:3000

Aesthetics Engine

Bridging the gap between JS and CSS.

2The className Attribute

The most fundamental rule of React styling: never use class in JSX. class is a reserved keyword in JavaScript, used for defining object-oriented classes, and since JSX compiles down to JavaScript function calls, using class as an attribute name would conflict with that.

React requires className instead, and automatically translates it back into a standard class attribute when it renders the actual HTML to the DOM — so the underlying browser output is identical to writing class directly.

āœ•
—
+
function MyComponent() {
  return <div className='container'>Hello!</div>;
}
localhost:3000

User Info

3Inline Styles Overview

Importing an entire CSS file can be overkill for a single style, especially one that needs to change dynamically based on state. React supports inline styles through the style prop — but unlike standard HTML, where style takes a CSS string, React requires a JavaScript object instead.

A style object like const headerStyle = { backgroundColor: 'blue', fontSize: '24px' } gets passed directly as <h1 style={headerStyle}>, applying those declarations straight to the element.

āœ•
—
+
const headerStyle = {
  backgroundColor: 'blue',
  fontSize: '24px'
};

<h1 style={headerStyle}>Styled Header</h1>
localhost:3000

Inline Objects

JS replaces CSS strings

4camelCase Properties

Inside a React inline style object, every CSS property that normally contains a hyphen — like background-color or font-size — must be rewritten in camelCase, as backgroundColor and fontSize. This isn't a React-specific quirk; it's because hyphens aren't valid inside unquoted JavaScript object property names.

So style={{ backgroundColor: 'black', color: 'white' }} is correct, while style={{ background-color: 'black' }} is a syntax error — properties without hyphens, like color, stay exactly as they are in CSS.

āœ•
—
+
<div className={`box `}></div>
<p style={{ color: isError ? 'red' : 'black' }}>Status</p>
localhost:3000

camelCase Required

For all hyphenated properties.

5Double Curly Braces

Inline styles are often written with what looks like a special double-curly-brace syntax, like style={{ color: 'red' }} — but there's nothing magic about it. It's simply a JavaScript object literal placed inside a normal JSX interpolation.

The outer { } tells JSX "this is JavaScript, not a string," and the inner { } is the object literal itself, with color: 'red' as one of its properties — two separate, ordinary pieces of syntax that happen to sit next to each other.

āœ•
—
+
import './styles.css';

function App() {
  return <div className='main-app'>Content</div>;
}
localhost:3000

Double Braces {{ }}

Just an object inside an interpolation

6Dynamic Inline Styles

Inline styles are especially powerful because the style prop is just a JavaScript object, which means state variables and ternary operators can be used directly inside the style declaration — no separate CSS class needed.

Something like style={{ backgroundColor: isError ? 'red' : 'green', opacity: isFading ? 0.5 : 1 }} produces a UI element that reacts fluidly to state changes, recalculating its appearance on every render.

āœ•
—
+
import styles from './Button.module.css';

<button className={styles.primary}>Click Me</button>
localhost:3000

65% Complete

7Dynamic Class Names

Inline styles are best for highly specific, dynamic values, like an exact progress bar percentage — but for larger stylistic changes, dynamically toggling a className string is usually preferable to computing every property inline.

JavaScript template literals make this straightforward: something like className={btn ${isSelected ? 'btn-selected' : ''}} conditionally appends a class name based on a state variable, letting the actual visual rules live in CSS rather than inline JS objects.

āœ•
—
+
// Choose the right tool for the job
localhost:3000

8Global CSS Imports

For standard application-wide styling, a plain .css file can be imported directly at the top of a component file, like import './global.css'. This tells the bundler (Vite, Webpack, etc.) to include those styles in the final build.

The catch is that these class names are globally scoped by default — a class defined in one file's CSS can unintentionally collide with a same-named class used by an entirely different component elsewhere in the app.

āœ•
—
+
<h1>Styling: Mastered</h1>
localhost:3000

Global Scope

Can cause naming collisions

9CSS Modules

CSS Modules solve the global-collision problem directly. Naming a file with a .module.css extension, like Button.module.css, tells React's build tooling to automatically generate a unique, locally scoped class name for every class defined in that file.

Instead of a plain string, the file is imported as an object — import styles from './Button.module.css' — and referenced by property, as in <button className={styles.primary}>, guaranteeing that class can't accidentally clash with one from another component.

āœ•
—
+
import './global.css';
localhost:3000
.Card_container__3x8z1

10Mastery Achieved

Putting it together: className is the required replacement for class in JSX, inline style objects handle values that need to change dynamically based on state, and CSS Modules solve the naming-collision problem that plain global CSS imports create.

Choosing between them comes down to the situation — reach for className and CSS/CSS Modules for most static and reusable styling, and inline styles specifically for values computed at render time from component state.

āœ•
—
+
<h1>Design: Premium</h1>
localhost:3000

Design Aesthetics Mastered āœ“

11Step-by-Step Breakdown

Styling React. Welcome to React Styling. Building a React application is only half the battle; the other half is making it look incredible. In traditional HTML, you use the 'class' attribute and a separate CSS file. In React, because we are writing JSX (which compiles down to JavaScript), things work a bit differently. Today, we'll master the various techniques to style React applications, from basic class names to dynamic inline styles and scoped CSS modules.

The className Attribute. The most fundamental rule of React styling: NEVER use 'class'. 'class' is a reserved keyword in JavaScript (used for defining Object-Oriented classes). Because JSX is really just syntactic sugar for JavaScript functions, React requires you to use 'className' instead to avoid conflicts. Under the hood, React automatically translates 'className' back into a standard HTML 'class' attribute when it renders to the DOM.

Which attribute MUST you use in JSX to apply CSS classes to an element?

  • →class
  • →classList
  • →className

Inline Styles Overview. Sometimes, importing an entire CSS file is overkill for a single specific style, especially if that style needs to change dynamically based on state. React supports inline styles via the style prop. However, instead of passing a CSS string like in standard HTML, you must pass a JavaScript object.

camelCase Properties. When defining an inline style object in React, there is a critical rule: all CSS properties that contain a hyphen (like background-color or font-size) MUST be converted to camelCase (backgroundColor and fontSize). This is because hyphens are not valid in standard JavaScript object property names without quotes.

How should the CSS property margin-top be written inside a React inline style object?

  • →margin-top
  • →marginTop

Double Curly Braces. You will often see inline styles written with double curly braces, like style={{ color: 'red' }}. This isn't a special JSX syntax; it's simply an object literal placed inside an interpolation block. The outer braces { } tell JSX we are injecting JavaScript, and the inner braces { } define the actual JavaScript object.

Dynamic Inline Styles. The true power of inline styles lies in their ability to be dynamic. Because the style prop takes a JavaScript object, you can use state variables and ternary operators directly within the style declaration to create fluid, interactive UI elements without touching CSS classes.

If isPrimary is a state boolean, how would you dynamically set the color property using a ternary operator inside an inline style?

  • →{isPrimary ? 'blue' : 'gray'}
  • →isPrimary ? 'blue' : 'gray'

Dynamic Class Names. While inline styles are good for highly specific, dynamic values (like a progress bar percentage), you should prefer dynamic className strings for larger stylistic changes. You can use JavaScript template literals (backticks) to conditionally inject class names based on state variables.

Global CSS Imports. For standard application-wide styling, you can simply import a standard .css file directly at the top of your React component file. This signals to your bundler (like Vite or Webpack) to include those styles in the final build. However, note that these classes become globally scoped and can conflict with other components.

CSS Modules. To solve the problem of global CSS collisions, React supports CSS Modules out of the box. If you name your file ending in .module.css, React will locally scope all class names automatically. You import the styles as an object, and reference them as properties.

If you want a CSS file to be locally scoped to prevent naming conflicts, what file extension pattern should you use?

  • →local.css
  • →module.css

Mastery Achieved. Styling mastery achieved! You now know how to build beautiful, dynamic interfaces using React. You understand why className is required, how to write JS objects for inline styles, and when to use template literals or CSS Modules for complex visual logic.

Level Up šŸš€

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Visual State Shouldn't Be the Only Signal

When dynamic inline styles or conditional class names communicate state, such as a red border for an invalid form field, pair that visual change with a programmatic signal like `aria-invalid` so assistive technology conveys the same information.

2CSS Modules Don't Change Underlying Semantics

Locally scoped class names from CSS Modules only affect naming and specificity — the actual HTML elements still need proper semantic tags and ARIA attributes; scoping styles doesn't substitute for accessible markup.

SEO Implications

  • 1

    CSS Import Strategy Doesn't Directly Affect Crawlability

    Whether styles come from global CSS, CSS Modules, or inline style objects has no direct bearing on SEO — what matters for crawlers is the text content and semantic HTML structure that ends up in the rendered DOM, not how it's styled.

  • 2

    Avoid Layout Shift from Late-Loading Styles

    Global CSS files that load after initial content renders can cause visible layout shift, which search engines factor into page experience signals — CSS Modules and colocated styles tend to load more predictably alongside the components that need them.

Best Practices

Reserve Inline Styles for Values Computed at Render Time

Use the `style` prop for values that genuinely depend on component state or props, like a dynamic width percentage; for static or reusable styling, className with CSS or CSS Modules is easier to maintain.

Prefer CSS Modules Over Global CSS for Component-Specific Styles

Naming a file `Component.module.css` and importing it as an object avoids the class-name collisions that plain global `.css` imports are prone to as an application grows.

Frequent Bugs

THE BUG

An inline style silently fails to apply, or React throws a syntax error.

THE FIX

A hyphenated CSS property was written as-is instead of camelCase, e.g. `background-color` instead of `backgroundColor`. All hyphenated properties in a style object must use camelCase.

THE BUG

A class name defined in one component's CSS file unexpectedly styles an unrelated component.

THE FIX

The class was defined in a plain global `.css` file, where all class names share one global namespace. Rename the file to `Component.module.css` and import it as an object to get automatically scoped class names.

Real-World Examples

Dynamic Status Badge with Inline Styles

A status badge component reads a boolean from state to switch its background color and opacity on every render, using the style prop's ability to accept a plain JavaScript object computed from state.

function StatusBadge({ isError, isFading }) {
  return (
    <div style={{ backgroundColor: isError ? 'red' : 'green', opacity: isFading ? 0.5 : 1 }}>
      Status
    </div>
  );
}

Interview Prep

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Mutating State Directly

// Wrong const [user, setUser] = useState({ name: 'Alice' }); user.name = 'Bob'; // React won't re-render // Correct setUser({ ...user, name: 'Bob' });

The Solution //

Never mutate a state variable directly (e.g., state.count = 1). Always use the setter function provided by useState to ensure the component re-renders.

The Error //

Missing 'key' prop in lists

// Wrong {items.map(item => <li>{item.name}</li>)} // Correct {items.map(item => <li key={item.id}>{item.name}</li>)}

The Solution //

When rendering a list of elements using .map(), always provide a unique 'key' prop to the outermost element to help React identify which items have changed.

Continue Learning