Skip to content

Next.js CSS 样式

在 Next.js 中,有多种方式可以为你的应用程序添加样式,从简单的全局样式表到强大的 CSS-in-JS 库。本章将介绍几种最常用的方法,帮助你根据项目需求选择最合适的样式方案。

1. 全局样式 (Global Styles)

全局样式适用于整个应用程序,通常用于定义基础样式、重置默认样式或引入第三方样式库。

如何添加全局样式表

  1. 创建样式文件:在 styles 目录下创建一个 CSS 文件,例如 styles/globals.css
  2. _app.js 中导入:在 pages/_app.js 文件中导入该样式表。这是唯一可以导入全局样式的地方。
jsx
// pages/_app.js

import '../styles/globals.css';

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

export default MyApp;

styles/globals.css 示例:

css
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
  line-height: 1.6;
  font-size: 18px;
}

* {
  box-sizing: border-box;
}

a {
  color: #0070f3;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

注意:全局样式会影响所有页面和组件,因此请谨慎使用,避免样式冲突。

2. 组件级 CSS (Component-Level CSS)

为了避免全局样式的命名冲突和作用域问题,Next.js 内置了对 CSS Modules 的支持。CSS Modules 可以将 CSS 作用域限定在单个组件内。

如何使用 CSS Modules

  1. 创建模块化 CSS 文件:创建一个以 .module.css 结尾的 CSS 文件,例如 components/Button.module.css
  2. 在组件中导入:在你的组件文件中导入该 CSS 文件,并像使用对象一样使用它。

components/Button.module.css 示例:

css
.error {
  color: white;
  background-color: red;
  padding: 10px 20px;
  border-radius: 5px;
  border: none;
  cursor: pointer;
}

.success {
  color: white;
  background-color: green;
}

components/Button.js 示例:

jsx
import styles from './Button.module.css';

export default function Button({ type, children }) {
  const buttonClass = type === 'error' ? styles.error : styles.success;

  return (
    <button type="button" className={buttonClass}>
      {children}
    </button>
  );
}

当你使用 CSS Modules 时,Next.js 会自动为每个类名生成一个唯一的哈希值,从而确保样式只应用于导入它的组件。例如,styles.error 可能会被编译成 Button_error__1a2b3c

3. Sass/SCSS 支持

Next.js 内置了对 Sass 的支持。在使用之前,你需要安装 sass 包:

bash
npm install sass
# 或者
yarn add sass

安装完成后,你就可以像使用普通 CSS 文件一样使用 .scss.sass 文件了。

全局 Sass/SCSS

你可以将 globals.scss 文件导入到 pages/_app.js 中:

jsx
// pages/_app.js
import '../styles/globals.scss';

组件级 Sass/SCSS

你也可以将 Sass 与 CSS Modules 结合使用,只需将文件命名为 .module.scss.module.sass

components/Alert.module.scss 示例:

scss
$primary-color: #0070f3;

.alert {
  padding: 1rem;
  border-radius: 5px;
  &.info {
    background-color: lighten($primary-color, 40%);
    color: darken($primary-color, 20%);
  }
}

components/Alert.js 示例:

jsx
import styles from './Alert.module.scss';

export default function Alert({ children }) {
  return <div className={`${styles.alert} ${styles.info}`}>{children}</div>;
}

4. CSS-in-JS

CSS-in-JS 是一种将 CSS 直接写在 JavaScript 代码中的技术。这种方法提供了强大的动态样式能力和组件化优势。Next.js 支持所有主流的 CSS-in-JS 库,例如:

  • Styled-components
  • Emotion

这些库通常需要一些额外的配置才能在 Next.js 中实现服务端渲染 (SSR)。

使用 Styled-components 示例

  1. 安装依赖

    bash
    npm install styled-components
  2. 配置 _document.js:为了让 Styled-components 在服务端正确渲染,你需要创建一个自定义的 pages/_document.js 文件来收集样式。

    jsx
    // pages/_document.js
    import Document, { Html, Head, Main, NextScript } from 'next/document';
    import { ServerStyleSheet } from 'styled-components';
    
    export default class MyDocument extends Document {
      static async getInitialProps(ctx) {
        const sheet = new ServerStyleSheet();
        const originalRenderPage = ctx.renderPage;
    
        try {
          ctx.renderPage = () =>
            originalRenderPage({
              enhanceApp: (App) => (props) =>
                sheet.collectStyles(<App {...props} />),
            });
    
          const initialProps = await Document.getInitialProps(ctx);
          return {
            ...initialProps,
            styles: (
              <>
                {initialProps.styles}
                {sheet.getStyleElement()}
              </>
            ),
          };
        } finally {
          sheet.seal();
        }
      }
    
      render() {
        return (
          <Html>
            <Head />
            <body>
              <Main />
              <NextScript />
            </body>
          </Html>
        );
      }
    }
  3. 创建 Styled Component

    jsx
    import styled from 'styled-components';
    
    const Title = styled.h1`
      font-size: 3rem;
      color: palevioletred;
      text-align: center;
    `;
    
    export default function HomePage() {
      return <Title>Hello World!</Title>;
    }

总结

Next.js 提供了灵活多样的样式方案,你可以根据项目需求和团队偏好进行选择:

  • 全局样式:适用于基础样式和第三方库。
  • CSS Modules:推荐用于组件级样式,提供局部作用域,避免冲突。
  • Sass/SCSS:如果你喜欢预处理器,Next.js 提供了开箱即用的支持。
  • CSS-in-JS:适用于需要动态样式和高度组件化的复杂应用。

在下一章中,我们将探讨如何在 Next.js 项目中集成和使用 Tailwind CSS,一个功能强大的原子化 CSS 框架。

本站内容仅供学习和研究使用。