Styling in React
Styling in React means applying CSS through the className attribute, the style prop's camelCase object, or scoped CSS Modules . You combine classes conditionally with template strings or a small classnames helper, choosing inline styles only for values that must be computed at runtime.
Learn Styling in React in our free React course — an interactive lesson with runnable examples, a practice exercise and a quick recall.
Part of the free React course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
1️⃣ className vs class & Inline Style Objects
Apply CSS classes with className (since class is reserved in JavaScript). The style prop takes a JavaScript object , so properties are camelCase ( backgroundColor , not background-color ) and values are usually strings like "16px" .
2️⃣ CSS Modules & Conditional Classes
CSS Modules scope class names to a single file: you import styles from a .module.css file and reference styles.button , which the build tool turns into a unique hashed name so it never collides. To toggle classes by state, build the string with a template literal or a tiny classnames -style helper that drops falsy parts.
Your turn — camelCase a property and toggle a class:
3️⃣ Choosing an Approach (and Utility CSS)
Default to classes — whether CSS Modules or a utility framework — because they cache well and support pseudo-classes ( :hover ) and media queries that inline styles cannot. Reserve inline styles for genuinely dynamic values you compute at runtime, like a progress bar width from state. Utility CSS (small single-purpose classes) shines when you want to style directly in markup without writing new CSS files.
These lines build a button that applies a CSS-Module class conditionally. Put them in the right order:
📋 Quick Reference
1. How do you write background-color in a style object?
Global class-name collisions, by scoping each class to one file with a unique hashed name.
For dynamic, runtime-computed values like a width from state — not for static, reusable looks.
Write one helper that assembles a button's class string from a variant, an optional size, and a disabled flag, dropping anything falsy. Run it and check your output.
Practice quiz
Which attribute applies a CSS class to a JSX element?
- class
- cssClass
- className
- styleName
Answer: className. JSX uses className because class is a reserved word in JavaScript. It sets the element's class attribute under the hood.
How do you write background-color in a React inline style object?
- { backgroundColor: "red" }
- { "background-color": "red" }
- { background_color: "red" }
- { BackgroundColor: "red" }
Answer: { backgroundColor: "red" }. The style prop takes a JS object, so properties are camelCase: backgroundColor, not background-color.
What value does the style prop expect?
- A CSS string like "color: red"
- The name of a CSS class
- A URL to a stylesheet
- A JavaScript object, e.g. style={{ fontSize: "16px" }}
Answer: A JavaScript object, e.g. style={{ fontSize: "16px" }}. style takes an object. Note the double braces: the outer is the JSX expression, the inner is the object literal.
What problem do CSS Modules solve?
- They make CSS load faster
- They scope class names to one file so names never collide globally
- They convert CSS to inline styles
- They add vendor prefixes automatically
Answer: They scope class names to one file so names never collide globally. Importing styles from a .module.css file turns styles.button into a unique hashed name at build time, preventing global collisions.
When are inline styles the right choice over a class?
- For genuinely dynamic, runtime-computed values like a width from state
- For every element, to be safe
- For static, reusable looks
- For hover and focus states
Answer: For genuinely dynamic, runtime-computed values like a width from state. Reserve inline styles for computed values (e.g. a progress bar width). Classes cache and support pseudo-classes and media queries that inline styles can't.
Why can't inline styles express :hover or media queries?
- React strips them out
- They require a build step
- Inline styles apply directly to one element and can't represent pseudo-classes or media-query rules
- They only work in production
Answer: Inline styles apply directly to one element and can't represent pseudo-classes or media-query rules. Pseudo-states and breakpoints are CSS rules, which inline styles simply lack. Use classes for hover, focus, and responsive styling.
What does a classnames-style helper like [a, on && b].filter(Boolean).join(" ") do?
- Sorts the class names alphabetically
- Drops falsy parts and joins the truthy class names into one string
- Validates that each class exists in CSS
- Converts kebab-case to camelCase
Answer: Drops falsy parts and joins the truthy class names into one string. filter(Boolean) removes false/null/undefined/empty entries, and join(" ") combines what's left into a space-separated className string.
What's wrong with style="color: red" in JSX?
- Nothing, it's valid
- color must be camelCase
- It should be className
- style needs an object, not a string: style={{ color: "red" }}
Answer: style needs an object, not a string: style={{ color: "red" }}. The style prop in JSX takes an object literal, not a CSS string. Single braces with a string is invalid.
How do you reference a scoped class from a CSS Module named Button.module.css?
- className="btn"
- className={styles.btn} after importing styles from the module
- className={"Button.module.css btn"}
- style={styles.btn}
Answer: className={styles.btn} after importing styles from the module. You import styles from "./Button.module.css" and use className={styles.btn}, which resolves to the unique hashed class name.
Why default to classes rather than inline styles for most styling?
- Classes are required by React
- Inline styles are deprecated
- Classes cache well and support pseudo-classes and media queries that inline styles cannot
- Classes render faster on the server
Answer: Classes cache well and support pseudo-classes and media queries that inline styles cannot. Classes (CSS Modules or utility CSS) are cacheable and support :hover and media queries, so they're the sensible default; inline styles are for dynamic values.