zzxworld

Tailwind CSS 使用入门

Tailwind CSS 是一个别具一格的 CSS 界面框架。用官网的一句话来介绍:Rapidly build modern websites without ever leaving your HTML。也就是只要引入 Tailwind CSS,在不需要使用任何自定义 CSS 文件的情况下就能完成一个时髦的网站界面。

认识 Tailwind CSS

仅凭开头的介绍感觉还是很神奇的。事实上它的思想一点都不神奇。来看看下面这段来自官网的示例代码:

<figure class="md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-slate-800">
    <img class="w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512">
    <div class="pt-6 md:p-8 text-center md:text-left space-y-4">
        <blockquote>
            <p class="text-lg font-medium">
            “Tailwind CSS is the only framework that I've seen scale
            on large teams. It’s easy to customize, adapts to any design,
            and the build size is tiny.”
            </p>
        </blockquote>
        <figcaption class="font-medium">
            <div class="text-sky-500 dark:text-sky-400">Sarah Dayan</div>
            <div class="text-slate-700 dark:text-slate-500">Staff Engineer, Algolia</div>
        </figcaption>
    </div>
</figure>

先不管这段代码的渲染结果。直接从上面的写法来看,大概就能明白 Tailwind CSS 的核心所在。其实就是把一些常用的 CSS 样式定义打散,原子化,然后使用的时候再根据需要进行重组。

如果是在大约 20 年前 CSS 样式表方兴未艾的时候就接触到 Web 开发,对这种使用方式应该会有种似曾相识的感觉。比如下面这段代码:

<div style="background:#CCC; border:1px sold #000; padding:20px;">
    <h1 style="color:#666; font-size:18px; border-bottom: 1px dahsed #999;">zzxworld</h1>
    <p style="color:#999; font-size:12px;">一个自由职业者,卖橙子的码农。</p>
</div>

两相对照,就能看出其中的一些共通点。style 属性和 class 作用相同,CSS 样式值被名称所取代。真是时过境迁,没想到二十年前随着 W3C 标准兴起而摒弃的样式写法,以 Tailwind CSS 的方式复活了。

不过「存在即合理」。既然 Tailwind CSS 现在这么受欢迎,说明还是解决了一些场景下 CSS 的使用问题。

安装 Tailwind CSS

Tailwind CSS 的使用和 Bootstrap 这类 CSS 框架的使用方式有点区别。仅靠引入一个 CSS 文件并不能正常使用。原因是 Tailwind CSS 在 class 属性定义中使用了一些非标准的写法。除此之外,Tailwind 的一些高级特性也不是原始 class 属性语法能够支撑的。所以在使用 Tailwind CSS 之前,需要先安装好 Node.js 环境。然后使用 npm 命令安装 Tailwind CSS:

npm install -D tailwindcss

然后初始化一个配置文件:

npx tailwindcss init

命令执行完后,就会在当前目录下创建一个 tailwind.config.js 文件。在这个配置文件中的 content 属性下配置好 HTML 模板目录信息:

module.exports = {
    content: ["./*.html"],
    theme: {
        extend: {},
    },
    plugins: [],
}

之所以要配置 HTML 模板目录,是因为 Tailwind CSS 能根据需要只输出使用了的 class 样式代码,减小最终 CSS 文件的大小。

创建一个 CSS 文件,命名为 style.css,并引入 Tailwind CSS 的样式定义。文件代码如下:

@tailwind base;
@tailwind components;
@tailwind utilities;

接下来创建一个测试用的 HTML 文件,命名为 index.html,代码如下:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="public/style.css" rel="stylesheet">
</head>
<body>
    <h1 class="h-screen w-screen table-cell align-middle text-center text-3xl font-bold underline">
        Hello zzxworld!
    </h1>
</body>
</html>

注意 link 标签的 href 属性,引用的是目前还不存在的 CSS 文件。这个文件需要使用下面的命令来生成:

npx tailwindcss -i ./style.css -o ./public/style.css --watch

后面加了 --watch 参数,命令执行后会一直监视当前目录下的 style.css 文件,以及 tailwind.config.js 文件中配置的模板文件改动。

在浏览器中访问这个 HTML 文件,显示的效果如下:

