Skip to content

样式篇

Next.js 支持多种方式添加样式:

  • 内联 CSS

  • CSS 模块:创建局部 CSS 避免命名冲突,提升可维护性

  • 全局 CSS

  • 外部样式表

  • Tailwind CSS:一个 CSS 框架,通过组合的方式声明样式

  • CSS-in-JS:将 CSS 直接嵌入到 JavaScript 组件中,实现动态和局部样式

  • Sass:最流行的 CSS 预处理器

内联 CSS

最基础的添加样式的方式便是使用内联 CSS,举个例子:

ts
function Page() {
  return (
    <>
      <div style={{ color: "red" }}>DashBoard子页面</div>
    </>
  );
}

export default Page;

CSS 模块

Next.js 内置了对 CSS 模块的支持。使用 CSS 模块,你只需要使用 .module.css 作为文件后缀名,Next.js 就会自动进行处理。

CSS 模块的作用在于实现局部 CSS,本质是创建一个不会重复的类名。这样你就可以在不同的文件里使用相同的类名,而不用担心发生样式冲突。这是最理想的实现组件级别 CSS 的方式。

让我们举个例子: 起名字必须是.module.css结尾

首选创建一个style.module.css文件,样式书写方式与普通的 CSS 文件一致:

css
.dashboard {
  padding: 24px;
  color: green;
}

然后,CSS 模块可以被导入到 app 目录下的任意文件,让我们导入并使用该样式:

ts
import DashBoardLayoutCSS from "@/app/css/dashboard/styles.module.css";
function Page() {
  return (
    <>
      <div className={DashBoardLayoutCSS.dashboard}>
        <div>DashBoard子页面</div>
      </div>
    </>
  );
}
export default Page;

全局样式

全局样式,顾名思义,应用到所有路由的样式,像我们传统写页面 CSS 的时候,都会引入 normalize.css 或者 reset.css 等,这种场景就适合使用全局样式。

创建文件 app/global.css

css
body {
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
  background: red;
  background: green;
}

然后,在根布局(app/layout.js)导入 global.css,该样式会被应用于应用里的每个路由:

ts
// app/layout.js
import "./global.css";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

外部样式表

你也可以通过导入外部包的方式添加样式.举个例子:

ts
// app/layout.js
import "bootstrap/dist/css/bootstrap.css";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className="container">{children}</body>
    </html>
  );
}

不过要注意,该外部包必须是从 npm 包直接导入或者下载完和你的代码放在一起。

  • 如果想要引入cdn外部文件文件的话 只有在layout.js中引入即可
ts
// app/layout.js
import "./globals.css";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <link
          href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
          rel="stylesheet"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

使用样式的时候要注意:

注意

  1. 即时刷新 在本地使用 next dev 运行项目的时候,本地样式(无论是全局样式还是 CSS 模块),都会在你保存更改后立刻刷新,你可以即时看到样式变化。

  2. 当使用 next build 的时候,CSS 文件会被打包成更少的压缩 .css 文件,这是为了减少网络请求,从而提高加载速度,所以不用担心创建多个 css 文件而影响了性能。

  3. 当你禁用 JavaScript 的时候,在生产版本(next start),样式依然会被加载。也就是说,打包构建后的代码中的 CSS 并不是通过 JS 注入的。但是开发的时候(next dev),为了开启快速刷新,JavaScript 依然是有必要的。

Tailwind CSS

CSS 的原子集

在使用 create-next-app 创建项目的时候,如果你在命令行中选择了使用 Tailwind CSS,则相关配置都会自动生成,可以直接使用。如果没有选择,希望引入 Tailwind CSS,可以参考此步骤。

安装

在项目的根目录执行以下命令:

ts

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

会同时生成 tailwind.config.jspostcss.config.js 文件。

配置 Tailwind

postcss.config.js 不需要修改。在 tailwind.config.js 中添加使用 Tailwind CSS 类名的文件路径:

ts
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",

    // 嫌麻烦,你也可以直接使用 `src` 目录
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

导入样式

添加 Tailwind CSS 指令,将 Tailwind 的样式注入到全局样式中。使用方式如下:

css
// app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;

在根布局(app/layout.tsx),导入 globals.css

ts
// app/layout.js
import "./globals.css";

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

使用类名

然后你就可以在应用里使用 Tailwind 的工具类名:

ts
// app/page.js
export default function Page() {
  return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1>;
}

Sass 使用

Sass 作为知名的 CSS 预处理器已无须过多介绍。Next.js 内置了对 Sass 文件的支持,你需要使用 .scss 和 .sass 作为文件后缀。

你也可以结合 CSS 模块使用组件级别的 Sass, 你需要使用.module.scss 或者 .module.sass 作为文件后缀。

安装

  • sass
bash
npm install --save-dev sass

然后直接使用

ts
import AllScss from "@/app/scss/dashpage.module.scss";
function Page() {
  return (
    <>
      <div className={AllScss.pageContent}>
        <div>DashBoard子页面</div>
      </div>
    </>
  );
}
export default Page;