CSS的復用代碼,是多添加點類好?還是增加點代碼量好?

CSS的一些常用代碼,我們有時候會提取出來公用,以減少代碼量,如下:

在HTML裡面通過增加類的形式引用樣式,如下

這時候我考慮的是,雖然減少了代碼量,但是增加了瀏覽器渲染成本,多一個類,就多一次查找多一次消耗。感覺有點不划算,想問問大家到底哪個消耗少?

同時想到了CSS預編譯,LESS、SASS只是優化了程序員的開發速度,但是對於性能優化,對於用戶來說,除了編譯的時候有點壓縮外,好像並沒有太多用?是不是這樣?


被邀請了,意外,血妖……

以下言論不具任何代表性,只是說一下自己的一點點看法而已。

就我個人而言,十分不喜歡這樣的寫法,對於這樣的寫法,雖然說在寫的時候會發覺效率挺快的,需要用到什麼,直接把相關的類名丟到標籤里即可。這樣的的話,就跟寫 inline style 真的沒什麼區別。

如果一定要說有什麼區別的話,那就是如果要修改某個類的時候呢,去修改 CSS 文件就可以了,而不用去查找替換每個標籤中的 inline style 內容。然而這個時候又有一個問題出現了,比如原本你寫的是 .fl 這個類,想要 float: left; ,但是需求變動,那是修改 HTML 中的類名為 .fr 呢,還是去修改 CSS 文件中的 .fl {float: left;} 為 .fr {float: right;}。

不過這個似乎並不是關鍵,每個人對於 CSS 的使用方式都不一樣,至於類名的命名方式也非常的多,每種都有各自的優缺點。如果要具體去談每種命名方式的優劣,就我個人來說,根據團隊的習慣來走就好,大家都認同的方式比較好上手。至於最終採用所謂的原子類還是什麼方式,並沒有最終的一個優劣吧。

對於題主的問題,我看到的是這個:

這時候我考慮的是,雖然減少了代碼量,但是增加了瀏覽器渲染成本,多一個類,就多一次查找多一次消耗。感覺有點不划算,想問問大家到底哪個消耗少?

對於這個,我想說,你多慮了。首先不說 CSS 的渲染方式,也不說多一次查找會不會多一次性能的消耗。我只想說,這一點點微乎其微的毫秒級,甚至更小的性能消耗真的是你所需要的嗎?你的項目有多少訪問量呢?

同時想到了CSS預編譯,LESS、SASS只是優化了程序員的開發速度,但是對於性能優化,對於用戶來說,除了編譯的時候有點壓縮外,好像並沒有太多用?是不是這樣?

less、sass最終編譯出來給瀏覽器看的是不是 CSS 呢?莫非題主是想把 less 或者 sass 丟到伺服器上,然後用戶打開網站的時候,你的網站樣式不是連接 CSS,而是連接 less 或者 sass 文件,然後讓客戶端的瀏覽器去解析?

我想應該不會是這樣吧。最終發布到伺服器上的樣式文件應該是 CSS 文件而已。那麼 less 和 sass 對於開發人員來說,應該是為了提高工作效率而使用的一個「工具」,最終解析出來的 CSS 內容是怎麼樣,這個應該就看寫 less 或者 sass 的開發人員的功底了。

最後的個人建議:

無關乎性能或者工具的使用,而是對於公用類的使用。一個公共使用的類,是提取了頁面中或者站點中可共用的模塊樣式,然後去做渲染。比如頁面中有 A 和 B 兩個模塊,存在著相同的點,那麼就提取出來作為公共模塊 `.mod`,再分別使用一個針對性的類名來處理兩個模塊之間的差異化。


蟹妖~

本來工程化就是在代碼效率和開發效率中找一個平衡點。

原子類的風格我不太喜歡,這基本上就和inline style差不多了。

我覺得在題主的項目中,這點代碼差異帶來的性能差異可以忽略不計,所以還是重點考慮選一個看著順眼的書寫方式吧。

題主的主要問題是項目太小,如果CSS代碼上幾千行規模,自然就知道less有啥用了...


多點類好。但「好」不因為類多,而是重用率高。重用率和類數量無必然關係,而和類合理性有很大關係。

「雖然減少了代碼量,但是增加了瀏覽器渲染成本,多一個類,就多一次查找多一次消耗「 - 這不重要。

實際上恰到好處的重用率往往CSS代碼量最小,長期可維護性最高,大量新樣式可以簡單組合已有效果。

當然這種方法其實設計上更難,把類的粒度分得恰到好處並不容易。


按照你的要求,代碼量要少,然後原子類要少,其實把類給繼承一下就好了。

假設頁面Index里有個類btn:

.left {
float: left;
}

.pageIndex .btn {
...
}

我們想要這個類繼承公共類left,實現左浮動,可以這樣:

.left, .pageIndex .btn {
float: left;
}

.pageIndex .btn {
...
}

看,這樣就實現啦!我們共享了left的代碼,同時又不需要在html中增加多的類。

嗯,你可能會說,誰tmd會這麼去做啊!!!

人肯定不會這麼去做,但是sass會這麼做:

.left {
float: left;
}

.pageIndex .btn {
@extend .left
...
}


"原子類"一詞,應該是我創造的。所以補充一下幾點使用心得。

http://cly84920.blog.163.com/blog/static/247500133201221310550706/

https://www.zhihu.com/question/21943416/answer/19838130


通常來講,我們定義一個 class 會為它賦予一些意義,簡單的可以分成t這麼幾種類型:

  • 布局類
  • 樣式類
  • 公共類
  • 兼容性類

舉個栗子,隨便拿 bootstrap 的一個按鈕來說吧

.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}

  • .btn 就作為按鈕的通用類,它定義了通用的 padding ,font-size 等基礎屬性,所有用到按鈕都用到這些默認屬性
  • 考慮到按鈕有不同風格,那用再定義一些風格的類吧, .btn-primary .btn-success .btn-info等

.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}

  • 然而寫一樣樣式不可能不考慮兼容性問題,那麼以上

-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;

就是一個簡單的兼容性寫法,在使用的時候我們只需要用到這個 .btn 就可以了。

上面說的只是在功能相對複雜的情況下,那麼如果我只想要一個功能呢??

比如說,上面這個按鈕默認字體是 14px,可是我想要 16px ,難道要寫一個 .btn-16 的 class 嗎? 當然不是啦,我們只需要在增加一個自己的 class 設置為 16px 即可,這樣我們就可以得到一個 .btn 的 16px 的按鈕啦。

那麼問題又來了?回到題主的問題(終於回來了),我們是不是要每增加一個屬性時就增加一個 class 呢?

其實主要是按照實際情況來,如果只需要單一實現一個屬性的功能那麼用原子類無可避免。

如果不是,或者只是頁面級那麼建議你根據具體功能作為 class 來寫屬性。

ps : 來知乎好些年了,還是第一次回答問題(緊張,怎麼樣裝作經常回答的樣子呢),很多問題回答了一半但因為知識結構不全等原因,也說不清楚,就刪掉了。以上可能都是些廢話也可能我沒說的清楚,但是我是以自己的真實的感知在回答,如有不妥各位看客請見諒。


在 bootstrap 中經常可以看到這樣的代碼:

&

Win10 發布後,大公司前端會怎麼發展?
誰能詳細解釋下什麼是單頁面?
CSS中margin-top/bottom(padding-top/bottom)百分比為何以最近的塊級祖先元素的寬度而不是高度作計算?

TAG:前端開發 | 前端工程師 | 前端性能優化 |