Skip to content

Update translations #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 183 additions & 20 deletions apps/docs/content/zh-hans/docs/01-app/01-getting-started/06-css.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
source-updated-at: '2025-05-16T04:52:11.000Z'
translation-updated-at: '2025-05-17T02:11:04.312Z'
source-updated-at: 2025-05-19T22:31:51.000Z
translation-updated-at: 2025-05-19T23:06:25.929Z
title: 如何在应用中使用 CSS
nav_title: CSS
description: 了解在应用中添加 CSS 的不同方式,包括 CSS 模块 (CSS Modules)、全局 CSS (Global CSS)、Tailwind CSS 等。
related:
title: 后续步骤
description: 进一步了解在应用中使用 CSS 的其他方法
title: 下一步
description: 进一步了解在应用中使用 CSS 的其他方式
links:
- app/guides/tailwind-css
- app/guides/sass
Expand All @@ -24,9 +24,11 @@ Next.js 提供了多种在应用中使用 CSS 的方式,包括:

## CSS 模块 (CSS Modules)

CSS 模块 (CSS Modules) 通过生成唯一的类名来实现 CSS 的局部作用域。这允许你在不同文件中使用相同的类名,而不用担心命名冲突
CSS 模块 (CSS Modules) 通过生成唯一的类名来实现 CSS 的局部作用域。这允许你在不同文件中使用相同的类名而无需担心命名冲突

要开始使用 CSS 模块,创建一个扩展名为 `.module.css` 的新文件,并将其导入到 `app` 目录中的任何组件:
<AppOnly>

要开始使用 CSS 模块 (CSS Modules),创建一个扩展名为 `.module.css` 的文件,并将其导入到 `app` 目录下的任意组件中:

```css filename="app/blog/styles.module.css"
.blog {
Expand All @@ -35,26 +37,58 @@ CSS 模块 (CSS Modules) 通过生成唯一的类名来实现 CSS 的局部作
```

```tsx filename="app/blog/page.tsx" switcher
import styles from './styles.module.css'
import styles from './blog.module.css'

export default function Page({ children }: { children: React.ReactNode }) {
return <main className={styles.blog}>{children}</main>
export default function Page() {
return <main className={styles.blog}></main>
}
```

```jsx filename="app/blog/page.js" switcher
import styles from './styles.module.css'
import styles from './blog.module.css'

export default function Layout() {
return <main className={styles.blog}></main>
}
```

</AppOnly>

