核心概念
在 Tailwind 项目中添加自定义样式的最佳实践。
在使用框架时,通常面临的最大挑战是要弄清楚当你需要框架没有处理的内容时该怎么办。
Tailwind 从一开始就设计成可扩展和可定制的,因此无论你构建什么,都不会觉得自己在与框架对抗。
本指南将涵盖定制设计令牌、如何在必要时突破这些约束、添加自定义 CSS 和使用插件扩展框架等主题。
如果你想更改颜色调色板、间距比例、排版比例或断点等内容,请使用 CSS 中的 @theme
指令添加自定义:
@theme { --font-display: "Satoshi", "sans-serif"; --breakpoint-3xl: 120rem; --color-avocado-100: oklch(0.99 0 0); --color-avocado-200: oklch(0.98 0.04 113.22); --color-avocado-300: oklch(0.94 0.11 115.03); --color-avocado-400: oklch(0.92 0.19 114.08); --color-avocado-500: oklch(0.84 0.18 117.33); --color-avocado-600: oklch(0.53 0.12 118.34); --ease-fluid: cubic-bezier(0.3, 0, 0, 1); --ease-snappy: cubic-bezier(0.2, 0, 0, 1); /* ... */}
要了解有关定制主题的更多信息,请查看 主题变量文档。
尽管通常可以使用有限的设计令牌集构建大部分精心设计的内容,但偶尔你需要突破这些约束以获得完美的像素效果。
当你发现在需要 top: 117px
的时候,以将背景图像放置在正确的位置时,可以使用 Tailwind 的方括号表示法动态生成具有任意值的类:
<div class="top-[117px]"> <!-- ... --></div>
这基本上就像内联样式,主要好处是你可以与 hover
和响应式修饰符(如 lg
)结合使用:
<div class="top-[117px] lg:top-[344px]"> <!-- ... --></div>
这适用于框架中的所有内容,包括背景颜色、字体大小、伪元素内容等:
<div class="bg-[#bada55] text-[22px] before:content-['Festivus']"> <!-- ... --></div>
如果你将 CSS 变量作为任意值引用,可以使用自定义属性语法:
<div class="fill-(--my-brand-color) ..."> <!-- ... --></div>
这实际上是 fill-[var(--my-brand-color)]
的简写,自动添加了 var()
函数。
如果你需要使用 Tailwind 默认未包含工具的 CSS 属性,还可以使用方括号表示法编写完全任意的 CSS:
<div class="[mask-type:luminance]"> <!-- ... --></div>
这 真的 像内联样式,但再次强调它的好处是你可以使用修饰符:
<div class="[mask-type:luminance] hover:[mask-type:alpha]"> <!-- ... --></div>
这对于 CSS 变量等情况也非常有用,尤其是当它们在不同条件下需要更改时:
<div class="[--scroll-offset:56px] lg:[--scroll-offset:44px]"> <!-- ... --></div>
任意 变体 就像任意值,但用于动态选择器修改,就像使用内置伪类变体 hover:{utility}
或响应式变体 md:{utility}
一样,但可以直接在 HTML 中使用方括号表示法。
<ul role="list"> {#each items as item} <li class="lg:[&:nth-child(-n+3)]:hover:underline">{item}</li> {/each}</ul>
在 任意变体 文档中了解更多信息。
当任意值需要包含空格时,请使用下划线 (_
) 代替,Tailwind 会在构建时自动将其转换为空格:
<div class="grid grid-cols-[1fr_500px_2fr]"> <!-- ... --></div>
在常见需要下划线但空格无效的情况下,Tailwind 会保留下划线而不是转换为空格,例如在 URL 中:
<div class="bg-[url('/what_a_rush.png')]"> <!-- ... --></div>
在罕见的情况下,如果你确实需要使用下划线,但由于空格也是有效的而导致歧义,可以用反斜杠转义下划线,Tailwind 不会将其转换为空格:
<div class="before:content-['hello\_world']"> <!-- ... --></div>
如果你在使用 JSX 之类的内容,反斜杠会从渲染的 HTML 中去掉,可以使用 String.raw() 以确保反斜杠不会被视为 JavaScript 转义字符:
<div className={String.raw`before:content-['hello\_world']`}> <!-- ... --></div>
Tailwind 中的许多实用工具共享一个公共命名空间,但映射到不同的 CSS 属性。例如 text-lg
和 text-black
都共享 text-
命名空间,但一个用于设置 font-size
,另一个用于设置 color
。
在使用任意值时,Tailwind 通常可以根据你传递的值自动处理这种歧义:
<!-- 将生成字体大小工具 --><div class="text-[22px]">...</div><!-- 将生成颜色工具 --><div class="text-[#bada55]">...</div>
不过有时确实会存在歧义,例如在使用 CSS 变量时:
<div class="text-(--my-var)">...</div>
在这种情况下,可以通过在值之前添加 CSS 数据类型 来“提示” Tailwind 基础类型:
<!-- 将生成字体大小工具 --><div class="text-(length:--my-var)">...</div><!-- 将生成颜色工具 --><div class="text-(color:--my-var)">...</div>
虽然 Tailwind 旨在处理大部分样式需求,但在需要时完全可以直接写普通 CSS:
@import "tailwindcss";.my-custom-style { /* ... */}
如果你只想为页面设置一些默认值(如文本颜色、背景颜色或字体系列),最简单的选项是将一些类添加到 html
或 body
元素:
<!doctype html><html lang="en" class="bg-gray-100 font-serif text-gray-900"> <!-- ... --></html>
这将基本样式决策保存在标记中,而不是隐藏在单独的文件中。
如果你想为特定 HTML 元素添加默认基本样式,请使用 @layer
指令将这些样式添加到 Tailwind 的 base
层:
@layer base { h1 { font-size: var(--text-2xl); } h2 { font-size: var(--text-xl); }}
使用 components
层为你想添加到项目中的任何复杂类,这些类仍然希望能够通过实用工具类进行重写。
传统上,这些类如 card
、btn
、badge
等。
@layer components { .card { background-color: var(--color-white); border-radius: var(--rounded-lg); padding: var(--spacing-6); box-shadow: var(--shadow-xl); }}
通过在 components
层中定义组件类,你仍然可以在必要时使用实用工具类来覆盖它们:
<!-- 将看起来像一个卡片,但具有平方角 --><div class="card rounded-none"> <!-- ... --></div>
使用 Tailwind 时,你可能不需要这些类型的类,阅读我们关于 管理重复 的指南以获取我们的建议。
components
层也是放置自定义样式的好地方,以便使用任何你正在使用的第三方组件:
@layer components { .select2-dropdown { /* ... */ }}
除了使用 Tailwind 附带的实用工具外,你还可以添加自己的自定义工具。这在你希望在项目中使用的 CSS 特性且 Tailwind 默认未包含工具时非常有用。
使用 @utility
指令将自定义工具添加到项目中:
@utility content-auto { content-visibility: auto;}
你现在可以在 HTML 中使用此工具:
<div class="content-auto"> <!-- ... --></div>
它也可以与 hover
、focus
和 lg
等变体一起使用:
<div class="hover:content-auto"> <!-- ... --></div>
自定义工具会自动插入到 utilities
层中,并与框架中的所有内置工具一起工作。
如果你的自定义工具比单个类名复杂,请使用嵌套定义工具:
@utility scrollbar-hidden { &::-webkit-scrollbar { display: none; }}
除了使用 @utility
指令注册简单工具外,你还可以注册接受参数的功能性工具:
@utility tab-* { tab-size: --value(--tab-size-*);}
特殊的 --value()
函数用于解析工具值。
使用 --value(--theme-key-*)
语法,将工具值解析为一组主题键:
@theme { --tab-size-2: 2; --tab-size-4: 4; --tab-size-github: 8;}@utility tab-* { tab-size: --value(--tab-size-*);}
这将匹配工具如 tab-2
、tab-4
和 tab-github
。
要将值解析为光秃值,请使用 --value({type})
语法,其中 {type}
是你希望验证该光秃值的数据类型:
@utility tab-* { tab-size: --value(integer);}
这将匹配工具如 tab-1
和 tab-76
。
要支持任意值,请使用 --value([{type}])
语法(请注意方括号),以告诉 Tailwind 哪些类型支持作为任意值:
@utility tab-* { tab-size: --value([integer]);}
这将匹配工具如 tab-[1]
和 tab-[76]
。如果要支持任何数据类型,可以使用 --value([*])
。
这三种形式的 --value()
函数可以在规则内作为多个声明使用,任何未能解析的声明将在输出中被省略:
@theme { --tab-size-github: 8;}@utility tab-* { tab-size: --value([integer]); tab-size: --value(integer); tab-size: --value(--tab-size-*);}
如果有必要,可以在每种情况下不同地处理该值,例如将光秃整数转换为百分比:
@utility opacity-* { opacity: --value([percentage]); opacity: calc(--value(integer) * 1%); opacity: --value(--opacity-*);}
--value()
函数还可以接受多个参数,并从左到右解析它们,如果你不需要在不同情况下不同地处理返回值:
@theme { --tab-size-github: 8;}@utility tab-* { tab-size: --value(--tab-size-*, integer, [integer]);}@utility opacity-* { opacity: calc(--value(integer) * 1%); opacity: --value(--opacity-*, [percentage]);}
要支持负值,将正值和负值分别注册为单独的实用工具:
@utility inset-* { inset: calc(var(--spacing) * --value([percentage], [length]));}@utility -inset-* { inset: calc(var(--spacing) * --value([percentage], [length]) * -1);}
通过使用 --modifier()
函数处理修饰符,它的工作方式与 --value()
函数完全相同,但针对存在的修饰符操作:
@utility text-* { font-size: --value(--text-*, [length]); line-height: --modifier(--leading-*, [length], [*]);}
如果没有修饰符,则任何依赖于修饰符的声明在输出中将不会包含。
为了处理分数,我们依赖 CSS 的 ratio
数据类型。如果与 --value()
一起使用,则信号 Tailwind 将值和修饰符视为一个值:
@utility aspect-* { aspect-ratio: --value(--aspect-ratio-*, ratio, [ratio]);}
这将匹配工具如 aspect-square
、aspect-3/4
和 aspect-[7/9]
。
使用 @variant
指令在自定义 CSS 中应用 Tailwind 变体:
.my-element { background: white; @variant dark { background: black; }}
如果需要同时应用多个变体,可以使用嵌套:
.my-element { background: white; @variant dark { @variant hover { background: black; } }}