1
1
---
2
- source-updated-at : ' 2025-05-16T04:52:11 .000Z'
3
- translation-updated-at : ' 2025-05-17T02:11:04.312Z '
2
+ source-updated-at : 2025-05-19T22:31:51 .000Z
3
+ translation-updated-at : 2025-05-19T23:06:25.929Z
4
4
title : 如何在应用中使用 CSS
5
5
nav_title : CSS
6
6
description : 了解在应用中添加 CSS 的不同方式,包括 CSS 模块 (CSS Modules)、全局 CSS (Global CSS)、Tailwind CSS 等。
7
7
related :
8
- title : 后续步骤
9
- description : 进一步了解在应用中使用 CSS 的其他方法 。
8
+ title : 下一步
9
+ description : 进一步了解在应用中使用 CSS 的其他方式 。
10
10
links :
11
11
- app/guides/tailwind-css
12
12
- app/guides/sass
@@ -24,9 +24,11 @@ Next.js 提供了多种在应用中使用 CSS 的方式,包括:
24
24
25
25
## CSS 模块 (CSS Modules)
26
26
27
- CSS 模块 (CSS Modules) 通过生成唯一的类名来实现 CSS 的局部作用域。这允许你在不同文件中使用相同的类名,而不用担心命名冲突 。
27
+ CSS 模块 (CSS Modules) 通过生成唯一的类名来实现 CSS 的局部作用域。这允许你在不同文件中使用相同的类名而无需担心命名冲突 。
28
28
29
- 要开始使用 CSS 模块,创建一个扩展名为 ` .module.css ` 的新文件,并将其导入到 ` app ` 目录中的任何组件:
29
+ <AppOnly >
30
+
31
+ 要开始使用 CSS 模块 (CSS Modules),创建一个扩展名为 ` .module.css ` 的文件,并将其导入到 ` app ` 目录下的任意组件中:
30
32
31
33
``` css filename="app/blog/styles.module.css"
32
34
.blog {
@@ -35,26 +37,58 @@ CSS 模块 (CSS Modules) 通过生成唯一的类名来实现 CSS 的局部作
35
37
```
36
38
37
39
``` tsx filename="app/blog/page.tsx" switcher
38
- import styles from ' ./styles .module.css'
40
+ import styles from ' ./blog .module.css'
39
41
40
- export default function Page({ children } : { children : React . ReactNode } ) {
41
- return <main className = { styles .blog } >{ children } </main >
42
+ export default function Page() {
43
+ return <main className = { styles .blog } ></main >
42
44
}
43
45
```
44
46
45
47
``` jsx filename="app/blog/page.js" switcher
46
- import styles from ' ./styles.module.css'
48
+ import styles from ' ./blog.module.css'
49
+
50
+ export default function Layout () {
51
+ return < main className= {styles .blog }>< / main>
52
+ }
53
+ ```
54
+
55
+ </AppOnly >
47
56
48
- export default function Page ({ children }) {
49
- return < main className= {styles .blog }> {children}< / main>
57
+ <PagesOnly >
58
+
59
+ 要开始使用 CSS 模块 (CSS Modules),创建一个扩展名为 ` .module.css ` 的文件,并将其导入到 ` pages ` 目录下的任意组件中:
60
+
61
+ ``` css filename="/styles/blog.module.css"
62
+ .blog {
63
+ padding : 24px ;
50
64
}
51
65
```
52
66
67
+ ``` tsx filename="pages/blog/index.tsx" switcher
68
+ import styles from ' ./blog.module.css'
69
+
70
+ export default function Page() {
71
+ return <main className = { styles .blog } ></main >
72
+ }
73
+ ```
74
+
75
+ ``` jsx filename="pages/blog/index.js" switcher
76
+ import styles from ' ./blog.module.css'
77
+
78
+ export default function Page () {
79
+ return < main className= {styles .blog }>< / main>
80
+ }
81
+ ```
82
+
83
+ </PagesOnly >
84
+
53
85
## 全局 CSS (Global CSS)
54
86
55
- 你可以使用全局 CSS 来在整个应用中应用样式。
87
+ 你可以使用全局 CSS (Global CSS) 在整个应用中应用样式。
88
+
89
+ <AppOnly >
56
90
57
- 要使用全局样式, 创建一个 ` app/global.css ` 文件,并在根布局中导入它,以将样式应用到应用中的** 每个路由** :
91
+ 创建一个 ` app/global.css ` 文件,并在根布局中导入它,以将样式应用到应用中的** 每个路由** :
58
92
59
93
``` css filename="app/global.css"
60
94
body {
65
99
```
66
100
67
101
``` tsx filename="app/layout.tsx" switcher
68
- // 这些样式将应用到应用中的每个路由
102
+ // 这些样式会应用到应用中的每个路由
69
103
import ' ./global.css'
70
104
71
105
export default function RootLayout({
@@ -82,7 +116,7 @@ export default function RootLayout({
82
116
```
83
117
84
118
``` jsx filename="app/layout.js" switcher
85
- // 这些样式将应用到应用中的每个路由
119
+ // 这些样式会应用到应用中的每个路由
86
120
import ' ./global.css'
87
121
88
122
export default function RootLayout ({ children }) {
@@ -94,11 +128,31 @@ export default function RootLayout({ children }) {
94
128
}
95
129
```
96
130
97
- > ** 须知:** 全局样式可以导入到 ` app ` 目录中的任何布局、页面或组件 。但由于 Next.js 使用 React 内置的样式表支持来与 Suspense 集成,目前这不会在路由之间导航时移除样式表,可能会导致冲突 。我们建议将全局样式用于** 真正** 全局的 CSS,而使用 [ CSS 模块 (CSS Modules)] ( #css-modules ) 来处理局部作用域的 CSS。
131
+ > ** 须知:** 全局样式可以导入到 ` app ` 目录下的任何布局、页面或组件中 。但由于 Next.js 使用 React 内置的样式表支持来与 Suspense 集成,目前这不会在路由切换时移除样式表,可能导致冲突 。我们建议将全局样式用于** 真正** 全局的 CSS,而使用 [ CSS 模块 (CSS Modules)] ( #css-modules ) 来限定 CSS 作用域 。
98
132
99
- ## 外部样式表 (External Stylesheets)
133
+ </ AppOnly >
100
134
101
- 由外部包发布的样式表可以导入到 ` app ` 目录中的任何位置,包括并置的组件:
135
+ <PagesOnly >
136
+
137
+ 在 ` pages/_app.js ` 文件中导入样式表,以将样式应用到应用中的** 每个路由** :
138
+
139
+ ``` tsx filename="pages/_app.js"
140
+ import ' @/styles/global.css'
141
+
142
+ export default function MyApp({ Component , pageProps }) {
143
+ return <Component { ... pageProps } />
144
+ }
145
+ ```
146
+
147
+ 由于样式表的全局性质,为避免冲突,你应该在 [ ` pages/_app.js ` ] ( /docs/pages/building-your-application/routing/custom-app ) 中导入它们。
148
+
149
+ </PagesOnly >
150
+
151
+ ## 外部样式表 (External stylesheets)
152
+
153
+ <AppOnly >
154
+
155
+ 外部包发布的样式表可以导入到 ` app ` 目录中的任何位置,包括同目录的组件:
102
156
103
157
``` tsx filename="app/layout.tsx" switcher
104
158
import ' bootstrap/dist/css/bootstrap.css'
@@ -128,4 +182,113 @@ export default function RootLayout({ children }) {
128
182
}
129
183
```
130
184
131
- 外部样式表必须直接从 npm 包导入,或下载并与你的代码库并置。不能使用 ` <link rel="stylesheet" /> ` 。
185
+ > ** 须知:** 在 React 19 中,也可以使用 ` <link rel="stylesheet" href="..." /> ` 。更多信息请参阅 [ React ` link ` 文档] ( https://react.dev/reference/react-dom/components/link ) 。
186
+
187
+ </AppOnly >
188
+
189
+ <PagesOnly >
190
+
191
+ Next.js 允许你从 JavaScript 文件中导入 CSS 文件。这是因为 Next.js 扩展了 [ ` import ` ] ( https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import ) 的概念,使其不仅限于 JavaScript。
192
+
193
+ ### 从 ` node_modules ` 导入样式
194
+
195
+ 自 Next.js ** 9.5.4** 起,允许从 ` node_modules ` 导入 CSS 文件到应用中的任何位置。
196
+
197
+ 对于全局样式表,如 ` bootstrap ` 或 ` nprogress ` ,你应该在 ` pages/_app.js ` 中导入文件。例如:
198
+
199
+ ``` jsx filename="pages/_app.js"
200
+ import ' bootstrap/dist/css/bootstrap.css'
201
+
202
+ export default function MyApp ({ Component, pageProps }) {
203
+ return < Component {... pageProps} / >
204
+ }
205
+ ```
206
+
207
+ 对于第三方组件所需的 CSS,你可以在组件中导入。例如:
208
+
209
+ ``` jsx filename="components/example-dialog.js"
210
+ import { useState } from ' react'
211
+ import { Dialog } from ' @reach/dialog'
212
+ import VisuallyHidden from ' @reach/visually-hidden'
213
+ import ' @reach/dialog/styles.css'
214
+
215
+ function ExampleDialog (props ) {
216
+ const [showDialog , setShowDialog ] = useState (false )
217
+ const open = () => setShowDialog (true )
218
+ const close = () => setShowDialog (false )
219
+
220
+ return (
221
+ < div>
222
+ < button onClick= {open}> Open Dialog< / button>
223
+ < Dialog isOpen= {showDialog} onDismiss= {close}>
224
+ < button className= " close-button" onClick= {close}>
225
+ < VisuallyHidden> Close< / VisuallyHidden>
226
+ < span aria- hidden> ×< / span>
227
+ < / button>
228
+ < p> Hello there . I am a dialog< / p>
229
+ < / Dialog>
230
+ < / div>
231
+ )
232
+ }
233
+ ```
234
+
235
+ </PagesOnly >
236
+
237
+ ## 排序与合并 (Ordering and Merging)
238
+
239
+ Next.js 在生产构建时会通过自动分块(合并)样式表来优化 CSS。** CSS 的顺序** 取决于** 你在代码中导入样式的顺序** 。
240
+
241
+ 例如,` base-button.module.css ` 会排在 ` page.module.css ` 之前,因为 ` <BaseButton> ` 在 ` page.module.css ` 之前导入:
242
+
243
+ ``` tsx filename="page.ts" switcher
244
+ import { BaseButton } from ' ./base-button'
245
+ import styles from ' ./page.module.css'
246
+
247
+ export default function Page() {
248
+ return <BaseButton className = { styles .primary } />
249
+ }
250
+ ```
251
+
252
+ ``` jsx filename="page.js" switcher
253
+ import { BaseButton } from ' ./base-button'
254
+ import styles from ' ./page.module.css'
255
+
256
+ export default function Page () {
257
+ return < BaseButton className= {styles .primary } / >
258
+ }
259
+ ```
260
+
261
+ ``` tsx filename="base-button.tsx" switcher
262
+ import styles from ' ./base-button.module.css'
263
+
264
+ export function BaseButton() {
265
+ return <button className = { styles .primary } />
266
+ }
267
+ ```
268
+
269
+ ``` jsx filename="base-button.js" switcher
270
+ import styles from ' ./base-button.module.css'
271
+
272
+ export function BaseButton () {
273
+ return < button className= {styles .primary } / >
274
+ }
275
+ ```
276
+
277
+ ### 推荐做法
278
+
279
+ 为了保持 CSS 顺序的可预测性:
280
+
281
+ - 尽量将 CSS 导入限制在单个 JavaScript 或 TypeScript 入口文件中
282
+ - 在应用的根目录中导入全局样式和 Tailwind 样式表
283
+ - 对于嵌套组件,使用 CSS 模块 (CSS Modules) 而非全局样式
284
+ - 为 CSS 模块使用一致的命名约定,例如使用 ` <name>.module.css ` 而非 ` <name>.tsx `
285
+ - 将共享样式提取到共享组件中以避免重复导入
286
+ - 关闭自动排序导入的 linter 或格式化工具,如 ESLint 的 [ ` sort-imports ` ] ( https://eslint.org/docs/latest/rules/sort-imports )
287
+ - 你可以在 ` next.config.js ` 中使用 [ ` cssChunking ` ] ( /docs/app/api-reference/config/next-config-js/cssChunking ) 选项来控制 CSS 的分块方式
288
+
289
+ ## 开发与生产环境 (Development vs Production)
290
+
291
+ - 在开发环境 (` next dev ` ) 中,CSS 更新会通过 [ 快速刷新 (Fast Refresh)] ( /docs/architecture/fast-refresh ) 即时应用
292
+ - 在生产环境 (` next build ` ) 中,所有 CSS 文件会自动合并为** 多个经过压缩和代码拆分** 的 ` .css ` 文件,确保为路由加载最少数量的 CSS
293
+ - 在生产环境中,即使禁用 JavaScript,CSS 仍会加载,但在开发环境中需要 JavaScript 以实现快速刷新 (Fast Refresh)
294
+ - CSS 顺序在开发环境中可能表现不同,请务必检查构建 (` next build ` ) 以验证最终的 CSS 顺序
0 commit comments