2021年, 是时候来尝试 Tailwind 框架编写 CSS 了

3,219 阅读5分钟

在过去的几年里, CSS 编写方式一直在变, 最开始结合HTML文档编写CSS代码到CSS模块化, 以及后来的 CSS-in-js, styled components

CSS 框架也是层出不穷, 从最初的 Bootstrap 到后来的 elementUI , antd

它们是每个CSS发展过程中为了优化前端开发而提供的一种解决方案, 但在如今的开发背景下, 都有所约束。

当你使用类似 antd 的UI库时, 一方面享受使用他人封装组件的便利, 另一方面也苦于难以根据自己的需求灵活地改变组件样式

当你自己编写 styled components, 同样的几行CSS代码很可能出现在不同的组件, 不同的样式中。

而我接下来提到的 tailwind 也是一种全新, 又非全新的CSS框架, 它将为这些问题提出一个新解。

什么是 Tailwind ?

这里常说的 Tailwind 指的就是 Tailwind CSS, 这是一个工具集 CSS 框架,能够助你快速实现定制化的网站设计。

根据我自己的理解, 它具有以下特点:

  1. 功能类优先
  2. 定制化生成工具集
  3. 使用PurgeCSS优化CSS文件体积

接下来我将进行逐一介绍及分析。

功能类优先 (Utility-First)

1. 什么是功能类?

tailwind 并非全新, 这里所指的功能类类似早些年广受排斥的原子类, 但又有些细微的差别。

减少编写成本

按照 less 预编译语言的说法, 每一个功能类就是一个拆分到最基础最原子的混合(mixin)

但是功能类既可以是原子类, 也可以是一定原子类的集合。

/* 同样一行 `background-color` 我们仅需要 `bg-` 即可表示。 */
.bg-gray-400 {
  --tw-bg-opacity: 1;
  background-color: rgba(156, 163, 175, var(--tw-bg-opacity));
}
<div class="bg-gray-400">Hello</div>

早年间, 编写这样一个工具类库, 能够减少我们编写CSS代码的开发成本, 但随着项目定制化精细化程度的增加, 文件体积将会猛然增长。

这些年开发工具的迭代, 像 webpack 这样的文件打包, 按需加载工具, 使得原子类组成的工具集可以更好地扬长避短。

减少代码冗余

tailwind 不会编写线性增长的CSS代码

在编写 styled-components 类似的样式过程中, 我们需要为每一个组件几乎重写一整套CSS样式。

随着项目的复杂度增大, 不同组件的增加, 将会使得冗余代码的数量堆叠。

tailwind 通过组合功能类能够达到同样的效果, 但代码却不会因为使用这些共享功能类而变得臃肿。

const ButtonA = styled.a`
  background: white;
  color: black;
`
<ButtonA> Documentation </ButtonA>

const ButtonB = styled.b`
  background: grey;
  color: white;
`
<ButtonB> Documentation </ButtonB>


<button className="bg-white text-black">A</button>
<button className="bg-gray text-white">

Facebook 采用了类似的方法,尽管使用了自定义 CSS-in-JS 库,但该库利用了原子CSS,这与 Tailwind 的 “功能类优先” 方法非常相似。

通过这种方法,他们将整个站点中的CSS捆绑包大小从413kb减少到74kb。减少了约82%!

定制化体现何处?

自由组合功能类

不同于 antd 等UI组件库, tailwind 本身不提供默认组件样式。

“Best practices” don’t actually work.

官方文档说明, 最佳实践实际上行不通, 意思是组件库所提供的样式未必就是项目中我们需要的样式。

我们需要去寻找默认组件中的样式类, 然后修改, 反而更加麻烦。

那么不如我们自由地组合功能类去完成我们需要的样式。

定制化生成功能类库

另一方面, tailwind 接纳 tailwind.config.js 文件进行配置,

我们可以根据我们地需要, 根据UI的需求, 定制化地生成符合我们当前项目的功能类库。

// tailwind.config.js
const colors = require('tailwindcss/colors')

module.exports = {
  theme: {
    colors: {
      gray: colors.coolGray,
      blue: colors.lightBlue,
      red: colors.rose,
      pink: colors.fuchsia,
    },
    fontFamily: {
      sans: ['Graphik', 'sans-serif'],
      serif: ['Merriweather', 'serif'],
    },
    extend: {
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      borderRadius: {
        '4xl': '2rem',
      }
    }
  },
  variants: {
    extend: {
      borderColor: ['focus-visible'],
      opacity: ['disabled'],
    }
  }
}

使用PurgeCSS优化CSS文件体积

定制化生成的CSS类库, 体积将随着需求的精细度和项目的复杂度成倍上涨, 这时候文件的大小将难以加入项目中。

这也是原子类的通病, 但是在现如今, 工具发达的今天, 这已不再是绝症。

Tailwind 使用 PurgeCSS 等工具在发布前对代码进行正则匹配,剔除没有使用过的原子类,最后可以将 6MB 的 css 缩减到 20kb-50kb;

这使得文件体积不再是功能类库生成的阻碍。

其他优点

这里就不展开细说了

  1. 自带支持自适应
  2. 类名容易记忆, 方便上手
  3. 能够对功能类进行再次混合
  4. 通过@apply 在css代码中引入混合, 以及其他一系列语法糖

Tailwind 简易食用指南

  1. 安装

具体参见官方文档, 如果项目支持postcss8, 则可以直接下载最新版本

如果项目仍需适配 postcss7 则可以下载兼容版本。

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
  1. 生成文件

通过命令创建基础配置文件 postcss.config.jstailwind.config.js

// 生成基础配置文件
npx tailwind init -p
// 生成默认配置文件
npx tailwind init --full
  1. 创建全局 tailwind.css

这个文件便是我们最后要加载进项目的css文件

// assets/styles/tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;
// app.tsx
import React from "react";
import "../assets/styles/tailwind.css";

const App: React.FunctionComponent = () => {
  const str = "Hello World!";
  return <div className="bg-gray-400">{str}</div>;
};

export default App;
  1. 安装tailwind 补全插件

要触发全局补全还需要生成功能类css文件

npx tailwindcss build ./assets/styles/tailwind.css -o ./tailwind.generator.css
  1. 祝大家体验愉快~

参考文章