1. 核心概念
  2. 添加自定义样式

使用框架时最大的挑战通常是弄清楚当你需要框架无法为你处理的事情时你应该做什么。

¥Often the biggest challenge when working with a framework is figuring out what you’re supposed to do when there’s something you need that the framework doesn’t handle for you.

Tailwind 从一开始就被设计成可扩展和可定制的,因此无论你在构建什么,你都不会觉得自己在与框架作斗争。

¥Tailwind has been designed from the ground up to be extensible and customizable, so that no matter what you’re building you never feel like you’re fighting the framework.

本指南涵盖的主题包括自定义你的设计标记、如何在必要时打破这些限制、添加你自己的自定义 CSS 以及使用插件扩展框架。

¥This guide covers topics like customizing your design tokens, how to break out of those constraints when necessary, adding your own custom CSS, and extending the framework with plugins.

自定义主题

¥Customizing your theme

如果你想更改调色板、间距比例、排版比例或断点等内容,请将自定义添加到 tailwind.config.js 文件的 theme 部分:

¥If you want to change things like your color palette, spacing scale, typography scale, or breakpoints, add your customizations to the theme section of your tailwind.config.js file:

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    screens: {
      sm: '480px',
      md: '768px',
      lg: '976px',
      xl: '1440px',
    },
    colors: {
      'blue': '#1fb6ff',
      'pink': '#ff49db',
      'orange': '#ff7849',
      'green': '#13ce66',
      'gray-dark': '#273444',
      'gray': '#8492a6',
      'gray-light': '#d3dce6',
    },
    fontFamily: {
      sans: ['Graphik', 'sans-serif'],
      serif: ['Merriweather', 'serif'],
    },
    extend: {
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      borderRadius: {
        '4xl': '2rem',
      }
    }
  }
}

主题配置 文档中了解有关自定义主题的更多信息。

¥Learn more about customizing your theme in the Theme Configuration documentation.


使用任意值

¥Using arbitrary values

虽然你通常可以使用一组受限的设计标记来构建大量精心设计的设计,但有时你需要突破这些限制以获得像素完美的东西。

¥While you can usually build the bulk of a well-crafted design using a constrained set of design tokens, once in a while you need to break out of those constraints to get things pixel-perfect.

当你发现自己真的需要像 top: 117px 这样的东西来在正确的位置获得背景图片时,使用 Tailwind 的方括号符号来动态生成一个具有任意值的类:

¥When you find yourself really needing something like top: 117px to get a background image in just the right spot, use Tailwind’s square bracket notation to generate a class on the fly with any arbitrary value:

<div class="top-[117px]">
  <!-- ... -->
</div>

这基本上类似于内联样式,主要好处是你可以将它与交互式修饰符(如 hover)和响应式修饰符(如 lg)结合使用:

¥This is basically like inline styles, with the major benefit that you can combine it with interactive modifiers like hover and responsive modifiers like lg:

<div class="top-[117px] lg:top-[344px]">
  <!-- ... -->
</div>

这适用于框架中的所有内容,包括背景颜色、字体大小、伪元素内容等:

¥This works for everything in the framework, including things like background colors, font sizes, pseudo-element content, and more:

<div class="bg-[#bada55] text-[22px] before:content-['Festivus']">
  <!-- ... -->
</div>

甚至可以使用 theme 函数 来引用 tailwind.config.js 文件中的设计标记:

¥It’s even possible to use the theme function to reference the design tokens in your tailwind.config.js file:

<div class="grid grid-cols-[fit-content(theme(spacing.32))]">
  <!-- ... -->
</div>

当使用 CSS 变量作为任意值时,不需要将变量封装在 var(...) 中 - 只需提供实际的变量名称就足够了:

¥When using a CSS variable as an arbitrary value, wrapping your variable in var(...) isn’t needed — just providing the actual variable name is enough:

<div class="bg-[--my-color]">
  <!-- ... -->
</div>

任意属性

¥Arbitrary properties

如果你需要使用 Tailwind 不包含开箱即用工具的 CSS 属性,你还可以使用方括号表示法来编写完全任意的 CSS:

¥If you ever need to use a CSS property that Tailwind doesn’t include a utility for out of the box, you can also use square bracket notation to write completely arbitrary CSS:

<div class="[mask-type:luminance]">
  <!-- ... -->
</div>

