自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

好家伙,這些寫 CSS 的新姿勢你還不知道?

開發(fā) 前端
本文就來聊聊以下三種 CSS 方案的優(yōu)缺點(diǎn)以及各自方案的代表作,希望對(duì)你有幫助!

現(xiàn)在大部分搞前端的應(yīng)該還是這樣寫 CSS 的: 

  1. .mock { 
  2.     margin: auto; 
  3.     font-size: 16px; 
  4.     // ... 
  5. <div class='mock'>mock</div> 

 以上代碼就是舉個(gè)例子,大部分情況應(yīng)該都是寫一個(gè)類,然后整一堆樣式進(jìn)去。

但是這種方式寫多了以后,你應(yīng)該會(huì)感受到一些痛點(diǎn),比如說:

  • 取名困難,節(jié)點(diǎn)結(jié)構(gòu)一多,取名真的是個(gè)難事。當(dāng)然了,我們可以用一些規(guī)范或者選擇器的方式去規(guī)避一些取名問題。
  • 需要用 JS 控制樣式的時(shí)候又得多寫一個(gè)類,尤其交互多的場景。
  • 組件復(fù)用大家都懂,但是樣式復(fù)用少之又少,這樣就造成了冗余代碼變多。
  • 全局污染,這個(gè)其實(shí)現(xiàn)在挺多工具都能幫我們自動(dòng)解決了。
  • 死代碼問題。JS 我們通過 tree shaking 的方式去除用不到的代碼減少文件體積,但是 CSS 該怎么去除?尤其當(dāng)項(xiàng)目變大以后,無用 CSS 代碼總會(huì)出現(xiàn)。
  • 樣式表的插入順序影響了 CSS 到底是如何生效的。
  • 等等,不一一說明了。其實(shí)對(duì)于筆者而言,第一二塊在開發(fā)中是最難受的兩個(gè)點(diǎn),尤其是剛寫前端,需要做活動(dòng) / 產(chǎn)品頁的時(shí)候。

當(dāng)下,社區(qū)里有一些 CSS 方案,能夠解決以上一些痛點(diǎn):

  • Atom CSS
  • CSS-in-JS
  • 上述兩者的結(jié)合體

本文就來聊聊以上三種方案的優(yōu)缺點(diǎn)以及各自方案的代表作。

Atom CSS

首先來聊聊啥叫做 Atom CSS:意思是一個(gè)類只干一件事,比如說: 

  1. .m-8 { 
  2.     margin: 8px; 

想象一下你按照這樣的思想搞出一大堆類似的類名,就能整出一個(gè)踐行 Atom CSS 方案的三方庫了,tailwindcss 就是這個(gè)方案里的佼佼者。其實(shí) Atom CSS 很多人應(yīng)該早都用過了,柵格系統(tǒng)上就有它的身影,無非不清楚原來它就是 Atom CSS 罷了。

我們先來看看如果用 tailwindcss 的話,寫好樣式的 HTML 大概長啥樣:  

 

上圖是人家官網(wǎng)上的,在這之前還有一段挺炫的動(dòng)畫??雌饋砗孟裢Ψ奖愕?,寫上一堆類名就能出左邊好看的樣式了,省了很多寫樣式的時(shí)間,但是讀者們可以來想想這種方式它會(huì)有啥好處及弊端?

在說優(yōu)缺點(diǎn)之前,我們先來聊聊 Atom CSS 的歷史。其實(shí)它并不是一個(gè)新興產(chǎn)物,這玩意你往前推個(gè)十年就能看到它的討論。正所謂天道好輪回,蒼天饒過誰。Atom CSS 以前火過,而且是被噴火的,沉寂了幾年之后這幾年又被拿出來說了。

接下來我們以 tailwindcss 為例來聊聊 Atom CSS 方案的優(yōu)劣點(diǎn)。

優(yōu)劣點(diǎn)

如果你想在團(tuán)隊(duì)內(nèi)部推廣這個(gè)產(chǎn)品,學(xué)習(xí)成本會(huì)是一個(gè)問題,畢竟需要大家都看得懂你這坨東西到底是啥意思,這算一個(gè)很明顯的缺陷。但是對(duì)于語法問題你還真的不用怎么擔(dān)心,tailwindcss 是有語法補(bǔ)全的工具鏈的,Webstorm 已經(jīng)內(nèi)置了,VSCode 需要大家自行裝個(gè)插件,所以噴寫 tailwindcss 語法麻煩的可以歇一歇。

樣式復(fù)用,就像寫組件一樣,這次我們是把樣式一個(gè)個(gè)抽離了出來,這樣帶來的一大好處是減少了 CSS 代碼文件體積。

原本傳統(tǒng)的寫法是定義一個(gè)類,然后寫上需要的樣式: 

  1. .class1 { 
  2.     font-size: 18px; 
  3.     margin: 10px; 
  4. .class2 { 
  5.     font-size: 16px; 
  6.     color: red; 
  7.     margin: 10px; 

這種寫法是存在一部分樣式重復(fù)的,換成 Atom CSS 就能減少一部分代碼的冗余。

把 CSS 當(dāng)成組件來寫。大家乍一看 tailwindcss 官網(wǎng)肯定會(huì)覺得我在 HTML 里寫個(gè)樣式要敲那么多類是有病吧? 

  1. <figure class="md:flex bg-gray-100 rounded-xl p-8 md:p-0"
  2.   <img class="w-32 h-32 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512"
  3.   <div class="pt-6 md:p-8 text-center md:text-left space-y-4"
  4.     <blockquote> 
  5.       <p class="text-lg font-semibold"
  6.         “Tailwind CSS is the only framework that I've seen scale 
  7.         on large teams. It’s easy to customize, adapts to any design, 
  8.         and the build size is tiny.” 
  9.       </p> 
  10.     </blockquote> 
  11.     <figcaption class="font-medium"
  12.       <div class="text-cyan-600"
  13.         Sarah Dayan 
  14.       </div> 
  15.       <div class="text-gray-500"
  16.         Staff Engineer, Algolia 
  17.       </div> 
  18.     </figcaption> 
  19.   </div> 
  20. </figure> 

其實(shí)我們是可以利用 Atom CSS 一次只干一件事的特性,將這些類隨意組裝成我們想要的類,這樣就可以提供出來一個(gè)更上層的通用樣式來復(fù)用。

比如說項(xiàng)目中的按鈕都是存在通用的圓角、內(nèi)邊距、字體等,這樣我們就可以封裝出這樣一個(gè)類: 

  1. .btn { 
  2.     @apply p-8 rounded-xl font-semibold 

效率工具。tailwindcss 用的好肯定是能提高寫布局的效率的,尤其對(duì)于需要做響應(yīng)式的頁面而言。當(dāng)然這東西其實(shí)也算是甲之蜜糖乙之砒霜,評(píng)價(jià)兩極分化很嚴(yán)重,有人認(rèn)為提高了效率,也有人認(rèn)為反而是增加了成本,或者說是脫褲子放屁。

提供了一整套規(guī)范化的設(shè)計(jì)模式,直接點(diǎn)說就是 tailwindcss 給你內(nèi)置好一套優(yōu)秀的設(shè)計(jì)主題了。但是這玩意對(duì)于規(guī)范的視覺團(tuán)隊(duì)來說是個(gè)不小的福音,不規(guī)范的話就可能是火葬場了。下面我給大家舉個(gè)例子: 

  1. // tailwind.config.js 
  2. const colors = require('tailwindcss/colors'
  3.  
  4. module.exports = { 
  5.   theme: { 
  6.     screens: { 
  7.       sm: '480px'
  8.       md: '768px'
  9.       lg: '976px'
  10.       xl: '1440px'
  11.     }, 
  12.     colors: { 
  13.       gray: colors.coolGray, 
  14.       blue: colors.lightBlue, 
  15.       red: colors.rose, 
  16.       pink: colors.fuchsia, 
  17.     }, 
  18.     fontFamily: { 
  19.       sans: ['Graphik''sans-serif'], 
  20.       serif: ['Merriweather''serif'], 
  21.     }, 
  22.     extend: { 
  23.       spacing: { 
  24.         '128''32rem'
  25.         '144''36rem'
  26.       }, 
  27.       borderRadius: { 
  28.         '4xl''2rem'
  29.       } 
  30.     } 
  31.   } 

以上是 tailwindcss 的主題配置文件,大家可以按照視覺的要求來做調(diào)整。比如說今天視覺覺得屏幕的 lg 尺寸應(yīng)該是 976px,過段時(shí)間又覺得需要改成 1000px。對(duì)于開發(fā)者而言我們只需要修改一行代碼就能全局生效了,很舒服。

但是假如說視覺原本定義的邊距規(guī)則如下: 

  1. // tailwind.config.js 
  2. module.exports = { 
  3.   theme: { 
  4.     spacing: { 
  5.       px: '1px'
  6.       0: '0'
  7.       0.5: '0.125rem'
  8.       1: '0.25rem'
  9.       1.5: '0.375rem'
  10.       2: '0.5rem'
  11.       2.5: '0.625rem'
  12.       3: '0.75rem'
  13.       3.5: '0.875rem'
  14.       4: '1rem'
  15.       5: '1.25rem'
  16.       6: '1.5rem'
  17.       7: '1.75rem'
  18.       8: '2rem'
  19.       // ... 
  20.     }, 
  21.   } 

現(xiàn)在需要我們把 6 換成 1.6rem,但是這個(gè)規(guī)則只需要作用在某些組件上,此時(shí)我們需要如何修改樣式?新增一個(gè) spacing 然后一個(gè)個(gè)去替換需要的地方么?

上述場景筆者認(rèn)為還是不少見的,最起碼在我們公司內(nèi)部是存在這樣的問題。已經(jīng)定義了視覺規(guī)范并體現(xiàn)在內(nèi)部的組件庫上,但是在業(yè)務(wù)中還是有不少視覺會(huì)去動(dòng)組件的基本樣式,這里改個(gè)邊距,那里改個(gè)顏色等等。原本組件庫是為了幫助開發(fā)者提效的,但是在這種場景下開發(fā)者反而會(huì)抱怨改動(dòng)樣式極大提高了他們的成本,并且大部分情況下還不得不這樣做。

再說回傳統(tǒng) CSS 的問題,其實(shí) tailwindcss 也解決了一部分,但是仍舊存在沒解決的點(diǎn),比如說:

  • 死代碼問題沒解決
  • 樣式表的插入順序依舊有影響

以上說了那么多,其實(shí)對(duì)于我們使用 tailwindcss 而言,有利也有弊。它肯定是存在很好用的場景的,比如說寫個(gè)人的產(chǎn)品頁,或者說業(yè)務(wù)中樣式變化不頻繁的場景中,但是如果說需要業(yè)務(wù)中全量切換到 tailwindcss 的話,筆者肯定是持保留態(tài)度的。

對(duì)于 Atom CSS 來說,大家應(yīng)該是不能否認(rèn)它的優(yōu)點(diǎn)的,但是我們是否有辦法在盡可能避免它的缺點(diǎn)的情況下又獲得它的優(yōu)點(diǎn)呢?答案是有的,但是在講答案之前我想先來聊聊 CSS-in-JS。

CSS-in-JS

CSS-in-JS(下文以 CIJ 縮寫表示)核心就是在用 JS 寫 CSS,這同樣也是一個(gè)頗具爭議的技術(shù)方案。

在這個(gè)領(lǐng)域下有兩個(gè)庫比較流行,分別為:styled-components(下文以 sc 縮寫表示) 以及 Emotion。筆者目前已經(jīng)用了一年多的 sc 了,來粗略談?wù)勊膬?yōu)缺點(diǎn)。

我們先來了解下 sc 是怎么使用的。首先說下 sc 和 Emotion 的語法是趨于一致的,應(yīng)該是為了 API 層面的統(tǒng)一吧,甚至前者還依賴了后者的一些包,以下是 sc 的常用寫法: 

  1. const Button = styled.a` 
  2.   display: inline-block; 
  3.  
  4.   ${props => props.primary && css` 
  5.     background: white; 
  6.     color: black; 
  7.   `} 
  8. render( 
  9.   <div> 
  10.     <Button 
  11.       href="https://github.com/styled-components/styled-components" 
  12.       target="_blank" 
  13.       rel="noopener" 
  14.       primary 
  15.     > 
  16.       GitHub 
  17.     </Button> 
  18.  
  19.     <Button as={Link} href="/docs"
  20.       Documentation 
  21.     </Button> 
  22.   </div> 

用法我們不多展開,有興趣的可以去官方看看,基本沒有學(xué)習(xí)成本的,主要是一些樣式組件上的使用。

另外 sc 并不是最終生成了內(nèi)聯(lián)樣式,而是幫我們插入了 style 標(biāo)簽。

優(yōu)劣點(diǎn)

筆者用了一年多的 sc,感覺這種方案對(duì)于 React 來說是很香的。并且解決了我很討厭的傳統(tǒng)寫 CSS 的一些點(diǎn),所以關(guān)于優(yōu)劣點(diǎn)這段的講述會(huì)有點(diǎn)主觀。

首先 CSS-in-JS 這種方案不僅能讓我們完整使用到 CSS 的功能,而且還擴(kuò)充了一些用法。比如說選擇器這塊,在 sc 中我們能通過選擇組件的方式來編寫樣式,如下代碼: 

  1. const Button = styled.a` 
  2.   ${Icon} { 
  3.     color: green; 
  4.   } 

另外既然我們通過 JS 來管理 CSS 了,那么我們就可以充分享受 JS 帶來的工具鏈好處了。一旦項(xiàng)目中出現(xiàn)沒有使用到的樣式組件,那么 ESLint 就可以幫助我們找到那些死代碼并清除,這個(gè)功能對(duì)于大型項(xiàng)目來說還是能減少一部分代碼體積的。

除此之外,樣式污染、取名問題、自動(dòng)添加前綴這些問題也很好的解決了。

除了以上這些,再來聊兩點(diǎn)不容易注意到的。

首先是動(dòng)態(tài)切換主題。因?yàn)槲覀兪峭ㄟ^ JS 來寫 CSS 了,那么我們就可以動(dòng)態(tài)地控制樣式。如果你的項(xiàng)目有切換主題這種類似的大量動(dòng)態(tài) CSS 的需求,那么這個(gè)方案會(huì)是一個(gè)不錯(cuò)的選擇。

還有個(gè)點(diǎn)是按需加載。因?yàn)槲覀兪峭ㄟ^ JS 寫的 CSS,現(xiàn)階段打包基本都走的 code split,那么就可以實(shí)現(xiàn) CSS 文件的按需加載,而不是傳統(tǒng)方式的一次性全部加載進(jìn)來(當(dāng)然也是可以優(yōu)化的,只是沒那么方便)。

聊完了優(yōu)點(diǎn)我們?cè)賮碚f說缺點(diǎn)。

第一個(gè)缺點(diǎn)很明顯,有學(xué)習(xí)成本,當(dāng)然筆者覺得這個(gè)學(xué)習(xí)曲線還是平緩的。

運(yùn)行時(shí)成本,sc 本身就有文件體積,加上還需要?jiǎng)討B(tài)生成 CSS,那么這其中必定有性能上的損耗。項(xiàng)目越大影響的也會(huì)越大,如果你的項(xiàng)目對(duì)于性能有很高的要求,那么需要謹(jǐn)慎考慮使用。另外因?yàn)?CSS 動(dòng)態(tài)生成,所以不能像傳統(tǒng) CSS 一樣緩存 CSS 文件了。

代碼復(fù)用性和傳統(tǒng)寫 CSS 的方式?jīng)]啥兩樣。

