Menu

CSS Modules

示例

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

CSS Modules

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

CSS Modules 通过自动创建唯一的类名来实现 CSS 的局部作用域。这使得你可以在不同文件中使用相同的类名而不用担心冲突。这种特性使 CSS Modules 成为引入组件级 CSS 的理想方式。

示例

例如,考虑在 components/ 文件夹中的一个可重用 Button 组件:

首先,创建 components/Button.module.css 并添加以下内容:

Button.module.css
/*
你不需要担心 .error {} 会与其他 `.css` 或
`.module.css` 文件发生冲突!
*/
.error {
  color: white;
  background-color: red;
}

然后,创建 components/Button.js,导入并使用上面的 CSS 文件:

components/Button.js
import styles from './Button.module.css'
 
export function Button() {
  return (
    <button
      type="button"
      // 注意如何通过导入的 `styles` 对象的属性来访问 "error" 类
      className={styles.error}
    >
      销毁
    </button>
  )
}

CSS Modules 仅对扩展名为 .module.css.module.sass 的文件启用

在生产环境中,所有 CSS Module 文件会自动合并成多个经过代码分割和压缩的 .css 文件。这些 .css 文件代表了应用程序中的热执行路径,确保只加载应用程序渲染所需的最少 CSS。

全局样式

要将样式表添加到你的应用程序,请在 pages/_app.js 中导入 CSS 文件。

例如,考虑以下名为 styles.css 的样式表:

styles.css
body {
  font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
    'Arial', sans-serif;
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

如果还没有,创建一个 pages/_app.js 文件。 然后导入 styles.css 文件。

pages/_app.js
import '../styles.css'
 
// 在新的 `pages/_app.js` 文件中需要这个默认导出
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

这些样式(styles.css)会应用到应用程序中的所有页面和组件。 由于样式表的全局性质,为了避免冲突,你只能在 pages/_app.js 中导入它们

在开发环境中,以这种方式表达样式表允许你在编辑样式时热重载——这意味着你可以保持应用程序状态。

在生产环境中,所有 CSS 文件会自动合并成一个经过压缩的 .css 文件。CSS 的合并顺序将与 _app.js 文件中 CSS 的导入顺序相匹配。特别注意包含自己的 CSS 的导入 JS 模块;JS 模块的 CSS 将遵循与导入 CSS 文件相同的排序规则进行合并。例如:

import '../styles.css'
// ErrorBoundary 中的 CSS 依赖于 styles.css 中的全局 CSS,
// 所以我们在 styles.css 之后导入它。
import ErrorBoundary from '../components/ErrorBoundary'
 
export default function MyApp({ Component, pageProps }) {
  return (
    <ErrorBoundary>
      <Component {...pageProps} />
    </ErrorBoundary>
  )
}

外部样式表

Next.js 允许你从 JavaScript 文件中导入 CSS 文件。 这是可能的,因为 Next.js 扩展了 import 的概念超出了 JavaScript。

node_modules 导入样式

从 Next.js 9.5.4 开始,允许在应用程序的任何位置导入来自 node_modules 的 CSS 文件。

对于全局样式表,如 bootstrapnprogress,你应该在 pages/_app.js 中导入文件。 例如:

pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'
 
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

对于第三方组件所需的 CSS,你可以在你的组件中导入。例如:

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}>打开对话框</button>
      <Dialog isOpen={showDialog} onDismiss={close}>
        <button className="close-button" onClick={close}>
          <VisuallyHidden>关闭</VisuallyHidden>
          <span aria-hidden>×</span>
        </button>
        <p>你好。我是一个对话框</p>
      </Dialog>
    </div>
  )
}

其他功能

Next.js 包含额外的功能来改善添加样式的编写体验:

  • 在使用 next dev 本地运行时,本地样式表(全局或 CSS modules)将利用 Fast Refresh 在保存编辑时立即反映更改。
  • 在使用 next build 构建生产版本时,CSS 文件将被打包成更少的经过压缩的 .css 文件,以减少获取样式所需的网络请求数量。
  • 如果你禁用 JavaScript,样式仍然会在生产构建(next start)中加载。但是,next dev 需要 JavaScript 来启用 Fast Refresh