内置对 CSS 的支持

示例

Next.js 允许你在 JavaScript 文件中导入(import) CSS 文件。 因为 Next.js 扩展了 JavaScript 中的 import 的概念,才能让这一功能成为可能。

添加全局样式表

要将样式表添加到您的应用程序中,请在 pages/_app.js 文件中导入(import)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 文件 (如果不存在的话)。 然后 importstyles.css 文件。

import '../styles.css'

// 新创建的 `pages/_app.js` 文件中必须有此默认的导出(export)函数
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

这些样式 (styles.css) 将应用于你的应用程序中的所有页面和组件。 由于样式表的全局特性,并且为了避免冲突,你应该 只在 pages/_app.js 文件中导入(import)样式表

在开发中,以这种方式表示样式可让你在编辑样式时对其进行热重载,这意味着你可以保持应用程序的状态。

在生产环境中,所有 CSS 文件将自动合并为一个经过精简的 .css 文件。

node_modules 目录导入(import)样式

从 Next.js 9.5.4 版本开始,你可以在应用程序中的任何位置从 node_modules 目录导入(import) CSS 文件了。

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

// pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

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

// components/ExampleDialog.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>
  )
}

添加组件级 CSS

Next.js 通过 [name].module.css 文件命名约定来支持 CSS 模块

CSS 模块通过自动创建唯一的类名从而将 CSS 限定在局部范围内。 这使您可以在不同文件中使用相同的 CSS 类名,而不必担心冲突。

此行为使 CSS 模块成为包含组件级 CSS 的理想方法。 CSS 模块文件 可以导入(import)到应用程序中的任何位置

例如,假设 components/ 目录下有一个可重用 Button 组件:

首先,创建 components/Button.module.css 文件并填入以下内容:

/*
You do not need to worry about .error {} colliding with any other `.css` or
`.module.css` files!
*/
.error {
  color: white;
  background-color: red;
}

然后,创建 components/Button.js 文件,导入(import)并使用上述 CSS 文件:

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

export function Button() {
  return (
    <button
      type="button"
      // Note how the "error" class is accessed as a property on the imported
      // `styles` object.
      className={styles.error}
    >
      Destroy
    </button>
  )
}

CSS 模块是一项 可选功能仅对带有 .module.css 扩展名的文件启用。 普通的 <link> 样式表和全部 CSS 文件仍然是被支持的。

在生产环境中,所有 CSS 模块文件将被自动合并为 多个经过精简和代码分割的 .css 文件。 这些 .css 文件代表应用程序中的热执行路径(hot execution paths),从而确保为应用程序绘制页面加载所需的最少的 CSS。

对 Sass 的支持

Next.js 允许你导入(import)具有 .scss.sass 扩展名的 Sass 文件。 你可以通过 CSS 模块以及 .module.scss.module.sass 扩展名来使用组件及的 Sass。

在使用 Next.js 的内置 Sass 支持前,请确保安装了 sass

npm install sass

对 Sass 的支持与上述内置 CSS 的支持具有相同的好处和限制。

注意: Sass 支持 两种不同的语法,每种语法都有自己的扩展名。 .scss 扩展名要求你使用 SCSS 语法, 而 .sass 扩展名要求你使用 缩进语法(即 "Sass").

如果你不确定选择哪个,请先选择 .scss 扩展名,因为该扩展名对应的语法是 CSS 的超集,无需专门学习 缩进语法 ("Sass")。

自定义 Sass 参数

如果要配置 Sass 编译器,可以使用 next.config.js 文件中的 sassOptions 参数进行配置。

例如,添加 includePaths

const path = require('path')

module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')],
  },
}

Sass Variables

Next.js supports Sass variables exported from CSS Module files.

For example, using the exported primaryColor Sass variable:

/* variables.module.scss */
$primary-color: #64FF00

:export {
  primaryColor: $primary-color
}
// pages/_app.js
import variables from '../styles/variables.module.scss'

export default function MyApp({ Component, pageProps }) {
  return (
    <Layout color={variables.primaryColor}>
      <Component {...pageProps} />
    </Layout>
  )
}

CSS-in-JS

示例

可以使用任何现有的 CSS-in-JS 解决方案。 最简单的一种是内联样式:

function HiThere() {
  return <p style={{ color: 'red' }}>hi there</p>
}

export default HiThere

我们引入了 styled-jsx 以支持作用域隔离(isolated scoped)的 CSS。 此目的是支持类似于 Web 组件的 “影子(shadow)CSS”,但不幸的是 不支持服务器端渲染且仅支持 JS

有关其他流行的 CSS-in-JS 解决方案(如样式化组件),请参见以上示例。

使用 styled-jsx 的组件就像这样:

function HelloWorld() {
  return (
    <div>
      Hello world
      <p>scoped!</p>
      <style jsx>{`
        p {
          color: blue;
        }
        div {
          background: red;
        }
        @media (max-width: 600px) {
          div {
            background: blue;
          }
        }
      `}</style>
      <style global jsx>{`
        body {
          background: black;
        }
      `}</style>
    </div>
  )
}

export default HelloWorld

请参阅 styled-jsx 文档 以获取更多示例。

常见问题

如果 JavaScript 被禁用,还能起作用吗?

使得,如果 JavaScript 被禁用,则 CSS 仍可以被加载到生产版本中(next start)。在开发过程中,我们要求启用 JavaScript,以便通过 快速刷新 来提供最佳的开发人员体验。

相关内容

以下是我们建议接下来需要学习的内容: