Skip to main content

CSS

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

CSS Modules

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

CSS 模块通过自动创建唯一的类名来局部作用域 CSS。这允许您在不同文件中使用相同的类名而无需担心冲突。这种行为使 CSS 模块成为包含组件级 CSS 的理想方式。

例子

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

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 模块文件将自动连接成 多个压缩和代码拆分.css文件。 这些.css文件代表了应用程序中的热执行路径,确保加载最少量的 CSS 以便应用程序进行渲染。

Global Styles

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

您需要知道:

  • 这与pages目录不同,在pages目录中,您只能在_app.js文件中导入全局样式。
  • Next.js 不支持使用全局样式,除非它们是真正的全局样式,意味着它们可以应用于所有页面并在应用程序的生命周期内存在。这是因为 Next.js 使用 React 内置的样式表支持与 Suspense 集成。目前,这种内置支持在您在路由之间导航时不会移除样式表。因此,我们建议使用 CSS 模块而不是全局样式。

例如,请思考一个名为app/global.css的样式表:

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

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

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

外部样式表

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

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" />

排序和合并

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

例如, 由于<BaseButton><Page>中首先被导入,因此base-button.module.css 的顺序将排在page.module.css之前:

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

为了保持可预测的顺序,我们建议如下:

  • 仅在单个 JS/TS 文件中导入一个 CSS 文件。
    • 如果使用全局类名,请在同一个文件中按希望应用的顺序导入全局样式。
  • 优先使用 CSS 模块而不是全局样式。
    • 为您的 CSS 模块使用一致的命名约定。例如,使用<name>.module.css 而不是 <name>.tsx
  • 将共享样式提取到一个单独的共享组件中。
  • 如果使用Tailwind, 请在文件顶层导入样式表, 最好在 根布局 中。
  • 关闭任何自动排序导入 linters/formatters (例如, ESLint 的 sort-import)。这可能会无意中影响您的 CSS,因为 CSS 导入顺序很重要。

您需要知道:

  • CSS 排序在开发模式下的行为可能会有所不同,请务必检查构建(next build)以验证最终的 CSS 顺序。
  • 您可以在next.config.js中使用cssChunking选项来控制 CSS 的分块方式。

附加功能

Next.js 包含附加功能,以改善添加样式的编写体验:

  • 当使用next dev本地运行时, 本地样式表(无论是全局样式还是 CSS 模块) 将利用快速刷新功能,在保存编辑时立即反映更改。
  • 在使用next build构建生产环境时,CSS 文件将被打包成更少的压缩.css文件,以减少检索样式所需的网络请求数量。
  • 如果禁用了 JavaScript,样式仍将在生产构建中加载。(next start).然而,next dev仍然需要 JavaScript 来启用快速刷新