去年我写了一篇简单的文章解释为什么我使用 Tailwind CSS, here
团队的成员读了以后反馈说“没讲清楚”,说我又来详细介绍一下 why we should use Utility-First CSS。
什么是 Utility-First CSS
Utility-First CSS 是 Tailwind CSS 官方宣传的一种编写 CSS 的方式。
简单说:提供大量基础的 CSS classname,然后利用 CSS 的组合能力,想堆砌乐高积木一样编写 CSS。
在 Utility-First CSS 之前有哪些编写 CSS 的方式
- BEM(Block Element Modifier)
- SCSS
- CSS-IN-JS
- CSS Modules
- ...
为什么会有这么多种方式?
要讨论这个问题,首先我们需要问 “这些开发方式试图解决什么问题?”
答:解决 CSS 模块化问题。
那么,CSS 模块化遇到了哪些问题?
https://github.com/camsong/blog/issues/5
- 全局污染
- 命名混乱
- 依赖管理不彻底
- 无法共享变量
- 代码压缩不彻底
在上述问题中,“全局污染” 可能是最受开发者诟病的问题了。
我以前也觉得 CSS global scope 是一个问题,但是学习了 Utility-First CSS 以后,我太爱 global scope 了。 只要使用得当,轻轻松松达到 Less is More 的效果。
对比一下 BEM CSS 和 Utility-First CSS
需求:一个简单的表格
传统风格
<style>
.table { ... }
.table-thead { ... }
.table-cell { ... }
.table-tbody { ... }
.table-row { ... }
.table-row > .table-cell { ... }
</style>
<table class="table">
<thead class="thead">
<tr>
<th class="table-cell">Name</th>
<th class="table-cell">Age</th>
<th class="table-cell">Address</th>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row">
<td class="table-cell">Jiang</td>
<td class="table-cell">29</td>
<td class="table-cell">Japan</td>
</tr>
<tr class="table-row">
<td class="table-cell">Jiang</td>
<td class="table-cell">29</td>
<td class="table-cell">Japan</td>
</tr>
</tbody>
</table>
思考:
- 有什么问题?
Utility-First 风格
<table class="bg-* m-* font-*">
<thead class="bg-* m-* font-*">
<tr>
<th class="bg-* m-* font-*">Name</th>
<th class="bg-* m-* font-*">Age</th>
<th class="bg-* m-* font-*">Address</th>
</tr>
</thead>
<tbody class="bg-* m-* font-*">
<tr>
<td class="bg-* m-* font-*">Jiang</td>
<td class="bg-* m-* font-*">29</td>
<td class="bg-* m-* font-*">Japan</td>
</tr>
<tr>
<td class="bg-* m-* font-*">Jiang</td>
<td class="bg-* m-* font-*">29</td>
<td class="bg-* m-* font-*">Japan</td>
</tr>
</tbody>
</table>
思考:
- 有什么感觉?
- 有没有解决上面提到的问题?
Utility-First 风格 + UI Component
const Th = ({children}) => (<th class="bg-* m-* font-*">{{children}}</th>)
const Td = ({children}) => (<td class="bg-* m-* font-*">{{chilren}}</td>)
<table class="bg-* m-* font-*">
<thead class="bg-* m-* font-*">
<tr>
<Th>Name</Th>
<Th>Age</Th>
<Th>Address</Th>
</tr>
</thead>
<tbody class="bg-* m-* font-*">
<tr>
<Td>Jiang</Td>
<Td>29</Td>
<Td>Japan</Td>
</tr>
<tr>
<Td>Jiang</Td>
<Td>29</Td>
<Td>Japan</Td>
</tr>
</tbody>
</table>
思考:
- 怎么样?
背后的思想是什么?
组合由于继承
TJ
有一个 YouTube 视频,我之前分享过,大家可以看一下。https://youtu.be/3XaXKiXtNjw
总结 Why we should use Utility-First CSS
Utility-First CSS 优点
- 不用起名,不费脑。
- 责任清晰,开发速度快,容易修改,容易调试。
- 官方实现,bug 少
Utility-First CSS 缺点
- 将 CSS 结构化转移到 HTML 中,代码写的乱。(我不认同,稍后解释)
- 不利于爬虫(就是不让你爬)
- 需要记忆新的 class(比 CSS 少 10 倍)
个人观点
- 这不是新技术,这是最基本、最核心的技术。
- 真正提高开发效率、代码品质、且可以掌握的技术。
- 尽早采用。