如何在应用中使用 CSS
Next.js 提供了几种在你的应用中使用 CSS 的方法,包括:
¥Next.js provides several ways to use CSS in your application, including:
本页将指导你如何使用每种方法。
¥This page will guide you through how to use each of these approaches.
CSS 模块
¥CSS Modules
CSS 模块通过生成唯一的类名在本地范围 CSS。这允许你在不同的文件中使用相同的类而不必担心冲突。
¥CSS Modules locally scope CSS by generating unique class names. This allows you to use the same class in different files without worrying about collisions.
要开始使用 CSS 模块,请创建一个扩展名为 .module.css
的新文件并将其导入到 app
目录内的任何组件中:
¥To start using CSS Modules, create a new file with the extension .module.css
and import it into any component inside the app
directory:
.blog {
padding: 24px;
}
import styles from './styles.module.css'
export default function Page({ children }: { children: React.ReactNode }) {
return <main className={styles.blog}>{children}</main>
}
import styles from './styles.module.css'
export default function Page({ children }) {
return <main className={styles.blog}>{children}</main>
}
全局 CSS
¥Global CSS
你可以使用全局 CSS 在整个应用中应用样式。
¥You can use global CSS to apply styles across your application.
要使用全局样式,请创建一个新的 CSS 文件,例如 app/global.css
:
¥To use global styles, create a new CSS file, for example app/global.css
:
body {
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}
导入根布局 (app/layout.js
) 中的文件以将样式应用于应用中的每个路由:
¥Import the file in the root layout (app/layout.js
) to apply the styles to every route in your application:
// 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
目录内的任何布局、页面或组件中。但是,由于 Next.js 使用 React 对样式表的内置支持来与 Suspense 集成。此内置支持目前不会在你在路由之间导航时删除样式表。因此,我们建议使用全局样式来实现真正的全局 CSS,使用 CSS 模块 来实现范围 CSS。¥Good to know: Global styles can be imported into any layout, page, or component inside the
app
directory. However, since Next.js uses React's built-in support for stylesheets to integrate with Suspense. This built-in support currently does not remove stylesheets as you navigate between routes. Therefore, we recommend using global styles for truly global CSS, and CSS Modules for scoped CSS.
Tailwind CSS
Tailwind CSS 是一个实用优先的 CSS 框架,可与 Next.js 无缝集成。
¥Tailwind CSS is a utility-first CSS framework that integrates seamlessly with Next.js.
安装 Tailwind
¥Installing Tailwind
要开始使用 Tailwind,请安装 Tailwind CSS 包并运行 init
命令以生成 tailwind.config.js
和 postcss.config.js
文件:
¥To start using Tailwind, install the Tailwind CSS packages and run the init
command to generate both the tailwind.config.js
and postcss.config.js
files:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
配置 Tailwind
¥Configuring Tailwind
在你的 Tailwind 配置文件中,添加将使用 Tailwind 类名的文件的路径:
¥Inside your Tailwind configuration file, add paths to the files that will use the Tailwind class names:
import type { Config } from 'tailwindcss'
export default {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
} satisfies Config
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {},
},
plugins: [],
}
使用 Tailwind
¥Using Tailwind
将 Tailwind 指令 添加到你的 全局样式表:
¥Add the Tailwind directives to your Global Stylesheet:
@tailwind base;
@tailwind components;
@tailwind utilities;
然后,导入 根布局 中的样式:
¥Then, import the styles in the root layout:
import type { Metadata } from 'next'
// These styles apply to every route in the application
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 (
<html lang="en">
<body>{children}</body>
</html>
)
}
// These styles apply to every route in the application
import './globals.css'
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
最后,你可以开始在应用中编写 Tailwind 的实用程序类。
¥Lastly, you can start writing Tailwind's utility classes in your application.
export default function Page() {
return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1>
}
export default function Page() {
return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1>
}
Sass
Next.js 使用 .scss
和 .sass
扩展和语法与 Sass 集成。
¥Next.js integrates with Sass using both the .scss
and .sass
extensions and syntax.
你还可以通过 CSS 模块 和 .module.scss
或 .module.sass
扩展使用组件级 Sass。
¥You can also use component-level Sass via CSS Modules and the .module.scss
or .module.sass
extension.
安装 Sass
¥Installing Sass
要开始使用 Sass,请安装 sass
包:
¥To start using Sass, install the sass
package:
npm install --save-dev sass
自定义 Sass 选项
¥Customizing Sass options
如果你想配置 Sass 选项,请使用 next.config.js
中的 sassOptions
选项。
¥If you want to configure your Sass options, use the sassOptions
option in next.config.js
.
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
sassOptions: {
additionalData: `$var: red;`,
},
}
export default nextConfig
/** @type {import('next').NextConfig} */
const nextConfig = {
sassOptions: {
additionalData: `$var: red;`,
},
}
export default nextConfig
JS 中的 CSS
¥CSS-in-JS
警告:需要运行时 JavaScript 的 CSS-in-JS 库目前不受 React Server Components 的支持。将 CSS-in-JS 与较新的 React 功能(如服务器组件和流式传输)结合使用需要库作者支持最新版本的 React。
¥Warning: CSS-in-JS libraries which require runtime JavaScript are not currently supported in React Server Components. Using CSS-in-JS with newer React features like Server Components and Streaming requires library authors to support the latest version of React.
app
目录中的客户端组件支持以下库(按字母顺序排列):
¥The following libraries are supported in Client Components in the app
directory (alphabetical):
目前正在开展以下支持工作:
¥The following are currently working on support:
如果你想设置服务器组件的样式,我们建议使用 CSS 模块 或其他输出 CSS 文件的解决方案,例如 Tailwind CSS。
¥If you want to style Server Components, we recommend using CSS Modules or other solutions that output CSS files, like Tailwind CSS.
配置 CSS-in-JS
¥Configuring CSS-in-JS
要配置 CSS-in-JS,你需要:
¥To configure CSS-in-JS, you need to:
-
创建一个样式注册表以收集渲染中的所有 CSS 规则。
¥Create a style registry to collect all CSS rules in a render.
-
使用
useServerInsertedHTML
钩子在任何可能使用规则的内容之前注入规则。¥Use the
useServerInsertedHTML
hook to inject rules before any content that might use them. -
创建一个客户端组件,在初始服务器端渲染期间使用样式注册表封装你的应用。
¥Create a Client Component that wraps your app with the style registry during initial server-side rendering.
styled-jsx
要为你的应用配置 styled-jsx
,请创建一个新的注册表:
¥To configure styled-jsx
for your application, create a new registry:
'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
}) {
// Only create stylesheet once with lazy initial state
// x-ref: https://react.nodejs.cn/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({ children }) {
// Only create stylesheet once with lazy initial state
// x-ref: https://react.nodejs.cn/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
然后,用注册表封装你的 根布局:
¥Then, wrap your root layout with the registry:
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
import StyledJsxRegistry from './registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
styled-components
要使用 styled-components
,请在 next.config.js
中启用它:
¥To use styled-components
, enable it in next.config.js
:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
compiler: {
styledComponents: true,
},
}
export default nextConfig
/** @type {import('next').NextConfig} */
const nextConfig = {
compiler: {
styledComponents: true,
},
}
export default nextConfig
然后,使用 styled-components
API 创建一个全局注册表组件来收集渲染期间生成的所有 CSS 样式规则,以及一个返回这些规则的函数。然后使用 useServerInsertedHTML
钩子将注册表中收集的样式注入到根布局中的 <head>
HTML 标签中。
¥Then, use the styled-components
API to create a global registry component to collect all CSS style rules generated during a render, and a function to return those rules. Then use the useServerInsertedHTML
hook to inject the styles collected in the registry into the <head>
HTML tag in the root layout.
'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
}) {
// Only create stylesheet once with lazy initial state
// x-ref: https://react.nodejs.cn/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 (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({ children }) {
// Only create stylesheet once with lazy initial state
// x-ref: https://react.nodejs.cn/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 (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
使用样式注册表组件封装根布局的 children
:
¥Wrap the children
of the root layout with the style registry component:
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({ children }) {
return (
<html>
<body>
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
</body>
</html>
)
}
外部样式表
¥External stylesheets
外部包发布的样式表可以导入到 app
目录中的任何位置,包括共置组件:
¥Stylesheets published by external packages can be imported anywhere in the app
directory, including colocated components:
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" />
。
¥External stylesheets must be directly imported from an npm package or downloaded and colocated with your codebase. You cannot use <link rel="stylesheet" />
.