跳到内容

如何在你的应用中使用 CSS

Next.js 提供了多种使用 CSS 为你的应用设置样式的方法,包括:

Tailwind CSS

Tailwind CSS 是一个实用工具优先的 CSS 框架,提供低级实用工具类来构建自定义设计。

安装 Tailwind CSS

终端
pnpm add -D tailwindcss @tailwindcss/postcss

将 PostCSS 插件添加到你的 postcss.config.mjs 文件中

postcss.config.mjs
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
}

在你的全局 CSS 文件中导入 Tailwind

styles/globals.css
@import 'tailwindcss';

在你的 pages/_app.js 文件中导入 CSS 文件

pages/_app.js
import '@/styles/globals.css'
 
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

现在你可以在你的应用中开始使用 Tailwind 的实用工具类了

pages/index.tsx
export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <h1 className="text-4xl font-bold">Welcome to Next.js!</h1>
    </main>
  )
}

须知: 如果你需要为非常旧的浏览器提供更广泛的浏览器支持,请参阅 Tailwind CSS v3 设置说明

CSS 模块

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

要开始使用 CSS Modules,创建一个以 .module.css 为扩展名的新文件,并将其导入到 pages 目录中的任何组件中

/styles/blog.module.css
.blog {
  padding: 24px;
}
pages/blog/index.tsx
import styles from './blog.module.css'
 
export default function Page() {
  return <main className={styles.blog}></main>
}

全局 CSS

你可以使用全局 CSS 来在你的应用中应用样式。

pages/_app.js 文件中导入样式表,将样式应用于你应用中的所有路由

pages/_app.js
import '@/styles/global.css'
 
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

由于样式表的全局性质,为避免冲突,你应该将它们导入到 pages/_app.js 中。

外部样式表

Next.js 允许你从 JavaScript 文件中导入 CSS 文件。这之所以可能,是因为 Next.js 扩展了 import 的概念,使其超越了 JavaScript。

node_modules 导入样式

从 Next.js 9.5.4 开始,允许在你的应用中的任何地方从 node_modules 导入 CSS 文件。

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

pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'
 
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

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

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>
  )
}

排序和合并

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

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

page.tsx
import { BaseButton } from './base-button'
import styles from './page.module.css'
 
export default function Page() {
  return <BaseButton className={styles.primary} />
}
base-button.tsx
import styles from './base-button.module.css'
 
export function BaseButton() {
  return <button className={styles.primary} />
}

建议

为了使 CSS 排序可预测

  • 尝试将 CSS 导入限制在单个 JavaScript 或 TypeScript 入口文件
  • 在你的应用程序根目录中导入全局样式和 Tailwind 样式表。
  • 使用 Tailwind CSS 来满足大部分样式需求,因为它涵盖了带有实用工具类的常见设计模式。
  • 当 Tailwind 实用工具不足时,使用 CSS Modules 来处理组件特定样式。
  • 为你的 CSS 模块使用一致的命名约定。例如,使用 <name>.module.css 而不是 <name>.tsx
  • 将共享样式提取到共享组件中,以避免重复导入。
  • 关闭自动排序导入的 linter 或格式化工具,例如 ESLint 的 sort-imports
  • 你可以在 next.config.js 中使用 cssChunking 选项来控制 CSS 的分块方式。

开发环境与生产环境

  • 在开发环境(next dev)中,CSS 更新会通过 快速刷新 即时应用。
  • 在生产环境(next build)中,所有 CSS 文件会自动合并成多个经过压缩和代码分割的 .css 文件,确保每个路由加载的 CSS 量最少。
  • 在生产环境中禁用 JavaScript 时 CSS 仍然会加载,但在开发环境中需要 JavaScript 才能进行快速刷新。
  • CSS 排序在开发环境中可能表现不同,请务必检查构建(next build)以验证最终的 CSS 顺序。