css styling solutions
1. Inline Styles
Directly apply styles to elements
React style attribute.
2. CSS Classes
React can use regular CSS files for styling, applying class names via the className attribute.
3. CSS Modules
React supports CSS Modules, which scope styles locally to a component. This avoids class name collisions and is especially useful in larger applications.
/* App.module.css */
.container {
background-color: lightblue;
padding: 20px;
text-align: center;
}
.title {
color: darkblue;
}
import styles from './App.module.css';
function App() {
return (
<div className={styles.container}>
<h1 className={styles.title}>Hello, World!</h1>
</div>
);
}
4. Styled JSX (Next.js only)
If you’re using Next.js, it has built-in support for Styled JSX, a scoped styling solution that lets you write CSS directly inside your components.
function App() {
return (
<div>
<h1>Hello, World!</h1>
<style jsx>{`
div {
background-color: lightblue;
padding: 20px;
text-align: center;
}
h1 {
color: darkblue;
}
`}</style>
</div>
);
}
export default App;
5. Global CSS
You can include a global CSS file (via <link> or imports) and apply styles globally across your React app.
Comparison Chart
| Category | Scope | Dynamic | Theming | Global Effects | Examples |
|---|---|---|---|---|---|
| Inline Styles | Element-specific | Yes | No | No | style={{}} |
| CSS Classes | Global | No | No | Yes | className="btn" |
| CSS Modules | Local to components | No | No | No | .btn {} |
| CSS-in-JS | Scoped to components | Yes | Yes | No | Styled Components |
| Utility-First CSS | Global | No | No | Yes | Tailwind CSS, Bootstrap |
| Component Framework | Scoped to components | Yes | Yes | No | Material-UI, Chakra |
| Preprocessors | Global | No | Limited | Yes | SASS, LESS |
| Inline Framework | Scoped to components | Yes | Yes | No | MUI’s sx prop |
| Global CSS | Global | No | No | Yes | index.css |
Tailwind and Stylex use atomic css: at compile time they create CSS classes with a single property, this makes them the most reusable, the CSS is able to be served statically (no JS required) and it's size eventually plateaus at some point. The names of these classes are hashes or seemingly random.