DEV Community

Vu Le
Vu Le

Posted on

How CSS-in-JS Works and Why It Matters

🧐 What Is CSS-in-JS?

CSS-in-JS is a styling approach where CSS is written within JavaScript files—often directly inside React components—using libraries like styled-components or Emotion.

Instead of maintaining separate .css files, CSS-in-JS lets you co-locate styles with the components they affect. This improves maintainability, enables powerful tooling (like theming and dynamic styles), and avoids common problems like global namespace collisions.

⚙️ How CSS-in-JS Works Under the Hood

Libraries like styled-components and @emotion/styled turn your style definitions into actual CSS rules injected into the document's <head> at runtime.

Here's what happens:

  1. You Define a Styled Component

import styled from 'styled-components';

const Button = styled.button`
  background: blue;
  color: white;
  padding: 10px;
`;
Enter fullscreen mode Exit fullscreen mode
  1. The Library Generates a Unique Class Name

At build or runtime, the library:

Parses your template literal

Hashes the content to generate a unique class name (e.g., .sc-a1234)

Injects a CSS rule like:

.sc-a1234 {
  background: blue;
  color: white;
  padding: 10px;
}

Enter fullscreen mode Exit fullscreen mode
  1. The Component Renders with That Class

Click me

You never have to manage the class name yourself—the library abstracts that for you.

⚡ Dynamic Styles

You can create styles that react to props or themes:

const Button = styled.button`
  background: ${(props) => props.primary ? 'blue' : 'gray'};
`;
Enter fullscreen mode Exit fullscreen mode

On render, the library evaluates the JavaScript expression, injects a new rule with a unique hash, and updates the DOM.

📚 Theming Support

Libraries like styled-components and emotion support theming out of the box. You define a theme object and wrap your app in a provider:

<ThemeProvider theme={{ primaryColor: 'tomato' }}>
  <App />
</ThemeProvider>
Enter fullscreen mode Exit fullscreen mode

Then access theme values in styles:

const Title = styled.h1`
  color: ${(props) => props.theme.primaryColor};
`;
Enter fullscreen mode Exit fullscreen mode

This enables centralized design tokens (e.g., colors, spacing, breakpoints) across your app.

✅ Benefits

  • Scoped styles by default (no global leakage)
  • Dynamic styling using JS expressions
  • Code co-location (styles + logic together)
  • Theme-aware styling
  • Removes need for class naming conventions (e.g., BEM)

🚫 Trade-Offs

  • Adds runtime overhead (unless extracted at build time)
  • Debugging can be harder (though devtools have improved)
  • Requires tooling/bundler support (e.g., Babel plugin for styled-components)

🧪 Popular CSS-in-JS Libraries

Library Notes
styled-components Most popular; good developer experience
@emotion/styled Similar API, faster runtime
vanilla-extract Type-safe, zero-runtime CSS-in-JS
Stitches Modern alternative with build-time extraction

🧵 When to Use It

CSS-in-JS shines in:

  • Component-based architectures (e.g., React)
  • Design systems with theme support
  • Projects where dynamic styles or runtime customization are key

It may be overkill for:

  • Static websites
  • Projects where global styles or traditional CSS files are sufficient

💡 Summary

CSS-in-JS moves styles into JavaScript for better modularity, dynamic capabilities, and maintainability in modern web apps. Tools like styled-components and emotion streamline the process of defining, scoping, and applying styles while unlocking features like theming and prop-based styling.

It's a powerful paradigm—but like all tools, it's best used where its benefits align with your project's needs.

Top comments (0)