編寫現代 CSS 程式碼的 20 個建議

發表於2016-12-03

明白何謂Margin Collapse

不同於其他很多屬性,盒模型中垂直方向上的Margin會在相遇時發生崩塌,也就是說當某個元素的底部Margin與另一個元素的頂部Margin相鄰時,只有二者中的較大值會被保留下來,可以從下面這個簡單的例子來學習:

在上述例子中我們會發現,紅色和藍色方塊的外邊距並沒有相加得到70px,而是隻有紅色的下外邊距保留了下來。我們可以使用一些方法來避免這種行為,不過建議來說還是儘量統一使用margin-bottom屬性,這樣就顯得和諧多了。

使用Flexbox進行佈局

CSS實戰之Flex詳解以及其在微信中的相容實現

在傳統的佈局中我們習慣使用Floats或者inline-blocks,不過它們更適合於格式化文件,而不是整個網站。而Flexbox則是專門的用於進行佈局的工具。Flexbox模型允許開發者使用很多便捷可擴充套件的屬性來進行佈局,估計你一旦用上就捨不得了:

我們已經在Tutorialzine上提供了很多的關於Flexbox的介紹與小技巧,譬如5 Flexbox Techniques You Need to Know About

使用CSS Reset

雖然這些年來隨著瀏覽器的迅速發展與規範的統一,瀏覽器特性碎片化的情況有所改善,但是在不同的瀏覽器之間仍然存在著很多的行為差異。而解決這種問題的最好的辦法就是使用某個CSS Reset來為所有的元素設定統一的樣式,保證你能在相對統一干淨的樣式表的基礎上開始工作。目前流行的Reset庫有 normalize.css, minireset以及 ress ,它們都可以修正很多已知的瀏覽器之間的差異性。而如果你不打算用某個外在的庫,那麼建議可以使用如下的基本規則:

上面的規則看起來沒啥用,不過如果不同的瀏覽器在預設情況下為你設定了不同的外邊距/內邊距的預設值,還是會挺麻煩的。

一切應為Border-box

雖然很多初學者並不瞭解box-sizing這個屬性,但是它確實相當的重要。而最好的理解它的方式就是看看它的兩種取值:

  • 預設值為content-box,即當我們設定某個元素的heght/width屬性時,僅僅會作用於其內容尺寸。而所有的內邊距與邊都是在其之上的累加,譬如某個<div>標籤設定為寬100,內邊距為10,那麼最終元素會佔用120(100 + 2*10)的畫素。
  • border-box:內邊距與邊是包含在了width/height之內,譬如設定了width:100px<div>無論其內邊距或者邊長設定為多少,其佔有的大小都是100px。

將元素設定為border-box會很方便你進行樣式佈局,這樣的話你就可以在父元素設定高寬限制而不擔心子元素的內邊距或者邊打破了這種限制。

以背景圖方式使用Images

如果需要在響應式的環境下展示圖片,有個簡單的小技巧就是使用該圖片作為某個<div>的背景圖而不是直接使用img標籤。基於這種方式配合上background-sizebackground-position這兩個屬性,可以很方便地按比例縮放:

不過這種方式也是存在缺陷的,譬如你無法設定圖片的懶載入、圖片無法被搜尋引擎或者其他類似的工具抓取到,有個不錯的屬性叫object-fit可以解決這個問題,不過該屬性目前的瀏覽器支援並不是很完善。

Better Table Borders

HTML中使用Tables進行佈局一直是個很頭疼的問題,它們使用起來很簡單,但是無法進行響應式操作,並且也不方便進行全域性樣式設定。譬如,如果你打算為Table的邊與單元的邊新增樣式,可能得到的結果如下:

2472698196-57ced1090b687_articlex

這裡存在的問題是出現了很多的重複的邊,會導致視覺上不協調的情況,那麼我們可以通過設定border-collapse:collapse來進行處理:
2919922177-57ced1090db24_articlex

註釋格式優化

CSS雖然談不上一門程式語言但是其仍然需要新增註釋以保障整體程式碼的可讀性,只要新增些簡單的註釋不僅可以方便你更好地組織整個樣式表還能夠讓你的同事或者未來的自己更好地理解。對於CSS中整塊的註釋或者使用在Media-Query中的註釋,建議是使用如下形式:

而設計的細節說明或者一些不重要的元件可以用如下單行註釋的方式:

同時,不要忘了CSS中是沒有//這種註釋方式的:

使用Kebab-case命名變數

對於樣式類名或者ID名的命名都需要在多個單詞之間新增-符號,CSS本身是大小寫不敏感的因此你是用不了camelCase的,另一方面,很久之前也不支援下劃線,所以現在的預設的命名方式就是使用-:

而涉及到具體的變數命名規範時,建議是使用BEM規範,只要遵循一些簡單的原則即可以保證基於元件風格的命名一致性。你也可以參考CSS Tricks來獲得更多的細節描述。

