样式是 Web 应用的重要组成部分,它决定了应用的外观和用户体验。Next.js 提供了多种 CSS 解决方案,让我们可以根据项目需求选择最合适的方式。这一节课我们会介绍如何在 Next.js 中使用各种 CSS 方案,包括全局 CSS、CSS Modules、Tailwind CSS 等,以及如何组织和优化样式代码。

最简单的样式方式是使用全局 CSS。在 Next.js App Router 中,全局样式应该放在 app 目录下的 globals.css 文件中,然后在根布局中导入。
让我们看一个例子:
|// app/globals.css * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; line-height: 1.6; color: #333; } .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; }
然后在根布局中导入:
|// app/layout.tsx import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="zh"> <body>{children}</body> </html> );
这样,全局样式就会应用到整个应用。全局样式适合定义重置样式、基础样式、字体等。
CSS Modules 是一种将 CSS 作用域限制在组件内的方式。每个 CSS 模块文件都会生成唯一的类名,避免了样式冲突的问题。
要使用 CSS Modules,我们需要创建以 .module.css 结尾的文件:
|// app/components/Button.module.css .button { padding: 10px 20px; background-color: #0070f3; color: white; border: none; border-radius: 5px; cursor: pointer; } .button:hover { background-color: #0051cc; } .primary { background-color: #0070f3; } .secondary { background-
然后在组件中导入并使用:
|// app/components/Button.tsx import styles from './Button.module.css'; export default function Button({ children, variant = 'primary' }: { children: React.ReactNode; variant?: 'primary' | 'secondary'; }) { return ( <button className
CSS Modules 会自动生成唯一的类名,比如 Button_button__abc123,这样就不会与其他组件的样式冲突。
我们也可以使用组合类名:
|// app/components/Button.module.css .button { padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; } .primary { composes: button; background-color: #0070f3; color: white; } .secondary { composes: button; background-color: #6c757d; color: white; }
使用 composes 关键字可以组合多个类,这样可以减少重复代码。
Tailwind CSS 是一个实用优先的 CSS 框架,它提供了大量的实用类,让我们可以快速构建界面。Tailwind CSS 4.0 带来了全新的高性能引擎 Oxide,构建速度大幅提升,同时简化了配置方式,采用 CSS 优先的配置方法。
首先,我们需要安装 Tailwind CSS 4.0:
|npm install -D tailwindcss@next
在 Tailwind CSS 4.0 中,我们不再需要 postcss.config.js 或 tailwind.config.js 文件。配置直接在 CSS 文件中完成。
然后,在全局 CSS 中使用 @import 导入 Tailwind CSS:
|// app/globals.css @import "tailwindcss";
这就是全部!Tailwind CSS 4.0 会自动检测项目中的所有模板文件,无需手动配置 content 数组。它会自动忽略 .gitignore 中的文件和二进制文件。
现在,我们可以在组件中使用 Tailwind 的实用类:
|// app/components/Button.tsx export default function Button({ children }: { children: React.ReactNode }) { return ( <button className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"> {children} </button> ); }
Tailwind 的类名非常直观:px-4 表示水平内边距为 1rem,py-2 表示垂直内边距为 0.5rem,bg-blue-500 表示蓝色背景,text-white 表示白色文字,rounded 表示圆角,hover:bg-blue-600 表示悬停时的背景色。
在 Tailwind CSS 4.0 中,我们使用 @theme 指令在全局 CSS 文件中直接配置主题,而不是使用 JavaScript 配置文件。这种方式更简洁,也更符合 CSS 的思维方式:
|// app/globals.css @import "tailwindcss"; @theme { --color-primary-50: #eff6ff; --color-primary-100: #dbeafe; --color-primary-500: #3b82f6; --color-primary-900: #1e3a8a; --font-family-sans
这样定义的主题变量会自动作为 CSS 变量,可以在运行时引用,用于内联样式或传递给动画库。在组件中,我们可以直接使用这些自定义颜色:
|// app/components/Button.tsx export default function Button({ children }: { children: React.ReactNode }) { return ( <button className="px-4 py-2 bg-primary-500 text-white rounded hover:bg-primary-900"> {children} </button> ); }
@theme 指令支持扩展所有 Tailwind 的设计标记,包括颜色、字体、间距、断点等。这种配置方式让主题配置更聚焦于关键设计标记,减少了配置工作量。
如果你需要添加额外的内容源(默认情况下会被忽略),可以使用 @source 指令:
|// app/globals.css @import "tailwindcss"; @source "../other-directory/**/*.{js,ts,jsx,tsx}";
Tailwind CSS 4.0 还内置了 CSS 转译功能,通过 Lightning CSS 自动处理供应商前缀、现代特性转译和压缩,无需额外的 PostCSS 插件。
虽然 Next.js 默认不支持 CSS-in-JS,但我们可以通过客户端组件来实现。不过,由于 Next.js 的服务器组件特性,CSS-in-JS 的使用需要特别注意。
对于需要 CSS-in-JS 的场景,我们可以使用 styled-jsx(Next.js 内置支持)或其他库。但要注意,CSS-in-JS 会增加客户端 JavaScript 的大小,可能影响性能,因此非必要情况下我们不推荐使用。
良好的样式组织可以让代码更易维护。以下是一些最佳实践:
首先,将全局样式和组件样式分开。全局样式放在 app/globals.css 中,组件样式使用 CSS Modules 或 Tailwind。
其次,使用一致的命名约定。如果使用 CSS Modules,可以使用 BEM 命名法或类似的约定:
|// app/components/Card.module.css .card { border: 1px solid #e0e0e0; border-radius: 8px; padding: 20px; } .card__header { margin-bottom: 16px; } .card__title { font-size: 1.5rem; font-weight: bold; } .card__body { color: #666; }
第三,创建可重用的样式组件或工具类。如果使用 Tailwind,可以创建自定义组件类。在 Tailwind CSS 4.0 中,我们使用 CSS 层叠层(@layer)来组织样式:
|// app/globals.css @import "tailwindcss"; @layer components { .btn { @apply px-4 py-2 rounded font-semibold; } .btn-primary { @apply bg-blue-500 text-white hover:bg-blue-600; } .btn-
然后可以在组件中使用:
|// app/components/Button.tsx export default function Button({ children, variant = 'primary' }: { children: React.ReactNode; variant?: 'primary' | 'secondary'; }) { return ( <button className={`btn btn-${variant}`}>
Next.js 支持所有标准的 CSS 响应式设计方法。如果使用 Tailwind,可以使用响应式前缀:
|// app/components/Grid.tsx export default function Grid({ children }: { children: React.ReactNode }) { return ( <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> {children} </div> ); }
这个例子创建了一个响应式网格:在移动设备上显示 1 列,在中等屏幕上显示 2 列,在大屏幕上显示 3 列。
如果使用 CSS Modules 或普通 CSS,可以使用媒体查询:
|// app/components/Grid.module.css .grid { display: grid; grid-template-columns: 1fr; gap: 1rem; } @media (min-width: 768px) { .grid { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 1024px) { .grid {
Next.js 支持多种实现暗色模式的方式。最常见的方法是结合 CSS 变量和媒体查询,根据用户系统的配色偏好(如浅色或深色)自动切换主题。你可以通过在全局样式文件中定义不同的变量值,并基于 prefers-color-scheme 媒体查询动态切换它们,实现页面在浅色模式和暗色模式之间自适应切换。
|// app/globals.css :root { --bg-color: #ffffff; --text-color: #000000; } @media (prefers-color-scheme: dark) { :root { --bg-color: #000000; --text-color: #ffffff; } } body {
如果使用 Tailwind,可以启用暗色模式。在 Tailwind CSS 4.0 中,暗色模式默认支持,我们可以直接在 CSS 中使用 @theme 指令配置暗色模式的颜色:
|// app/globals.css @import "tailwindcss"; @theme { --color-bg: #ffffff; --color-text: #000000; @media (prefers-color-scheme: dark) { --color-bg: #1f2937; --color-text: #ffffff; } }
或者,我们可以使用 dark: 前缀直接在类名中指定暗色模式样式:
|// app/components/Card.tsx export default function Card({ children }: { children: React.ReactNode }) { return ( <div className="bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"> {children} </div> ); }
Tailwind CSS 4.0 的暗色模式支持更加灵活,可以基于媒体查询(prefers-color-scheme)或类名(.dark)来切换。
在这一节课中,我们探索了 Next.js 中的各种 CSS 解决方案。我们学习了如何使用全局 CSS、CSS Modules、Tailwind CSS,了解了如何组织样式代码,如何实现响应式设计和暗色模式,以及如何优化样式性能。 选择合适的 CSS 方案对于项目的可维护性和性能都很重要。CSS Modules 适合需要作用域隔离的场景,Tailwind CSS 适合快速开发和原型设计,全局 CSS 适合基础样式和重置样式。
在下一节课,我们将学习图片和静态资源,了解如何使用 Next.js 的 Image 组件优化图片加载,如何管理静态文件,以及如何优化字体加载。