Styling: global CSS, CSS Modules and Tailwind

Next.js · Essentials · 9 min

Every app needs styles, and Next.js supports several approaches with specific rules about where they can be imported.

Next.js supports several styling approaches out of the box.

Tailwind CSS is set up by default in new projects. Tailwind v4 needs only @import "tailwindcss"; in app/globals.css (plus the @tailwindcss/postcss PostCSS plugin the template configures). Then use utility classes: className="flex gap-4 p-6 text-lg".

Global CSS: import a stylesheet in the root layout (import './globals.css'). Global styles apply to every route; keep them for resets, base typography and CSS variables. You can import global CSS from any component, but it still applies everywhere, so prefer the root layout.

CSS Modules: files named *.module.css are locally scoped. Import them as an object and use the generated class names: import styles from './card.module.css' then className={styles.card}. Class names are hashed, so they never collide across components. Sass is supported with the sass package (.module.scss).

CSS-in-JS libraries that need runtime JavaScript work only in Client Components and need extra setup; zero-runtime options and Tailwind fit Server Components best.

In production, CSS is automatically bundled, minified and code-split per route. Be aware that the order of CSS imports determines precedence when two rules conflict.

Example

/* app/globals.css */
@import "tailwindcss";

:root { --brand: #111111; }

/* app/ui/card.module.css */
.card { border: 1px solid #ddd; border-radius: 8px; padding: 1rem; }
.title { color: var(--brand); }

// app/ui/card.tsx
import styles from './card.module.css'

export function Card({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div className={styles.card}>                       {/* class="card_card__x7Yz" */}
      <h2 className={`${styles.title} text-xl font-bold`}>{title}</h2>   {/* + Tailwind */}
      {children}
    </div>
  )
}

// app/layout.tsx:  import './globals.css'   (global styles, once, in the root layout)

Remember

  • Tailwind is the default; v4 needs only @import "tailwindcss" in globals.css
  • Import global CSS in the root layout; it applies to all routes
  • *.module.css gives locally scoped, hashed class names

Watch out for

  • Expecting a CSS Module class to apply when written as a plain string (className="card"); use styles.card.

Check yourself

  1. What does importing styles from './button.module.css' give you?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: nextjs.org/docs/app/getting-started/css