淺談Atomic CSS 的發展背景與Tailwind CSS - Huli
文章推薦指數: 80 %
總之呢,那篇貼文引起了臉書上前端社團的熱烈討論,在短短兩三天內迅速多出許多討論相關技術的文章。
而有許多人在討論的議題,其實比起Tailwind CSS 這個 ...
Huli
文章列表
分類
推薦閱讀
關於我
English
我最近正好奇著大家讀完我的技術文章後的感想,有空的話可以幫我填一下:表單連結
淺談AtomicCSS的發展背景與TailwindCSS
2022年5月23日
Front-end
這陣子在Front-EndDevelopersTaiwan臉書社團上有一系列關於TailwindCSS的討論,起因是另一篇已經刪除的貼文,那篇貼文我有看過,因為怕原文內容跟記憶內容有落差,因此這邊就不講我記憶中的原文大概是在寫什麼了,畢竟這也不是這篇所關注的重點。
總之呢,那篇貼文引起了臉書上前端社團的熱烈討論,在短短兩三天內迅速多出許多討論相關技術的文章。
而有許多人在討論的議題,其實比起TailwindCSS這個工具,更多的是在討論AtomicCSS這個概念本身。
AtomicCSS這個詞由ThierryKoblentz所提出,最早出自於這篇2013年發表的必讀的經典:ChallengingCSSBestPractices。
那什麼是AtomicCSS?這邊直接取用Let’sDefineExactlyWhatAtomicCSSis這篇文章給的定義:
AtomicCSSistheapproachtoCSSarchitecturethatfavorssmall,single-purposeclasseswithnamesbasedonvisualfunction.
例如說像這樣子的東西就是AtomicCSS:
12.bg-blue{background-color:#357edd;}.margin-0{margin:0;}
而TailwindCSS就是實作了AtomicCSS這個概念的一個CSS框架。
在2019年的時候我也寫過一篇在講AtomicCSS的文章,但那時用的是另外一個同義詞叫做FunctionalCSS:邪魔歪道還是苦口良藥?FunctionalCSS經驗分享,在那篇裡面已經有提到一些這篇想講的東西,但我覺得還不夠完整,因此才又寫了一篇。
在這篇文章中,我希望跟大家一起讀一下這些經典文章,因為你會發現有些爭論的點可能早在八九年前就已經被提出、討論或甚至是解決了。
接著就可以來看看最早的AtomicCSS跟現在的TailwindCSS的差別在哪,優缺點又是什麼?
大綱如下:
AtomicCSS的誕生背景
AtomicCSS到底想解決什麼問題?
針對AtomicCSS的問題與反駁
我對AtomicCSS的看法
TailwindCSS改良了哪些部分?
結語
AtomicCSS的誕生背景如開頭所述,AtomicCSS一詞出自於Yahoo!的工程師ThierryKoblentz(以下簡稱TK)在2013年所發表的ChallengingCSSBestPractices。
在看這篇文章之前,我們可以先看一下2022年2月的這篇專訪:TheMakingofAtomicCSS:AnInterviewWithThierryKoblentz,在這篇裡面提及了更多AtomicCSS出現的背景以及早期在Yahoo!內部的應用。
根據文章中的說法,有天他的主管來問他有沒有一種可以不改到stylesheet但還是可以動到畫面的方法,因為他想避免把東西改壞。
於是TK就做了一個「utility-sheet」,讓工程師可以在不改到stylesheet的狀況下依然能改到前端的樣式。
聽起來這個utility-sheet應該就是一個靜態的CSS檔案,然後裡面有著各種utilityclass。
接著過了幾年,一個工程主管問他是否能「全部都用utilityclass」來改寫Yahoo!的首頁,在當時可以說是先驅中的先驅了。
最後他們寫了一個純靜態(static)的CSS並取名為Stencil來完成這件事(這邊會講到純靜態是為了跟等一下會出現的東西來做對比),並且從中發現了很多這樣子使用的好處。
這套純靜態的CSS的特色之一是可以強迫遵從一些designstyle,例如說只寫了margin-left-1、margin-left-2、margin-left-3之類的class,然後每一個對應到的是x4,因此你的margin就只有4px、8px跟12px這些4的倍數可以用,利用這個來強迫設計遵循既有的規則。
不過後來他們發現這套系統行不通。
因為在現實世界中,每個designteam都有自己不同的要求,他們想要的padding、margin、字體、顏色全部都不同,所以靜態是不行的,需要客製化,需要動態產生。
於是Atomizer就誕生了,一個幫你產生相對應CSS檔案的工具。
例如說你有個頁面寫了:
1
上面看到的這些語法叫做ACSS,其實功能基本上跟現在的TailwindCSS已經滿類似的了,只是使用的語法不太一樣而已。
這套ACSS系統的命名規則的靈感是來自於Emmet,一個可以利用語法幫你快速建置HTML的套件,而classname中的()的靈感則是來自於函式呼叫。
接著TK談到了在像是Yahoo!這種大型企業寫CSS跟其他地方有什麼不同,你會面臨到的狀況超級複雜,包括跨國跨時區的溝通、分佈各地的團隊成員、幾百個共用的component、l10n跟i18n、一堆legacycode,以及一堆的辦公室政治。
在需要維護一個超級複雜的專案的狀況之下,他開始反思一些常見做法(commonpractice)是否真的能帶來益處,最後卻發現有些概念除了沒有帶來益處以外,甚至是有害的。
在複雜的專案之中,有很多你可能沒想過的狀況會發生,所以維護變得很艱難,必須要小心翼翼去避開一些陷阱。
另外,在內部推廣ACSS的旅程剛開始並不順利,看起來有許多team都對那樣的語法卻步(我猜就如同我在之前的文章寫的一樣,一開始看到都會覺得這是什麼邪魔歪道),但是ACSS帶來的好處反映在數據上面,採用了ACSS的專案少了大約36%的CSS與HTML的大小,因此至今依然有許多專案還用著ACSS。
如果你把A網頁的HTML複製,貼上到B網頁去,你會發現UI完全沒變,使用了ACSS之後不會因為你在別的頁面就有不同的樣式,這就是ACSS所帶來的好處,原文是這樣寫的:
ThisisbecauseACSSmakesthesecomponentspageagnostic.
「pageagnostic」是我覺得很重要的一個性質,這個之後會再提到。
原文的專訪還有提到更多故事背景跟挑戰,不過在這邊我就不繼續再提了,有興趣的讀者們可以去看原文。
而之前TechBridge的好夥伴Arvin以前在Yahoo!待過,在公司內有寫過ACSS,他在2017年的時候有寫過一篇文章,也很值得一看:淺談CSS方法論與AtomicCSS。
這篇專訪中其實對於AtomicCSS想解決的問題並沒有到這麼多的著墨,不過從中可以看見TK在工作上需要維護大型的專案,因此自然也會碰到許多痛點,不難想像出AtomicCSS誕生的背景也與此有關。
想知道AtomicCSS要解決什麼問題,就要來看經典之作了。
AtomicCSS到底想解決什麼問題?底下我會引用許多來自於ChallengingCSSBestPractices的內容,因為原文寫得很清楚。
如果英文閱讀能力ok的話,也強烈推薦讀者們自己看過一遍。
在文章開頭的quicksummary,就有這樣一段:
WhenitcomestoCSS,Ibelievethatthesacredprincipleof“separationofconcerns”(SoC)hasleadustoacceptbloat,obsolescence,redundancy,poorcachingandmore.Now,I’mconvincedthattheonlywaytoimprovehowweauthorstylesheetsisbymovingawayfromthisprinciple.
大家都知道在寫網頁的時候要注重關注點分離(separationofconcerns),讓HTML做好它的事情,只關注內容,而CSS只關注樣式,兩者透過classname連結在一起。
可是作者發現這樣子的概念,其實會帶來許多負面影響,因此這篇文章就是來說服大家不要再把這種做法奉為信條,如果有更好的路,那幹嘛執著在這呢?
接著文中舉了一個簡單的例子,稱之為mediaobject,HTML長這樣:
12345678
於是我們可以包一個div在外面,像這樣:
12345678910
第二點其實看起來也滿正常,要共用style的話,寫成.media,.bg不是很常見嗎?檔案大的話也是必然的吧?
第三點的話這個context是個很重要的概念,例如說我們最後這個規則:#rightRail.bd,讓在#rightRail底下的.bd改變字體大小,有不同的樣式。
所以我們的mediaobject會根據context(是否在#rightRail)底下有不同的樣式,就寫了不同的CSS規則去處理。
一旦讓你的CSS規則跟context有關,在大型專案中維護就會變得困難。
舉例來說,如果有人手賤去改了rightRail這個id,想說改成blockRightRail會更好,那你的樣式就壞了。
你可能會質疑說:「不對啊,這是他的錯啊,他要改的話應該就要確認其他地方不會壞」,有改過的人都知道,要確認其他地方有沒有壞,是多麽困難的一件事情,更何況是在大型專案之中。
很可能你改A的時候,根本不會預期B會壞掉,因為你根本不知道他們有關。
或如果別的team想把你這個mediaobject拿去用,於是就連同CSS一起複製貼上到他們專案,可是卻發現他們的id並沒有rigthRails,那就要去改動style。
第四點的話也是只有在Yahoo!這種大型公司才比較會做到的事情(至少我是沒做過),就是在做l10n的時候會有很多細節要考慮,例如說有些國家的閱讀方向是左到右,有些是右到左。
上面的case如果要改變方向,就要加上這兩個規則:
12345678910.rtl.media.img{margin-right:auto;/*reset*/float:right;margin-left:10px;}.rtl.media.imgExt{margin-left:auto;/*reset*/float:left;margin-right:10px;}
接著,作者就提出了AtomicCSS的概念,然後以AtomicCSS來改寫,並告訴你這樣改的好處在哪,HTML跟CSS如下:
12345678
第二點,現在所有需要overflow:hidden跟zoom:1的元素,我都只要用一個classname叫做.Bfc就可以搞定了,無論有多少個元素要用,我都只有一個CSSselector。
第三點,現在的classname已經跟context無關了,我上面講的問題完全不會發生。
今天我樣式要變,我可以很安心地把classname刪掉,因為我知道其他地方絕對不會壞掉。
這就是開頭第一段所講的「pageagnostic」,沒有context的classname才能做到容易刪改,而且可以搬來搬去還能保證相同樣式。
換句話說,它解決的是scope的問題,就如同原文所說:
Ibelievethatthisapproachisagame-changerbecauseitnarrowsthescopedramatically.Wearestylingnotintheglobalscope(thestylesheet),butatthemoduleandblocklevel.Wecanchangethestyleofamodulewithoutworryingaboutbreakingsomethingelseonthepage.
最後關於剛剛第四點的方向問題,已經透過classname抽象化了,如果要改方向的話,只需要把CSS改成這樣即可:
123456.Fl-start{float:right;}.Mend-10{margin-left:10px;}
透過改寫成AtomicCSS,我們成功解掉了傳統CSS寫法上會碰到的幾個問題,而且具有以下優點:
CSS大小是線性成長的,重複的規則都會用到同一個classname,因此檔案大小大幅降低
很容易可以支援RTL跟LTR
classname變得與context無關,scope也變小,因此更好維護也更好改動
其中我認為最重要的是第三點,這也是我支持AtomicCSS的原因。
在改樣式的時候,你可以直接把classname刪掉而不用怕影響到其他的元素,這是多麽美好的一件事情,你再也不用擔心改A壞B,因為classname都跟context無關了。
TailwindCSS的作者以前有寫過一篇文章,對於AtomicCSS如何解決傳統CSS的問題有更多著墨跟範例,如果上面的理由無法說服你,可以看看這篇文章:CSSUtilityClassesand“SeparationofConcerns”。
總之呢,在原文中TK也預期到了僅管這個做法能解決問題,但讀者一定會有一堆疑惑,所以準備來一一擊破。
針對AtomicCSS的問題與反駁關於底下的問題跟反駁,除了文章以外,我可能還會引用到這三處的資料:
ACSSFAQ
HTML5DevConf:RenatoIwashima,“AtomicCascadingStyleSheets”
ThierryKoblentz在FEDLondon2015的簡報
1.你的classname沒有語義,這樣不行啊,規格不是這樣寫的關於semantic的問題,在2012時也有一篇文章討論過這件事情:AboutHTMLsemanticsandfront-endarchitecture,在HTMLspec裡面確實有這個段落:
Therearenoadditionalrestrictionsonthetokensauthorscanuseintheclassattribute,butauthorsareencouragedtousevaluesthatdescribethenatureofthecontent,ratherthanvaluesthatdescribethedesiredpresentationofthecontent.
如果這個元素是個image,那你的classname應該取叫image,而不是取叫它的樣式例如說:display-blockwidth-[150px]margin-3之類的。
而上面引的那篇文章提到說其實在維護大型專案時,這樣的命名策略反而會變成一種阻礙,我們根本沒理由一定要照著這個做,因為:
跟content有關的語義你看HTML就看得出來了
除了一個叫做Microformats的標準以外,classname對機器跟一般訪客來說沒什麼太大的意義
我們會用classname,只是因為要跟JS或是CSS結合在一起。
你想想,如果一個網站不需要style也不需要JS,是不是就不會取classname了?那這樣你的網站有比較不semantic嗎?
對開發者而言,classname應該包含一些更有用的資訊
接著他舉了一個例子:
1234News
[newscontent]
你看內容就知道這個區塊是來呈現news的,根本不需要classname也行。
這讓我想到當初JSX的發展,也是直接破壞掉了以往JavaScript跟HTML應該要分開的bestpractice。
如果大家都執著於前人訂下的規範,當作信條一樣遵從,而不去反思這個信條存在的理由,就不會有這麼多革新的東西出現。
就如同ChallengingCSSBestPractices一文中在最後提到的:
Tools,notrules.Weallneedtobeopentonewlearnings,newapproaches,newbestpracticesandweneedtobeabletosharethem.
2.你的classname太難懂了,看不懂,可讀性很差直接截一張FEDLondon2015裡的簡報圖,他們說ACSS的語法參考自Emmet,可讀性其實不會差:
不過這個解釋我不是很買單就是了,因為對於一個沒用過Emmet的人來說,看起來真的不太好懂,要花一段時間去熟悉那些縮寫。
3.你這跟inlinestyle有什麼不同?其實本質上是一樣的,都是把style限制在很小的scope裡面,但AtomicCSS解決了inlinestyle的幾個壞處:
CSS的優先順序很高,很難蓋過去
很冗長
不支援pseudo-class或是pseudo-element
底下截一張官網的圖:
AtomicCSS保留了inlinestyle的好處,也就是scope很小,同時也解決了上面提到的那些壞處。
4.你說可以降低CSS大小,但HTML大小不是也會上升嗎?那只是把成本轉到別的地方而已在原本ACSS的寫法下,其實classname的長度不會比本來大多少。
舉例來說,原本叫做profile__image-background,改寫之後可能是D-ibBgc(#ff0010)之類的。
根據他們自己做的統計,Yahoo!自己的網站平均的classname長度是22,而其他沒有用ACSS寫法的Twitter平均是28,USAtoday是38,衛報網站是36,只有特別對classname做了uglify的Facebook是18,些微勝出而已。
而且,除了classname並沒有明顯變長以外,ACSS還有一個好處是重複字元很多,所以gzip的壓縮率會比較高。
官網有給了一個數據是說他們自己經過測試後,semanticclasses可以降35%大小,而ACSS可以降48%。
5.那共用元件像是button該怎麼辦?難道我要每個地方都改樣式?在ChallengingCSSBestPractices一文中有一個段落是在講這個:
ThetechniqueI’mdiscussinghereisnotaboutbanning“semantic”classnamesorrulesthatgroupmanydeclarations.Theideaistoreevaluatethebenefitsofthecommonapproach,ratherthanadoptingitasthedefactotechniqueforstylingWebpages.Inotherwords,wearerestrictingthe“component”approachtothefewcasesinwhichitmakesthemostsense.
AtomicCSS的出現並沒有要完全取代傳統semantic的做法,正確的做法應該是哪個適合就用哪個。
而官網FAQ也有特別提到類似的事情:
Ifchangingsomestylingrequiresyoutoeditmultiplefiles,thenyoushouldusetheclassicCSSapproach
舉例來說,你的程式裡面有個按鈕會一直重複出現,這時候如果每次都複製貼上HTML,要改class的時候就要每個檔案都改,顯然是不合理。
在這種狀況下,用傳統的做法當然會是更好的。
我對AtomicCSS的看法前面看完了這麼多經典教材,來講一下我自己的想法。
首先,我認為AtomicCSS帶來了兩個獨特的好處:
降低CSS檔案大小
最大程度縮減scope,讓維護變得容易
第一點是顯而易見的,這個應該就不用再多提了,CSS檔案大小會小很多,這一點是其他CSS的解決方案沒辦法做到的。
第二點就如同我之前所講的,你改一個元素的classname,保證只會改到這個元素本身,而不會動到其他地方,這是我認為AtomicCSS帶來的最大的好處,讓style變成localscope。
有些人可能會疑惑說:「但你講的這個,CSS-in-JS或是CSSmodules也都做得到啊」,沒錯,這兩個解決方案也可以解決scope的問題。
但AtomicCSS剛誕生的時候似乎這些解決方案都還不存在(或是還在非常早期),所以這裡比較的對象是傳統CSS的解決方案(像是OOCSS、BEM、SMACSS這些管理CSS的方法)。
除了優點以外,我也認為AtomicCSS有一些缺點以及不適合使用的地方:
classname很長,直接看HTML的話不好閱讀
如果沒辦法做到component化,那就不適合使用AtomicCSS
需要花一段時間上手AtomicCSS的語法以及熟悉各種縮寫
三大框架的流行導致了現在的前端工程師普遍都會以component的思考方式去開發,而非傳統的HTML就管理內容、JavaScript就管理程式、CSS就管理樣式。
以元件的方式去思考後,三者會合在一起,變成一個獨立封裝的元件。
而元件化之後,前兩項問題也就迎刃而解了。
第一點的話開發時我們都是去看component的檔案,不會直接去看到HTML,而看到component時根據它的命名我們也會知道它在幹嘛,不需要classname做為輔助。
第二點的話因為都變成component,所以可以保證要改動的時候只要改一個地方就好。
而第三點是我認為要導入AtomicCSS相關工具需要付出的成本,那就是熟悉新的語法跟各種縮寫,這個是避免不掉的。
但是對我來說,這樣的成本不高,學習曲線也不高,頂多就是剛開始入門時要一直查表。
比起它帶來的效益,成本其實已經很小了。
最後提一下CSS-in-JS跟CSSmodules這兩個方案,一樣都解決了scope的問題,但跟AtomicCSS比起來有兩樣是做不到的。
第一點是CSS-in-JS跟CSSmodules這兩個方案據我所知,應該都需要搭配一些前端的library或是框架來使用,例如說React或Vue,但AtomicCSS不需要。
舉例來說,假設今天一個專案它的component是在後端用templateengine達成的,而非在前端,那就沒辦法用這兩套解決方案。
第二點是CSS大小,沒辦法跟AtomicCSS一樣這麼小。
不過關於這點,可以參考Facebook提出的AtomicCSS-in-JS方案,讓你寫起來像CSS-in-JS,可以用傳統CSS語法,但實際上產生時卻幫你用AtomicCSS的方式來產生,巧妙地融合了兩者的優點,是滿值得關注的一項技術。
TailwindCSS改良了哪些部分?上面談到了這麼多AtomicCSS的東西,最後我們簡單來看一下TailwindCSS,比起一開始Yahoo!創造的Atomizer,它有哪些優勢?
其實在功能面上我覺得沒有相差太多,最大的優勢是我認為它的DX(DeveloperExperience)更為突出,例如說它使用了更好看懂的classname,文件也更加完整,很快就可以查到什麼語法應該怎樣寫:
不過事實上,我認為這些基於AtomicCSS的框架最佳化的方向都是類似的,都是針對DX的方向去做改善。
例如說WindiCSS就帶來很多語法上的改善以及新的用法,而UnoCSS以及masterCSS也都有各自不同的做法,來增加開發者的體驗或是加快編譯的效率。
至於這些最佳化的細節我就不熟了,詳情可以參考重新构想原子化CSS這篇文章。
我對TailwindCSS也沒有到很熟,這邊補充一個需要注意的地方,那就是TailwindCSS是去掃你的sourcecode字串有哪些符合特定格式,所以如果你的classname是用動態產生的,就會抓不到,像這樣:
12345//這樣寫抓不到
為什麼我會這樣說呢?
分享一個小故事,以前我在維護一個用Redux的專案時有一系列操作長很像,例如說post、user跟restaurant的CRUD之類的,程式碼有很大一部分都重複,因此我就寫了一個utils來處理共同邏輯,只要寫generateActions('user'),就自動幫你動態產生出readUser與createUser之類的actions。
那時我想說這樣很讚,但同事提醒我說如果你這樣做,那全域搜尋readUser的時候就搜不到東西,因為那是程式動態產生的,在原始碼裡面找不到。
雖然我那時不覺得有什麼,但過了兩個月後我知道我錯了。
當你面對一個不熟悉的專案時,要去修一個bug,最常做的就是拿你手上的資訊去搜尋原始碼,看看出現在哪邊。
如果你搜不到東西,那是滿挫折的一件事情,會需要花更多時間去找問題到底在哪個範圍。
因此,可以被搜尋到是很重要的。
或是再舉一個例子,假設今天設計師突然改變心意,說所有之前用text-red-600的地方應該要改成text-red-500,但新的地方還是會用到text-red-600,所以我們不能直接改設定檔的色碼,一定要去改sourcecode,把text-red-600都換成text-red-500。
此時你會怎麼做?全域搜尋然後取代,搞定。
此時,像上面那種動態產生classname的case除非你特別記得,否則就不會被改到。
因為搜尋不到,所以你也不知道那邊其實會出現text-red-600。
如果真的要用動態產生,那至少加個註解標注一下會用到的東西的全名,讓它能被搜尋到。
結語「每樣工具都有它適合的地方」這句話大家都知道,但重點是「那它到底適合什麼地方?不適合什麼地方?它解決了什麼問題?又額外創造了哪些問題?」,基於這些問題去討論一項技術,才能更深入地去了解它。
AtomicCSS是在維護大型專案的時空背景之下誕生的,如果你沒有碰到那種「牽一髮而動全身,改一個地方要檢查好多地方會不會壞掉」的狀況,那你用了AtomicCSS,可能確實感覺不到它的好處,因為它想解決的問題你根本沒有碰到。
對於那些「它想解決的問題,你的專案沒碰到」的狀況下,導不導入的差異本來就不大,有些甚至還會增加不必要的複雜度。
若是在一個「相同的元件卻四處分散,當你改HTML時需要同時改很多地方」的專案用上了AtomicCSS,那確實是不適合,官方文件也不推薦這樣做。
如果硬要用,那碰到維護性的問題時並不是AtomicCSS的錯,而是當時選擇技術的人的錯(就跟你說不適合了還要用)。
又或是你寫了一個UIlibrary,而這個library又需要支援一些UI的客製化,如果你用AtomicCSS來做樣式,那你要怎麼完成這件事?難道要把每一個HTML元素都開放傳classname進去嗎?在這個狀況下,像是antd那樣使用傳統的CSS解決方案說不定比較適合,因為可以直接改原本的Less檔案,就能輕鬆客製化。
(daisyUI是靠著把HTML一起開放出來,藉此達成客製化,我上面指的案例比較像是寫一個Reactcomponent,把實作細節包在裡面的那種)
每個專案都有不同適合的技術與工具,在做選擇時應該先了解每個專案的需求,以及每一項技術的優缺點,才能挑到相對合適的技術。
最後,從AtomicCSS的歷史中,我覺得最值得學習的其實是「Tools,notrules」那一段。
以前的最佳實踐不一定適用於現在的狀況,以前的classname不是這樣用的,不代表現在就不行。
我們不該墨守成規,不該執著在那些規則上面;如果別的做法有顯而易見的好處,那為何不呢?
參考資料:
ChallengingCSSBestPractices
Let’sDefineExactlyWhatAtomicCSSis
TheMakingofAtomicCSS:AnInterviewWithThierryKoblentz
Atomizer
ACSSFAQ
HTML5DevConf:RenatoIwashima,“AtomicCascadingStyleSheets”
ThierryKoblentz在FEDLondon2015的簡報
AboutHTMLsemanticsandfront-endarchitecture
AtomicCSS-in-JS
淺談CSS方法論與AtomicCSS
邪魔歪道還是苦口良藥?FunctionalCSS經驗分享
客觀評價TailwindCSS
UnoCSS-一統天下的明日之星?
重新构想原子化CSS
在VUESFC(vue-cli)規劃TailwindCSS架構
#Front-end
DEFCONCTF2022Qualifier筆記
m0leConCTF2022筆記
評論
Yourbrowserisout-of-date!
Updateyourbrowsertoviewthiswebsitecorrectly.Updatemybrowsernow
×
延伸文章資訊
- 1Tailwind CSS 入門與語法 - iT 邦幫忙
小弟我之前一直是使用Bootstrap 做為前端CSS 框架,由於最近聽到很多Tailwind CSS 的花式吹捧,讓我也開始感興趣了,今天就一起來研究一下吧!
- 2Tailwind CSS 中文文档- 无需离开您的HTML,即可快速建立 ...
Tailwind CSS 是一个功能类优先的CSS 框架,它由Adam Wathan 创建。本站提供Tailwind CSS 官方文档中文翻译致力于为广大国内开发者提供准确的中文文档,助力开发者...
- 3還在跟複雜的CSS 的設定奮鬥嗎?用Tailwind 來幫你實現真正 ...
簡單來說Tailwind CSS 是一套Utility-First CSS,相當具有彈性,也非常適合快速 ... Tailwind CSS 把大致上CSS 會用到的屬性都用單個class 來表示。
- 4Tailwind CSS 台灣| Facebook
這裡是Tailwind CSS 台灣社團,歡迎討論和張貼Tailwind CSS 相關(包含但不限於Headless UI、Tailwind UI、Windi CSS 等) 的分享、問題、新聞、...
- 5【Tailwind CSS 教學- 4 】utility first 有機會成為未來CSS 王者?
Tailwind 三大優勢 · 再也不用想命名,例如 sidebar-inner-wrapper ,因為所有都是utility class,例如 .mt-1 、. · CSS 不會因為網站而變得...