这真的很像内联样式,但同样的好处是你可以使用修饰符:

¥This is really like inline styles, but again with the benefit that you can use modifiers:

<div class="[mask-type:luminance] hover:[mask-type:alpha]">
  <!-- ... -->
</div>

这对于 CSS 变量之类的东西也很有用,尤其是当它们需要在不同条件下更改时:

¥This can be useful for things like CSS variables as well, especially when they need to change under different conditions:

<div class="[--scroll-offset:56px] lg:[--scroll-offset:44px]">
  <!-- ... -->
</div>

任意变体

¥Arbitrary variants

任意变体类似于任意值,但用于进行即时选择器修改,就像你可以使用内置伪类变体(如 hover:{utility})或响应式变体(如 md:{utility})一样,但直接在 HTML 中使用方括号表示法。

¥Arbitrary variants are like arbitrary values but for doing on-the-fly selector modification, like you can with built-in pseudo-class variants like hover:{utility} or responsive variants like md:{utility} but using square bracket notation directly in your HTML.

<ul role="list">
{#each items as item}
  <li class="lg:[&:nth-child(3)]:hover:underline">{item}</li>
{/each}
</ul>

任意变体 文档中了解更多信息。

¥Learn more in the arbitrary variants documentation.

处理空格

¥Handling whitespace

当任意值需要包含空格时,请改用下划线 (_),Tailwind 会在构建时自动将其转换为空格:

¥When an arbitrary value needs to contain a space, use an underscore (_) instead and Tailwind will automatically convert it to a space at build-time:

<div class="grid grid-cols-[1fr_500px_2fr]">
  <!-- ... -->
</div>

在下划线很常见但空格无效的情况下,Tailwind 将保留下划线而不是将其转换为空格,例如在 URL 中:

¥In situations where underscores are common but spaces are invalid, Tailwind will preserve the underscore instead of converting it to a space, for example in URLs:

<div class="bg-[url('/what_a_rush.png')]">
  <!-- ... -->
</div>

在极少数情况下,你实际上需要使用下划线,但由于空格也有效而导致歧义,请使用反斜杠转义下划线,Tailwind 不会将其转换为空格:

¥In the rare case that you actually need to use an underscore but it’s ambiguous because a space is valid as well, escape the underscore with a backslash and Tailwind won’t convert it to a space:

<div class="before:content-['hello\_world']">
  <!-- ... -->
</div>

如果你使用的是像 JSX 这样的东西,其中反斜杠从渲染的 HTML 中剥离,请使用 String.raw() 这样反斜杠就不会被视为 JavaScript 转义字符:

¥If you’re using something like JSX where the backslash is stripped from the rendered HTML, use String.raw() so the backslash isn’t treated as a JavaScript escape character:

<div className={String.raw`before:content-['hello\_world']`}>
  <!-- ... -->
</div>

解决歧义

¥Resolving ambiguities

Tailwind 中的许多工具共享一个公共命名空间,但映射到不同的 CSS 属性。例如 text-lgtext-black 都共享 text- 命名空间,但一个用于 font-size,另一个用于 color

¥Many utilities in Tailwind share a common namespace but map to different CSS properties. For example text-lg and text-black both share the text- namespace, but one is for font-size and the other is for color.

使用任意值时,Tailwind 通常可以根据你传入的值自动处理这种歧义:

¥When using arbitrary values, Tailwind can generally handle this ambiguity automatically based on the value you pass in:

<!-- Will generate a font-size utility -->
<div class="text-[22px]">...</div>

<!-- Will generate a color utility -->
<div class="text-[#bada55]">...</div>

有时它确实是模棱两可的,例如在使用 CSS 变量时:

¥Sometimes it really is ambiguous though, for example when using CSS variables:

<div class="text-[var(--my-var)]">...</div>

在这些情况下,你可以通过在值前添加 CSS 数据类型 将基础类型 “hint” 为 Tailwind:

¥In these situations, you can “hint” the underlying type to Tailwind by adding a CSS data type before the value:

<!-- Will generate a font-size utility -->
<div class="text-[length:var(--my-var)]">...</div>

<!-- Will generate a color utility -->
<div class="text-[color:var(--my-var)]">...</div>

使用 CSS 和@layer

¥Using CSS and @layer

当你需要向 Tailwind 项目添加真正自定义的 CSS 规则时,最简单的方法是将自定义 CSS 添加到你的样式表中:

¥When you need to add truly custom CSS rules to a Tailwind project, the easiest approach is to just add the custom CSS to your stylesheet:

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

.my-custom-style {
  /* ... */
}

要获得更多功能,你还可以使用 @layer 指令将样式添加到 Tailwind 的 basecomponentsutilities 层:

¥For more power, you can also use the @layer directive to add styles to Tailwind’s base, components, and utilities layers:

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .my-custom-style {
    /* ... */
  }
}
为什么 Tailwind 将样式分组为 “layers”?

