近年来,Tailwind CSS 在前端开发领域备受关注,在GitHub上获得了70000+的Star。尽管市面上有众多的 CSS 框架可供选择,但 Tailwind CSS 凭借其独特的概念、强大的特性和灵活性越来越受到开发者的喜爱。那么,为何 Tailwind CSS 如此受欢迎呢?本文将深入探讨这个问题,并介绍 Tailwind CSS 的概念、特点、技巧和组件库,以更好地理解和使用它!
Tailwind CSS 概念
原子 CSS
在学习 Tailwind CSS 之前,先来了解一下什么是原子 CSS。
原子 CSS(Atomic CSS)是一种CSS 架构方法,旨在通过使用单一的、独立的类来构建样式,从而提供可重用且高度可组合的样式规则。
例如,使用以下 CSS 创建一个 bg-blue 类:
.bg-blue { background-color: rgb(81, 191, 255); }
如果将此类添加到
标签中,它将获得蓝色背景,颜色如上面代码rgb(81, 191, 255)
所示。
HTML 如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div><h1 class="bg-blue">Hello world!</h1></div> </body> </html>
效果如下:我们可以编写这种单一用途的 CSS 规则并将它们全部保存在全局 CSS 文件中。这样就可以在任何地方使用这些单一用途的实用程序类。只需要在 HTML 中来使用这些全局 CSS 文件即可,还可以在单个 HTML 标签中使用这些类的组合。
来看另一个例子,有以下规则的 CSS:
.bg-blue { background-color: rgb(81, 191, 255); } .bg-green { background-color: rgb(81, 255, 90); } .text-underline { text-decoration: underline; } .text-center { text-align: center; } .font-weight-400 { font-weight: 400; }
然后在 HTML 文件中使用它,如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div><h1 class="bg-blue">Hello world 1</h1></div> <div><h1 class="text-underline">Hello world 2</h1></div> <div class="text-center"> <h1 class="bg-green font-weight-400 text-underline">Hello world 3</h1> </div> </body> </html>
效果如下:可以看到:
- **组合多个实用程序类:**第 14 行中组合了多个类,即
bg-green
、font-weight-400
和text-underline
。这些样式在 Hello world 3 文本中都生效了。 - **实用程序类的可重用性:**第 12 行和第 14 行中多次使用了
text-underline
类。
当然,如果想遵循这种原子 CSS 架构,就需要创建多个单一用途的实用程序类。这就是 Tailwind CSS 的用武之地。原子 CSS 的概念并不新鲜,但 Tailwind CSS 将其提升到了另一个水平。
Tailwind CSS 是什么?
Tailwind CSS 是一个实用优先的 CSS 框架,旨在使用户能够更快、更轻松地创建应用。可以使用实用程序类来控制布局、颜色、间距、排版、阴影等,以创建完全自定义的组件设计,Tailwind CSS 在 Github 上有 70.6k Star,并且 npm 周安装量达到了 636w+。一开始对 Tailwind CSS 的印象并不太好,而更喜欢干净的 HTML 干净以及语义化的类名,后者在前端关注点分离中发挥着重要作用。使用 Tailwind 和这么多的类很奇怪,让我想起了内联样式。不过,随着时代的变化,HTML、CSS 和 JavaScript 之间的联系也在变化。这开启了改变类在项目中的角色的可能性,并且实用程序优先的方法非常适合现代的、基于 JavaScript 的时代。
Tailwind 是一个 CSS 框架,但它并不是新的 Bootstrap。Bootstrap 等传统 CSS 框架为用户提供了许多预定义的功能,如组件和布局系统。而 Tailwind 并非如此,因为它不附带预定义组件。两者的目标都是让开发更轻松,但实现方式有所不同:**传统框架试图避免CSS 及其复杂性,而 Tailwind CSS 希望改变编写 CSS 的方式。**因此,与其他 CSS 框架相比,它提供了更大的灵活性和控制力。
Tailwind CSS 有很多优势:
- 编写的自定义 CSS 更少:使用 Tailwind,可以通过直接在HTML中应用预先存在的类来设置元素的样式。通过以这种方式使用实用程序类,可以构建自定义设计而无需编写 CSS。
- **可以保持 CSS 文件较小:**如果没有像 Tailwind 这样的框架,就必须在添加新功能和组件时继续编写 CSS。这样 CSS 文件不断增长并变得越来越大。通过使用 Tailwind 的等实用程序,大多数样式都是可重用的,因此很少需要编写新的 CSS。
- 不必定义类名:使用 Tailwind 时,可以从预定义的设计系统中选择类。这意味着无需为某些样式和组件选择“完美”的类名而烦恼,也无需记住像
sidebar-inner-wrapper
这样复杂的类名。 - **可以做出更安全的更改:**使用传统方法,如果对 CSS 进行更改,则可能会破坏网站上的某些内容。不同于 CSS,在HTML中使用的实用类是局部的。这意味着可以更改它们而不必担心影响站点上其他部分的功能。
Tailwind CSS 核心理念
学习如何使用 Tailwind CSS 最重要的部分实际上是使用它的类,理解实用程序优先的方法。
假设想要设计一个简单的按钮样式:
html
复制代码
<buttonclass="btn"> 按钮 button>
传统的方法如下所示:
.btn { display: inline-block; border: 1px solid #34D399; background-color: transparent; border-radius: 0.375rem; padding: 0.5rem 1.5rem; color: #34D399; line-height: 1; cursor: pointer; text-decoration: none; transition: background-color 300ms, color 300ms; } .btn:hover { background-color: #34D399; color: #FFF; }
使用 Tailwind CSS,无需编写一行 CSS 即可重新创建此按钮,而是使用一堆低级实用程序类:
html
复制代码
<buttonclass="inline-block border border-green-400 bg-transparent rounded-md py-2 px-6 text-green-400 leading-none cursor-pointer hover:bg-green-400 hover:text-white transition-colors duration-300"> Examplebutton>
可以看到,这里使用了很多类来为之前相同的按钮样式设置样式,但每个类只管理一个或几个经常一起使用的CSS属性。这些类的命名描述了它们的功能:inline-block
将CSS的display
属性设置为display: inline-block;
,bg-transparent
将background-color
属性设置为background-color: transparent;
,而cursor-pointer
则将cursor
属性设置为cursor: pointer;
。
有些类看起来不太直观,比如py-2
用于管理垂直内边距,而px-6
用于管理水平内边距。还有一些类同时设置多个属性,比如transition-colors
:
.transition-colors { transition-property: background-color,border-color,color,fill,stroke; transition-timing-function: cubic-bezier(.4,0,.2,1); transition-duration: 150ms; }
尽管有些类不太容易理解,但基本概念始终是相同的。除了基础知识、自定义和插件外,官方文档的所有章节都致力于解释Tailwind生成的类的名称和默认值,几乎涵盖了每个常用的CSS属性,甚至一些不太常见的属性。
Tailwind CSS 特性
响应式设计
Tailwind CSS默认支持响应式设计,这意味着它生成的每个类都有对应的变体,只在特定的媒体查询匹配时才应用。默认情况下,Tailwind是以移动设备优先的方式进行设计的:它的所有媒体查询都是基于**min-width**
的类型。每个类都会根据每个断点生成一个对应的变体,例如,可以使用sm
断点来表示640px
。因此,如果想要在屏幕宽度达到640px及以上时应用text-white
类,可以写作sm:text-white
。 还可以结合响应式和状态变体,例如使用sm:hover:text-white
表示在屏幕宽度达到640px
及以上且处于 hover 状态时应用text-white
类。
函数和指令
通过使用指令和函数,可以更灵活地定制和扩展你的CSS样式,并结合Tailwind的强大功能实现更高效的开发。
指令
Tailwind 指令是用于执行各种操作的特殊声明,比如使用@variants
指令生成一些类的变体,或者使用带有 @screen
指令的 Tailwind 媒体查询。对于@apply
指令需要特别注意,这个指令允许在自定义样式中使用 Tailwind的 实用类:
css
复制代码
.custom-button {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;}
这里使用@apply
指令将Tailwind的实用类应用到.custom-button
类上,以快速设置背景颜色、文字颜色、字体加粗、内边距和圆角等样式。
函数
Tailwind还提供了一些函数,用于在CSS中动态生成样式。例如,可以使用theme
函数来获取配置文件中的颜色值:
css
复制代码
.btn-primary {
background-color: theme('colors.blue.500');}
这里使用theme
函数来获取配置文件中blue.500
定义的颜色,并将其作为背景颜色应用到.btn-primary
类。
定制化
默认的 Tailwind CSS 设置非常适合非常通用的用例,但如果项目需要,也可以根据需要调整和自定义实用程序类。 Tailwind 项目中通常有两个配置文件:框架内部使用的一个,以及可以在项目根目录下创建的 tailwind.config.js
文件。 每次构建项目时,在生成所有实用程序类之前,Tailwind 都会查找自定义配置文件,找到后它会尝试将其与内部配置合并,作为未指定的参数的后备。 因此,自定义配置文件可以指定仅生成几个类的设置,但如果没有指定任何相关内容,则所有 Tailwind 默认类都将继续工作。
文件结构
每个 Tailwind CSS 配置文件至少有以下参数:
module.exports = { purge: [], presets: [], darkMode: false, // or 'media' or 'class' theme: { screens: {}, colors: {}, spacing: {}, }, variantOrder: [ 'first', 'last', 'odd', ], variants: { accessibility: ['responsive', 'focus-within', 'focus'], alignContent: ['responsive'], alignItems: ['responsive'], /* etc. */ }, plugins: [], }
某些设置(例如presets
)与实用程序类自定义无关。 darkMode
参数为类启用暗模式变体,插件允许使用更多功能和实用程序类(例如 Tailwind Typography)来扩展 Tailwind,这对于 Markdown 生成的内容样式非常有用。还有更多设置,官方文档有详细描述,但最重要的是theme
、variants
和 purge
。
theme
在 theme 中能够自定义调色板、响应能力和容器设置、间距实用程序甚至占位符不透明度实用程序。最常见的更改实用程序是断点、调色板和间距。
自定义断点
项目的断点在screens
对象中进行管理:
module.exports = { theme: { screens: { sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px', }, }, }
默认情况下,Tailwind 不仅生成实用程序的普通版本,例如 text-white
,而且还为screens
对象内指定的每个断点生成响应变体:sm:text-white
、md:text-white
、xl:text-white
。这里可以包含更多或更少的断点,并且screens
对象支持各种程度的自定义,例如,使用桌面优先最大宽度媒体查询,或使用最小和最大宽度的范围媒体查询。
自定义调色板
调色板在颜色colors
内部进行管理:
module.exports = { theme: { colors: { transparent: 'transparent', current: 'currentColor', teal: { 50: '#f0fdfa', 100: '#ccfbf1', 200: '#99f6e4', }, emerald: { 50: '#ecfdf5', 100: '#d1fae5', 200: '#a7f3d0', }, }, }, }
当提供字符串参数时,Tailwind 将为该颜色生成所有与颜色相关的实用程序,例如 bg-transparent
、border-transparent
等。当提供对象时,实用程序将像 bg-teal-50
、text-emerald-200
中那样“嵌套”。还可以在对象内提供特殊的 DEFAULT
值,Tailwind 将生成该颜色的“非嵌套”版本:
module.exports = { theme: { colors: { emerald: { DEFAULT: '#059669', // Generates bg-emerald, text-emerald, border-emerald... 50: '#ecfdf5', 100: '#d1fae5', 200: '#a7f3d0', }, }, }, }
这样的嵌套逻辑适用于 Tailwind 支持的几乎所有实用程序。注意,一切都是基于对象的:这就是为什么在使用 theme()
函数从自定义 CSS 访问嵌套实用程序时必须使用点表示法。
自定义间距
Tailwind 配置中的间距对象本身不会生成任何实用程序。它是许多实际实用程序默认继承的设置对象,正如在默认配置中看到的那样:
module.exports = { theme: { margin: (theme, { negative }) => ({ auto: 'auto', ...theme('spacing'), ...negative(theme('spacing')), }), padding: (theme) => theme('spacing'), width: (theme) => ({ auto: 'auto', ...theme('spacing'), '1/2': '50%', /* ...and so on */ }), }, }
它的使用非常简单,只需根据需要修改键/值对,所有与间距相关的实用程序(例如 padding
或 margin
)将默认继承这些值。
module.exports = { theme: { spacing: { px: '1px', 0: '0px', 0.5: '0.125rem', 1: '0.25rem', 1.5: '0.375rem', 2: '0.5rem', 2.5: '0.625rem', 3: '0.75rem', /* ...and so on */ }, }, }
覆盖或扩展
自定义主题时,可以为自定义的每个实用程序扩展或覆盖 Tailwind 的默认值。默认情况下,当在theme
对象内设置实用程序时,将覆盖默认值。 以过渡持续时间为例。 在默认配置文件中,其值为:
module.exports = { theme: { transitionDuration: { DEFAULT: '150ms', 75: '75ms', 100: '100ms', 150: '150ms', 200: '200ms', 300: '300ms', 500: '500ms', 700: '700ms', 1000: '1000ms', }, }, }
这将使用诸如duration-300
之类的类来声明300ms
的过渡持续时间。 如果在自定义 tailwind.config.js
文件中声明:
module.exports = { theme: { transitionDuration: { 2000: '2000ms', }, }, }
Tailwind会生成一个名为duration-2000
的类,将过渡时长设置为2000毫秒。但是,将失去其他类,如duration-300
或用于过渡时长为150毫秒的默认类。实际上,这种方法可能更好,因为这样 Tailwind CSS 只会生成实际使用的类,这在开发模式下可以提高性能。
如果在上面的示例中,默认值已经满足需求,可以进行扩展。想扩展的每个工具都必须放在特殊的extend
对象内。下面通过扩展默认工具来添加一个2000毫秒的过渡时长,而不是替换它们:
module.exports = { theme: { extend: { transitionDuration: { 2000: '2000ms', }, } }, }
这样就可以使用duration-2000
类,而不会丢失duration-300
和所有其他默认实用程序。
变体
可以为每个实用程序生成许多变体:hover
、visited
、focus
、checked
、active
、odd
、even
等,为每个工具生成所有可能的变体会导致生成成千上万个无用的类,构建过程缓慢,开发模式下生成巨大的CSS文件,并且需要清理许多无用的样式以进行生产。因此,默认情况下,只有响应式变体是始终启用的,而其他所有变体只有在你期望找到它们的地方才会被默认激活(例如,backgroundColor
工具的hover
变体)。
变体对象中的每个属性都必须有一个实用程序名称作为键,并以一组启用的变体作为值:
module.exports = { variants: { accessibility: ['responsive', 'focus-within', 'focus'], alignContent: ['responsive'], alignItems: ['responsive'], }, }
与 theme
一样,在自定义变体时,可以覆盖或扩展实用程序的设置:
module.exports = { variants: { // 除了默认值之外,还将生成“active”变体 extend: { backgroundColor: ['active'] } }, }
指定变体的顺序很重要。变体是由数组定义的,它们在数组中的顺序决定了相对类在最终样式表中的位置。这很重要,因为一个元素可以同时处于活动和焦点状态下:优先使用的类别不是由在HTML元素中输入它们的顺序决定的,而是由这些类在最终CSS中的顺序决定的。
当覆盖变体时,对于给定的工具,可以完全控制数组,但在扩展它们时则不能。通过扩展添加的变体会被Tailwind自动排序,遵循一个内部顺序,可以使用variantOrder
参数自定义该顺序。
70k Star 的 Tailwind CSS 为何这么火?(下)https://developer.aliyun.com/article/1411599