Tailwind CSS 为什么这么火?
近年来,Tailwind CSS 在前端开发领域备受关注,在GitHub上收获了70000+ Star。尽管市面上有众多的 CSS 框架可供选择,但 Tailwind CSS 凭借其独特的概念、强大的特性和灵活性越来越受到开发者的喜爱。那么,为何 Tailwind CSS 如此受欢迎呢?本文将深入探讨这个问题,并介绍 Tailwind CSS 的概念、特性、技巧和组件库,以更好地理解和使用它!
1.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 如下:
Document
Hello world!
效果如下:
我们可以编写这种单一用途的 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 文件中使用它,如下所示:
Document
Hello world 1
Hello world 2
Hello world 3
效果如下:
图片
可以看到:
- 组合多个实用程序类:第 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 最重要的部分实际上是使用它的类,理解实用程序优先的方法。
假设想要设计一个简单的按钮样式:
按钮
传统的方法如下所示:
.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 即可重新创建此按钮,而是使用一堆低级实用程序类:
Example
可以看到,这里使用了很多类来为之前相同的按钮样式设置样式,但每个类只管理一个或几个经常一起使用的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属性,甚至一些不太常见的属性。
2.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的 实用类:
.custom-button {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
这里使用@apply指令将Tailwind的实用类应用到.custom-button类上,以快速设置背景颜色、文字颜色、字体加粗、内边距和圆角等样式。
函数
Tailwind还提供了一些函数,用于在CSS中动态生成样式。例如,可以使用theme函数来获取配置文件中的颜色值:
.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中的顺序决定的。