---
title: "样式设置"
description: "学习如何为您的 Nuxt 应用程序设置样式。"
canonical_url: "https://nuxt.zhcndoc.com/docs/4.x/getting-started/styling"
---
# 样式设置

> 学习如何为您的 Nuxt 应用程序设置样式。

Nuxt 在样式方面高度灵活。你可以编写自己的样式，或引用本地和外部样式表。你可以使用 CSS 预处理器、CSS 框架、UI 库和 Nuxt 模块来为你的应用添加样式。

## 本地样式表

如果你正在编写本地样式表，最合适的存放位置是 [`app/assets/` 目录](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/assets)。

### 在组件中导入

你可以在页面、布局和组件中直接导入样式表。可以使用 JavaScript 导入，或使用 CSS 的 [`@import` 语句](https://developer.mozilla.org/en-US/docs/Web/CSS/@import)。

```vue [app/pages/index.vue]
<script>
// 服务器端兼容性，使用静态导入
import '~/assets/css/first.css'

// 注意：动态导入不支持服务器端
import('~/assets/css/first.css')
</script>

<style>
@import url("~/assets/css/second.css");
</style>
```

<tip>

这些样式表将被内联到 Nuxt 渲染的 HTML 中。

</tip>

### css 属性

你也可以在 Nuxt 配置中使用 `css` 属性。
样式表最合适的存放位置是 [`app/assets/` 目录](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/assets)。然后你可以引用其路径，Nuxt 会将其包含在应用的所有页面中。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  css: ['~/assets/css/main.css'],
})
```

<tip>

这些样式表将被内联到 Nuxt 渲染的 HTML 中，作为全局样式注入并出现在所有页面中。

</tip>

### 字体处理

将本地字体文件放在你的 `public/` 目录中，例如 `public/fonts`。然后可以在样式表中使用 `url()` 来引用它们。

```css [assets/css/main.css]
@font-face {
  font-family: 'FarAwayGalaxy';
  src: url('/fonts/FarAwayGalaxy.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
```

然后在样式表、页面或组件中按名称引用你的字体：

```vue
<style>
h1 {
  font-family: 'FarAwayGalaxy', sans-serif;
}
</style>
```

### 通过 NPM 分发的样式表

你也可以引用通过 npm 分发的样式表。我们以流行的 `animate.css` 库为例。

<code-group sync="pm">

```bash [npm]
npm install animate.css
```

```bash [yarn]
yarn add animate.css
```

```bash [pnpm]
pnpm install animate.css
```

```bash [bun]
bun install animate.css
```

```bash [deno]
deno install npm:animate.css
```

</code-group>

然后你可以在页面、布局和组件中直接引用它：

```vue [app/app.vue]
<script>
import 'animate.css'
</script>

<style>
@import url("animate.css");
</style>
```

该包也可以作为字符串在你的 Nuxt 配置的 css 属性中引用。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  css: ['animate.css'],
})
```

## 外部样式表

你可以通过在 nuxt.config 文件的 head 部分添加 link 元素来在应用中包含外部样式表。你可以通过不同的方法实现该结果。注意，本地样式表也可以通过这种方式包含。

你可以使用 Nuxt 配置中的 [`app.head`](https://nuxt.zhcndoc.com/docs/4.x/api/nuxt-config#head) 属性来操作 head：

```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
  app: {
    head: {
      link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }],
    },
  },
})
```

### 动态添加样式表

你可以在代码中使用 useHead 组合式函数来动态设置 head 的值。

<read-more to="https://nuxt.zhcndoc.com/docs/4.x/api/composables/use-head">



</read-more>

```tstwoslash
useHead({
  link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }],
})
```

Nuxt 在底层使用 `unhead`，你可以参考 [它的完整文档](https://unhead.unjs.io)。

### 使用 Nitro 插件修改渲染的 head

如果你需要更高级的控制，可以使用钩子拦截渲染的 HTML 并以编程方式修改 head。

在 `~/server/plugins/my-plugin.ts` 中创建一个插件，如下所示：

```ts [server/plugins/my-plugin.ts]
export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook('render:html', (html) => {
    html.head.push('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">')
  })
})
```

外部样式表是阻塞渲染的资源：在浏览器渲染页面之前必须加载和处理它们。包含不必要的大量样式的网页渲染时间会更长。你可以在 [web.dev](https://web.dev/articles/defer-non-critical-css) 上阅读更多相关内容。

## 使用预处理器

要使用像 SCSS、Sass、Less 或 Stylus 这样的预处理器，先安装它们。

<code-group>

```bash [Sass & SCSS]
npm install -D sass
```

```bash [Less]
npm install -D less
```

```bash [Stylus]
npm install -D stylus
```

</code-group>

编写样式表的自然位置是 `app/assets` 目录。然后你可以在 `app.vue`（或布局文件）中使用预处理器语法导入源文件。

```vue [app/pages/app.vue]
<style lang="scss">
@use "~/assets/scss/main.scss";
</style>
```

或者，你可以使用 Nuxt 配置的 `css` 属性。

```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
  css: ['~/assets/scss/main.scss'],
})
```

<tip>

在这两种情况下，编译后的样式表都会被内联到 Nuxt 渲染的 HTML 中。

</tip>

如果你需要向预处理文件注入代码，例如包含颜色变量的 [Sass partial](https://sass-lang.com/documentation/at-rules/use#partials)，可以使用 Vite 的 [预处理器选项](https://vite.dev/config/shared-options#css-preprocessoroptions)。

在你的 `app/assets` 目录中创建一些 partials：

<code-group sync="preprocessor">

```scss [assets/_colors.scss]
$primary: #49240F;
$secondary: #E4A79D;
```

```sass [assets/_colors.sass]
$primary: #49240F
$secondary: #E4A79D
```

</code-group>

然后在你的 `nuxt.config` 中：

<code-group>

```ts [SCSS]twoslash
export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "~/assets/_colors.scss" as *;',
        },
      },
    },
  },
})
```

```ts [SASS]twoslash
export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorOptions: {
        sass: {
          additionalData: '@use "~/assets/_colors.sass" as *\n',
        },
      },
    },
  },
})
```

</code-group>

Nuxt 默认使用 Vite。如果你希望改用 webpack，请参考各预处理器 loader 的[文档](https://webpack.js.org/loaders/sass-loader)。

### 预处理器 Workers（实验性）

Vite 提供了一个[实验性选项](https://vite.dev/config/shared-options#css-preprocessormaxworkers)，可以加速预处理器的使用。

你可以在 `nuxt.config` 中启用它：

```ts
export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorMaxWorkers: true, // 你的 CPU 核数减 1
    },
  },
})
```

<note>

这是一个实验性选项，请参考 Vite 文档并[提供反馈](https://github.com/vitejs/vite/discussions/15835)。

</note>

## 单文件组件（SFC）样式

Vue 和 SFC 最棒的特性之一，就是它们能够自然而然地处理样式。你可以直接在组件文件的 style 块中编写 CSS 或预处理器代码，因此无需使用 CSS-in-JS 之类的工具，也能获得出色的开发体验。不过，如果你希望使用 CSS-in-JS，可以找到支持它的第三方库和模块，例如 [pinceau](https://github.com/Tahul/pinceau)。

你可以参考 [Vue 文档](https://vuejs.org/api/sfc-css-features) 获取有关在 SFC 中为组件添加样式的完整参考。

### class 和 style 绑定

你可以利用 Vue SFC 的特性，通过 class 和 style 属性来为组件添加样式。

<code-group>

```vue [Ref and Reactive]
<script setup lang="ts">
const isActive = ref(true)
const hasError = ref(false)
const classObject = reactive({
  'active': true,
  'text-danger': false,
})
</script>

<template>
  <div
    class="static"
    :class="{ 'active': isActive, 'text-danger': hasError }"
  />
  <div :class="classObject" />
</template>
```

```vue [Computed]
<script setup lang="ts">
const isActive = ref(true)
const error = ref(null)

const classObject = computed(() => ({
  'active': isActive.value && !error.value,
  'text-danger': error.value && error.value.type === 'fatal',
}))
</script>

<template>
  <div :class="classObject" />
</template>
```

```vue [Array]
<script setup lang="ts">
const isActive = ref(true)
const errorClass = ref('text-danger')
</script>

<template>
  <div :class="[{ active: isActive }, errorClass]" />
</template>
```

```vue [Style]
<script setup lang="ts">
const activeColor = ref('red')
const fontSize = ref(30)
const styleObject = reactive({ color: 'red', fontSize: '13px' })
</script>

<template>
  <div :style="{ color: activeColor, fontSize: fontSize + 'px' }" />
  <div :style="[baseStyles, overridingStyles]" />
  <div :style="styleObject" />
</template>
```

</code-group>

更多信息请参阅 [Vue 文档](https://vuejs.org/guide/essentials/class-and-style)。

### 使用 v-bind 的动态样式

你可以在 style 块中使用 v-bind 函数引用 JavaScript 变量和表达式。
这种绑定是动态的，这意味着如果变量值发生变化，样式也会随之更新。

```vue
<script setup lang="ts">
const color = ref('red')
</script>

<template>
  <div class="text">
    hello
  </div>
</template>

<style>
.text {
  color: v-bind(color);
}
</style>
```

### Scoped 样式

`scoped` 属性允许你将样式隔离到组件内部。使用此属性声明的样式只会应用于该组件。

```vue
<template>
  <div class="example">
    hi
  </div>
</template>

<style scoped>
.example {
  color: red;
}
</style>
```

### CSS Modules

你可以使用带有 `module` 属性的 [CSS Modules](https://github.com/css-modules/css-modules)。通过注入的 `$style` 变量访问它。

```vue
<template>
  <p :class="$style.red">
    This should be red
  </p>
</template>

<style module>
.red {
  color: red;
}
</style>
```

### 预处理器支持

SFC 的 style 块支持预处理器语法。Vite 对 .scss、.sass、.less、.styl 和 .stylus 文件提供开箱即用的支持，无需配置。你只需先安装相应包，然后即可在 SFC 中通过 lang 属性直接使用。

<code-group>

```vue [SCSS]
<style lang="scss">
  /* 编写 scss 代码 */
</style>
```

```vue [Sass]
<style lang="sass">
  /* 编写 sass 代码 */
</style>
```

```vue [LESS]
<style lang="less">
  /* 编写 less 代码 */
</style>
```

```vue [Stylus]
<style lang="stylus">
  /* 编写 stylus 代码 */
</style>
```

</code-group>

你可以参考 [Vite CSS 文档](https://vite.dev/guide/features#css) 和 [@vitejs/plugin-vue 文档](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue)。
对于 webpack 用户，请参考 [vue loader 文档](https://vue-loader.vuejs.org)。

## 使用 PostCSS

Nuxt 内置了 postcss。你可以在 `nuxt.config` 文件中进行配置。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  postcss: {
    plugins: {
      'postcss-nested': {},
      'postcss-custom-media': {},
    },
  },
})
```

为了在 SFC 中获得正确的语法高亮，你可以使用 postcss 的 lang 属性。

```vue
<style lang="postcss">
  /* 编写 postcss 代码 */
</style>
```

默认情况下，Nuxt 已经预配置了以下插件：

- [postcss-import](https://github.com/postcss/postcss-import)：增强 `@import` 规则
- [postcss-url](https://github.com/postcss/postcss-url)：转换 `url()` 语句
- [autoprefixer](https://github.com/postcss/autoprefixer)：自动添加厂商前缀
- [cssnano](https://cssnano.github.io/cssnano)：压缩和清理

## 使用布局实现多套样式

如果你需要对应用的不同部分使用完全不同的样式，可以使用布局。为不同的布局使用不同的样式。

```vue
<template>
  <div class="default-layout">
    <h1>Default Layout</h1>
    <slot />
  </div>
</template>

<style>
.default-layout {
  color: red;
}
</style>
```

<read-more to="https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/layouts">



</read-more>

## 第三方库和模块

Nuxt 在样式方面不做强制性选择，并为你提供了多种可选方案。你可以使用任何你想要的样式工具，例如流行的库 [UnoCSS](https://unocss.dev) 或 [Tailwind CSS](https://tailwindcss.com)。

社区和 Nuxt 团队已经开发了许多 Nuxt 模块以简化集成。你可以在网站的 [modules 部分](https://nuxt.zhcndoc.com/modules) 发现它们。以下是一些帮助你入门的模块：

- [UnoCSS](https://nuxt.zhcndoc.com/modules/unocss)：按需即时原子 CSS 引擎
- [Tailwind CSS](https://nuxt.zhcndoc.com/modules/tailwindcss)：实用优先的 CSS 框架
- [Fontaine](https://github.com/nuxt-modules/fontaine)：字体度量回退
- [Pinceau](https://github.com/Tahul/pinceau)：可适配的样式框架
- [Nuxt UI](https://ui.nuxt.com)：现代 Web 应用的 UI 库
- [Panda CSS](https://panda-css.com/docs/installation/nuxt)：在构建时生成原子 CSS 的 CSS-in-JS 引擎

Nuxt 模块开箱即用，为你提供出色的开发体验，但请记住，如果你喜欢的工具没有对应模块，并不意味着你不能在 Nuxt 中使用它！你可以为自己的项目自行配置。根据工具的不同，你可能需要使用 [Nuxt 插件](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/plugins) 和／或[创建自己的模块](https://nuxt.zhcndoc.com/docs/4.x/guide/modules)。如果你这样做了，请与[社区](https://nuxt.zhcndoc.com/modules)分享！

### 轻松加载 Web 字体

你可以使用 [Nuxt Google Fonts 模块](https://github.com/nuxt-modules/google-fonts) 来加载 Google 字体。

如果你正在使用 [UnoCSS](https://unocss.dev/integrations/nuxt)，请注意它自带 [web fonts 预设](https://unocss.dev/presets/web-fonts)，可以方便地从常见提供者（包括 Google Fonts 等）加载字体。

## 高级

### 过渡

Nuxt 内置了与 Vue 相同的 `<Transition>` 元素，也支持实验性的 [View Transitions API](https://nuxt.zhcndoc.com/docs/4.x/getting-started/transitions#view-transitions-api-experimental)。

<read-more to="https://nuxt.zhcndoc.com/docs/4.x/getting-started/transitions">



</read-more>

### 字体高级优化

我们建议使用 [Fontaine](https://github.com/nuxt-modules/fontaine) 来减少你的 [CLS](https://web.dev/cls)。如果你需要更高级的功能，可以考虑创建一个 Nuxt 模块来扩展构建过程或 Nuxt 运行时。

<tip>

请始终利用 Web 生态系统中各种可用的工具和技术，使为你的应用添加样式变得更简单、更高效。无论你使用原生 CSS、预处理器、postcss、UI 库还是模块，Nuxt 都能满足你的需求。祝你样式愉快！

</tip>

### LCP 高级优化

你可以通过以下方式加速全局 CSS 文件的下载：

- 使用 CDN，使文件更靠近你的用户
- 压缩你的资源，最好使用 Brotli
- 使用 HTTP2/HTTP3 进行传输
- 在同一域名下托管资源（不要使用不同的子域）

如果你使用像 Cloudflare、Netlify 或 Vercel 这样的现代平台，其中大多数优化会自动为你完成。
你可以在 [web.dev](https://web.dev/articles/optimize-lcp) 找到 LCP 优化指南。

如果你的所有 CSS 都被 Nuxt 内联，你可以（实验性地）完全阻止在渲染的 HTML 中引用外部 CSS 文件。
你可以通过一个钩子实现，该钩子可以放在模块中，或放在你的 Nuxt 配置文件中。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  hooks: {
    'build:manifest': (manifest) => {
      // 找到 app 入口的 css 列表
      const css = Object.values(manifest).find(options => options.isEntry)?.css
      if (css) {
        // 从数组末尾向前遍历
        for (let i = css.length - 1; i >= 0; i--) {
          // 如果以 'entry' 开头，则从数组中移除
          if (css[i].startsWith('entry')) {
            css.splice(i, 1)
          }
        }
      }
    },
  },
})
```


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
