写在前文
最近我自己也体验了一下 tailwindcss,作为一个很喜欢写 CSS 的人,体验完之后,说实话还是觉得有点儿不太顺手,但是我确实因为它不愿意再新建一个 CSS 文件了。这种有点儿难受又有点儿爽的心态让我继续沉迷于 tailwindcss 。恰好昨晚看到我的好朋友在知乎上写了一些关于它的文章,情不自禁转来分享大家。
下面是原文:
经过一段时间的使用,tailwindcss 方案已经能够很流畅的使用了,没有想象中的不适感,整体设计风格很统一,熟练之后能够很流畅地写出复杂样式,和传统的css、less相比,明显的感受是上下文切换变少了,和 css-in-js 相比,敲键盘次数变少了,原以为只是一个 css 工具集,但它的强大超出我的预期,一些复杂的联动效果也能轻松完成。
能点击进来看到本文的应该都多多少少听过 tailwindcss,本文会结合我的使用体验,将tailwindcss方案的核心思想梳理一番。
官方在线 Playground 地址: Tailwind Play(
https://play.tailwindcss.com/)
一直以来一个项目的 css 方案都是让前端开发者头痛的问题,相似结构的重复样式导致冗余[1]、样式和内容耦合导致内容变动后样式也对应修改、大量无意义元素取名困难、大型项目容易命名冲突,缺少和JS类似的模块化方案,css语义不清晰阅读困难、缺少嵌套支持等。
传统的方案例如语义化 CSS 追求的是内容优先,例如 CSS 禅意花园: CSS 设计之美(
https://www.csszengarden.com/tr/zh-cn/) ,这种规范以 HTML 内容优先,HTML无关样式,通过样式表让HTML具有不同的风格,这是早期人们对样式表的理解。优点是内容无关样式,但是缺点同样地导致样式非常和内容相关,内容变动导致样式需要大量修改。
BEM 方案通过给HTML增加大量类名,优点是依然保留的上面的语义化,HTML 可读性好,而且可以避免类名重复,缺点对应的是类名膨胀,尤其是在书写具有相似结构的组件时,会产生大量冗余的类名,在面对一些无意义元素时也需要对其命名。
为了解决BEM, 自定义类名等方案带来的问题,使用工具类能有效地减少css冗余、样式复用等问题,于是作者以工具类优先的原则开发了 tailwindcss。
tailwindcss 本体是一个 Postcss 插件, 支持命令行启动,其核心工作流程如下[2]。
tailwindcss是一个postcss插件,工作流如图 tailwind 会将生成的样式表插入到对应的插槽中。所以我们必须有一个css文件包含下面三句,否则tailwindcss不会产生任何效果。
@tailwind base;@tailwind components;@tailwind utilities;
其中 tailwind base 相当于一份重置样式表,包含了最基础的样式。tailwind components 包含了一些组件类, 组件相当于复合样式,tailwind utilities 包含了工具类,也就是 flex mx-auto 这些内置样式。
这么划分的原因是因为 css 的优先级规则,tailwindcss 全部都是一级样式,在类名权重相等的情况,下面的样式可以覆盖上面的样式,所以工具类优先,组件类次之,基础样式兜底,生成的样式顺序尤为重要,所以 上面三句指令的顺序非必须建议不要修改。
tailwindcss 内置了大量工具类名,理论上可以做到100%使用内置方案覆盖,下面看一些具体的命名规则:
tailwindcss 的命名规范很统一,具有唯一性的样式属性会直接作为对应的类名,例如 block, absolute, flex, top-0, overflow-hidden, whitespace-nowrap, border, border-black 只看名称就能唯一确定属性,符合开发直觉。
对于一些 css 通用名称,tailwindcss提供了统一的规范。例如 left, right, top, bottom, 分别对应 l, r, t, b。left-right 对应 x, top-bottom 对应 y。 所以产生了下面的类名:
所以如果想写一个上边框黑色,上下外边距 2px, 上内边距10px,可以如下:
<div class="border-t border-black my-[2px] pt-[10px] "/>
其他简写也会符合越常用越简写的原则,来看一些案例
所以我想写一个宽高 200, 黑底白字,过渡效果为背景色,过渡时间为 300ms,可以如下
<div class="w-[200px] h-[200px] bg-black text-white transition-bg duration-[300ms]">
再有一些类名也大致满足如上规则,前期需要对照文档查每个属性的类名,习惯之后可以凭借记忆和规则猜出类名。
在 tailwindcss 中,修改器语法为 修改器:类名 修改器的种类很多且可扩展。内置的修改器如下:
案例 1:hover:bg-sky-500 当 hover 时应用此类名
<div class="hover:bg-sky-500 w-[200px] h-[200px] bg-black text-white transition-bg duration-[300ms]">
案例2:first:bg-sky-500 第一个子元素
<div> <div class="w-[20px] h-[20px] mt-[10px] bg-gray-300 first:bg-sky-500"/> <div class="w-[20px] h-[20px] mt-[10px] bg-gray-300 first:bg-sky-500"/> <div class="w-[20px] h-[20px] mt-[10px] bg-gray-300 first:bg-sky-500"/> </div>Ï
案例3: group, group-hover 父状态选择器,当父组件 hover 时,子元素高亮
<div class="group border-b whitespace-nowrap text-gray-300"> <div class="w-[20px] h-[20px] mt-[10px] bg-gray-300"> pick me </div> <div class="w-[20px] h-[20px] mt-[10px] bg-gray-300 group-hover:text-sky-500"> pick me </div> <div class="w-[20px] h-[20px] mt-[10px] bg-gray-300"> pick me</div></div>
案例4: !, important 修改器。
由于权重问题,有时我们的的确确添加了两个相同功能类名,例如 bg-white, bg-black, 此时我们想强制让某一个生效,则可以使用 ! 修改器。这种情况可能出现在你想覆盖某个组件内样式的场景。
<div class="bg-white !bg-black"/>
在 tailwindcss 3.x 之后,tailwindcss 默认开启了JIT模式,该模式能够让我们书写动态 CSS 样式,不再受到静态规则集的限制。除了内置了一些常用属性值, 例如 ml-2 表示 margin-left: 0.5rem , 有时我们需要一些特定的值,tailwindcss 对这种情况提供了很好的支持,任何需要自定义值的属性,可以使用方括号来表示。例如
JIT模式的支持解决了传统 class 方案的不灵活的问题,从此再也不需要添加自定义样式。
对于一些需要 media query 实现的响应式样式,tailwindcss 提供了一组默认规则,使用 min-width 实现的断点功能实现响应式方案。默认的几个断点如下
min-width 表示当屏幕尺寸大于等于该值则应用此规则。所以 tailwindcss 的规则是基于 大于等于 做判断, 下图可以直观感受下每个选择器的范围。
这样的特性使得,我们的基础样式必须为小屏幕手机的才可以,所以 tailwindcss 具有移动端优先的特点。
<div className="flex flex-wrap sm:flex-nowrap"/>
上面的样式为:在小屏幕手机上应用 flex flex-wrap, 在大屏幕上应用 flex-nowrap.
如果想在项目内添加自己实现的类,例如如下
.article { position: relative; color: orange; line-height: 1.2; font-family: ...; @apply text-ellipsis;}
这里 tailwind 建议写在主文件(具有tailwind指令的文件)并放在对应的 layer 下,所以需要改成如下
@tailwind base;@tailwind components;@tailwind utilities;@layer components { .article { position: relative; color: orange; line-height: 1.2; font-family: ...; @apply text-ellipsis; }}
原因是因为 css 类名都是一级类名,权重相同,只能使用顺序来确保覆盖规则,使用这个指令可以让生成的最终css文件内, article 类名在 utilities之前,这样当我们写如下样式
<div class="article absolute"/>
才能保证工具类名(absolute)正确覆盖组件类名(article)。放在 layer 代码块之内还有一个好处,tailwindcss 会自动帮我们剔除没有用到的类名,如果放在普通 css 代码块内则没有这种效果。
我已经有好几个个人应用完全使用 tailwindcss 了,期间没有写过一行 css,经过实践验证目前的版本已经足够好用了(相比于2.x)。个人感觉该方案的书写便利程度远超 css-in-js, css module 等方案,推荐各位尝试,相信不会令大家失望。
作者:龙背上的骑兵
来源:微信公众号:相学长
出处
:https://mp.weixin.qq.com/s/YH3RCYGdvd67jkmN8DPIgg