避免重複程式碼

大部分元素的CSS屬性都是從DOM樹根部繼承而來,這也是其命名為級聯樣式表的由來。我們以font屬性為例,該屬性往往是繼承自父屬性,因此我們並不需要再單獨地為元素設定該屬性。我們只需要在html或者body中新增該屬性然後使其層次傳遞下去即可:

使用transform新增CSS Animations

不建議直接改變元素的widthheight屬性或者left/top/bottom/right這些屬性來達到動畫效果,而應該優先使用transform()屬性來提供更平滑的變換效果,並且能使得程式碼的可讀性會更好:

Transform的幾個屬性translaterotatescale都具有比較好的瀏覽器相容性可以放心使用。

不要重複造輪子

現在CSS社群已經非常龐大,並且不斷地有新的各式各樣的庫開源出來。這些庫可以幫助我們解決從小的程式碼片到用於構建完整的響應式應用的全框架。所以如果下次你再碰到什麼CSS問題的時候,在打算擼起袖子自己上之前可以嘗試在GitHUB或者CodePen上搜尋可行方案。

儘可能使用低優先順序的選擇器

並不是所有的CSS選擇器的優先順序都一樣,很多初學者在使用CSS選擇器的時候都是考慮以新的特性去複寫全部的繼承特性,不過這一點在某個元素多狀態時就麻煩了,譬如下面這個例子:

我們本來希望將.active類新增到按鈕上然後使其顯示為紅色,不過在上面這個例子中很明顯起不了作用,因為button已經以ID選擇器設定過了背景色,也就是所謂的Higher Selector Specificity。一般來說,選擇器的優先順序順序為:ID(#id) > Class(.class) > Type(header)

避免使用!important

認真的說,千萬要避免使用!important,這可能會導致你在未來的開發中無盡的屬性重寫,你應該選擇更合適的CSS選擇器。而唯一的可以使用!important屬性的場景就是當你想去複寫某些行內樣式的時候,不過行內樣式本身也是需要避免的。

使用text-transform屬性設定文字大寫

Em, Rem, 以及 Pixel

已經有很多關於人們應該如何使用em,rem,以及px作為元素尺寸與文字尺寸的討論,而筆者認為,這三個尺寸單位都有其適用與不適用的地方。不同的開發與專案都有其特定的設定,因此並沒有通用的規則來決定應該使用哪個單位,這裡是我總結的幾個考慮:

  • em – 其基本單位即為當前元素的font-size值,經常適用於media-queries中,em是特別適用於響應式開發中。
  • rem – 其是相對於html屬性的單位,可以保證文字段落真正的響應式尺寸特性。
  • px – Pixels 並沒有任何的動態擴充套件性,它們往往用於描述絕對單位,並且可以在設定值與最終的顯示效果之間保留一定的一致性。

在大型專案中使用前處理器

估計你肯定聽說過 Sass, Less, PostCSS, Stylus這些前處理器與對應的語法。Preprocessors可以允許我們將未來的CSS特性應用在當前的程式碼開發中,譬如變數支援、函式、巢狀式的選擇器以及很多其他的特性,這裡我們以Sass為例:

使用Autoprefixers來提升瀏覽器相容性

使用特定的瀏覽器字首是CSS開發中常見的工作之一,不同的瀏覽器、不同的屬性對於字首的要求也不一樣,這就使得我們無法在編碼過程中記住所有的字首規則。並且在寫樣式程式碼的時候還需要加上特定的瀏覽器字首支援也是個麻煩活,幸虧現在也是有很多工具可以輔助我們進行這樣的開發:

在生產環境下使用Minified程式碼

為了提升頁面的載入速度,在生產環境下我們應該預設使用壓縮之後的資原始碼。在壓縮的過程中,會將所有的空白與重複剔除掉從而減少整個檔案的體積大小。當然,經過壓縮之後的程式碼毫無可讀性,因此在開發階段我們還是應該使用普通的版本。對於CSS的壓縮有很多的現行工具:

選擇哪個工具肯定是依賴於你自己的工作流啦~

多參閱Caniuse

不同的瀏覽器在相容性上差異很大,因此如果我們可以針對我們所需要適配的瀏覽器,在caniuse上我們可以查詢某個特性的瀏覽器版本適配性,是否需要新增特定的字首或者在某個平臺上是否存在Bug等等。不過光光使用caniuse肯定是不夠的,我們還需要使用些額外的服務來進行檢測。

Validate:校驗

對於CSS的校驗可能不如HTML校驗或者JavaScript校驗那麼重要,不過在正式釋出之前用Lint工具校驗一波你的CSS程式碼還是很有意義的。它會告訴你程式碼中潛在的錯誤,提示你一些不符合最佳實踐的程式碼以及給你一些提升程式碼效能的建議。就像Minifers與Autoprefixers,也有很多可用的工具:

相關文章