最后點(diǎn)是代碼耦合問題。會(huì)有人覺得在大型項(xiàng)目中將 CSS 及 JS 寫在一起會(huì)增加維護(hù)成本,并且也不符合 CSS 需要分離開來想法。

Atom CSS 加上 CSS-in-JS 的縫合怪

看了上文,如果你覺得兩種方案都挺好的話,可以了解下 twin.macro,這個(gè)庫(還有別的競品)把這兩種方案融合了起來。 

  1. import 'twin.macro' 
  2.  
  3. const Input = () => <input tw="border hover:border-black" /> 
  4. const Input = tw.input`border hover:border-black` 

這種方案之上其實(shí)還有更好玩的方式,能幫助我們盡量取其精華而去其糟粕。

自動(dòng)生成 Atom CSS 的 CSS-in-JS 方案

假如說我不僅想用 CSS-in-JS,還想把 Atom CSS 也給整上,但是又不想記 / 寫一大堆類名,我這個(gè)想法能實(shí)現(xiàn)么?

答案是有的。利用運(yùn)行時(shí)的方式把單個(gè)樣式抽離出來,最后實(shí)現(xiàn)雖然我們寫的是 CSS-in-JS,但是最終呈現(xiàn)的是 Atom CSS 的樣子。

以 styletron 舉個(gè)例子,開發(fā)時(shí)候的代碼長這樣: 

  1. import { styled } from "styletron-react"
  2.  
  3. export default () => { 
  4.   // Create a styled component by passing 
  5.   // an element name and a style object 
  6.   const Anchor = styled("a", { 
  7.     fontSize: "20px"
  8.     color: "red" 
  9.   }); 
  10.   return <Anchor href="/getting-started">Start!</Anchor>; 
  11. }; 

