CSS-in-JS Approaches
In this page:
The Simplest Form: Inline style Objects
React's built-in style prop accepts a plain JavaScript object, with property names in camelCase instead of CSS's kebab-case (backgroundColor instead of background-color). This is the most basic form of CSS-in-JS, needing no extra library at all.
Note: Define the style object as a separate variable (or outside the component) for anything beyond a couple of properties, to keep JSX readable.
Warning: Inline styles via the style prop can't express hover states, media queries, or pseudo-elements — for those, you need a real CSS-in-JS library.
Example: The Simplest Form: Inline style Objects
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function App() {
const boxStyle = { padding: "16px", backgroundColor: "lightblue", borderRadius: "8px" };
return <div style={boxStyle}>Styled with an inline object</div>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
Dynamic Inline Styles Based on Props
Because the style object is just JavaScript, its values can be computed dynamically from props or state, letting a component's appearance change based on data, without needing separate CSS classes for every possible variation.
Note: This is a quick way to handle a small number of dynamic values (like a progress bar's width) without pulling in a full CSS-in-JS library.
Warning: For many conditional style variations, a growing pile of ternaries inside a style object becomes hard to read — consider className-based approaches instead at that point.
Example: Dynamic Inline Styles Based on Props
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function ProgressBar({ percent }) {
return (
<div style={{ width: "200px", background: "#eee" }}>
<div style={{ width: percent + "%", background: "green", height: "10px" }} />
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<ProgressBar percent={60} />);
</script>
</body>
</html>
When to Reach for a Full CSS-in-JS Library
Inline style objects are fine for small, simple cases, but they can't express hover/focus states, animations, or media queries. Libraries like styled-components or Emotion fill this gap, offering real CSS syntax (including pseudo-selectors) while still keeping styles colocated with components.
Note: If you find yourself wanting ':hover' or '@media' inside a style prop and hitting a wall, that's the signal to reach for a dedicated library.
Warning: Adding a whole CSS-in-JS library just for one hover effect might be overkill — plain CSS or CSS Modules can also express hover states without extra dependencies.
Example: When to Reach for a Full CSS-in-JS Library
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
// Inline style objects CAN'T do this:
// '&:hover': { background: 'darkblue' } -- not supported by the style prop
// Libraries like styled-components CAN:
// const Btn = styled.button`&:hover { background: darkblue; }`;
function App() {
return <p>See react-styled-components for the full hover-capable example.</p>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>
- Assuming CSS-in-JS means only styled-components — it's a broader category including inline style objects, styled-components, Emotion, and others.
- Using camelCase incorrectly in plain inline style objects (it's backgroundColor, not background-color).
- Not realizing inline style objects (React's built-in style prop) can't express hover/media-query states, unlike full CSS-in-JS libraries.
- CSS-in-JS describes several approaches to writing styles as JavaScript, colocated with components.
- The simplest form is React's built-in style prop, taking a plain JS object with camelCased properties.
- Full libraries like styled-components or Emotion add support for pseudo-selectors, theming, and more.
- The right choice depends on project needs — inline styles for simple one-offs, a library for a whole design system.
React's inline style prop needs no install; libraries like styled-components/Emotion require npm install.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: