快速掌握最流行的原子化 CSS 框架 —— Tailwind

<html> <head></head> <body> <div class="content ql-editor"> <p><br></p> <p>Tailwind 是流行的原子化 css 框架。</p> <p><br></p> <p>有多流行呢?</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/eqkrjs6u.jpeg"></p> <p><br></p> <p>它现在有 68k star 了,要知道 express 才 60k:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/3f9nlufv.jpeg"></p> <p>那什么是原子化 css?</p> <p><br></p> <p>我们平时写 css 是这样的:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> &lt;div&nbsp;class="aaa"&gt;&lt;/div&gt; </div> </div> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.aaa</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">font-size</span>:&nbsp;<span class="ql-token hljs-number">16px</span>; </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">border</span>:&nbsp;<span class="ql-token hljs-number">1px</span>&nbsp;solid&nbsp;<span class="ql-token hljs-number">#000</span>; </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">padding</span>:&nbsp;<span class="ql-token hljs-number">4px</span>; </div> <div class="ql-code-block"> } </div> </div> <p><br></p> <p>在 html 里指定 class,然后在 css 里定义这个 class 的样式。</p> <p><br></p> <p>也就是 class 里包含多个样式:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/dmel42eu.jpeg"></p> <p><br></p> <p>而原子化 css 是这样的写法:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> &lt;div&nbsp;class="text-base&nbsp;p-1&nbsp;border&nbsp;border-black&nbsp;border-solid"&gt;&lt;/div&gt; </div> </div> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.text-base</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">font-size</span>:&nbsp;<span class="ql-token hljs-number">16px</span>; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.p-1</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">padding</span>:&nbsp;<span class="ql-token hljs-number">4px</span>; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.border</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">border-width</span>:&nbsp;<span class="ql-token hljs-number">1px</span>; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.border-black</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">border-color</span>:&nbsp;black; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.border-solid</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">border-style</span>:&nbsp;solid; </div> <div class="ql-code-block"> } </div> </div> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/j73fc9vx.jpeg"></p> <p><br></p> <p>定义一些细粒度的 class,叫做原子 class,然后在 html 里直接引入这些原子化的 class。</p> <p><br></p> <p>这个原子化 css 的概念还是很好理解的,但它到底有啥好处呢? 它解决了什么问题?</p> <p><br></p> <p>口说无凭,我们试下 tailwind 就知道了,它就是一个提供了很多原子 class 的 css 框架。</p> <p><br></p> <p>我们通过 crerate-react-app 创建一个 react 项目:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> npx&nbsp;create-react-app&nbsp;tailwind-test </div> </div> <p><br></p> <p>然后进入 tailwind-test 目录,执行</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> npm&nbsp;install&nbsp;-D&nbsp;tailwindcss </div> <div class="ql-code-block"> npx&nbsp;tailwindcss&nbsp;init </div> </div> <p><br></p> <p>安装 tailwindcss 依赖,创建 tailwindcss 配置文件。</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/kg16acz7.jpeg"></p> <p><br></p> <p>tailwind 实际上是一个 postcss 插件,因为 cra 内部已经做了 postcss 集成 tailwind 插件的配置,这一步就不用做了:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/fl9qvtxw.jpeg"></p> <p><br></p> <p>然后在入口 css 里加上这三行代码:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/wj52wfys.jpeg"></p> <p><br></p> <p>这三行分别是引入 tailwind 的基础样式、组件样式、工具样式的。</p> <p><br></p> <p>之后就可以在组件里用 tailwind 提供的 class 了:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"><span class="ql-token hljs-keyword">import</span>&nbsp;<span class="ql-token hljs-string">'./App.css'</span>; </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"><span class="ql-token hljs-keyword">function</span>&nbsp;<span class="ql-token hljs-title">App</span>()&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;<span class="ql-token hljs-keyword">return</span>&nbsp;( </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-tag">&lt;div&nbsp;className='text-base&nbsp;p-1&nbsp;border&nbsp;border-black&nbsp;border-solid'&gt;</span>guang<span class="ql-token hljs-tag">&lt;/div&gt;</span> </div> <div class="ql-code-block"> &nbsp;&nbsp;); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"><span class="ql-token hljs-keyword">export</span>&nbsp;<span class="ql-token hljs-keyword">default</span>&nbsp;<span class="ql-token hljs-title">App</span>; </div> </div> <p><br></p> <p>我们执行 npm run start 把开发服务跑起来。</p> <p><br></p> <p>可以看到,它正确的加上了样式:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/dkm7n4ez.jpeg"></p> <p><br></p> <p>用到的这些原子 class 就是 tailwind 提供的:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/y9vb9ls7.jpeg"></p> <p><br></p> <p>这里的 p-1 是 padding:0.25rem,你也可以在配置文件里修改它的值:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/muhjgtq7.jpeg"></p> <p><br></p> <p>在 <a href="http://tailwind.config.js" target="_blank">tailwind.config.js</a> 的 <a href="http://theme.extend" target="_blank">theme.extend</a> 修改 p-1 的值,设置为 30px。</p> <p><br></p> <p>刷新页面,就可以看到 p-1 的样式变了:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/6j313hw1.jpeg"></p> <p><br></p> <p>.text-base 是 font-size、line-height 两个样式,这种通过数组配置:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/uwq07a4c.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/ppb5ny3f.jpeg"></p> <p><br></p> <p>也就是说所有 tailwind 提供的所有内置原子 class 都可以配置。</p> <p><br></p> <p>但这些都是全局的更改,有的时候你想临时设置一些值,可以用 [] 语法。</p> <p><br></p> <p>比如 text-[14px],它就会生成 font-size:14px 的样式:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/2sgaif94.jpeg"></p> <p><br></p> <p>比如 aspect-[4/3],就是这样的样式:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/o9wlojmq.jpeg"></p> <p><br></p> <p>我们平时经常指定 hover 时的样式,在 tailwind 里怎么指定呢?</p> <p><br></p> <p>很简单,这样写:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/9axdswxg.jpeg"></p> <p><br></p> <p>生成的就是带状态的 class:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/1ng71n35.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/s13ivl1m.jpeg"></p> <p><br></p> <p>此外,写响应式的页面的时候,我们要指定什么宽度的时候用什么样式,这个用 tailwind 怎么写呢?</p> <p><br></p> <p>也是一样的写法:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/4t2fly2o.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/zlqkuufy.jpeg"></p> <p><br></p> <p>生成的是这样的代码:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/goyxbgat.jpeg"></p> <p><br></p> <p>这个断点位置自然也是可以配置的:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/weffg7t2.jpeg"></p> <p><br></p> <p>可以看到 md 断点对应的宽度变了:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/wivbdspv.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/zqomhp5g.jpeg"></p> <p><br></p> <p>光这些就很方便了。</p> <p><br></p> <p>之前要这么写:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> &lt;div&nbsp;class="aaa"&gt;&lt;/div&gt; </div> </div> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.aaa</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">background</span>:&nbsp;red; </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">font-size</span>:&nbsp;<span class="ql-token hljs-number">16px</span>; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"><span class="ql-token hljs-selector-class">.aaa:hover</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">font-size</span>:&nbsp;<span class="ql-token hljs-number">30px</span>; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"><span class="ql-token hljs-keyword">@media</span>(min-width:768px)&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-selector-class">.aaa</span>&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attribute">background</span>:&nbsp;blue; </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;} </div> <div class="ql-code-block"> } </div> </div> <p><br></p> <p>现在只需要这样:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> &lt;div&nbsp;class="text-[14px]&nbsp;bg-red-500&nbsp;hover:text-[30px]&nbsp;md:bg-blue-500"&gt;&lt;/div&gt; </div> </div> <p><br></p> <p>省去了很多样板代码,还省掉了 class 的命名。</p> <p><br></p> <p>并且这些 class 都可以通过配置来统一修改。</p> <p><br></p> <p>感受到原子化 css 的好处了么?</p> <p><br></p> <p>tailwind 文档提到了 3 个好处:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/zaj1da89.jpeg"></p> <p><br></p> <p>不用起 class 名字,这点简直太爽了,我就经常被起 class 名字折磨。</p> <p><br></p> <p>css 不会一直增长,因为如果你用之前的写法可能是这样的:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/pd9zuv0u.jpeg"></p> <p><br></p> <p>多个 class 里都包含了类似的样式,但你需要写多次,而如果用了原子 class,就只需要定义一次就好了。</p> <p><br></p> <p>css 没有模块作用域,所以可能你在这里加了一个样式,结果别的地方样式错乱了。</p> <p><br></p> <p>而用原子 class 就没这种问题,因为样式是只是作用在某个 html 标签的。</p> <p><br></p> <p>我觉得光这三点好处就能够说服我用它了,特别是不用起 class 名字这点。</p> <p><br></p> <p>当然,社区也有一些反对的声音,我们来看看他们是怎么说的:</p> <p><br></p> <p><strong style="color: rgb(74, 74, 74);">一堆 class,可读性、可维护性太差了</strong></p> <p><br></p> <p>真的么?</p> <p><br></p> <p>这种把 css 写在 html 里的方式应该是更高效才对。</p> <p><br></p> <p>想想为啥 vue 要创造个单文件组件的语法,把 js、css、template 放在一个文件里写,不就是为了紧凑么?</p> <p><br></p> <p>之前你要在 css、js 文件里反复跳来跳去的,查找某个 class 的样式是啥,现在不用这么跳了,直接在 html 里写原子样式,它不香么?</p> <p><br></p> <p>而且 tailwindcss 就前面提到的那么几个语法,没啥学习成本,很容易看懂才对。</p> <p><br></p> <p><strong style="color: rgb(74, 74, 74);">但是还要每次去查文档哪些 class 对应什么样式呀</strong></p> <p><br></p> <p>这个可以用 tailwind css 提供的 vscode 插件来解决:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/zy9mwz04.jpeg"></p> <p><br></p> <p>安装这个 Tailwind CSS IntelliSense 之后的体验是这样的:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/ogfw2zi7.jpeg"></p> <p><br></p> <p>有智能提示,可以查看它对应的样式。</p> <p><br></p> <p>不需要记。</p> <p><br></p> <p><strong style="color: rgb(74, 74, 74);">难以调试</strong></p> <p><br></p> <p>在 chrome devtools 里可以直接看到有啥样式,而且样式之间基本没有交叉,很容易调试:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/jfm9pwm1.jpeg"></p> <p><br></p> <p>相反,我倒是觉得之前那种写法容易多个 class 的样式相互覆盖,还要确定优先级和顺序,那个更难调试才对:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/jt2ltv8g.jpeg"></p> <p><br></p> <p><strong style="color: rgb(74, 74, 74);">类型太长了而且重复多次</strong></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/0r1pkxan.jpeg"></p> <p><br></p> <p>这种问题可以用 @layer @apply 指令来扩展:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/0ue96o4e.jpeg"></p> <p><br></p> <p>前面讲过 @tailwind 是引入不同的样式的,而 @layer 就是在某一层样式做修改和扩充,里面可以用 @apply 应用其他样式。</p> <p><br></p> <p>效果是这样的:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/00ah03ja.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/qrx2z9yn.jpeg"></p> <p><br></p> <p><strong style="color: rgb(74, 74, 74);">内置 class 不能满足我的需求</strong></p> <p><br></p> <p>其实上面那个 @layer 和 @apply 就能扩展内置原子 class。</p> <p><br></p> <p>但如果你想跨项目复用,那可以开发个 tailwind 插件</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"><span class="ql-token hljs-keyword">const</span>&nbsp;plugin&nbsp;=&nbsp;<span class="ql-token hljs-built_in">require</span>(<span class="ql-token hljs-string">'tailwindcss/plugin'</span>); </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"><span class="ql-token hljs-variable">module</span>.<span class="ql-token hljs-property">exports</span>&nbsp;=&nbsp;<span class="ql-token hljs-title">plugin</span>(<span class="ql-token hljs-keyword">function</span>(<span class="ql-token hljs-params">{&nbsp;addUtilities&nbsp;}</span>)&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-title">addUtilities</span>({ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-string">'.guang'</span>:&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attr">background</span>:&nbsp;<span class="ql-token hljs-string">'blue'</span>, </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-attr">color</span>:&nbsp;<span class="ql-token hljs-string">'yellow'</span> </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-string">'.guangguang'</span>:&nbsp;{ </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="ql-token hljs-string">'font-size'</span>:&nbsp;<span class="ql-token hljs-string">'70px'</span> </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} </div> <div class="ql-code-block"> &nbsp;&nbsp;&nbsp;&nbsp;}) </div> <div class="ql-code-block"> }) </div> </div> <p><br></p> <p>在 <a href="http://tailwind.config.js" target="_blank">tailwind.config.js</a> 里引入:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/vq1nszn7.jpeg"></p> <p><br></p> <p>这样就可以用这个新加的原子 class 了:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/k6wfqigx.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/83myq3du.jpeg"></p> <p><br></p> <p>插件的方式或者 @layer 的方式都可以扩展。</p> <p><br></p> <p><strong style="color: rgb(74, 74, 74);">tailwind 的 class 名和我已有的 class 冲突了咋办?</strong></p> <p><br></p> <p>比如我本来有个 border 的 class:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/ns751hk1.jpeg"></p> <p><br></p> <p>而 tailwind 也有,不就冲突了么?</p> <p><br></p> <p>这个可以通过加 prefix 解决:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/35v1nmfm.jpeg"></p> <p><br></p> <p>不过这样所有的原子 class 都得加 prefix 了:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/9nxhgima.jpeg"></p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/z6vtdsbm.jpeg"></p> <p><br></p> <p>知道了什么是原子 css 以及 tailwind 的用法之后,我们再来看看它的实现原理。</p> <p><br></p> <p>tailwind 可以单独跑,也可以作为 postcss 插件来跑。这是因为如果单独跑的话,它也会跑起 postcss,然后应用 tailwind 的插件:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/mxm8oqxp.jpeg"></p> <p><br></p> <p>所以说,<strong style="color: rgb(74, 74, 74);">tailwind 本质上就是个 postcss 插件</strong>。</p> <p><br></p> <p>postcss 是一个 css 编译器,它是 parse、transform、generate 的流程。</p> <p><br></p> <p>在 <a href="http://astexplorer.net" target="_blank">astexplorer.net</a> 可以看到 postcss 的 AST:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/r4bh7e4d.jpeg"></p> <p><br></p> <p>而 postcss 就是通过 AST 来拿到 @tailwind、@layer、@apply 这些它扩展的指令,分别作相应的处理,也就是对 AST 的增删改查。</p> <p><br></p> <p>那它是怎么扫描到 js、html 中的 className 的呢?</p> <p><br></p> <p>这是因为它有个 extractor 的东西,用来通过正则匹配文本中的 class,之后添加到 AST 中,最终生成代码。</p> <p><br></p> <p>extractor 的功能看下测试用例就明白了:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/ovx6o30e.jpeg"></p> <p><br></p> <p>所以说,<strong style="color: rgb(74, 74, 74);">tailwind 就是基于 postcss 的 AST 实现的 css 代码生成工具,并且做了通过 extractor 提取 js、html 中 class 的功能。</strong></p> <p><br></p> <p>tailwind 还有种叫 JIT 的编译方式,这个原理也容易理解,本来是全部引入原子 css 然后过滤掉没有用到的,而 JIT 的话就是根据提取到的 class 来动态引入原子 css,更高效一点。</p> <p><br></p> <p>最后,为啥这个 css 框架叫 tailwind 呢?</p> <p><br></p> <p>因为作者喜欢叫做 kiteboarding 风筝冲浪的运动。</p> <p><br></p> <p>就是这样的,一个风筝,一个冲浪板:</p> <p><br></p> <p><img src="https://pic.code-nav.cn/planet_post_image/1797461877294809089/wo31q6m6.jpeg"></p> <p><br></p> <p>这种运动在顺风 tailwind 和逆风 headwind 下有不同的技巧。而 tailwind 的时候明显更加省力。</p> <p><br></p> <p>所以就给这个 css 框架起名叫 tailwind 了。</p> <p><br></p> <p>确实,我也觉得用这种方式来写 css 更加省力、高效,不用写 class 名字了,代码更简洁了,还不容易样式冲突了。</p> <p><br></p> <h2 class="ql-align-center"><strong style="font-size: 18px; color: rgb(72, 179, 120);">总结</strong></h2> <p><br></p> <p>tailwind 是一个流行的原子化 css 框架。</p> <p><br></p> <p>传统 css 写法是定义 class,然后在 class 内部写样式,而原子化 css 是预定义一些细粒度 class,通过组合 class 的方式完成样式编写。</p> <p><br></p> <p>tailwind 用起来很简单:</p> <p><br></p> <p>所有预定义的 class 都可以通过配置文件修改值,也可以通过 aaa-[14px] 的方式定义任意值的 class。</p> <p><br></p> <p>所有 class 都可以通过 hover:xxx、md:xxx 的方式来添加某个状态下的样式,响应式的样式,相比传统的写法简洁太多了。</p> <p><br></p> <p>它的优点有很多,我个人最喜欢的就是不用起 class 的名字了,而且避免了同样的样式在多个 class 里定义多次导致代码重复,并且局部作用于某个标签,避免了全局污染。</p> <p><br></p> <p>它可以通过 @layer、@apply 或者插件的方式扩展原子 class,支持 prefix 来避免 class 名字冲突。</p> <p><br></p> <p>tailwind 本质上就是一个 postcss 插件,通过 AST 来分析 css 代码,对 css 做增删改,并且可以通过 extractor 提取 js、html 中的 class,之后基于这些来生成最终的 css 代码。</p> <p><br></p> <p>是否感受到了 tailwind 的简洁高效,易于扩展?就是这些原因让它成为了最流行的原子化 css 框架。</p> <p><br></p> </div> </body> </html>

下载 APP