在 CSS 中,当两个选择器具有相同的特异性时,样式表中规则的顺序决定了哪个声明获胜:

¥In CSS, the order of the rules in your stylesheet decides which declaration wins when two selectors have the same specificity:

.btn {
  background: blue;
  /* ... */
}

.bg-black {
  background: black;
}

在这里,两个按钮都是黑色的,因为 .bg-black 在 CSS 中位于 .btn 之后:

¥Here, both buttons will be black since .bg-black comes after .btn in the CSS:

<button class="btn bg-black">...</button>
<button class="bg-black btn">...</button>

为了解决这个问题,Tailwind 将其生成的样式组织成三个不同的 “layers” — 这是 ITCSS 推广的概念。

¥To manage this, Tailwind organizes the styles it generates into three different “layers” — a concept popularized by ITCSS.

  • base 层用于重置规则或应用于纯 HTML 元素的默认样式。

    ¥The base layer is for things like reset rules or default styles applied to plain HTML elements.

  • components 层用于你希望能够使用工具覆盖的基于类的样式。

    ¥The components layer is for class-based styles that you want to be able to override with utilities.

  • utilities 层用于小型、单一用途的类,这些类应始终优先于任何其他样式。

    ¥The utilities layer is for small, single-purpose classes that should always take precedence over any other styles.

明确这一点可以更容易地理解你的样式将如何相互交互,并且使用 @layer 指令可以让你控制最终的声明顺序,同时仍然以你喜欢的任何方式组织你的实际代码。

¥Being explicit about this makes it easier to understand how your styles will interact with each other, and using the @layer directive lets you control the final declaration order while still organizing your actual code in whatever way you like.

@layer 指令通过自动将样式重新定位到相应的 @tailwind 指令来帮助你控制声明顺序,还可以为你自己的自定义 CSS 启用 modifierstree-shaking 等功能。

¥The @layer directive helps you control declaration order by automatically relocating your styles to the corresponding @tailwind directive, and also enables features like modifiers and tree-shaking for your own custom CSS.

添加基本样式

¥Adding base styles

如果你只想为页面设置一些默认值(如文本颜色、背景颜色或字体系列),最简单的选择就是向 htmlbody 元素添加一些类:

¥If you just want to set some defaults for the page (like the text color, background color, or font family), the easiest option is just adding some classes to the html or body elements:

<!doctype html>
<html lang="en" class="text-gray-900 bg-gray-100 font-serif">
  <!-- ... -->
</html>

这会将你的基本样式决策与所有其他样式一起保存在标记中,而不是将它们隐藏在单独的文件中。

¥This keeps your base styling decisions in your markup alongside all of your other styles, instead of hiding them in a separate file.

如果你想为特定的 HTML 元素添加自己的默认基本样式,请使用 @layer 指令将这些样式添加到 Tailwind 的 base 层:

¥If you want to add your own default base styles for specific HTML elements, use the @layer directive to add those styles to Tailwind’s base layer:

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  h1 {
    @apply text-2xl;
  }
  h2 {
    @apply text-xl;
  }
  /* ... */
}

如果要引用 theme 中定义的任何值,请在添加自定义基本样式时使用 theme 函数或 @apply 指令。

¥Use the theme function or @apply directive when adding custom base styles if you want to refer to any of the values defined in your theme.

添加组件类

¥Adding component classes

components 层用于你想要添加到你的项目中的任何更复杂的类,你仍然希望能够使用工具类覆盖这些类。

¥Use the components layer for any more complicated classes you want to add to your project that you’d still like to be able to override with utility classes.

传统上,这些类是 cardbtnbadge 之类的类。

¥Traditionally these would be classes like card, btn, badge — that kind of thing.

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .card {
    background-color: theme('colors.white');
    border-radius: theme('borderRadius.lg');
    padding: theme('spacing.6');
    box-shadow: theme('boxShadow.xl');
  }
  /* ... */
}

