如何在應用程式中使用 CSS

Next.js 提供了多種在應用程式中使用 CSS 的方式,包括:

CSS 模組 (CSS Modules)

CSS 模組透過生成唯一的類別名稱來實現 CSS 的局部作用域。這讓您可以在不同檔案中使用相同的類別名稱,而不用擔心命名衝突。

要開始使用 CSS 模組,請建立一個副檔名為 .module.css 的新檔案,並將其導入到 pages 目錄下的任何元件中:

/styles/blog.module.css
.blog {
  padding: 24px;
}
import styles from './blog.module.css'

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

全域 CSS (Global CSS)

您可以使用全域 CSS 來為整個應用程式套用樣式。

將樣式表導入到 pages/_app.js 檔案中,即可將樣式套用到應用程式中的每個路由

pages/_app.js
import '@/styles/global.css'

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

由於樣式表的全域性質,為避免衝突,您應該在 pages/_app.js 中導入它們。

外部樣式表 (External stylesheets)

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}>開啟對話框</button>
      <Dialog isOpen={showDialog} onDismiss={close}>
        <button className="close-button" onClick={close}>
          <VisuallyHidden>關閉</VisuallyHidden>
          <span aria-hidden>×</span>
        </button>
        <p>你好,我是一個對話框</p>
      </Dialog>
    </div>
  )
}

排序與合併 (Ordering and Merging)

Next.js 在生產環境建置時會透過自動分塊(合併)樣式表來優化 CSS。CSS 的順序取決於您在程式碼中導入樣式的順序

例如,base-button.module.css 會排在 page.module.css 之前,因為 <BaseButton> 是在 page.module.css 之前導入的:

import { BaseButton } from './base-button'
import styles from './page.module.css'

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

建議

為了保持 CSS 順序的可預測性:

  • 嘗試將 CSS 導入集中在單一的 JavaScript 或 TypeScript 入口檔案中
  • 在應用程式的根目錄導入全域樣式和 Tailwind 樣式表
  • 對於嵌套元件,使用 CSS 模組而非全域樣式
  • 為 CSS 模組使用一致的命名慣例。例如,使用 <name>.module.css 而非 <name>.tsx
  • 將共享樣式提取到共享元件中,避免重複導入
  • 關閉會自動排序導入的 linter 或格式化工具,如 ESLint 的 sort-imports
  • 您可以在 next.config.js 中使用 cssChunking 選項來控制 CSS 的分塊方式

開發環境與生產環境 (Development vs Production)

  • 在開發環境 (next dev) 中,CSS 更新會透過快速刷新 (Fast Refresh) 即時套用
  • 在生產環境 (next build) 中,所有 CSS 檔案會自動串接成多個經過最小化和程式碼分割.css 檔案,確保為每個路由加載最少的 CSS
  • 在生產環境中,即使禁用 JavaScript,CSS 仍會加載,但在開發環境中需要 JavaScript 來實現快速刷新
  • CSS 順序在開發環境中可能表現不同,請務必檢查建置結果 (next build) 以驗證最終的 CSS 順序

On this page