【譯】改善 CSS 的 10 個最佳實踐
CSS 看起來是一種非常直接且不易犯錯的語言。只需要添加規則以對網站進行樣式設置就可以了,對嗎?對于只需要幾個 CSS 文件的小型站點,可能是這種情況。但是在大型程序中,這樣可能會使樣式迅速失控。如何讓它們更可控?
事實是,就像其他任何語言一樣,CSS的細微差別可以使你的設計有天壤之別。這是 CSS 的 10 條技巧 —— 可以幫助你從樣式中獲得最大收益的最佳實踐。
1. 你真的需要框架嗎?
首先,確定你是否真的需要使用 CSS 框架。現在有許多輕量級的方法可以替代繁重的框架。通常,你不會使用框架中的每個選擇器,因此你的程序中會包含冗余代碼。
如果你只需要使用按鈕的樣式,將它們復制到你自己的 CSS 文件中,然后刪除其余的樣式。另外,你可以使用開發者工具中的代碼覆蓋率檢測來識別未使用的 CSS 規則。
要打開它,請在“工具”面板中搜索 Coverage。您可以通過單擊 Ctrl
+ Shift
+ P
來打開工具面板。打開后,單擊重新加載圖標開始錄制。所有顯示紅色的內容都是沒有使用的。
你可以在上面的例子中看到,它表示了 98% 的 CSS 都沒有被使用。請注意,實際上并非如此 —— 某些 CSS 樣式僅在用戶與網站互動后才應用。移動設備的樣式也會被標記為未使用。因此,在刪除所有內容之前,請確保這些樣式確實沒有在任何地方使用。
2. 選用一套 CSS 規范
考慮為你的項目使用一套 CSS 規范。CSS 規范使 CSS 文件具有一致性。它們有助于擴展和維護您的項目。這里有一些我推薦的 CSS 規范。
BEM
BEM —— Block(塊)、Element(元素)、Modifier(修飾符)—— 是最流行的 CSS 規范之一。它是一組命名約定,你可以使用它們輕松地設計可復用組件。命名約定遵循以下模式:
.block { ... }
.block__element { ... }
.block--modifier { ... }
-
.block
:塊代表一個組件。它們是獨立的實體,并且對自身有意義。 -
.block__element
:這些是.block
的一部分。它們沒有獨立的含義,必須綁定到一個塊上。 -
.block--modifier
:它們被用作塊或元素的標志。我們可以使用它們來改變元素的外觀、行為或狀態。例如,要使用隱藏標記,我們可以命名為.block--hidden
。
ITCSS
倒三角 CSS 通過引入不同的層來實現不同的特性,幫助你更好地組織你的文件。你走得越深,就越具體。
OOCSS
Object-oriented CSS 或 OOCSS 遵循兩個主要的原則。
「分離結構和視覺效果」
這意味著你要將視覺效果與結構代碼分開定義。這在實踐中意味著什么?
/* 待優化的內容 */
.box {
width: 250px;
height: 250px;
padding: 10px;
border: 1px solid #CCC;
box-shadow: 1px 2px 5px #CCC;
border-radius: 5px;
}
/* 優化后 */
.box {
width: 250px;
height: 250px;
padding: 10px;
}
.elevated {
border: 1px solid #CCC;
box-shadow: 1px 2px 5px #CCC;
border-radius: 5px;
}
「分隔容器和內容」
這意味著你不希望任何元素依賴于它的位置。相同的元素無論在頁面的什么位置看起來都應該是相同的。
/* 待優化的內容 */
.main span.breadcumb { ... }
/* 優化后 */
.breadcrumb { ... }
3. 設置預處理器
設置預處理器可以在很多方面給你帶來好處。預處理器是一種工具,它允許你使用 CSS 中不存在的高級特性。這些特性可能是循環變量甚至函數之類的東西。
現在有很多預處理器。最著名的三個大概是 Sass、Less 和 Stylus。我建議使用 Sass,因為它有一個成熟的社區,而且你可以在網上找到大量關于它的文檔。
那么,預處理器能提供什么幫助?
更好地組織樣式
預處理可以幫你更好地組織樣式。它們能夠將你的文件拆解成更小的可復用文件。它們可以相互導入,或者分別導入你的應用。
// 為一個 SCSS 文件導入不同的模塊
@import 'settings';
@import 'tools';
@import 'generic';
@import 'elements';
@import 'objects';
@import 'components';
@import 'trumps';
嵌套選擇器
另一種增強可讀性的好方法是嵌套選擇器。這是一個簡單而強大但 CSS 所缺少的功能。
.wrapper {
.sidebar {
&.collapsed {
display: none;
}
.list {
.list-item {
...
&.list-item--active {
...
}
}
}
}
}
分層結構使我們更加清晰的看出不同元素的結合關系。
自動為你的規則添加前綴
CSS 中有一些非標準或實驗性功能的前綴。不同的瀏覽器為其使用不同的前綴,例如:
-
-webkit-
:適用于基于 WebKit 的瀏覽器,例如 Chrome、Safari 或 Opera 的較新版本。 -
-moz-
:適用于 Firefox。 -
-o-
:適用于舊版 Opera。 -
-ms-
:用于 IE 和 Edge。
為了支持所有主流瀏覽器,我們必須多次定義某些屬性。
.gradient {
background: rgb(30,87,153);
background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);
background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);
background: linear-gradient(to bottom, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e5799', endColorstr='#7db9e8', GradientType=0);
}
預處理器可以解決此問題,它借助了 mixin
—— 可以代替硬編碼值使用的函數。
@mixin gradient() {
background: rgb(30,87,153);
background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);
background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);
background: linear-gradient(to bottom, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e5799', endColorstr='#7db9e8', GradientType=0);
}
.gradient {
@include gradient();
}
在需要的時候添加 mixin
可以避免編寫冗余代碼。
使用后處理器
更好的選擇是后處理器。一旦 CSS 由預處理器生成,則后處理器可以運行其他優化步驟。最受歡迎的后處理器之一是 [PostCSS](https://postcss.org/)
。
你可以使用 PostCSS
來自動為 CSS 規則添加前綴,就必擔心會遺漏主要的瀏覽器。他們使用 Can I Use 中的值,因此它始終保持最新的。
另一個很好的后處理器是 [autoprefixer](https://www.npmjs.com/package/autoprefixer)
。使用 autoprefixer
,當您要支持最新四個版本時 — 無需在CSS文件中寫入任何前綴就可以完成所有工作!
const autoprefixer = require('autoprefixer')({
browsers: [
'last 4 versions',
'not ie < 9'
]
});
使用配置進行一致的設計
除了 mixin
,你還可以選擇使用變量。與 linter 一起,你可以強制執行自己的設計規則。
// 字體定義
$font-12: 12px;
$font-21: 21px;
// 顏色定義
$color-white: #FAFAFA;
$color-black: #212121;
4. 使用標簽代替 CSS
現在讓我們進入實際的 CSS 應用。這經常被忽略。通常,你可以簡單地通過使用正確的 HTML 標簽來減小 CSS 包的大小。假設你的標題包含以下規則:
span.heading {
display: block;
font-size: 1.2em;
margin-top: 1em;
margin-bottom: 1em;
}
你使用了一個 span
標簽作為標題。你重寫了默認的顯示、間距和字體樣式。這可以通過使用 h1
、h2
或 h3
來避免。默認情況下,它們具有你試圖用其他標簽達到的樣式。你可以立即少寫四條不必要的樣式規則。
5. 使用簡寫屬性
為了進一步減少樣式規則數量,通常使用 簡寫屬性。對于上面的示例,我們可以寫:
.heading {
margin: 1em 0;
}
對于其他屬性,如邊框、邊框或背景,也是如此。
6. 減少冗余
這與上一點是密切相關的。有時很難發現冗余,特別是當兩個選擇器中的重復規則未遵循相同順序時。但是,如果你的類僅在一個或兩個規則中有所不同,最好將這些規則外包出去,作為一個額外的類使用。這是優化前的代碼:
<style>
.warning {
width: 100%;
height: 50px;
background: yellow;
border-radius: 5px;
}
.elevated-warning {
width: 100%;
height: 50px;
font-size: 150%;
background: yellow;
box-shadow: 1px 2px 5px #CCC;
border-radius: 5px;
}
</style>
<div class="warning">?</div>
<div class="elevated-warning"></div>
試著用類似的方法:
<style>
.warning {
width: 100%;
height: 50px;
background: yellow;
border-radius: 5px;
}
.warning--elevated {
font-size: 150%;
box-shadow: 1px 2px 5px #CCC;
}
</style>
<div class="warning">?</div>
<div class="warning warning--elevated"></div>
7. 避免使用復雜的選擇器
使用復雜的選擇器有兩個主要問題。首先,增加的特性不僅會使以后重寫現有規則變得更加困難,還會增加瀏覽器匹配選擇器所需的時間。
匹配選擇器
當瀏覽器解析選擇器并確定它與哪個元素匹配時,它們是從右到左進行的。就性能而言,這比相反的方式更快。讓我們以下面的選擇器為例。
.deeply .nested .selector span {
...
}
瀏覽器將首先從 span
開始。它將匹配所有 span
標簽,然后轉到下一個匹配項。它將過濾掉 .selector
類中的 span
,以此類推。
不建議使用 CSS 的標簽選擇器,因為它會匹配所有的標簽。雖然只有幾分之一毫秒的差異,但積少成多。另一個更重要的原因是,減少選擇器復雜性是一種好習慣。
理解選擇器
不僅機器很難進行解析,人類也難以理解。以如下為例:
[type="checkbox"]:checked + [class$="-confirmation"]::after {
...
}
你認為上述規則什么時候適用?通過創建自定義類并使用 JavaScript 進行切換,可以簡化此過程。
.confirmation-icon::after {
...
}
現在看起來舒服多了。如果你發現自己仍然需要過于復雜的選擇器,而且你相信沒有其他選擇,請在下面留下你的評論解釋你的解決方案。
/**
* 選中復選框后創建確認圖標。
* 選擇所有以類名“-confirmation”結尾的標簽
* 前面有一個選中的復選框。
* PS.:沒有其他方法可以解決此問題,請不要嘗試修復它。
**/
.checkbox:checked + label[class$="-confirmation"]::after {
...
}
8. 不要刪除輪廓
這是開發人員在編寫 CSS 時最常犯的錯誤之一。雖然你可能認為刪除輪廓創建的高亮沒有什么錯,但事實上,你正在使網站無法訪問。通常將此規則添加為 CSS 的重置值。
:focus {
outline: none;
}
然而,這樣的話,那些只能用鍵盤導航的用戶將對網站聚焦的地方和內容一無所知。
如果默認樣式對你的品牌不利,請創建自定義輪廓。只要確保在聚焦元素方面有某種指示即可。
9. 以移動設備優先
當你必須處理媒體查詢時,請始終使用移動設備優先。以移動設備為先的方法意味著當你開始編寫 CSS 時,需要以小屏幕開發為基礎,然后再擴展到其他設備。這也稱為漸進增強。
這將確保你主要添加額外的規則來迎合大屏幕設備,而不是重寫現有的 CSS 規則。這樣可以減少最終使用的規則數量。
您如何判斷是否使用移動優先?如果你的媒體查詢使用 min-width
,你就在正確的軌道上。
/* 移動優先的媒體查詢,所有 600px 以上的設備都會獲得以下樣式 */
@media (min-width: 600px) {
/* 你的CSS規則 */
}
/* 非移動優先媒體查詢,所有 600px 以下的設備都會獲得以下樣式 */
@media (max-width: 600px) {
/* 你的CSS規則 */
}
10. 壓縮
最后,壓縮文件包以減少它們的大小。因為壓縮過程刪除了注釋和空白字符,所以文件包只需更少的寬帶就能獲取。
如果還沒有,也可以在服務器端啟用壓縮。
進一步減小 CSS —— 「和標記」 —— 大小的另一種好方法是混淆類名。
為此,你可以根據項目設置選擇幾個選項:
-
「Webpack」:對于 Webpack,可以使用 [css-loader](https://github.com/webpack-contrib/css-loader)
模塊。 -
「Gulp」: 對于 Gulp,可以使用 [gulp-minify-cssnames](https://www.npmjs.com/package/gulp-minify-cssnames)
插件。 -
「自定義」: 如果你沒有用于項目設置的專用軟件包,那么我會提供一個教程,向你展示如何創建 自己的實現.
總結
遵循以上 10 個簡單步驟將有助于你編寫有以下優點的 css 文件:
-
更輕巧 -
易于維護 -
易于擴展
不僅如此,使用一些實用工具,如預定義的調色板或排版規則,將幫助您創建更穩定的設計。你的樣式復用性也將更高,你就可以為下一個項目節省時間。
還有哪些未在本文提及,而你遵循的 CSS 最佳實踐呢?在評論中告訴我們!
感謝你花時間閱讀本文,祝你愉快!
智能推薦
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...
猜你喜歡
19.vue中封裝echarts組件
19.vue中封裝echarts組件 1.效果圖 2.echarts組件 3.使用組件 按照組件格式整理好數據格式 傳入組件 home.vue 4.接口返回數據格式...
【一只蒟蒻的刷題歷程】【藍橋杯】歷屆試題 九宮重排 (八數碼問題:BFS+集合set)
資源限制 時間限制:1.0s 內存限制:256.0MB 問題描述 如下面第一個圖的九宮格中,放著 1~8 的數字卡片,還有一個格子空著。與空格子相鄰的格子中的卡片可以移動到空格中。經過若干次移動,可以形成第二個圖所示的局面。 我們把第一個圖的局面記為:12345678. 把第二個圖的局面記為:123.46758 顯然是按從上到下,從左到右的順序記錄數字,空格記為句點。 本題目的任務是已知九宮的初態...
dataV組件容器寬高發生變化后,組件不會自適應解決方法
項目中需要大屏幕數據展示,于是使用了dataV組件,但是使用是發現拖動瀏覽器邊框,dataV組件顯示異常,如圖: 于是查了官網,官網的解釋如下: 于是按照官網的意思編寫代碼: 于是可以自適應了...