通过在 components 层定义组件类,必要时仍然可以使用实用类来覆盖它们:

¥By defining component classes in the components layer, you can still use utility classes to override them when necessary:

<!-- Will look like a card, but with square corners -->
<div class="card rounded-none">
  <!-- ... -->
</div>

使用 Tailwind,你可能并不像你想象的那样经常需要这些类型的类。阅读我们关于 重用样式 的指南,了解我们的建议。

¥Using Tailwind you probably don’t need these types of classes as often as you think. Read our guide on Reusing Styles for our recommendations.

components 层也是为你使用的任何第三方组件放置自定义样式的好地方:

¥The components layer is also a good place to put custom styles for any third-party components you’re using:

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .select2-dropdown {
    @apply rounded-b-lg shadow-md;
  }
  .select2-search {
    @apply border border-gray-300 rounded;
  }
  .select2-results__group {
    @apply text-lg font-bold text-gray-900;
  }
  /* ... */
}

如果要引用 theme 中定义的任何值,请在添加自定义组件样式时使用 theme 函数或 @apply 指令。

¥Use the theme function or @apply directive when adding custom component styles if you want to refer to any of the values defined in your theme.

添加自定义工具

¥Adding custom utilities

将你自己的任何自定义工具类添加到 Tailwind 的 utilities 层:

¥Add any of your own custom utility classes to Tailwind’s utilities layer:

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .content-auto {
    content-visibility: auto;
  }
}

当你希望在项目中使用某个 CSS 功能,而 Tailwind 不包含开箱即用的工具时,这会很有用。

¥This can be useful when there’s a CSS feature you’d like to use in your project that Tailwind doesn’t include utilities for out of the box.

在自定义 CSS 中使用修饰符

¥Using modifiers with custom CSS

你使用 @layer 添加到 Tailwind 的任何自定义样式都将自动支持 Tailwind 的修饰符语法,用于处理悬停状态、响应式断点、夜间模式等内容。

¥Any custom styles you add to Tailwind with @layer will automatically support Tailwind’s modifier syntax for handling things like hover states, responsive breakpoints, dark mode, and more.

CSS
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .content-auto {
    content-visibility: auto;
  }
}
HTML
<div class="lg:dark:content-auto">
  <!-- ... -->
</div>

悬停、聚焦、以及其他状态 文档中了解有关这些修饰符如何工作的更多信息。

¥Learn more about how these modifiers work in the Hover, Focus, and Other States documentation.

删除未使用的自定义 CSS

¥Removing unused custom CSS

你添加到 basecomponentsutilities 层的任何自定义样式只有在你的 HTML 中实际使用这些样式时才会包含在你编译的 CSS 中。

¥Any custom styles you add to the base, components, or utilities layers will only be included in your compiled CSS if those styles are actually used in your HTML.

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  /* This won't be included in your compiled CSS unless you actually use it */
  .card {
    /* ... */
  }
}

如果你想添加一些应该始终包含的自定义 CSS,请将其添加到你的样式表中而不使用 @layer 指令:

¥If you want to add some custom CSS that should always be included, add it to your stylesheet without using the @layer directive:

main.css
@tailwind base;
@tailwind components;

/* This will always be included in your compiled CSS */
.card {
  /* ... */
}

@tailwind utilities;

确保将你的自定义样式放在它们需要去的地方以获得你想要的优先行为。在上面的示例中,我们在 @tailwind utilities 之前添加了 .card 类,以确保工具仍然可以覆盖它。

¥Make sure to put your custom styles where they need to go to get the precedence behavior you want. In the example above, we’ve added the .card class before @tailwind utilities to make sure utilities can still override it.

使用多个 CSS 文件

¥Using multiple CSS files

如果你正在编写大量 CSS 并将其组织到多个文件中,请确保在使用 Tailwind 处理它们之前将这些文件合并到一个样式表中,否则你会看到有关在没有相应的 @tailwind 指令的情况下使用 @layer 的错误。

¥If you are writing a lot of CSS and organizing it into multiple files, make sure those files are combined into a single stylesheet before processing them with Tailwind, or you’ll see errors about using @layer without the corresponding @tailwind directive.

最简单的方法是使用 postcss-import 插件:

¥The easiest way to do this is using the postcss-import plugin:

