70k Star 的 Tailwind CSS 为何这么火?(上)https://developer.aliyun.com/article/1411598
清除
默认情况下,Tailwind 生成如此多的类,最终未压缩的 CSS 大小达到 3739.4 kB,这是巨大的。 可以仔细选择要启用或禁用的实用程序,禁用所有未使用的变体和不太常见的断点,但最终仍然需要清除所有未使用的类和变体。
Tailwind CSS 使用 PurgeCSS 来对未使用的样式进行 tree-shake 并获得更小的最终 CSS。 默认情况下,PurgeCSS 仅在生产模式下运行。
配置文件公开了可以根据需要自定义的清除参数。 首先,可以使用 Tailwind CSS 实用程序提供每个文件的简单路径数组,以便 PurgeCSS 可以检测要保留哪些类以及要删除哪些类:
module.exports = { purge: [ './src/**/*.html', './src/**/*.vue', './src/**/*.jsx', ], theme: {}, variants: {}, plugins: [], }
重要的是要包含按名称引用 Tailwind 实用程序之一的每个可能文件,例如动态切换某些类的 JavaScript 文件; 如果不这样做,PurgeCSS 将看不到这些类在其他地方使用,并且如果不在其他地方使用,则会将其删除。
Tailwind CSS 技巧
这一部分来探讨一些可以显着增强开发体验的 Tailwind 技巧。
动态实用程序类
Tailwind 会清除未使用的类,这就是为什么它能够拥有如此多的功能,同时仍然保持我 CSS 包尺寸较小。 因此,如果想使用动态类名,则需要将所有想要的类名写入代码中的某个位置。 这是为了让 Tailwind 能够静态分析代码。
例如,这样是行不通的:
const DoesntWork = () => { const colors = ['red', 'green', 'yellow']; const [color, setColor] = React.useState(colors[0]); const changeColor = () => { setColor('green'); }; return ( <> <div className={`w-40 h-40 border bg-${color}-500`}></div> <select value={color} className={`bg-${color}-500`} onChange={(e) => setColor(e.target.value)} > <option value="">choose</option> {colors.map((c) => ( <option key={c} value={c}> {c} </option> ))} </select> <button onClick={changeColor}>Change color</button> </> ); };
这是因为 Tailwind 无法静态地找到它的类。 bg-${color}-500
需要在运行时进行评估。 但是,如果确实使用完整的类名,Tailwind 编译器可以使其工作:
const Works = () => { const colors = ['bg-red-500', 'bg-green-500', 'bg-yellow-500']; const [color, setColor] = React.useState(colors[0]); const changeColor = () => { setColor('bg-green-500'); }; return ( <> <div className={`w-40 h-40 border ${color}`}></div> <select value={color} className={`${color}`} onChange={(e) => setColor(e.target.value)} > <option value="">choose</option> {colors.map((c) => ( <option key={c} value={c}> {c} </option> ))} </select> <button onClick={changeColor}>Change color</button> </> ); };
在 CSS 中使用 Tailwind
有时需要使用 CSS 来设计样式,例如,当使用第三方库时。 这时就可以通过使用 @apply
指令或 theme
函数来使用 Tailwind 颜色,下面来看一个例子:
.__some-external-class { /* 通过 @apply 可以使用 Tailwind 中的任何实用程序类名称 */ @apply text-blue-300 bg-gray-300 py-2 px-6 rounded-lg uppercase; /* 或使用 theme() 函数 */ color: theme('colors.blue.300'); background-color: theme('colors.gray.300'); padding: theme('padding.2') theme('padding.6'); border-radius: theme('borderRadius.lg'); text-transform: uppercase; }
任意值
在 Tailwind 中编写纯 CSS 的另一种方法是使用方括号 ([]
)。 这就是所谓的“任意值”。可以这样做:
html
复制代码
<divclass="w-[100vw] bg-[rebbecapurple]">div>
更重要的是,还可以使用 theme
函数:
html
复制代码
<divclass="grid grid-cols-[fit-content(theme(spacing.32))]"> div>
如果想引用 CSS 自定义属性,则无需使用 var
关键字(自 v3.3 起)。 可以直接将 CSS 变量作为任意值传递:
html
复制代码
<divclass="bg-[--my-color]"> div>
此外,还可以轻松定义自定义变量,如下所示:
html
复制代码
<divclass="--my-color: rebbecapurple"> <h1class="bg-[--my-color]">Helloh1>div>
group
和 peer
实用程序类
Tailwind 允许使用帮助类(如:hover
、:checked
、:disabled
、:focus
等)根据元素的状态来更改其样式。因此,可以轻松实现以下效果:
html
复制代码
<buttonclass="bg-purple-500 border border-blue-500 text-white text-2xl uppercase p-6 rounded-md m-4 transition-colors hover:bg-purple-800 hover:border-blue-200 hover:text-gray-200">Click me!button>
结果如下:如果想根据另一个元素的状态更改样式怎么办? 这就是对等和组实用程序类派上用场的地方。
基于父状态的样式
例如,当父元素悬停时,可以通过将父元素转变为组并使用 group
和 group-hover:
实用程序类来更改子元素的样式:
<div class="group"> <div class="bg-gray-200">父元素</div> <p class="hidden group-hover:block">子元素</p> </div>
css
.group:hover .group-hover\:block { /* 悬停时子元素的样式 */ display: block; }
在上述代码中,父元素使用 group
类来标识自己为组,并且子元素使用了 hidden
类来初始隐藏。然后,通过使用 group-hover:
前缀,将子元素的样式设置为在父元素悬停时显示(即 display: block
)。这样就实现了基于父状态改变子元素样式的效果。
基于兄弟状态的样式
对等类修饰符可用于根据同级元素的状态来设置元素的样式。可以使用peer-{modifier}
,其中{modifier}
可以是任何伪类修饰符。
这是一个简单的例子: HTML:
<div> <buttonclass="peer-hover:bg-blue-500">按钮button> <button>另一个按钮button>div>
CSS:
.peer-hover\:bg-blue-500:hover ~ button {
/* 鼠标悬停时第二个按钮的背景色改变 */ background-color: #6EE7B7;}
在上面的示例中,当鼠标悬停在第一个按钮上时,通过使用 peer-hover:bg-blue-500
类,在同级元素中选择后续兄弟元素(即第二个按钮),并将其背景色更改为蓝色(即 background-color: #6EE7B7;
)。
重命名
在使用 Tailwind CSS 的 group
和 peer
实用程序类时,您可以为组和同级元素分配唯一的名称,以区分不同的组和同级元素。 HTML:
<div class="group group-example"> <div class="bg-gray-200">父元素</div> <p class="hidden group-example:hover:block">子元素</p> </div>
css
.group-example:hover .group-example:hover\:block { /* 悬停时子元素的样式 */ display: block; }
在上述代码中,在 group
类和同级元素的实用程序类后面添加了 /example
,将其分配为唯一名称。这样可以确保这些类只会应用于特定的组和同级元素之间,而不会与其他地方使用相同的类产生冲突。
动画实用类
Tailwind 有一些非常有用且易于使用的动画实用程序类。 例如,可以添加过渡颜色类并设置 300 毫秒的持续时间,以在悬停时创建平滑的颜色变化效果。还可以传递动画曲线和动画延迟:
html
复制代码
<divclass="... hover:bg-gray-300 transition-colors duration-300 ease-in-out" />
几乎所有可设置动画的属性都可供开发者使用。除此之外,还有一些预制动画可用,例如:animate-spin
、animate-ping
、animate-bounce
和 animate-pulse
。
响应式设计
Tailwind 是一个移动优先框架,这意味着无前缀的实用程序对所有屏幕尺寸都有效,而带前缀的实用程序会覆盖特定断点及以上断点处的样式。这有助于首先编写 CSS 移动设备,因为需要从小屏幕到大屏幕进行定义。
假设想要一个图像或视频网格,希望设计在移动设备上为一列,然后在较大的屏幕上为 2 列,在桌面上为 3 列我们会这样写:
<div class="grid grid-cols-1 gap-10 p-5 sm:grid-cols-2 md:grid-cols-3"> <div class="w-full aspect-video bg-cyan-500"></div> <div class="w-full aspect-video bg-cyan-500"></div> <div class="w-full aspect-video bg-cyan-500"></div> <div class="w-full aspect-video bg-cyan-500"></div> <div class="w-full aspect-video bg-cyan-500"></div> <div class="w-full aspect-video bg-cyan-500"></div> </div>
自定义最小和最大实用程序类也可用于更动态的用例。 此外,可以将自定义断点添加到 tailwind.config.js
配置文件中。
编辑器扩展
适用于 IDE 的 Tailwind CSS Intellisense 扩展是 Tailwind 如此易用的主要原因之一。 它会自动完成类名称,显示正在使用的颜色,并在将鼠标悬停在类上时解释该类的详细信息。除此之外,还可以使用 Tailwind Prettier 插件让 Prettier 对类进行排序。
创建自定义实用程序类
可以使用 Tailwind 配置文件来创建自定义实用程序类。 如果想在应用的多个位置使用特定样式,这非常有用。 因此,如果想添加另一个盒子阴影类,那么就需要这样做:
// tailwind.config.js module.exports = { content: ['./src/**/*.{html,js}'], theme: { extend: { boxShadow: { neon: "0 0 5px theme('colors.purple.200'), 0 0 20px theme('colors.purple.700')" } } }, }
然后可以在代码中这样来使用它:
html
复制代码
<divclass="w-20 h-10 rounded shadow-neon">div>
创建自定义 Tailwind 插件
如果希望能够通过传递颜色来选择自定义实用程序的颜色,需要制作自定义 Tailwind 插件,它允许我们创建非常灵活且可重用的实用程序。
下面来重用霓虹灯阴影示例。要添加该功能,可以在 tailwind.config.js 中定义插件:
// tailwind.config.js const plugin = require('tailwindcss/plugin'); module.exports = { content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], theme: { // ... our previous config }, plugins: [ // 获取颜色可以使用"theme"属性 plugin(({ theme, addUtilities }) => { const neonUtilities = {}; const colors = theme('colors'); // 遍历颜色 for (const color in colors) { // 检查颜色是否为对象,因为Tailwind中的一些颜色是对象而另一些是字符串 if (typeof colors[color] === 'object') { // 选择使用两种颜色 const color1 = colors[color]['500']; const color2 = colors[color]['700']; // 在这里构建实际的类名 neonUtilities[`.neon-${color}`] = { boxShadow: `0 0 5px ${color1}, 0 0 20px ${color2}`, }; } } // 这将把实用程序类添加到Tailwind中 addUtilities(neonUtilities); }), ], };
然后可以直接在 HTML(或 JSX)中使用新创建的实用程序类:
html
复制代码
<divclass="m-20 w-20 h-10 rounded-lg neon-blue">div>
可以在 Tailwind 调色板中更改为想要的任何颜色:
将 Tailwind 颜色导入为对象
可以将 Tailwind 颜色作为 JavaScript 中的对象导入。如果想要使用 Tailwind 颜色来创建自定义主题,或者向调色板添加另一个名称,这将非常有用。
例如,可以创建一个将作为类添加的原色:
// 从 Tailwind 导入所有颜色 const colors = require('tailwindcss/colors'); module.exports = { content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], theme: { extend: { colors: { // 将“primary”类名称设置为所需的颜色+设置默认值。 primary: { ...colors.sky, DEFAULT: colors.sky['600'] }, }, }, }, plugins: [], };
简单的渐变
可以使用渐变色标创建复杂的渐变。 为此,可以使用 bg-gradient-to-class
并将其与 t(上)、r(右)、b(下)和 l(左)组合。 还可以用 tr(右上角)、bl(左下角)等来表示角点。然后可以组合:from
、to
和via
来制作一些渐变。
下面来看一些例子:
javascript
复制代码
{ /* 第一个“to”👇🏽 指定方向 */}
class="bg-gradient-to-r from-indigo-500 ..."> { /* “from-”设置从哪种颜色开始然后淡出 */}
渲染的输出将是一个以靛蓝开始并逐渐渐变为透明的渐变:可以使用 to-
来设置结束:
html
复制代码
<divclass="bg-gradient-to-r from-indigo-500 to-pink-400...">
这将渲染一个以靛蓝开始并逐渐淡化为粉红色的渐变:可以通过使用 via
来控制中间的颜色:
html
复制代码
<divclass="bg-gradient-to-r from-indigo-500 via-green-400 to-pink-400...">
这将呈现几乎彩虹的渐变,如下所示:
轻松截断文本
另一个实用程序类是 line-clamp
,它允许通过简单地添加数字(例如 line-clamp-3
)来截断多行文本:
<article class="mt-20 border border-slate-300 rounded-md p-4 ml-6 text-white w-60"> <p class="line-clamp-3"> Nulla dolor velit adipisicing duis excepteur esse in duis nostrud occaecat mollit incididunt deserunt sunt. Ut ut sunt laborum ex occaecat eu tempor labore enim adipisicing minim ad. Est in quis eu dolore occaecat excepteur fugiat dolore nisi aliqua fugiat enim ut cillum. Labore enim duis nostrud eu. Est ut eiusmod consequat irure quis deserunt ex. Enim laboris dolor magna pariatur. Dolor et ad sint voluptate sunt elit mollit officia ad enim sit consectetur enim. </p> </article>
渲染结果将在 3 行文本后放一个省略号:
容器查询
容器查询允许根据元素本身的大小应用样式。现在,Tailwind 中有一个名为 @tailwindcss/container-queries
的插件可以开始使用容器查询。将此插件添加到项目后,可以使用 @container
标记元素,并且子元素可以使用 @sm
和 @md
等变体:
<div class="@container"> <div class="@lg:text-sky-400"> <!-- ... --> </div> </div>
Tailwind CSS 组件库
最后来看几个 Tailwind CSS UI 组件库。
Tailwind UI
Tailwind UI 是一个由 Tailwind CSS 团队创建的可重用 UI 组件和模板集合。它提供了一系列精美设计和预构建的组件,可以帮助开发人员更快速地构建现代化和高度定制化的用户界面。它的设计风格简洁、现代,适用于各种 Web 应用程序和网站。它提供了各种常见的 UI 组件,如按钮、表单、导航栏、卡片等,每个组件都经过精心设计和开发,以确保外观一致性和交互性。除了单独的组件之外,Tailwind UI 还提供了一些完整的页面模板,包括登录页面、仪表盘、博客布局等,可以直接作为项目的基础或参考使用。Tailwind UI 总共有超过 500 个组件,文档包含 React、Vue 和原始 HTML 的组件代码。官网:tailwindui.com/
daisyUI
daisyUI 是一个开源的 Tailwind CSS 插件,它提供了一套额外的实用工具类和组件,以扩展和增强 Tailwind CSS 的功能。它的目标是简化构建用户界面的过程,提供更多可选的样式和组件,同时保持 Tailwind CSS 的哲学和设计原则。它通过引入新的类名来扩展 Tailwind CSS,这些类名可以直接应用于 HTML 元素,从而快速设置特定的样式和功能。官网:daisyui.com/
Tailwind Elements
Tailwind Elements 是一个由开发者社区创建的免费和开源项目,它为 Tailwind CSS 提供了一套额外的可重用 UI 组件。它的目标是为开发人员提供一组常见且易于使用的 UI 组件,以帮助他们更快速地构建用户界面。这些组件包括按钮、表单元素、导航栏、卡片、提示框等,每个组件都经过设计和开发,并与 Tailwind CSS 的哲学相匹配。官网:tailwind-elements.com/
Flowbite
Flowbite 是一个基于 Tailwind CSS 的前端 UI 框架和组件库。它提供了一套现代、响应式和易于使用的UI组件,可以帮助开发人员快速构建出色的用户界面。它的设计目标是简化开发过程,并提供一致性和灵活性。它内置了一系列的高质量组件,包括导航菜单、卡片、表格、表单元素、按钮等,同时还有一些布局和实用工具类,方便开发人员进行快速开发和定制。Flowbite 有超过450 个组件,文档包含 HTML 组件代码,以及作为最流行框架的库安装的选项。Tailwind Elements 拥有500 多个组件(涵盖所有类别),文档包含 HTML 组件代码,可以选择将其安装为库。官网:flowbite.com/
Tailwind UI Kit
Tailwind UI Kit 是一个基于 Tailwind CSS 的 UI 组件库,提供了一套现成的、可重用的用户界面组件,方便开发人员快速构建漂亮的网页。它包含各种常见的界面元素和组件,例如导航栏、卡片、表单、按钮、模态框等等。每个组件都经过精心设计和开发,并符合现代的 UI 设计准则。Tailwind UI Kit 拥有超过 1300 个组件,文档包含 HTML、Vue、Angular 和 React 的组件代码。官网:tailwinduikit.com/
Hyper UI
Hyper UI 是一个适用于应用程序 UI、电子商务和营销的免费 Tailwind CSS 组件,支持暗模式、RTL 和 Alpine JS等,旨在为开发人员提供现代化的、可定制的用户界面组件。官网:www.hyperui.dev/