<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 7485字,需瀏覽 15分鐘

           ·

          2023-06-22 03:00

          Tailwind 是流行的原子化 css 框架。

          大廠技術(shù)  高級(jí)前端  精選文章

          點(diǎn)擊上方 全站前端精選,關(guān)注公眾號(hào)

          回復(fù)1,加入高級(jí)前段交流

          有多流行呢?

          它現(xiàn)在有 68k star 了,要知道 express 才 60k:

          那什么是原子化 css?

          我們平時(shí)寫(xiě) css 是這樣的:

          <div class="aaa"></div>
          .aaa {
              font-size16px;
              border1px solid #000;
              padding4px;
          }

          在 html 里指定 class,然后在 css 里定義這個(gè) class 的樣式。

          也就是 class 里包含多個(gè)樣式:

          而原子化 css 是這樣的寫(xiě)法:

          <div class="text-base p-1 border border-black border-solid"></div>
          .text-base {
              font-size16px;
          }
          .p-1 {
              padding4px;
          }
          .border {
              border-width1px;
          }
          .border-black {
              border-color: black;
          }
          .border-solid {
              border-style: solid;
          }

          定義一些細(xì)粒度的 class,叫做原子 class,然后在 html 里直接引入這些原子化的 class。

          這個(gè)原子化 css 的概念還是很好理解的,但它到底有啥好處呢? 它解決了什么問(wèn)題?

          口說(shuō)無(wú)憑,我們?cè)囅?tailwind 就知道了,它就是一個(gè)提供了很多原子 class 的 css 框架。

          我們通過(guò) crerate-react-app 創(chuàng)建一個(gè) react 項(xiàng)目:

          npx create-react-app tailwind-test

          然后進(jìn)入 tailwind-test 目錄,執(zhí)行

          npm install -D tailwindcss
          npx tailwindcss init

          安裝 tailwindcss 依賴(lài),創(chuàng)建 tailwindcss 配置文件。

          tailwind 實(shí)際上是一個(gè) postcss 插件,因?yàn)?cra 內(nèi)部已經(jīng)做了 postcss 集成 tailwind 插件的配置,這一步就不用做了:

          然后在入口 css 里加上這三行代碼:

          這三行分別是引入 tailwind 的基礎(chǔ)樣式、組件樣式、工具樣式的。

          之后就可以在組件里用 tailwind 提供的 class 了:

          import './App.css';

          function App({
            return (
              <div className='text-base p-1 border border-black border-solid'>guang</div>
            );
          }

          export default App;

          我們執(zhí)行 npm run start 把開(kāi)發(fā)服務(wù)跑起來(lái)。

          可以看到,它正確的加上了樣式:

          用到的這些原子 class 就是 tailwind 提供的:

          這里的 p-1 是 padding:0.25rem,你也可以在配置文件里修改它的值:

          在 tailwind.config.js 的 theme.extend 修改 p-1 的值,設(shè)置為 30px。

          刷新頁(yè)面,就可以看到 p-1 的樣式變了:

          .text-base 是 font-size、line-height 兩個(gè)樣式,這種通過(guò)數(shù)組配置:

          也就是說(shuō)所有 tailwind 提供的所有內(nèi)置原子 class 都可以配置。

          但這些都是全局的更改,有的時(shí)候你想臨時(shí)設(shè)置一些值,可以用 [] 語(yǔ)法。

          比如 text-[14px],它就會(huì)生成 font-size:14px 的樣式:

          比如 aspect-[4/3],就是這樣的樣式:

          我們平時(shí)經(jīng)常指定 hover 時(shí)的樣式,在 tailwind 里怎么指定呢?

          很簡(jiǎn)單,這樣寫(xiě):

          生成的就是帶狀態(tài)的 class:

          此外,寫(xiě)響應(yīng)式的頁(yè)面的時(shí)候,我們要指定什么寬度的時(shí)候用什么樣式,這個(gè)用 tailwind 怎么寫(xiě)呢?

          也是一樣的寫(xiě)法:

          生成的是這樣的代碼:

          這個(gè)斷點(diǎn)位置自然也是可以配置的:

          可以看到 md 斷點(diǎn)對(duì)應(yīng)的寬度變了:

          光這些就很方便了。

          之前要這么寫(xiě):

          <div class="aaa"></div>
          .aaa {
              background: red;
              font-size16px;
          }

          .aaa:hover {
              font-size30px;
          }

          @media(min-width:768px) {
              .aaa {
                  background: blue;
              }
          }

          現(xiàn)在只需要這樣:

          <div class="text-[14px] bg-red-500 hover:text-[30px] md:bg-blue-500"></div>

          省去了很多樣板代碼,還省掉了 class 的命名。

          并且這些 class 都可以通過(guò)配置來(lái)統(tǒng)一修改。

          感受到原子化 css 的好處了么?

          tailwind 文檔提到了 3 個(gè)好處:

          不用起 class 名字,這點(diǎn)簡(jiǎn)直太爽了,我就經(jīng)常被起 class 名字折磨。

          css 不會(huì)一直增長(zhǎng),因?yàn)槿绻阌弥暗膶?xiě)法可能是這樣的:

          多個(gè) class 里都包含了類(lèi)似的樣式,但你需要寫(xiě)多次,而如果用了原子 class,就只需要定義一次就好了。

          css 沒(méi)有模塊作用域,所以可能你在這里加了一個(gè)樣式,結(jié)果別的地方樣式錯(cuò)亂了。

          而用原子 class 就沒(méi)這種問(wèn)題,因?yàn)闃邮绞侵皇亲饔迷谀硞€(gè) html 標(biāo)簽的。

          我覺(jué)得光這三點(diǎn)好處就能夠說(shuō)服我用它了,特別是不用起 class 名字這點(diǎn)。

          當(dāng)然,社區(qū)也有一些反對(duì)的聲音,我們來(lái)看看他們是怎么說(shuō)的:

          一堆 class,可讀性、可維護(hù)性太差了

          真的么?

          這種把 css 寫(xiě)在 html 里的方式應(yīng)該是更高效才對(duì)。

          想想為啥 vue 要?jiǎng)?chuàng)造個(gè)單文件組件的語(yǔ)法,把 js、css、template 放在一個(gè)文件里寫(xiě),不就是為了緊湊么?

          之前你要在 css、js 文件里反復(fù)跳來(lái)跳去的,查找某個(gè) class 的樣式是啥,現(xiàn)在不用這么跳了,直接在 html 里寫(xiě)原子樣式,它不香么?

          而且 tailwindcss 就前面提到的那么幾個(gè)語(yǔ)法,沒(méi)啥學(xué)習(xí)成本,很容易看懂才對(duì)。

          但是還要每次去查文檔哪些 class 對(duì)應(yīng)什么樣式呀

          這個(gè)可以用 tailwind css 提供的 vscode 插件來(lái)解決:

          安裝這個(gè) Tailwind CSS IntelliSense 之后的體驗(yàn)是這樣的:

          有智能提示,可以查看它對(duì)應(yīng)的樣式。

          不需要記。

          難以調(diào)試

          在 chrome devtools 里可以直接看到有啥樣式,而且樣式之間基本沒(méi)有交叉,很容易調(diào)試:

          相反,我倒是覺(jué)得之前那種寫(xiě)法容易多個(gè) class 的樣式相互覆蓋,還要確定優(yōu)先級(jí)和順序,那個(gè)更難調(diào)試才對(duì):

          類(lèi)型太長(zhǎng)了而且重復(fù)多次

          這種問(wèn)題可以用 @layer @apply 指令來(lái)擴(kuò)展:

          前面講過(guò) @tailwind 是引入不同的樣式的,而 @layer 就是在某一層樣式做修改和擴(kuò)充,里面可以用 @apply 應(yīng)用其他樣式。

          效果是這樣的:

          內(nèi)置 class 不能滿(mǎn)足我的需求

          其實(shí)上面那個(gè) @layer 和 @apply 就能擴(kuò)展內(nèi)置原子 class。

          但如果你想跨項(xiàng)目復(fù)用,那可以開(kāi)發(fā)個(gè) tailwind 插件

          const plugin = require('tailwindcss/plugin');

          module.exports = plugin(function({ addUtilities }{
              addUtilities({
                  '.guang': {
                      background'blue',
                      color'yellow'
                  },
                  '.guangguang': {
                      'font-size''70px'
                  }
              })
          })

          在 tailwind.config.js 里引入:

          這樣就可以用這個(gè)新加的原子 class 了:

          插件的方式或者 @layer 的方式都可以擴(kuò)展。

          tailwind 的 class 名和我已有的 class 沖突了咋辦?

          比如我本來(lái)有個(gè) border 的 class:

          而 tailwind 也有,不就沖突了么?

          這個(gè)可以通過(guò)加 prefix 解決:

          不過(guò)這樣所有的原子 class 都得加 prefix 了:

          知道了什么是原子 css 以及 tailwind 的用法之后,我們?cè)賮?lái)看看它的實(shí)現(xiàn)原理。

          tailwind 可以單獨(dú)跑,也可以作為 postcss 插件來(lái)跑。這是因?yàn)槿绻麊为?dú)跑的話,它也會(huì)跑起 postcss,然后應(yīng)用 tailwind 的插件:

          所以說(shuō),tailwind 本質(zhì)上就是個(gè) postcss 插件

          postcss 是一個(gè) css 編譯器,它是 parse、transform、generate 的流程。

          在 astexplorer.net 可以看到 postcss 的 AST:

          而 postcss 就是通過(guò) AST 來(lái)拿到 @tailwind、@layer、@apply 這些它擴(kuò)展的指令,分別作相應(yīng)的處理,也就是對(duì) AST 的增刪改查。

          那它是怎么掃描到 js、html 中的 className 的呢?

          這是因?yàn)樗袀€(gè) extractor 的東西,用來(lái)通過(guò)正則匹配文本中的 class,之后添加到 AST 中,最終生成代碼。

          extractor 的功能看下測(cè)試用例就明白了:

          所以說(shuō),tailwind 就是基于 postcss 的 AST 實(shí)現(xiàn)的 css 代碼生成工具,并且做了通過(guò) extractor 提取 js、html 中 class 的功能。

          tailwind 還有種叫 JIT 的編譯方式,這個(gè)原理也容易理解,本來(lái)是全部引入原子 css 然后過(guò)濾掉沒(méi)有用到的,而 JIT 的話就是根據(jù)提取到的 class 來(lái)動(dòng)態(tài)引入原子 css,更高效一點(diǎn)。

          最后,為啥這個(gè) css 框架叫 tailwind 呢?

          因?yàn)樽髡呦矚g叫做 kiteboarding 風(fēng)箏沖浪的運(yùn)動(dòng)。

          就是這樣的,一個(gè)風(fēng)箏,一個(gè)沖浪板:

          這種運(yùn)動(dòng)在順風(fēng) tailwind 和逆風(fēng) headwind 下有不同的技巧。而 tailwind 的時(shí)候明顯更加省力。

          所以就給這個(gè) css 框架起名叫 tailwind 了。

          確實(shí),我也覺(jué)得用這種方式來(lái)寫(xiě) css 更加省力、高效,不用寫(xiě) class 名字了,代碼更簡(jiǎn)潔了,還不容易樣式?jīng)_突了。

          總結(jié)

          tailwind 是一個(gè)流行的原子化 css 框架。

          傳統(tǒng) css 寫(xiě)法是定義 class,然后在 class 內(nèi)部寫(xiě)樣式,而原子化 css 是預(yù)定義一些細(xì)粒度 class,通過(guò)組合 class 的方式完成樣式編寫(xiě)。

          tailwind 用起來(lái)很簡(jiǎn)單:

          所有預(yù)定義的 class 都可以通過(guò)配置文件修改值,也可以通過(guò) aaa-[14px] 的方式定義任意值的 class。

          所有 class 都可以通過(guò) hover:xxx、md:xxx 的方式來(lái)添加某個(gè)狀態(tài)下的樣式,響應(yīng)式的樣式,相比傳統(tǒng)的寫(xiě)法簡(jiǎn)潔太多了。

          它的優(yōu)點(diǎn)有很多,我個(gè)人最喜歡的就是不用起 class 的名字了,而且避免了同樣的樣式在多個(gè) class 里定義多次導(dǎo)致代碼重復(fù),并且局部作用于某個(gè)標(biāo)簽,避免了全局污染。

          它可以通過(guò) @layer、@apply 或者插件的方式擴(kuò)展原子 class,支持 prefix 來(lái)避免 class 名字沖突。

          tailwind 本質(zhì)上就是一個(gè) postcss 插件,通過(guò) AST 來(lái)分析 css 代碼,對(duì) css 做增刪改,并且可以通過(guò) extractor 提取 js、html 中的 class,之后基于這些來(lái)生成最終的 css 代碼。

          是否感受到了 tailwind 的簡(jiǎn)潔高效,易于擴(kuò)展?就是這些原因讓它成為了最流行的原子化 css 框架。

          • 前端 社群



            下方加 Nealyang 好友回復(fù)「 加群」即可。



            如果你覺(jué)得這篇內(nèi)容對(duì)你有幫助,我想請(qǐng)你幫我2個(gè)小忙:

            1. 點(diǎn)個(gè)「在看」,讓更多人也能看到這篇文章

          瀏覽 33
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成人在线免费观看视频 | 色婷婷久久 | 亚洲靠逼视频免费看 | 亚洲AV无码18日韩 | 欧美一级在线观看 |