postcss.config.js
module.exports = {
  plugins: {
    'postcss-import': {},
    tailwindcss: {},
    autoprefixer: {},
  }
}

在我们的 构建时导入 文档中了解更多信息。

¥Learn more in our build-time imports documentation.

图层和每个组件的 CSS

¥Layers and per-component CSS

Vue 和 Svelte 等组件框架支持在每个组件文件中的 <style> 块中添加每个组件的样式。

¥Component frameworks like Vue and Svelte support adding per-component styles within a <style> block that lives in each component file.

虽然你可以像这样在组件样式中使用 @applytheme 等功能,但 @layer 指令将不起作用,你会看到有关在没有匹配的 @tailwind 指令的情况下使用 @layer 的错误:

¥While you can use features like @apply and theme inside component styles like this, the @layer directive will not work and you’ll see an error about @layer being used without a matching @tailwind directive:

不要在组件样式中使用 @layer

Card.svelte
<div>
  <slot></slot>
</div>

<style>
  /* Won't work because this file is processed in isolation */
  @layer components {
    div {
      background-color: theme('colors.white');
      border-radius: theme('borderRadius.lg');
      padding: theme('spacing.6');
      box-shadow: theme('boxShadow.xl');
    }
  }
</style>

这是因为在幕后,像 Vue 和 Svelte 这样的框架正在独立处理每个 <style> 块,并针对每个块单独运行 PostCSS 插件链。

¥This is because under-the-hood, frameworks like Vue and Svelte are processing every single <style> block independently, and running your PostCSS plugin chain against each one in isolation.

这意味着如果你有 10 个组件,每个组件都有一个 <style> 块,Tailwind 将单独运行 10 次,并且每次运行对其他运行的了解为零。因此,Tailwind 无法获取你在 @layer 中定义的样式并将它们移动到相应的 @tailwind 指令,因为据 Tailwind 所知,没有 @tailwind 指令可将其移动到。

¥That means if you have 10 components that each have a <style> block, Tailwind is being run 10 separate times, and each run has zero knowledge about the other runs. Because of this, Tailwind can’t take the styles you define in a @layer and move them to the corresponding @tailwind directive, because as far as Tailwind can tell there is no @tailwind directive to move it to.

一种解决方案是在组件样式中不使用 @layer

¥One solution to this is to simply not use @layer inside your component styles:

不使用 @layer 添加你的样式

Card.svelte
<div>
  <slot></slot>
</div>

<style>
  div {
    background-color: theme('colors.white');
    border-radius: theme('borderRadius.lg');
    padding: theme('spacing.6');
    box-shadow: theme('boxShadow.xl');
  }
</style>

你失去了控制样式优先级的能力,但不幸的是,由于这些工具的工作方式,这完全超出了我们的控制范围。

¥You lose the ability to control the precedence of your styles, but unfortunately that’s totally out of our control because of how these tools work.

我们的建议是,你根本不要使用这样的组件样式,而是按照其预期的使用方式使用 Tailwind - 作为单个全局样式表,你可以直接在 HTML 中使用这些类:

¥Our recommendation is that you just don’t use component styles like this at all and instead use Tailwind the way it’s intended to be used — as a single global stylesheet where you use the classes directly in your HTML:

使用 Tailwind 的工具而不是组件样式

Card.svelte
<div class="bg-white rounded-lg p-6 shadow-xl">
  <slot></slot>
</div>

编写插件

¥Writing plugins

你还可以使用 Tailwind 的插件系统而不是使用 CSS 文件向你的项目添加自定义样式:

¥You can also add custom styles to your project using Tailwind’s plugin system instead of using a CSS file:

tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  // ...
  plugins: [
    plugin(function ({ addBase, addComponents, addUtilities, theme }) {
      addBase({
        'h1': {
          fontSize: theme('fontSize.2xl'),
        },
        'h2': {
          fontSize: theme('fontSize.xl'),
        },
      })
      addComponents({
        '.card': {
          backgroundColor: theme('colors.white'),
          borderRadius: theme('borderRadius.lg'),
          padding: theme('spacing.6'),
          boxShadow: theme('boxShadow.xl'),
        }
      })
      addUtilities({
        '.content-auto': {
          contentVisibility: 'auto',
        }
      })
    })
  ]
}

插件 文档中了解有关编写自己的插件的更多信息。

¥Learn more about writing your own plugins in the Plugins documentation.