tailwindcss-demo-page

因为只是演示使用方法,所以这个效果有点简单。如果想体验更复杂好看的示例可以通过查看 Tailwind CSS 的官网来了解。

在 Laravel 框架中安装 Tailwind CSS

上面是自定义引入并安装 Tailwind CSS 样式库的流程步骤。对于一些成熟的后端开发框架,Tailwind CSS 的安装方式会存在一些差异。比如我常用的 Laravel。这是一个全栈开发框架,它引入 Tailwind CSS 的流程跟上面相比就存在一些区别。

首先同样是安装 Tailwind CSS,以及一些依赖项:

npm install -D tailwindcss postcss autoprefixer

然后初始化 Tailwind CSS 配置文件:

npx tailwindcss init

接下来就需要在 Laravel Mix 配置文件 webpack.mix.js 中添加相关配置代码:

mix.js("resources/js/app.js", "public/js")
    .postCss("resources/css/app.css", "public/css", [
        require("tailwindcss"),
    ]);

以及在 Tailwind CSS 配置文件 tailwind.config.js 中设置 Laravel 的模板目录和 JS 源码路径:

module.exports = {
    content: [
      "./resources/**/*.blade.php",
      "./resources/**/*.js",
      "./resources/**/*.vue",
    ],
    theme: {
      extend: {},
    },
    plugins: [],
}

后面的使用就基本类似了。

按需输出

这应该是 Tailwind CSS 对我来说比较有吸引力的一点。在使用 Bootstrap 这类 CSS 框架时,即便只用了其中一小部分样式,也必须要引入一个完整的框架代码,这从数据传输和使用率来说,是很大的资源浪费。而 Tailwind CSS 很好的解决了这个问题,可以根据实际使用的样式名称只输出所需的样式代码。

还是以最上面的演示项目为例,使用这个「按需输出」功能的命令如下:

npx tailwindcss -i ./style.css -o ./public/style.css --minify

输出的文件信息如下:

tailwindcss-minify-output-info

可以看到大小才 3.5K。

合并 class

同样以最上面的演示项目为例,我可以看到在完成一个 HTML 标签的样式时,使用 Tailwind CSS 会不可避免的产生冗长的 class 属性值。比如其中的 H1 标签样式定义:

<h1 class="h-screen w-screen table-cell align-middle text-center text-3xl font-bold underline">
    Hello zzxworld!
</h1>

如果是在需要多次重复的标签上使用这段样式定义,那意味着 class 属性也是要不断重复的,这变相的增加了代码体积。Tailwind CSS 提供的 @apply 方法可以解决这个问题。

在上面示例的 style.css 文件中追加如下 CSS 代码:

.title {
    @apply h-screen w-screen table-cell align-middle text-center text-3xl font-bold underline;
}

然后修改 H1 标签的 class 属性值为如下样式:

<h1 class="title">
    Hello zzxworld!
</h1>

就这样,在效果不变的前提下,解决了样式重复使用导致的代码冗余问题。

总结

我已经习惯了只在 CSS 文件中定义样式,并推崇「语义化」的样式名称。所以对于 Tailwind CSS 一开始还不太容易接受。不过在体验了一下后,逐渐放飞了自我。

根据标签的用途来给 class 取名并不是一项容易的事情。即便是想了一个很贴切的名称,抛开维护价值,其他方面并没有任何优劣之分。所以我已经开始接受使用 Tailwind CSS 这种样式工具来开发 Web 界面。特别是对于搭建产品原型的工作,相信能带来效率方面的提升。

而且 Tailwind CSS 也提供了合并 Class 的功能,在需要的时候,我也可以通过语义化的样式名称来进行优化。按需输出 CSS 代码的方式更是降低了网络传输的开销,提升了应用的访问速度。

唯一令我担心的就是在原生 CSS 样式之外,又多了一套样式名称的记忆成本。

最后,如果你对按需输出 CSS 代码的功能感兴趣,但就是对 Tailwind CSS 无爱,可以看看这个工具:PurgeCSS。它能让你在任何 CSS 框架或代码上实现按需输出的功能。事实上 Tailwind CSS 也是基于它来实现的类似功能。