Next.js does not force a styling approach on you - it supports several first-class options and makes each easy to set up. In this lesson you will learn the three most common approaches, when each one shines, and how to combine them cleanly in a single project.
Global styles apply everywhere and are imported exactly once, in the root layout:
/* app/globals.css */
:root {
--brand: #0070f3;
--max-width: 72rem;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.6;
}// app/layout.js
import './globals.css';Use global CSS for resets, CSS variables, base typography, and little else. If every component's styles are global, class name collisions become inevitable as the project grows - that is the problem CSS Modules solve.
Any file ending in .module.css is a CSS Module. Class names inside it are automatically made unique at build time, so styles can never leak between components:
/* app/components/Card.module.css */
.card {
border: 1px solid #e5e5e5;
border-radius: 8px;
padding: 1.25rem;
}
.title {
color: var(--brand);
font-size: 1.25rem;
}// app/components/Card.js
import styles from './Card.module.css';
export default function Card({ title, children }) {
return (
<div className={styles.card}>
<h2 className={styles.title}>{title}</h2>
{children}
</div>
);
}In the browser, styles.card becomes something like Card_card__x7Kd2 - unique per component. CSS Modules need zero dependencies, work in Server Components, and keep styles colocated with the component that owns them.
Tailwind takes the opposite approach: instead of writing CSS files, you compose small utility classes directly in JSX. create-next-app offers to configure it for you.
export default function Card({ title, children }) {
return (
<div className='rounded-lg border border-gray-200 p-5 shadow-sm'>
<h2 className='text-xl font-semibold text-blue-600'>{title}</h2>
<div className='mt-2 text-gray-700'>{children}</div>
</div>
);
}Why teams love it: no naming decisions, no dead CSS accumulating, consistent spacing and color scales, and responsive design with prefixes like md:flex. The trade-off is busier markup and a small learning curve for the class vocabulary. Unused classes are stripped at build time, so production CSS stays tiny.
These are not exclusive. A very common setup is Tailwind for most UI plus globals.css for design tokens, with the occasional CSS Module for something genuinely complex like an animation-heavy component.
Runtime CSS-in-JS libraries like styled-components require client-side JavaScript, which conflicts with Server Components - they only work in Client Components and need extra configuration. For new App Router projects, prefer CSS Modules or Tailwind; they are zero-runtime and work everywhere.
Next up: Lesson 11 covers two of Next.js's biggest performance wins - automatic image and font optimization.