Skip to main content

CSS

Next.js 支持多种处理 CSS 的方式,包括:

¥Next.js supports multiple ways of handling CSS, including:

CSS 模块

¥CSS Modules

Next.js 使用 .module.css 扩展内置了对 CSS 模块的支持。

¥Next.js has built-in support for CSS Modules using the .module.css extension.

CSS 模块通过自动创建唯一的类名来本地化 CSS。这允许你在不同的文件中使用相同的类名,而不必担心冲突。这种行为使得 CSS 模块成为包含组件级 CSS 的理想方式。

¥CSS Modules locally scope CSS by automatically creating a unique class name. This allows you to use the same class name in different files without worrying about collisions. This behavior makes CSS Modules the ideal way to include component-level CSS.

示例

¥Example

CSS 模块可以导入到 app 目录内的任何文件中:

¥CSS Modules can be imported into any file inside the app directory:

import styles from './styles.module.css'

export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section className={styles.dashboard}>{children}</section>
}
import styles from './styles.module.css'

export default function DashboardLayout({ children }) {
return <section className={styles.dashboard}>{children}</section>
}
.dashboard {
padding: 24px;
}

CSS 模块仅适用于具有 .module.css.module.sass 扩展名的文件。

¥CSS Modules are only enabled for files with the .module.css and .module.sass extensions.

在生产中,所有 CSS 模块文件将自动连接成许多缩小和代码分割的 .css 文件。这些 .css 文件代表应用中的热执行路径,确保加载最少量的 CSS 供应用绘制。

¥In production, all CSS Module files will be automatically concatenated into many minified and code-split .css files. These .css files represent hot execution paths in your application, ensuring the minimal amount of CSS is loaded for your application to paint.

全局样式

¥Global Styles

全局样式可以导入到 app 目录内的任何布局、页面或组件中。

¥Global styles can be imported into any layout, page, or component inside the app directory.

很高兴知道:

¥Good to know:

  • 这与 pages 目录不同,在 pages 目录中只能导入 _app.js 文件内的全局样式。

    ¥This is different from the pages directory, where you can only import global styles inside the _app.js file.

  • Next.js 不支持使用全局样式,除非它们实际上是全局的,这意味着它们可以应用于所有页面并且可以在应用的整个生命周期内存在。这是因为 Next.js 使用 React 对样式表的内置支持来与 Suspense 集成。此内置支持目前不会在你在路由之间导航时删除样式表。因此,我们建议使用 CSS 模块而不是全局样式。

    ¥Next.js does not support usage of global styles unless they are actually global, meaning they can apply to all pages and can live for the lifetime of the application. This is because Next.js uses React's built-in support for stylesheets to integrate with Suspense. This built-in support currently does not remove stylesheets as you navigate between routes. Because of this, we recommend using CSS Modules over global styles.

例如,考虑名为 app/global.css 的样式表:

¥For example, consider a stylesheet named app/global.css:

body {
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}

在根布局 (app/layout.js) 内,导入 global.css 样式表以将样式应用到应用中的每个路由:

¥Inside the root layout (app/layout.js), import the global.css stylesheet to apply the styles to every route in your application:

// 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>
)
}
// 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>
)
}

外部样式表

¥External Stylesheets

外部包发布的样式表可以导入到 app 目录中的任何位置,包括共置组件:

¥Stylesheets published by external packages can be imported anywhere in the app directory, including colocated components:

import 'bootstrap/dist/css/bootstrap.css'

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className="container">{children}</body>
</html>
)
}
import 'bootstrap/dist/css/bootstrap.css'

export default function RootLayout({ children }) {
return (
<html lang="en">
<body className="container">{children}</body>
</html>
)
}

很高兴知道:外部样式表必须直接从 npm 包导入或下载并与你的代码库放在一起。你不能使用 <link rel="stylesheet" />

¥Good to know: External stylesheets must be directly imported from an npm package or downloaded and colocated with your codebase. You cannot use <link rel="stylesheet" />.