export default function Page({ children }) {
return <main className={styles.blog}>{children}</main>
<PagesOnly>

要开始使用 CSS 模块 (CSS Modules),创建一个扩展名为 `.module.css` 的文件,并将其导入到 `pages` 目录下的任意组件中:

```css filename="/styles/blog.module.css"
.blog {
padding: 24px;
}
```

```tsx filename="pages/blog/index.tsx" switcher
import styles from './blog.module.css'

export default function Page() {
return <main className={styles.blog}></main>
}
```

```jsx filename="pages/blog/index.js" switcher
import styles from './blog.module.css'

export default function Page() {
return <main className={styles.blog}></main>
}
```

</PagesOnly>

## 全局 CSS (Global CSS)

你可以使用全局 CSS 来在整个应用中应用样式。
你可以使用全局 CSS (Global CSS) 在整个应用中应用样式。

<AppOnly>

要使用全局样式,创建一个 `app/global.css` 文件,并在根布局中导入它,以将样式应用到应用中的**每个路由**:
创建一个 `app/global.css` 文件,并在根布局中导入它,以将样式应用到应用中的**每个路由**:

```css filename="app/global.css"
body {
Expand All @@ -65,7 +99,7 @@ body {
```

```tsx filename="app/layout.tsx" switcher
// 这些样式将应用到应用中的每个路由
// 这些样式会应用到应用中的每个路由
import './global.css'

export default function RootLayout({
Expand All @@ -82,7 +116,7 @@ export default function RootLayout({
```

```jsx filename="app/layout.js" switcher
// 这些样式将应用到应用中的每个路由
// 这些样式会应用到应用中的每个路由
import './global.css'

export default function RootLayout({ children }) {
Expand All @@ -94,11 +128,31 @@ export default function RootLayout({ children }) {
}
```

> **须知:** 全局样式可以导入到 `app` 目录中的任何布局、页面或组件。但由于 Next.js 使用 React 内置的样式表支持来与 Suspense 集成,目前这不会在路由之间导航时移除样式表,可能会导致冲突。我们建议将全局样式用于**真正**全局的 CSS,而使用 [CSS 模块 (CSS Modules)](#css-modules) 来处理局部作用域的 CSS。
> **须知:** 全局样式可以导入到 `app` 目录下的任何布局、页面或组件中。但由于 Next.js 使用 React 内置的样式表支持来与 Suspense 集成,目前这不会在路由切换时移除样式表,可能导致冲突。我们建议将全局样式用于**真正**全局的 CSS,而使用 [CSS 模块 (CSS Modules)](#css-modules) 来限定 CSS 作用域

## 外部样式表 (External Stylesheets)
</AppOnly>

由外部包发布的样式表可以导入到 `app` 目录中的任何位置,包括并置的组件:
<PagesOnly>

在 `pages/_app.js` 文件中导入样式表,以将样式应用到应用中的**每个路由**:

```tsx filename="pages/_app.js"
import '@/styles/global.css'

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

由于样式表的全局性质,为避免冲突,你应该在 [`pages/_app.js`](/docs/pages/building-your-application/routing/custom-app) 中导入它们。

</PagesOnly>

## 外部样式表 (External stylesheets)

<AppOnly>

外部包发布的样式表可以导入到 `app` 目录中的任何位置,包括同目录的组件:

```tsx filename="app/layout.tsx" switcher
import 'bootstrap/dist/css/bootstrap.css'
Expand Down Expand Up @@ -128,4 +182,113 @@ export default function RootLayout({ children }) {
}
```

外部样式表必须直接从 npm 包导入,或下载并与你的代码库并置。不能使用 `<link rel="stylesheet" />`。
> **须知:** 在 React 19 中,也可以使用 `<link rel="stylesheet" href="..." />`。更多信息请参阅 [React `link` 文档](https://react.dev/reference/react-dom/components/link)。

</AppOnly>

<PagesOnly>

Next.js 允许你从 JavaScript 文件中导入 CSS 文件。这是因为 Next.js 扩展了 [`import`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import) 的概念,使其不仅限于 JavaScript。

### 从 `node_modules` 导入样式

自 Next.js **9.5.4** 起,允许从 `node_modules` 导入 CSS 文件到应用中的任何位置。

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

```jsx filename="pages/_app.js"
import 'bootstrap/dist/css/bootstrap.css'

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

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

```jsx filename="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}>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>
)
}
```

</PagesOnly>

## 排序与合并 (Ordering and Merging)

Next.js 在生产构建时会通过自动分块(合并)样式表来优化 CSS。**CSS 的顺序**取决于**你在代码中导入样式的顺序**。

例如,`base-button.module.css` 会排在 `page.module.css` 之前,因为 `<BaseButton>` 在 `page.module.css` 之前导入:

```tsx filename="page.ts" switcher
import { BaseButton } from './base-button'
import styles from './page.module.css'

export default function Page() {
return <BaseButton className={styles.primary} />
}
```

```jsx filename="page.js" switcher
import { BaseButton } from './base-button'
import styles from './page.module.css'

export default function Page() {
return <BaseButton className={styles.primary} />
}
```

```tsx filename="base-button.tsx" switcher
import styles from './base-button.module.css'

export function BaseButton() {
return <button className={styles.primary} />
}
```

```jsx filename="base-button.js" switcher
import styles from './base-button.module.css'

export function BaseButton() {
return <button className={styles.primary} />
}
```

### 推荐做法

为了保持 CSS 顺序的可预测性:

- 尽量将 CSS 导入限制在单个 JavaScript 或 TypeScript 入口文件中
- 在应用的根目录中导入全局样式和 Tailwind 样式表
- 对于嵌套组件,使用 CSS 模块 (CSS Modules) 而非全局样式
- 为 CSS 模块使用一致的命名约定,例如使用 `<name>.module.css` 而非 `<name>.tsx`
- 将共享样式提取到共享组件中以避免重复导入
- 关闭自动排序导入的 linter 或格式化工具,如 ESLint 的 [`sort-imports`](https://eslint.org/docs/latest/rules/sort-imports)
- 你可以在 `next.config.js` 中使用 [`cssChunking`](/docs/app/api-reference/config/next-config-js/cssChunking) 选项来控制 CSS 的分块方式

## 开发与生产环境 (Development vs Production)

- 在开发环境 (`next dev`) 中,CSS 更新会通过 [快速刷新 (Fast Refresh)](/docs/architecture/fast-refresh) 即时应用
- 在生产环境 (`next build`) 中,所有 CSS 文件会自动合并为**多个经过压缩和代码拆分**的 `.css` 文件,确保为路由加载最少数量的 CSS
- 在生产环境中,即使禁用 JavaScript,CSS 仍会加载,但在开发环境中需要 JavaScript 以实现快速刷新 (Fast Refresh)
- CSS 顺序在开发环境中可能表现不同,请务必检查构建 (`next build`) 以验证最终的 CSS 顺序
Loading