CSS
Next.js 支持多种处理 CSS 的方式,包括:
CSS Modules
Next.js 内置支持使用 .module.css
扩展名的 CSS Modules。
CSS Modules 通过自动创建唯一的类名来本地化 CSS 作用域。这允许你在不同文件中使用相同的类名而不必担心冲突。这种特性使 CSS Modules 成为包含组件级 CSS 的理想方式。
示例
例如,考虑 components/
文件夹中的一个可重用 Button
组件:
首先,创建 components/Button.module.css
文件,内容如下:
/*
你不需要担心 .error {} 会与任何其他 `.css` 或
`.module.css` 文件冲突!
*/
.error {
color: white;
background-color: red;
}
然后,创建 components/Button.js
,导入并使用上述 CSS 文件:
import styles from './Button.module.css'
export function Button() {
return (
<button
type="button"
// 注意 "error" 类是如何作为导入的 `styles` 对象的属性被访问的
className={styles.error}
>
Destroy
</button>
)
}
CSS Modules 仅对带有 .module.css
和 .module.sass
扩展名的文件启用。
在生产环境中,所有 CSS Module 文件将自动连接成多个经过代码分割的压缩 .css
文件。
这些 .css
文件代表了应用程序中的热执行路径,确保为应用程序加载最少量的 CSS 以进行渲染。
全局样式
要向你的应用程序添加样式表,请在 pages/_app.js
中导入 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
文件。
import '../styles.css'
// 在新的 `pages/_app.js` 文件中需要这个默认导出
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
这些样式(styles.css
)将应用于你应用程序中的所有页面和组件。
由于样式表的全局性质,以及为了避免冲突,你只能在 pages/_app.js
中导入它们。
在开发过程中,以这种方式表达样式表可以让你的样式在编辑时热重载——这意味着你可以保持应用程序状态。
在生产环境中,所有 CSS 文件将自动连接成一个压缩的 .css
文件。CSS 连接的顺序将与 CSS 导入到 _app.js
文件的顺序相匹配。特别注意包含自己 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 文件。
对于全局样式表,如 bootstrap
或 nprogress
,你应该在 pages/_app.js
中导入文件。
例如:
import 'bootstrap/dist/css/bootstrap.css'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
对于导入第三方组件所需的 CSS,你可以在你的组件中这样做。例如:
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>
)
}
其他功能
Next.js 包含额外功能以改善添加样式的创作体验:
- 当使用
next dev
本地运行时,本地样式表(全局或 CSS 模块)将利用 Fast Refresh 在保存编辑时立即反映更改。 - 当使用
next build
构建生产版本时,CSS 文件将被打包成更少的压缩.css
文件,以减少获取样式所需的网络请求数量。 - 如果你禁用 JavaScript,样式仍然会在生产构建(
next start
)中加载。但是,next dev
仍然需要 JavaScript 来启用 Fast Refresh。