實(shí)際編譯出來的時(shí)候長這樣: 

  1. <html> 
  2.   <head> 
  3.     <style> 
  4.       .foo { 
  5.         font-size: 20px; 
  6.       } 
  7.       .bar { 
  8.         color: red; 
  9.       } 
  10.     </style> 
  11.   </head> 
  12.   <body> 
  13.     <a href="/getting-started" class="foo bar">Start!</a> 
  14.   </body> 
  15. </html> 

這樣的方式就能很好地享受到兩種方案帶來的好處了。但是這類方案筆者找了些競品,覺得還沒有前兩者方案來的流行,大家了解一下即可。另外這種方式帶來的運(yùn)行時(shí)成本應(yīng)該會(huì)更大,也許可以配套打包工具在本地先做一次預(yù)編譯(一個(gè)不成熟的想法,說錯(cuò)勿噴)?

總結(jié)

說了那么多方案,可能讀者會(huì)有疑問,那么我到底該用啥?這里筆者說下自己的想法。

首先對(duì)于 sc 來說,筆者覺得很香,在項(xiàng)目中大范圍用起來未嘗不可,當(dāng)然我們還可以搭配著 Atom CSS 一起來寫通用樣式。

對(duì)于 Atom CSS,筆者個(gè)人認(rèn)為不適合項(xiàng)目中大規(guī)模使用,起碼在我們公司內(nèi)部不會(huì)是一個(gè)好方案,畢竟視覺真的會(huì)來動(dòng)某些通用樣式。 

 

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2018-09-02 15:43:56

Python代碼編程語言

2022-05-05 12:02:45

SCSS函數(shù)開發(fā)

2020-06-03 08:53:40

CSS偽類 JS

2015-07-13 08:49:54

2020-10-28 08:06:09

Vue3框架數(shù)據(jù)

2016-07-22 17:55:07

云計(jì)算

2022-07-17 06:53:24

微服務(wù)架構(gòu)

2021-05-26 08:21:43

@Autowired項(xiàng)目@Resouce

2017-10-16 13:30:28

windows 10技巧輸入法

2024-05-20 09:27:00

Web 開發(fā)CSS

2020-12-14 07:51:16

JS 技巧虛值

2021-02-03 08:24:32

JavaScript技巧經(jīng)驗(yàn)

2024-12-17 08:33:42

2023-05-22 15:37:31

CSS元素JavaScript

2022-04-14 09:01:19

CSS父選擇器CSS類

2020-10-12 08:20:54

CSS居中內(nèi)聯(lián)

2023-08-14 15:56:52

CSS 偽元素開發(fā)

2021-03-18 14:02:56

iOS蘋果細(xì)節(jié)

2021-06-02 15:14:32

安卓微信移動(dòng)應(yīng)用

2021-10-22 09:41:26

橋接模式設(shè)計(jì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)