我的 CSS 就是這么可愛——如何組織 CSS
本文轉載自微信公眾號「微醫大前端技術」,作者許浩星 。轉載本文請聯系微醫大前端技術公眾號。
寫在前面
開局先問大家一個問題:前端三劍客分別是誰?
不用說,絕大部分前端開發都會脫口而出:HTML、CSS 和 JavaScript。要是這個還需要猶豫的話,朋友自己去墻角反省一下自己[手動狗頭]。既然被稱為三劍客,那么就意味著這三者在前端開發中起到了重要的作用。HTML 負責頁面結構的搭建,CSS 負責頁面的布局與美化,而 JS 負責的是賦予靜態頁面以動態的邏輯。從這個角度來看,這三者真的是缺一不可。但是隨著業務需求的緊逼,我們往往做不到“雨露均沾”,有意無意得忽略了某個角色——CSS。
就比如我自己,在日常的業務開發中,就經常將注意力放在了 HTML 結構和 JS 邏輯上,對于 CSS 就冷淡了很多。這樣子造成的后果就是當頁面的交互豐富、樣式多樣的時候,我們寫的 CSS 代碼行數多的嚇人,而且再也不想再看第二遍。用高情商的話說就是,我們寫的 CSS 代碼讓后續的開發者維護起來很有挑戰性。
靜下心來,我仔細地剖析了一下原因,發現主要是因為樣式代碼的穩定性高。寫完了一遍 CSS,以后基本不可能再要修改了。這種“一次性”很難不讓人帶著一點糊弄的“心態”去開發,然后留下一堆爛攤子給后面的同事罵人??。
但是!天道好輪回!如果碰到了需要去修改別人寫過的 CSS 樣式,那么這就是噩夢??。很難不讓人改的懷疑人生,最后選擇重寫一遍(嗚嗚嗚,別罵了,別罵了)!在碰到過這種情況后,我意識到我們需要從一個整體的角度來指導 CSS 書寫,從而讓樣式文件變得更加美麗!這也是我寫這篇文章的初衷。
一、CSS 與審美
??審美是主觀的,它受到各方面因素的影響,例如文化背景,知識體系和性格愛好等等。我們作為前端開發,在編程這個領域內更是經常與審美打交道。有時候我們經常說某某代碼寫的垃圾,看半天也看不懂。某某大佬代碼寫的強無敵,條理清晰和邏輯完備。這些對于代碼的評價就是我們對于審美認知的體現。
??CSS 的存在就是賦予頁面美麗,如下面動圖所示:
上面的動圖我想每一位用戶都更喜歡加了 CSS 文件之后的頁面吧,因為符合人的審美。
既然 CSS 能夠讓頁面更加漂亮,那么對于 CSS 本身,我們更應該讓它美起來!
二、什么樣的 CSS 是受人喜歡的?
??前面我們已經找到了我們的目的:讓 CSS 更加好看!那么好看的目的是什么呢?是讓人喜歡。讓我們在需求開發時不抗拒去修改原有的代碼。那么這就引出了一個問題:什么樣的代碼讓人抗拒去修改?我們看看下面的兩種 CSS 代碼:
個人來說,第一眼看上去,左邊的代碼“擠”在一起,顯得亂糟糟的。而右邊的代碼更為清晰,每塊之間還有空行,讓人感覺更為舒服。那么問題來了,為什么右邊的代碼會讓我看上去舒服點?我在仔細比較這兩塊代碼的區別之后,我找到了答案:
每塊代碼之間間隔有序,不至于給人一個無比龐大的概念。
層級控制不超過 3 層,避免了過多嵌套層級“惡心”人
遵循了 BEM 命名規范,潛在的傳遞了關于元素之間的層級關系
??總結起來就是:將代碼的邏輯關注點分割個多個開發者可以輕易消化的小塊,同時做到一定意義的自解釋。這樣的處理減少了人腦需要處理這些代碼邏輯的難度,自然會給人舒服的感覺!
那么我們下面思考的更加深入點,抽象出 CSS 的書寫原則。
三、CSS 的一些書寫原則
??CSS 本身是沒有什么內置的組織方式的,并且有各種書寫的方式,例如:內聯和外鏈等等。所以我們需要自己完成建立編寫 CSS 時維持統一性和規則性的工作。Web 社區也已經存在了多種工具和方法,來幫助開發者管理大的 CSS 項目。我們可以借鑒并調整為適合我們自己的書寫方式。但在這之前,我們需要明確幾個 CSS 書寫原則。
- 少即是多
- 自解釋
- 可復用
??上面 3 條原則是我在開發過程中自己總結出來的,如果大家有更多的想法??,歡迎和我一起探討。先說說第一條原則:少即是多(Less is more)。這句話的英文版本是建筑師凡德羅在建筑領域提出的觀點。他反對機械化生產的產品中存在的繁復的無意義的裝飾。這同樣也適用于 CSS 的編寫中。在前端三劍客中,HTML 是結構,JS 是行為,CSS 則是表現。換句話說,CSS 的作用是裝飾頁面。在這個前提下,去除那些冗余繁復的 CSS 代碼不僅能減小瀏覽器的性能消耗,還能讓開發者更加深入的思考表現與結構之間的關系。我認為這對于前端開發工程師的思維成長是有幫助的。
- // 存在多余的代碼
- .footer {
- margin-top: 30px;
- margin-bottom: 20px;
- }
- // 優化
- .footer {
- margin: 30px 0 20px 0;
- }
上面的代碼就是最簡單的少即是多的實踐,但不僅限于此。我們更需要從整體上進行思考與實踐。那么如何做到這一點呢?無它,惟手熟爾。所以每次開發中,都要記住我們的口號:“絕不多寫一行 CSS!”。
第 2 條原則自解釋的意思是 CSS 的書寫要盡量說明自己是干什么的,減少額外的注釋代碼。
- // 存在模糊地方
- .footer:first-child {
- color: #FFF;
- font-size: 18px;
- }
- // .footer-title {
- color: #FFF;
- font-size: 18px;
- }
上面的代碼解釋了這個元素的目的,是 footer 部分中關于 title 的文本。這樣可以讓我們很容易定位到對應的 html 元素,從而進行樣式的修改。對于這條原則的實現,社區已經有了一套很完善的方案:BEM 命名。這套規范即避免了不同文件下的命名沖突,還很好的賦予了 CSS 類名的語義化。讓我們的腦子對于 CSS 那種模糊的印象變得條理清晰。
- <div class="person-center__wrap">
- <div class="person-center__main">
- <div class="userInfo-name">
- 王狗蛋
- </div>
- <div class="userinfo-age">
- 24
- </div>
- </div>
- <div class="person-center__footer">
- <div class="sctions-comfirm">
- 確定
- </div>
- </div>
- </div>
上面這段代碼就較好的使用 BEM 命名將額外的頁面結構信息塞到了 CSS 類名上了,讓開發者不至于摸不清 CSS 的對應 DOM 結構。再配上預處理語言 SASS 等,更加從心智上將消除了 CSS 的信息缺少與模糊性,保證了頁面結構、表現和行為的統一性。
最后一條可復用的原則就不多說了,懂得都懂。這條原則的基礎是 CSS 預處理語言的使用。因為 CSS 本身是一種描述語言,本身是沒有邏輯的。但是隨著業務的越來越復雜,我們渴望將邏輯代碼加入 CSS 中。這也是 SASS 預處理語言興起的原因之一。加入邏輯的 CSS 預處理語言中,我們可以定義變量、使用循環和條件判斷,從而復用 CSS 代碼。
四、保持 CSS 整潔的技巧
在了解了書寫 CSS 的原則之后,我們還需要在實踐中運用它們。在這個過程,一些保持 CSS 整潔的技巧對我們實踐是很有幫助的。
1. 確定項目的代碼規范
??在和多人進行項目的開發時,第一時間需要檢查該項目是否有了 CSS 的代碼規范。遵循項目的代碼規范進行開發,是保持 CSS 整潔的基礎,也是不讓別人吐槽的護盾。如果你的個人喜好跟規范相沖突,那么還是請遵守規范,因為別人或許不喜歡你的風格。
2. 保持統一
??當你開始進行需求開發并書寫 CSS 代碼時,最重要的是保持各方面的統一。例如之前的代碼使用的是 rem 單位,并且在代碼開頭進行了換算和變量定義。那么你需要做的就是跟隨!!而不是標新立異的使用另一套自己的方式。
統一在所有的地方都會起到實際作用,例如對類使用相同的命名常規,選擇一種描述顏色的方式,或者維護一個統一的格式化方式(例如你是使用 Tab 還是空格來縮進代碼?如果是代碼,用多少個?)
一直遵守一系列規則,你會在編寫 CSS 的時候省去不少精神上的預負擔,因為一些決定已經定型了。要知道代碼是寫給人看的,順帶著可以在機器上運行。在這里給我們團隊的開發規范打個廣告:微醫前端開發手冊 1.1(修訂中),歡迎大家提出意見,共同進步。
3. 將 CSS 格式化成可讀的形式
你可以看到很多 CSS 格式化的方式,一些開發者將所有的規則放在一行里面,像是這樣:
- .box { background-color: #567895; }
- h2 { background-color: black; color: white; }
??還有的開發者更喜歡將所有的東西放在新的一行,并且不同元素之間空行:
- .person-center {
- &-wrap {
- width: 100%;
- }
- &-main {
- color: #FFF;
- font-size: 16px;
- font-weight: 500;
- }
- }
??CSS 不會管你使用哪種方式來進行格式化,我的看法是在遵循代碼規范的前提下讓 CSS 代碼更加具有可讀性。保證了你自己還愿意下次看,才能保證其他開發者能夠看的下去你的代碼。
4. 為你的 CSS 加上注釋
代碼自解釋為前提,但是在某些定制需求時需要加上注釋,表明相關業務背景和其他信息。這樣做不僅可以幫任何未來的開發者處理你的 CSS 文件,也可以在你離開項目一段時間后,幫你在回來時重新上手。
- /* 這是一條 CSS 注釋,
- 它可以分成好幾行。*/
在你的樣式表里面的邏輯段落之間,加入一塊注釋,是個好技巧。在你快速掠過的時候,這些注釋可以幫你快速定位不同的段落,甚至給了你搜索或者跳轉到那段 CSS 的關鍵詞。如果你使用了一個不存在于代碼里面的字符串,你可以從段落到段落間跳轉,只需要搜索一下,下面我們用的是||。
- /* || General styles */
- ...
- /* || Typography */
- ...
- /* || Header and Main Navigation */
- ...
或許你是照著一個社區教程來做事的,CSS 有些不夠直觀。此時,你應該在注釋里面加入教程的 URL。你應該在你一年或者更長時間以后重新審視你的項目,但只是模模糊糊地想起來之前有個優秀的教程,不知道它在哪里的時候,感謝之前加入注釋的自己。
5. 在你的樣式表里面加上邏輯段落
??在樣式表里面先給一般的東西加上樣式是個好想法。這也就是除了你想特定對某個元素做點什么以外,所有將會廣泛生效的樣式。典型地,你可以為以下的元素設定規則:
- body
- p
- h1, h2, h3, h4, h5
- ul 和 ol
- table 屬性
- 鏈接
在這段樣式表里面,我們提供了用于站點類型的默認樣式,為數據表格、列表等設立了一份默認的樣式。
- /* || GENERAL STYLES */
- body { ... }
- h1, h2, h3, h4 { ... }
- ul { ... }
- blockquote { ... }
??在這段之后,我們可以定義一些實用類,例如一個用來移除默認列表樣式的類,我們打算將其展示為靈活樣式或者其他樣式。如果你知道你想要在許多不同的元素上應用的東西,那么你可以把它們加到這里。
- /* || UTILITIES */
- .nobullets {
- list-style: none;
- margin: 0;
- padding: 0;
- }
- ...
然后我們可以加上在整個站點都會用到的所有東西,這可能是像基礎頁面布局、抬頭或者導航欄樣式之類的東西。
- /* || SITEWIDE */
- .main-nav { ... }
- .logo { ... }
最后我們可以在 CSS 里面加上特指的東西,將它們分成上下文、頁面甚至它們使用的組件。
- /* || STORE PAGES */
- .product-listing { ... }
- .product-box { ... }
通過使用這種方式排布代碼,我們至少能大致了解,我們能在樣式表的哪個部分尋找想要更改的東西。
6. 避免太特定的選擇器
如果你創建了很特定的選擇器,你經常會發現,你需要在你的 CSS 中復用一塊代碼,以將同樣的規則應用到其他元素上。例如,你也許會有像是下面的選擇器那樣的代碼,它在帶有main類的
上應用了規則。 如果你之后想要在main外的什么地方上應用相同的規則,或者在 外的其他地方,你可能必須在這些規則中加入另一個選擇器,或者直接新建個規則。或者,你也可以建立一個名為box的類,在任何地方應用。 將東西設置的更為特定,有時也有意義,但是這一般與其說是通常實踐,倒不如說是例外。 這個技巧可以說是我們已經做到很好了。一般項目中都會有一個 styles,里面存儲一些全局共用的樣式文件。根據這些文件的作用,一般又會被細分為reset.csss、variables.less等文件。搭配上預處理語言的 mixin 功能,我們就可以維護一份常用的樣式文件,避免在具體的頁面書寫冗雜的 CSS 代碼。 這可以讓你更容易保持 CSS 的組織性,也意味著如果有多人在寫 CSS,你會更少遇到有兩個人需要同時編寫相同的樣式表的情況,防止在源代碼的控制上產生沖突。 人區別于大猩猩的一處就是善于使用工具解決我們遇到的困難。身處于互聯網的浪潮中,我們更應該擁抱那些有幫助的工具??。使用 stylelint + githook 來規范我們的 CSS 代碼,使用 Less/Sass 預處理語言讓 CSS 更加有“邏輯” 。它們解放了我們的大腦,也在潛移默化中培養我們的編碼規范。 沒有人是完美的,人的一個優勢就是可以通過學習來提升自己。那么我們作為程序員,更需要與厲害的同行交流經驗,學習別人好的編碼規范融入自己的日常開發中。每個人都是獨立的個體,每個人也都有著自己的想法,身處于這行,開放思想,用于承認自己的不足,才是能夠永遠進步的源泉!! ??這包括了線下團隊之間開展專題討論和線上參與社區討論等等措施,多與人溝通才能開拓我們的技術視野。 原諒我在最后的小結起了一個很文藝的標題。我最近在看一部蠻老的日劇:《龍櫻》,劇中男主阿部寬跟備考東大的幾個“笨蛋”說考試是一場與自己的對話,也是一場與競爭對手的對話。 走上職場的我們,無論是初入職場的激情滿滿還是磨練了幾年后的波動如山,限制著影響著我們的只有自己。但是信息繭房不僅封閉了我們對外界的認知,更剝奪了我們對自己的認知。 將時間尺度拉到,拉到 1 年、3 年、5 年乃至 10 年。你寫的代碼作為時間的錨點一直存在于那里,這又不是一種另類的未來與現在的對話嗎?所以如何組織 CSS 呢?第一原則就是當成與自己的對話,做到你不嫌棄自己。在這基礎上,掌握并找到適合自己的編碼原則,使用規范和工具來糾正監督自己,剩下的就是實踐 => 修改 => 再實踐 => 再修改的無限循環。 整潔的代碼是由整潔的人寫出來的,寫出可愛的代碼也一定是個可愛的人。我最開始寫代碼的理想的想通過虛擬世界來幫助我理解現實世界的復雜性。我們在將復雜、錯亂的 CSS 代碼進化為整潔、邏輯關注點清晰的代碼。這一過程同時也是一場與自己的對話,問自己喜歡什么,問自己想要什么。在這種潛意識的一個個疑問中,我們整理著內心。 我們在 0 和 1 的世界里,思考著物理世界的喜怒哀樂,希望朋友們能夠撇去浮燥世界帶來的浮沫,都能找到生活的真諦!畢竟努力工作只是手段,我們的目標是未來的幸福快樂生活!諸君共勉!7. 分割大樣式表為多個小樣式表
8.善用工具
9. 學習與模仿
五、寫代碼是與自己的對話