Next.js 支持不同的应用程序样式设计方法,包括:
Next.js 内置支持使用 .module.css
扩展名的 CSS 模块。
CSS 模块通过自动创建唯一的类名来本地化 CSS 范围。这样,你就可以在不同的文件中使用相同的类名,而不必担心冲突。这种行为使 CSS 模块成为包含组件级 CSS 的理想方式。
CSS 模块可以导入 app
目录下的任何文件:
// app/dashboard/layout.tsx
import styles from './styles.module.css'
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return {children}
}
// app/dashboard/styles.module.css
.dashboard {
padding: 24px;
}
CSS 模块是一项可选功能,仅适用于扩展名为 .module.css
的文件。仍支持常规 样式表和全局 CSS 文件。
在生产过程中,所有 CSS 模块文件都将自动串联成许多经过精简和代码拆分的 .css
文件。这些 .css
文件代表应用程序中的热执行路径,可确保加载的 CSS 量最少,以便应用程序绘制。
全局样式可导入 app
目录中的任何布局、页面或组件。
需要知道:这与
pages
目录不同,后者只能在_app.js
文件中导入全局样式。
例如,请看名为 app/global.css
的样式表:
body {
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}
在根布局(app/layout.js
)中,导入 global.css
样式表可将样式应用到应用程序中的每个路由:
// app/layout.tsx
// 这些样式应用于应用程序中的每个路由
import './global.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
第三方包发布的样式表可以导入 app
目录中的任何位置,包括共用组件:
// app/layout.tsx
import 'bootstrap/dist/css/bootstrap.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
需要知道:外部样式表必须直接从 npm 包导入,或下载并与代码库放在一起。不能使用
。
Next.js 包含一些附加功能,可提升添加样式的编写体验:
next dev
在本地运行时,本地样式表(全局或 CSS 模块)将利用快速刷新功能,在编辑保存时即时反映更改。next build
为生产版本构建时,CSS 文件将被捆绑到更少的 .css
文件中,以减少检索样式所需的网络请求数量。next start
)中加载。不过,next dev
仍需要 JavaScript 才能启用快速刷新。Tailwind CSS 是一个实用优先的 CSS 框架,与 Next.js 配合使用效果极佳。
安装 Tailwind CSS 包,运行 init
命令生成 tailwind.config.js
和 postcss.config.js
文件:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
在 tailwind.config.js
中,为将使用 Tailwind CSS 类名的文件添加路径:
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory.
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
}
你无需修改 postcss.config.js
。
添加 Tailwind CSS 指令,Tailwind 会使用这些指令将生成的样式注入到应用程序中的全局样式表中,例如:
/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
在根布局(app/layout.tsx
)中,导入 globals.css
样式表,以便将样式应用到应用程序中的每个路由。
// app/layout.tsx
import type { Metadata } from 'next'
// 这些样式适用于应用程序中的每个路由
import './globals.css'
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
安装 Tailwind CSS 并添加全局样式后,你就可以在应用程序中使用 Tailwind 的实用类。
// app/page.tsx
export default function Page() {
return Hello, Next.js!
}
从 Next.js 13.1 开始,Turbopack 支持 Tailwind CSS 和 PostCSS。
警告:服务器组件目前不支持需要运行时 JavaScript 的 CSS-in-JS 库。将 CSS-in-JS 与较新的 React 功能(例如:服务器组件和流式传输)一起使用,需要库作者支持最新版本的 React,包括并发渲染。
我们正与 React 团队合作开发上游 API,以处理 CSS 和 JavaScript 静态资源,并支持 React 服务器组件和流架构。
app
目录中的客户端组件支持以下库(按字母顺序排列):
chakra-ui
kuma-ui
@mui/material
pandacss
styled-jsx
styled-components
style9
tamagui
tss-react
vanilla-extract
目前正在为以下组件提供支持:
emotion
需要知道:我们正在测试不同的 CSS-in-JS 库,并将为支持 React 18 功能和(或)
app
目录的库添加更多示例。
如果你想为服务器组件设计样式,我们建议你使用 CSS 模块或其他可输出 CSS 文件的解决方案,例如:PostCSS 或 Tailwind CSS。
app
中配置 CSS-in-JS配置 CSS-in-JS 是一个三步选择过程,其中包括:
useServerInsertedHTML
钩子,用于在任何可能使用规则的内容之前注入规则。styled-jsx
在客户端组件中使用 styled-jsx
,需要使用 v5.1.0
。首先,创建一个新注册表:
// app/registry.tsx
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({
children,
}: {
children: React.ReactNode
}) {
// 只创建一次具有懒惰初始状态的样式表
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}>
})
return {children}
}
然后,用注册表包裹根布局:
// app/layout.tsx
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
这里有一个例子。
下面举例说明如何配置 styled-components@6
或更新版本:
首先,在 next.config.js
中启用样式化组件。
// next.config.js
module.exports = {
compiler: {
styledComponents: true,
},
}
然后,使用 styled-components
API 创建一个全局注册表组件,用于收集渲染过程中生成的所有 CSS 样式规则,并创建一个函数来返回这些规则。然后使用 useServerInsertedHTML
钩子将注册表中收集的样式注入根布局中的 HTML 标签。
// lib/registry.tsx
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({
children,
}: {
children: React.ReactNode
}) {
// 只创建一次具有懒惰初始状态的样式表
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}>
})
if (typeof window !== 'undefined') return <>{children}>
return (
{children}
)
}
用样式注册表组件包裹根布局的 chidren
:
// app/layout.tsx
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
这里有一个例子。
需要知道:
在服务器渲染过程中,样式将被提取到全局注册表中,并刷新到 HTML 的
中。这将确保样式规则被放置在任何可能使用它们的内容之前。将来,我们可能会使用即将推出的 React 功能来确定注入样式的位置。
在流式传输过程中,我们会收集每个分块的样式,并将其添加到现有样式中。在客户端水合完成后,
styled-components
将像往常一样接管并注入任何进一步的动态样式。我们特别在样式注册表树的顶层使用了客户端组件,因为这样提取 CSS 规则的效率更高。它可以避免在后续服务器渲染时重新生成样式,并防止它们被发送到服务器组件有效载荷中。
对于需要配置样式化组件编译的个别属性的高级用例,可以阅读我们的 Next.js 样式化组件 API 参考资料了解更多。
在使用 .scss
和 .sass
扩展名安装包后,Next.js 内置了与 Sass 集成的支持。你可以通过 CSS 模块和 .module.scssor
或 .module.sass
扩展使用组件级 Sass。
首先,安装 sass:
npm install --save-dev sass
需要知道:
Sass 支持两种不同的语法,每种语法都有自己的扩展名。
.scss
扩展名要求你使用 SCSS 语法,而.sass
扩展名则要求使用缩进语法 (“Sass”)。如果你不确定该选择哪一种,请从
.scss
扩展名开始,它是 CSS 的超集,不需要你学习缩进语法 (“Sass”)。
如果要配置 Sass 编译器,请在 next.config.js
中使用 sassOptions
。
// next.config.js
const path = require('path')
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
}
Next.js 支持从 CSS 模块文件导出的 Sass 变量。
例如,使用导出的 primaryColor
Sass 变量:
// app/variables.module.scss
$primary-color: #64ff00;
:export {
primaryColor: $primary-color;
}
// app/page.js
// 映射到根 `/` 路径
import variables from './variables.module.scss'
export default function Page() {
return <h1 style={{ color: variables.primaryColor }}>Hello, Next.js!</h1>
}