什么是 Tailwind CSS?

近来,一种叫做 Tailwind 的 CSS 框架走进我们的视野,并有大行其道之势。按照 Tailwind CSS 的官网介绍,它是一种基于“工具优先”( utility-first )的 CSS 框架,包含了一系列诸如 flex
、 pt-4
、 text-center
、rotate-90
这样的基础原语类,并基于 MIT 协议开源。那么它到底有哪些优势呢?又该如何使用呢?我们来一起看一下。
我们为什么需要 Tailwind CSS
用实例说话,比如通常情况下,当我们想要在一个 HTML 页面中引入一个按钮时,我们一般会先在页面中插入这个按钮,然后再通过定义一系列的行内 style 、专门的 style 块或者 CSS 文件来设置按钮的外观甚至表现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Demo</title>
<link rel="stylesheet" href="/public/css/styles.css">
<style>
.button1 {
padding: 6px;
color: white;
background: #cf932e;
}
.button1:hover {
background: #ff8c00;
}
.button2 {
padding: 6px;
color: #cf932e;
background: white;
}
.button2:hover {
color: #ff8c00;
}
</style>
</head>
<body>
<div>
<button class="button1">Click me!</button>
<button class="button2">Click him!</button>
</div>
</body>
</html>
这种方式应用起来较为灵活,可以完全按照我们的想法来定制按钮。但是当我们想要插入完全不同的按钮时,我们就需要再去定义一系列的 CSS,灵活性有了,但是却有大量的重复而繁琐的工作。而且在这样编写代码的过程中,我们需要时刻注意所使用的 Magic Number 是否用对了。现代前端技术中已经可以通过引入 CSS 变量的方式来集中管理样式中所使用的各种数据,但是这样一来又反过来限制了灵活性。
针对这种重复性劳动的问题,很早之前就有大牛开发了类似 Bootstrap、UIKit 等的前端样式库。这些样式库已经为我们封装好了各种各样的常用元素样式,在使用的时候,我们只需要在对应的元素上引入需要的 CSS class 即可:
<div>
<button class="btn btn-primary">Click them!</button>
</div>
可是如前面所讨论到的,这样的方式虽然为我们省去了很多工作,但同样引入了很多限制,在我们需要定制化元素样式的时候,还是需要自己去创建各种诸如 btn-custom
的 CSS class 来完成工作。同时,因为定义了各种你需要或者不需要的元素样式,这样的样式库通常比较大,页面的加载速度可能会收到一定程度的影响。
于是,Tailwind CSS 诞生了。
灵活性
Tailwind CSS 基于“工具优先” ( Utility-First )的理念,即基于各种 CSS 原语,定义了一系列独立的工具 class ,这些 class 覆盖了全部的 CSS 语法场景并有所拓展。在我们为元素设置格式的时候,只需要使用这些相互独立的工具 class 即可。下面我们尝试用 Tailwind CSS 来实现上面的例子:
...
<div>
<!-- button1 -->
<button class="p-6 text-white bg-pink-500 hover:bg-pink-600 ">Click me!</button>
<!-- button2 -->
<button class="p-6 text-pink-500 bg-white hover:text-pink-600">Click him!</button>
</div>
...
我们可以看到,语法相当简单:p-6
用于设置 padding 为6个单位,具体的单位值,我们可以进行配置;text-white
用于设置字体颜色为白色;bg-pink-500
用于设置背景颜色为紫色;hover:bg-pink-600
用于设置在鼠标悬浮的时候背景色加深。实际上,Tailwind CSS 就是通过这样的一系列预定义的与独立的 CSS 原语相对应的工具 class 来实现功能的。我们不需要再额外的定义大量的 CSS ,在 HTML 元素行内添加我们需要的原语类即可完成相应的工作。
可封装性
有的朋友不禁要问:“这和使用行内 style 有什么区别呢?”
其实,区别还是挺大的。首先,绝大部分这些工具 class 中所包含的诸如尺寸、颜色等,我们都是可以统一配置的,而嵌入行内 style 中的 Magic Number 是无法实现这样的统一配置的。另外,诸如 hover:bg-pink-600
和 md:bg-pink-600
(页面的响应式定义)这样的功能是无法便捷地在行内 style 中定义实现的。事实上,在 Tailwind CSS 中,类似 hover:
、 md:
等这样的工具叫做“变体” (Variants),可以用来很方便的实现一些常规的 CSS 操作。
当我们设计了一种元素风格,比如上面定义了一种按钮格式,我们需要复用这些按钮格式的时候,是不是需要到处粘贴上面的代码呢?事实上我们不需要为这点担心。当我们一旦沉淀了一种设计,我们就可以将这一系列的 class 用如下的方式封装起来。
<style>
.button1 {
@apply p-6 text-white bg-pink-500 hover:bg-pink-600;
}
.button2 {
@apply p-6 text-pink-500 bg-white hover:text-pink-600;
}
</style>
在我们需要使用已经封装好的工具 class 的时候,按下面的方式引用即可,和使用普通的 class 没有任何区别:
...
<div>
<!-- button1 -->
<button class="button1">Click me!</button>
<!-- button2 -->
<button class="button2">Click him!</button>
</div>
...
可裁剪性
既然 Tailwind CSS 也预定义了一系列的工具 class ,那 Tailwind CSS 库会不会很大呢?会不会像其他库那样影响页面加载的速度呢?
将 Tailwind CSS 引入我们的项目有两种方式,一种是直接引用已经预编译好的 Tailwind CSS 静态库,另外一种是引入 Tailwind CSS 的 npm 包,然后再经过 Webpack 、Gulp 等打包工具及相应扩展来编译引入。实际上,通过第一种方式引入,库的确很大,会对页面加载速度产生影响,这也是官方所不推荐的使用方式。通过第二种方式引入,可以通过相应的设置,在项目编译打包的时候根据实际用到的工具 class 来对 Tailwind CSS 库进行裁剪,最后打完的包中仅包含用到的部分。这样真正解决了额外引入库的“性价比”问题。
可扩展性
作为一个成熟框架的设计者,肯定考虑到了在设计中是无法枚举所有使用者的需求的,最好的方式是在框架的设计中为使用者预留扩展接口,由使用者来根据自己的需求来扩展框架的功能。事实上, Tailwind CSS 的设计者们也是这样做的。他们为使用者预留了很好的扩展接口,使用者可以通过 plugins 来扩展 Tailwind CSS 的功能。 关于 plugins 的使用,我们会在后续的文章中来为大家具体介绍。大家也可以参考 Tailwind CSS 官方文档 来具体了解 plugins。
本篇结束语
上面我们讨论了以往原生 CSS 及 CSS 库在使用中的优缺点,以及 Tailwind CSS 是如何扬长避短集大成的。事实证明,Tailwind CSS 的确解决了不少 HTML 样式设计中的痛点,成为了受 Web 前端工程师追捧的 CSS 框架。在后面的文章里,笔者还会就如何使用 Tailwind CSS 来与大家展开讨论。