Tailwind-添加自定义样式
在 Tailwind 项目中添加自定义样式的最佳实践。
在 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 通常可以根据您传入的值自动处理这种歧义
HTML
<!-- Will generate a font-size utility -->
<div class="text-[22px]">...</div>
<!-- Will generate a color utility -->
<div class="text-[#bada55]">...</div>但有时它确实是模棱两可的,例如在使用 CSS 变量时
<div class="text-(--my-var)">...</div>在这些情况下,您可以通过在值之前添加CSS 数据类型来“提示”Tailwind 底层类型
<!-- Will generate a font-size utility -->
<div class="text-(length:--my-var)">...</div>
<!-- Will generate a color utility -->
<div class="text-(color:--my-var)">...</div>使用自定义 CSS
虽然 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);
}
}添加组件类
对于您想要添加到项目中的任何更复杂的类,但仍然希望能够使用 utility 类覆盖它们,请使用 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 层中定义组件类,您仍然可以使用实用程序类在必要时覆盖它们
<!-- Will look like a card, but with square corners -->
<div class="card rounded-none">
<!-- ... -->
</div>使用 Tailwind,您可能不需要这些类型的类,就像您认为的那么频繁。请阅读我们的管理重复指南以获取我们的建议。
components 层也是放置您正在使用的任何第三方组件的自定义样式的绝佳位置
@layer components {
.select2-dropdown {
/* ... */
}
}使用变体
使用 @variant 指令在自定义 CSS 中应用 Tailwind 变体
app.css
.my-element {
background: white;
@variant dark {
background: black;
}
}编译后的 CSS
.my-element {
background: white;
@media (prefers-color-scheme: dark) {
background: black;
}
}如果您需要同时应用多个变体,请使用嵌套
app.css
.my-element {
background: white;
@variant dark {
@variant hover {
background: black;
}
}
}编译后的 CSS
.my-element {
background: white;
@media (prefers-color-scheme: dark) {
&:hover {
@media (hover: hover) {
background: black;
}
}
}
}添加自定义实用程序
简单实用程序
除了使用 Tailwind 附带的实用程序外,您还可以添加自己的自定义实用程序。当您想要在项目中使用 Tailwind 开箱即用不包含实用程序的 CSS 功能时,这可能很有用。
使用 @utility 指令向您的项目添加自定义 utility
@utility content-auto {
content-visibility: auto;
}您现在可以在 HTML 中使用此实用程序
<div class="content-auto">
<!-- ... -->
</div>它也适用于诸如 hover、focus 和 lg 之类的变体
<div class="hover:content-auto">
<!-- ... -->
</div>自定义实用程序与框架中所有内置实用程序一起自动插入到 utilities 层中。
复杂utility
如果您的自定义utility比单个类名更复杂,请使用嵌套来定义实用程序
@utility scrollbar-hidden {
&::-webkit-scrollbar {
display: none;
}
}函数型utility
除了使用 @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 之类的utility。
任意值
要支持任意值,请使用 --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] 之类的实用程序。
添加自定义变体
除了使用 Tailwind 附带的变体外,您还可以使用 @custom-variant 指令添加自己的自定义变体
@custom-variant theme-midnight {
&:where([data-theme="midnight"] *) {
@slot;
}
}现在您可以在 HTML 中使用 theme-midnight:<utility> 变体
<html data-theme="midnight">
<button class="theme-midnight:bg-black ..."></button>
</html>当不需要嵌套时,您可以使用速记语法创建变体
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));当自定义变体具有多个规则时,它们可以相互嵌套
@custom-variant any-hover {
@media (any-hover: hover) {
&:hover {
@slot;
}
}
}评论
评论加载中……