Files
Arian Tron 61f56f997c
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled
first commit
2026-03-10 19:37:31 +03:30

459 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: CSS
description: Learn about the different ways to add CSS to your application, including Tailwind CSS, CSS Modules, Global CSS, and more.
related:
title: Next Steps
description: Learn more about the alternatives ways you can use CSS in your application.
links:
- app/guides/tailwind-v3-css
- app/guides/sass
- app/guides/css-in-js
---
Next.js provides several ways to style your application using CSS, including:
- [Tailwind CSS](#tailwind-css)
- [CSS Modules](#css-modules)
- [Global CSS](#global-css)
- [External Stylesheets](#external-stylesheets)
- [Sass](/docs/app/guides/sass)
- [CSS-in-JS](/docs/app/guides/css-in-js)
## Tailwind CSS
[Tailwind CSS](https://tailwindcss.com/) is a utility-first CSS framework that provides low-level utility classes to build custom designs.
<AppOnly>
Install Tailwind CSS:
```bash package="pnpm"
pnpm add -D tailwindcss @tailwindcss/postcss
```
```bash package="npm"
npm install -D tailwindcss @tailwindcss/postcss
```
```bash package="yarn"
yarn add -D tailwindcss @tailwindcss/postcss
```
```bash package="bun"
bun add -D tailwindcss @tailwindcss/postcss
```
Add the PostCSS plugin to your `postcss.config.mjs` file:
```js filename="postcss.config.mjs"
export default {
plugins: {
'@tailwindcss/postcss': {},
},
}
```
Import Tailwind in your global CSS file:
```css filename="app/globals.css"
@import 'tailwindcss';
```
Import the CSS file in your root layout:
```tsx filename="app/layout.tsx" switcher
import './globals.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
```
```jsx filename="app/layout.js" switcher
import './globals.css'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
```
Now you can start using Tailwind's utility classes in your application:
```tsx filename="app/page.tsx" switcher
export default function Page() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1 className="text-4xl font-bold">Welcome to Next.js!</h1>
</main>
)
}
```
```jsx filename="app/page.js" switcher
export default function Page() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1 className="text-4xl font-bold">Welcome to Next.js!</h1>
</main>
)
}
```
</AppOnly>
<PagesOnly>
Install Tailwind CSS:
```bash package="pnpm"
pnpm add -D tailwindcss @tailwindcss/postcss
```
```bash package="npm"
npm install -D tailwindcss @tailwindcss/postcss
```
```bash package="yarn"
yarn add -D tailwindcss @tailwindcss/postcss
```
```bash package="bun"
bun add -D tailwindcss @tailwindcss/postcss
```
Add the PostCSS plugin to your `postcss.config.mjs` file:
```js filename="postcss.config.mjs"
export default {
plugins: {
'@tailwindcss/postcss': {},
},
}
```
Import Tailwind in your global CSS file:
```css filename="styles/globals.css"
@import 'tailwindcss';
```
Import the CSS file in your `pages/_app.js` file:
```jsx filename="pages/_app.js"
import '@/styles/globals.css'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
```
Now you can start using Tailwind's utility classes in your application:
```tsx filename="pages/index.tsx" switcher
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1 className="text-4xl font-bold">Welcome to Next.js!</h1>
</main>
)
}
```
```jsx filename="pages/index.js" switcher
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1 className="text-4xl font-bold">Welcome to Next.js!</h1>
</main>
)
}
```
</PagesOnly>
> **Good to know:** If you need broader browser support for very old browsers, see the [Tailwind CSS v3 setup instructions](/docs/app/guides/tailwind-v3-css).
## CSS Modules
CSS Modules locally scope CSS by generating unique class names. This allows you to use the same class in different files without worrying about naming collisions.
<AppOnly>
To start using CSS Modules, create a new file with the extension `.module.css` and import it into any component inside the `app` directory:
```css filename="app/blog/blog.module.css"
.blog {
padding: 24px;
}
```
```tsx filename="app/blog/page.tsx" switcher
import styles from './blog.module.css'
export default function Page() {
return <main className={styles.blog}></main>
}
```
```jsx filename="app/blog/page.js" switcher
import styles from './blog.module.css'
export default function Layout() {
return <main className={styles.blog}></main>
}
```
</AppOnly>
<PagesOnly>
To start using CSS Modules, create a new file with the extension `.module.css` and import it into any component inside the `pages` directory:
```css filename="/styles/blog.module.css"
.blog {
padding: 24px;
}
```
```tsx filename="pages/blog/index.tsx" switcher
import styles from './blog.module.css'
export default function Page() {
return <main className={styles.blog}></main>
}
```
```jsx filename="pages/blog/index.js" switcher
import styles from './blog.module.css'
export default function Page() {
return <main className={styles.blog}></main>
}
```
</PagesOnly>
## Global CSS
You can use global CSS to apply styles across your application.
<AppOnly>
Create a `app/global.css` file and import it in the root layout to apply the styles to **every route** in your application:
```css filename="app/global.css"
body {
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}
```
```tsx filename="app/layout.tsx" switcher
// These styles apply to every route in the application
import './global.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
```
```jsx filename="app/layout.js" switcher
// These styles apply to every route in the application
import './global.css'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
```
> **Good to know:** Global styles can be imported into any layout, page, or component inside the `app` directory. However, since Next.js uses React's built-in support for stylesheets to integrate with Suspense, this currently does not remove stylesheets as you navigate between routes which can lead to conflicts. We recommend using global styles for _truly_ global CSS (like Tailwind's base styles), [Tailwind CSS](#tailwind-css) for component styling, and [CSS Modules](#css-modules) for custom scoped CSS when needed.
</AppOnly>
<PagesOnly>
Import the stylesheet in the `pages/_app.js` file to apply the styles to **every route** in your application:
```tsx filename="pages/_app.js"
import '@/styles/global.css'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
```
Due to the global nature of stylesheets, and to avoid conflicts, you should import them inside [`pages/_app.js`](/docs/pages/building-your-application/routing/custom-app).
</PagesOnly>
## External stylesheets
<AppOnly>
Stylesheets published by external packages can be imported anywhere in the `app` directory, including colocated components:
```tsx filename="app/layout.tsx" switcher
import 'bootstrap/dist/css/bootstrap.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className="container">{children}</body>
</html>
)
}
```
```jsx filename="app/layout.js" switcher
import 'bootstrap/dist/css/bootstrap.css'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className="container">{children}</body>
</html>
)
}
```
> **Good to know:** In React 19, `<link rel="stylesheet" href="..." />` can also be used. See the [React `link` documentation](https://react.dev/reference/react-dom/components/link) for more information.
</AppOnly>
<PagesOnly>
Next.js allows you to import CSS files from a JavaScript file. This is possible because Next.js extends the concept of [`import`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import) beyond JavaScript.
### Import styles from `node_modules`
Since Next.js **9.5.4**, importing a CSS file from `node_modules` is permitted anywhere in your application.
For global stylesheets, like `bootstrap` or `nprogress`, you should import the file inside `pages/_app.js`. For example:
```jsx filename="pages/_app.js"
import 'bootstrap/dist/css/bootstrap.css'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
```
To import CSS required by a third-party component, you can do so in your component. For example:
```jsx filename="components/example-dialog.js"
import { useState } from 'react'
import { Dialog } from '@reach/dialog'
import VisuallyHidden from '@reach/visually-hidden'
import '@reach/dialog/styles.css'
function ExampleDialog(props) {
const [showDialog, setShowDialog] = useState(false)
const open = () => setShowDialog(true)
const close = () => setShowDialog(false)
return (
<div>
<button onClick={open}>Open Dialog</button>
<Dialog isOpen={showDialog} onDismiss={close}>
<button className="close-button" onClick={close}>
<VisuallyHidden>Close</VisuallyHidden>
<span aria-hidden>×</span>
</button>
<p>Hello there. I am a dialog</p>
</Dialog>
</div>
)
}
```
</PagesOnly>
## Ordering and Merging
Next.js optimizes CSS during production builds by automatically chunking (merging) stylesheets. The **order of your CSS** depends on the **order you import styles in your code**.
For example, `base-button.module.css` will be ordered before `page.module.css` since `<BaseButton>` is imported before `page.module.css`:
```tsx filename="page.tsx" switcher
import { BaseButton } from './base-button'
import styles from './page.module.css'
export default function Page() {
return <BaseButton className={styles.primary} />
}
```
```jsx filename="page.js" switcher
import { BaseButton } from './base-button'
import styles from './page.module.css'
export default function Page() {
return <BaseButton className={styles.primary} />
}
```
```tsx filename="base-button.tsx" switcher
import styles from './base-button.module.css'
export function BaseButton() {
return <button className={styles.primary} />
}
```
```jsx filename="base-button.js" switcher
import styles from './base-button.module.css'
export function BaseButton() {
return <button className={styles.primary} />
}
```
### Recommendations
To keep CSS ordering predictable:
- Try to contain CSS imports to a single JavaScript or TypeScript entry file
- Import global styles and Tailwind stylesheets in the root of your application.
- **Use Tailwind CSS** for most styling needs as it covers common design patterns with utility classes.
- Use CSS Modules for component-specific styles when Tailwind utilities aren't sufficient.
- Use a consistent naming convention for your CSS modules. For example, using `<name>.module.css` over `<name>.tsx`.
- Extract shared styles into shared components to avoid duplicate imports.
- Turn off linters or formatters that auto-sort imports like ESLints [`sort-imports`](https://eslint.org/docs/latest/rules/sort-imports).
- You can use the [`cssChunking`](/docs/app/api-reference/config/next-config-js/cssChunking) option in `next.config.js` to control how CSS is chunked.
## Development vs Production
- In development (`next dev`), CSS updates apply instantly with [Fast Refresh](/docs/architecture/fast-refresh).
- In production (`next build`), all CSS files are automatically concatenated into **many minified and code-split** `.css` files, ensuring the minimal amount of CSS is loaded for a route.
- CSS still loads with JavaScript disabled in production, but JavaScript is required in development for Fast Refresh.
- CSS ordering can behave differently in development, always ensure to check the build (`next build`) to verify the final CSS order.