排序和合并

¥Ordering and Merging

Next.js 通过自动分块(合并)样式表来在生产构建期间优化 CSS。CSS 顺序由你将样式表导入应用代码的顺序决定。

¥Next.js optimizes CSS during production builds by automatically chunking (merging) stylesheets. The CSS order is determined by the order in which you import the stylesheets into your application code.

例如,base-button.module.css 将在 page.module.css 之前排序,因为 <BaseButton><Page> 中首先导入:

¥For example, base-button.module.css will be ordered before page.module.css since <BaseButton> is imported first in <Page>:

import styles from './base-button.module.css'

export function BaseButton() {
return <button className={styles.primary} />
}
import styles from './base-button.module.css'

export function BaseButton() {
return <button className={styles.primary} />
}
import { BaseButton } from './base-button'
import styles from './page.module.css'

export function Page() {
return <BaseButton className={styles.primary} />
}
import { BaseButton } from './base-button'
import styles from './page.module.css'

export function Page() {
return <BaseButton className={styles.primary} />
}

为了维持可预测的订单,我们建议如下:

¥To maintain a predictable order, we recommend the following:

  • 仅在单个 JS/TS 文件中导入 CSS 文件。

    ¥Only import a CSS file in a single JS/TS file.

    • 如果使用全局类名,请按照你希望应用的顺序将全局样式导入同一文件中。

      ¥If using global class names, import the global styles in the same file in the order you want them to be applied.

  • 与全局样式相比,更喜欢 CSS 模块。

    ¥Prefer CSS Modules over global styles.

    • 为 CSS 模块使用一致的命名约定。例如,使用 <name>.module.css 而不是 <name>.tsx

      ¥Use a consistent naming convention for your CSS modules. For example, using <name>.module.css over <name>.tsx.

  • 将共享样式提取到单独的共享组件中。

    ¥Extract shared styles into a separate shared component.

  • 如果使用 Tailwind,请在文件顶部导入样式表,最好在 根布局 中。

    ¥If using Tailwind, import the stylesheet at the top of the file, preferably in the Root Layout.

  • 关闭任何自动对导入进行排序的 linters/formatters(例如,ESLint 的 sort-import)。这可能会无意中影响你的 CSS,因为 CSS 导入顺序很重要。

    ¥Turn off any linters/formatters (e.g., ESLint's sort-import) that automatically sort your imports. This can inadvertently affect your CSS since CSS import order matters.

很高兴知道:

¥Good to know:

  • CSS 排序在开发模式下可能会有所不同,请始终确保检查构建(next build)以验证最终的 CSS 顺序。

    ¥CSS ordering can behave differently in development mode, always ensure to check the build (next build) to verify the final CSS order.

  • 你可以使用 next.config.js 中的 cssChunking 选项来控制 CSS 的分块方式。

    ¥You can use the cssChunking option in next.config.js to control how CSS is chunked.

附加功能

¥Additional Features

Next.js 包含其他功能来改善添加样式的创作体验:

¥Next.js includes additional features to improve the authoring experience of adding styles:

  • 当使用 next dev 在本地运行时,本地样式表(全局或 CSS 模块)将利用 快速刷新 在保存编辑时立即反映更改。

    ¥When running locally with next dev, local stylesheets (either global or CSS modules) will take advantage of Fast Refresh to instantly reflect changes as edits are saved.

  • 当使用 next build 进行生产构建时,CSS 文件将被打包到更少的缩小的 .css 文件中,以减少检索样式所需的网络请求数量。

    ¥When building for production with next build, CSS files will be bundled into fewer minified .css files to reduce the number of network requests needed to retrieve styles.

  • 如果禁用 JavaScript,样式仍将在生产版本 (next start) 中加载。然而,next dev 仍需要 JavaScript 来启用 快速刷新

    ¥If you disable JavaScript, styles will still be loaded in the production build (next start). However, JavaScript is still required for next dev to enable Fast Refresh.