红尘一场 發表於 2023-8-31 11:41:00

Tailwind CSS的初次邂逅

<h1 id="TailwindCSS的初次邂逅-官方文档">官方文档</h1>
<p>英文文档:Tailwind CSS - Rapidly build modern websites without ever leaving your HTML.</p>
<p>中文文档:Tailwind CSS - 只需书写 HTML 代码,无需书写 CSS,即可快速构建美观的网站。 | TailwindCSS中文文档 | TailwindCSS中文网</p>
<h1 id="TailwindCSS的初次邂逅-热度">热度</h1>
<p>从npm.devtool的标签可以看出,截至2023年8月,tailwindCss每个月npm下载量高达600万次,star数量也有7万+,依赖于它的Package及Github Repo更是成千上万,足以见得它的受欢迎程度。</p>
<h1 id="TailwindCSS的初次邂逅-简介">简介</h1>
<div class="confluence-information-macro confluence-information-macro-information conf-macro output-block" data-hasbody="true" data-macro-name="info">
<p class="title">来自官网</p>
<div class="confluence-information-macro-body">
<p>只需书写 HTML 代码,无需书写 CSS,即可快速构建美观的网站。</p>
<p>本 CSS 框架本质上是一个工具集,包含了大量类似&nbsp;<code>flex</code>、&nbsp;<code>pt-4</code>、&nbsp;<code>text-center</code>&nbsp;以及&nbsp;<code>rotate-90</code>&nbsp;等工具类,可以组合使用并直接在 HTML 代码上实现任何 UI 设计。</p>
</div>
</div>
<h1 id="TailwindCSS的初次邂逅-使用情况">使用情况</h1>
<p>一般项目中的CSS样式分为四种粒度:</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_275544" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">&lt;div style=</code><code class="java string">"{ borderRadius: '0.5rem', padding: '1rem' }"</code><code class="java plain">&gt; Click &lt;/div&gt;</code></div>
<div class="line number2 index1 alt1">&nbsp;</div>
<div class="line number3 index2 alt2"><code class="java plain">&lt;div&nbsp;</code><code class="java keyword">class</code><code class="java plain">=</code><code class="java string">"rounded-lg p-4"</code><code class="java plain">&gt; Click &lt;/div&gt;</code></div>
<div class="line number4 index3 alt1">&nbsp;</div>
<div class="line number5 index4 alt2"><code class="java plain">&lt;div&nbsp;</code><code class="java keyword">class</code><code class="java plain">=</code><code class="java string">"button"</code><code class="java plain">&gt; Click &lt;/div&gt;</code></div>
<div class="line number6 index5 alt1"><code class="java plain">&lt;style&gt;.button{ border-radius:&nbsp;</code><code class="java string">'0.5rem'</code><code class="java plain">; padding:&nbsp;</code><code class="java string">'1rem'</code><code class="java plain">; }&lt;/style&gt;</code></div>
<div class="line number7 index6 alt2">&nbsp;</div>
<div class="line number8 index7 alt1"><code class="java plain">&lt;Button&gt; Click &lt;/Button&gt;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p>越往下,粒度越大,而TailwindCss位于第二层,我们称为“原子化的CSS”</p>
<h1 id="TailwindCSS的初次邂逅-思考问题">思考问题</h1>
<h3 id="TailwindCSS的初次邂逅-备受争议的问题:开发者已经很熟悉的css语言,还需要学习TailwindCss的语法,有一定的学习成本、新的记忆负担,乍一看不足以提供多大的便利性">备受争议的问题:开发者已经很熟悉的css语言,还需要学习TailwindCss的语法,有一定的学习成本、新的记忆负担,乍一看不足以提供多大的便利性</h3>
<p>仅仅是这种样式:text-center(text-align: center)、p-4(padding: 1rem; /* 16px */)。一个类名代表了一个样式属性,貌似提供不了多大的便利,而且刚开始用,不熟悉的语法还需要对照文档去找,有些麻烦</p>
<p><strong>复杂样式</strong>,比如这种样式:比如一个 grid-cols-3 和 shadow :</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_412286" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java comments">/* 三等分的 Grid 属性 */</code></div>
<div class="line number2 index1 alt1"><code class="java plain">.grid-cols-</code><code class="java value">3</code>&nbsp;<code class="java plain">{</code></div>
<div class="line number3 index2 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">grid-template-columns: repeat(</code><code class="java value">3</code><code class="java plain">, minmax(</code><code class="java value">0</code><code class="java plain">, 1fr));</code></div>
<div class="line number4 index3 alt1"><code class="java plain">}</code></div>
<div class="line number5 index4 alt2"><code class="java comments">/* box-shadow 各个位置的参数的含义我们很难记住,这个时候用一个.shadow就绝对方便 */</code></div>
<div class="line number6 index5 alt1"><code class="java plain">.shadow {</code></div>
<div class="line number7 index6 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">box-shadow:&nbsp;</code><code class="java value">0</code>&nbsp;<code class="java plain">1px 3px&nbsp;</code><code class="java value">0</code>&nbsp;<code class="java plain">rgba(</code><code class="java value">0</code><code class="java plain">,&nbsp;</code><code class="java value">0</code><code class="java plain">,&nbsp;</code><code class="java value">0</code><code class="java plain">,&nbsp;</code><code class="java value">0.1</code><code class="java plain">),&nbsp;</code><code class="java value">0</code>&nbsp;<code class="java plain">1px 2px&nbsp;</code><code class="java value">0</code>&nbsp;<code class="java plain">rgba(</code><code class="java value">0</code><code class="java plain">,&nbsp;</code><code class="java value">0</code><code class="java plain">,&nbsp;</code><code class="java value">0</code><code class="java plain">,&nbsp;</code><code class="java value">0.06</code><code class="java plain">);</code></div>
<div class="line number8 index7 alt1"><code class="java plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p><strong>语义化类名</strong>,记忆成本不会很高,用过几次就熟悉了;而且官方文档清晰,配合VsCode插件语法提示学习成本真的不高</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_826549" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">&lt;button&nbsp;</code><code class="java keyword">class</code><code class="java plain">=</code><code class="java string">"text-lg text-white ring animate-spin"</code><code class="java plain">&gt; Click &lt;/button&gt;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<ul>
<li>text-lg,一个较大字体</li>
<li>text-white,白色的文字</li>
<li>ring,给按钮加一个圆圈</li>
<li>animate-spin,一个现成的动画</li>
<li>而且如果你的UI规范规定次级标题字体为15px(只是举例,一般不用奇数),还可以对这个“text-lg”进行重写,或者新增一个自己的类名:text-title,实现全局的复用(通过 tailwind.config.js 配置文件实现,可以查看官网说明)</li>
</ul>
<p>使用起来比较爽的<strong>响应式布局</strong>:</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_984474" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">&lt;div&nbsp;</code><code class="java keyword">class</code><code class="java plain">=</code><code class="java string">"grid sm:grid-cols-1 lg:grid-cols-2"</code><code class="java plain">&gt;</code></div>
<div class="line number2 index1 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">&lt;el-form&gt;</code></div>
<div class="line number3 index2 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">&lt;el-form-item&gt;&lt;/el-form-item&gt;</code></div>
<div class="line number4 index3 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">&lt;el-form-item&gt;&lt;/el-form-item&gt;</code></div>
<div class="line number5 index4 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">&lt;el-form-item&gt;&lt;/el-form-item&gt;</code></div>
<div class="line number6 index5 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">&lt;el-form-item&gt;&lt;/el-form-item&gt;</code></div>
<div class="line number7 index6 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">&lt;/el-form&gt;</code></div>
<div class="line number8 index7 alt1"><code class="java plain">&lt;/div&gt;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p>上面的效果如果自己通过grid布局写的话:</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_610021" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java color1">@media</code>&nbsp;<code class="java plain">(min-width: 1024px) {</code></div>
<div class="line number2 index1 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">.container {</code></div>
<div class="line number3 index2 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">grid-template-columns: repeat(</code><code class="java value">2</code><code class="java plain">,minmax(</code><code class="java value">0</code><code class="java plain">,1fr));</code></div>
<div class="line number4 index3 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">}</code></div>
<div class="line number5 index4 alt2"><code class="java plain">}</code></div>
<div class="line number6 index5 alt1"><code class="java color1">@media</code>&nbsp;<code class="java plain">(min-width: 640px) {</code></div>
<div class="line number7 index6 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">.container {</code></div>
<div class="line number8 index7 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">grid-template-columns: repeat(</code><code class="java value">1</code><code class="java plain">,minmax(</code><code class="java value">0</code><code class="java plain">,1fr));</code></div>
<div class="line number9 index8 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">}</code></div>
<div class="line number10 index9 alt1"><code class="java plain">}</code></div>
<div class="line number11 index10 alt2"><code class="java plain">.conainer {</code></div>
<div class="line number12 index11 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">display: grid;</code></div>
<div class="line number13 index12 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">gap: 1rem;</code></div>
<div class="line number14 index13 alt1"><code class="java plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p><strong>修饰符和各种伪类、暗黑模式</strong>等的支持,使用前缀的方式:</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_474250" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">&lt;div&nbsp;</code><code class="java keyword">class</code><code class="java plain">=</code><code class="java string">"focus:ring-2 hover:bg-red-700 dark:bg-gray-800"</code><code class="java plain">&gt;&lt;/div&gt;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p>除以上的好处,还有一些好处是:</p>
<ul>
<li>不用冥思苦想查字典查翻译去给各个class起奇奇怪怪的类名,如果有类名的命名规范还好一些,有的时候更多的是没什么规范,不全局搜索还找不到这个类,或者存在多余的没有样式依赖的“空白类”</li>
<li>自己设置一个 fontSize,padding、margin 实在不知道设置多少尺寸,tailwindcss 有较大的约束</li>
</ul>
<p>通过以上的尝试,你是不是觉得TailwindCss还是很好用的。</p>
<h3 id="TailwindCSS的初次邂逅-类似于行内样式的类名堆砌是否让代码不好维护,特别是人员调动后?">类似于行内样式的类名堆砌是否让代码不好维护,特别是人员调动后?</h3>
<p>我自己之前接手了一个用bootstrap写的项目,由于之前没有接触过,乍一看不明白那么多的类名是什么含义,但找到文档并了解文档的排版规律,什么类名大概代表什么样式,要找对应的样式去文档中翻查,其实比有些项目人员自己写的动辄100+行的样式文件理解的不是一星半点,顿时觉得真香,可以说维护起来比之前的项目更容易</p>
<p>至于在浏览器中的调试,还是一目了然的,而且没有之前各种class的重复性覆盖的问题:</p>
<p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img width="506" class="confluence-embedded-image confluence-external-resource lazyload" data-image-src="https://picx.zhimg.com/v2-67202362faf54a8fe4fc5e0609345f16_r.jpg?source=1940ef5c" data-src="https://picx.zhimg.com/v2-67202362faf54a8fe4fc5e0609345f16_r.jpg?source=1940ef5c"></span></p>
<h3 id="TailwindCSS的初次邂逅-虽然CSS代码体积变少了,但是HTML代码体积变大了,还有最终打包出来的css文件的体积问题">虽然CSS代码体积变少了,但是HTML代码体积变大了,还有最终打包出来的css文件的体积问题</h3>
<p>这的确是一个问题,html标签的类名会很长很长</p>
<p>tailwindCss也支持把很多类名提取出来成为一个组件,但是我自己没有这样用过</p>
<p>最终打包出来的css文件的体积:因为它需要把所有的css属性全部都封装一遍,所以css文件巨大,3M多。所以不建议在页面内直接引入Tailwind 原生css文件的做法。 Tailwind CSS官方团队为了解决这个问题,提出了一个方案,在编译的时候引入PurgeCSS 这个工具,构建的时候,会自动删除掉所有你没用到的css。只保留你用到的css。这样最终打包出来的css文件极小极小,一般的项目构建出来的css文件, 压缩一下甚至不会超过10K。</p>
<h3 id="TailwindCSS的初次邂逅-这种类似的原子化的CSS工具有很多:bootstrap、unocssCss等,TailwindCss与之相比有多大的优势">这种类似的原子化的CSS工具有很多:bootstrap、unocssCss等,TailwindCss与之相比有多大的优势</h3>
<p>它和bootstrap之类的css框架有什么区别呢?区别在于bootstrap帮你封装好了一些样式,比如卡片,表单,按钮,导航等等。Tailwind CSS没有封装任何样式,一丝一毫都没有。bootstrap降低了定制性,你很难依靠bootstrap去定制一个自己的类,虽然bootstrap也有部分原子化的类名,但那只是常用的一些css属性。Tailwind CSS完全自由,你可以玩出自己的花样,你甚至可以通过Tailwind CSS,打造一套属于自己的类似bootstrap这样的ui框架。</p>
<p>如果使用bootstrap,你如果想改变一个按钮的样式,就会比较困难。你得用覆盖式的写法,通过自己的样式覆盖掉bootstrap自带的样式。如果框架本身不支持修改,你通过自己的写法去修改框架本身的特性,这是一种很脏的写法。非常别扭。</p>
<h3 id="TailwindCSS的初次邂逅-TailwindCss的限制有哪些?">TailwindCss的限制有哪些?</h3>
<p><strong>elemen-plus的组件样式重写</strong>,在代码中想彻底摆脱&lt;style&gt;样式完全使用tailWindCss还是不行的,比如这种代码,处理表单页面el-select、el-input、el-date-picker长度不一致:</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_390844" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">.el-form-item {</code></div>
<div class="line number2 index1 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">margin-right:&nbsp;</code><code class="java value">0</code>&nbsp;<code class="java plain">!important;</code></div>
<div class="line number3 index2 alt2"><code class="java plain">}</code></div>
<div class="line number4 index3 alt1"><code class="java plain">.el-form-item__label {</code></div>
<div class="line number5 index4 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">position: absolute;</code></div>
<div class="line number6 index5 alt1"><code class="java plain">}</code></div>
<div class="line number7 index6 alt2"><code class="java plain">.el-form-item__content {</code></div>
<div class="line number8 index7 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">width:&nbsp;</code><code class="java value">100</code><code class="java plain">%;</code></div>
<div class="line number9 index8 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">padding-left: 80px;</code></div>
<div class="line number10 index9 alt1"><code class="java plain">}</code></div>
<div class="line number11 index10 alt2"><code class="java plain">.el-select,</code></div>
<div class="line number12 index11 alt1"><code class="java plain">.el-input_inner {</code></div>
<div class="line number13 index12 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">width:&nbsp;</code><code class="java value">100</code><code class="java plain">%;</code></div>
<div class="line number14 index13 alt1"><code class="java plain">}</code></div>
<div class="line number15 index14 alt2"><code class="java plain">:deep(.el-date-editor.el-input) {</code></div>
<div class="line number16 index15 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">width:&nbsp;</code><code class="java value">100</code><code class="java plain">%;</code></div>
<div class="line number17 index16 alt2"><code class="java plain">}</code></div>
<div class="line number18 index17 alt1"><code class="java plain">:deep(.el-date-editor .el-input__wrapper) {</code></div>
<div class="line number19 index18 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">flex-direction: row-reverse !important;</code></div>
<div class="line number20 index19 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">.el-input__suffix {</code></div>
<div class="line number21 index20 alt2"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">position: absolute;</code></div>
<div class="line number22 index21 alt1"><code class="java spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="java plain">right: 3px;</code></div>
<div class="line number23 index22 alt2"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">}</code></div>
<div class="line number24 index23 alt1"><code class="java plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p>除此之外,<strong>较为复杂的类选择器</strong>,父级元素鼠标悬浮时,子元素的样式处理:</p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_751460" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">.container:hover .item {}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<p><strong>CSS function</strong></p>
<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code">
<div class="codeContent panelContent pdl">
<div>
<div id="highlighter_179855" class="syntaxhighlighter sh-confluence nogutterjava">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="code">
<div class="container" title="Hint: double-click to select code">
<div class="line number1 index0 alt2"><code class="java plain">.body {</code></div>
<div class="line number2 index1 alt1"><code class="java spaces">&nbsp;&nbsp;</code><code class="java plain">height: calc(100vh - 6rem)</code></div>
<div class="line number3 index2 alt2"><code class="java plain">}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<h1 id="TailwindCSS的初次邂逅-开发插件推荐">开发插件推荐</h1>
<p>VsCode插件,语法提示:Tailwind CSS IntelliSense</p>
<p>&nbsp;</p>
<p>最后,初次使用,如以上总结有不严谨甚至错误,请指出。</p><br><br>
来源:https://www.cnblogs.com/nicolelhh/p/17669197.html
頁: [1]
查看完整版本: Tailwind CSS的初次邂逅