標籤:

CSS 屬性排序千千萬,我只愛那一種

不知道有多少人思考過將 CSS 屬性排序的問題。反正在我書寫網頁的無數個日子裡,是有想過這個問題的。

因為大多數時候,調樣式寫屬性完全就是按需要來,調一個加一條,樣式調好後,整個元素的代碼也就確定了。

偶爾會因為美觀刻意把自己認為需要提前的屬性放到前面一下,僅此而已。

這種下意識的行為讓我覺得,冥冥之中,應該有一些可用的約定,來指導我們,將這些紛繁的 CSS 樣式屬性進行合理地排列。

果不其然,著名 CSS 站點 css-tricks 為此專門做了個問卷調查,結果顯示:

  • 按類型來分組的占 45%
  • 完全不 care 這件事,寫起來隨意的佔39%
  • 按屬性字母順序的佔14%
  • 最後還有按一行代碼長度來排序的佔2%

感受下最後這種排序方式:

.button {n box-shadow: inset .25em .25em .5em rgba(0, 0, 0, .3), .5em .5em 0 #444;n font-family: Avenir, Helvetica, Arial, sans-serif;n border: .25em solid #196e76;n text-decoration: underline;n text-transform: uppercase;n display: inline-block;n padding: 1em 4em 2em;n text-align: center;n margin: 1em auto;n font-size: 3em;n color: #fff;n}n

將 CSS 屬性排序的意義

屬性順序本無關緊要,夫意欲何為?

我認為,讓 CSS 屬性保持一定的規律有一些好處:

  • 作為寫程序的人,除了希望代碼的輸出具有確定性,即每寫一行代碼我知道我在寫什麼,我能預知到結果,還希望從代碼風格上保持一致,這樣在寫類似功能時,寫出來的東西是有某種確定性的,代碼會有種統一的風格在裡面,同時閱讀起來會很輕鬆
  • 當這些看似雜亂無序的屬性在書寫時遵從一定規律後,改起來會很方便。比如我習慣將 widthheight這種基本的常用的屬性寫在元素樣式的最前面,我在改的時候就直接到最前面去找
  • 會有一種,哲學上的美。恩,就是看起來舒心的那種。寫碼也是種藝術創作,只不過陳老師用相機,我們用鍵盤。沒有風格的編碼是新手,想到哪寫到哪,而具有一定風格的代碼或許是老司機,雖然所堅持的風格不一定普適。

盒模型規則的排序

關於 CSS 屬性書寫時的排序問題,是有一些討論已經存在的,比如 StackOverflow 上的這個提問 Conventional Order of CSS properties,裡面有提到一個叫作 The CSS Box Model Convention 的約定,該約定里羅列的順序是按照 CSS 盒模型來的。

具體來說,可概括為如下的分組順序:

  1. 展示類型及文檔流相關/Display & Flow
  2. 定位信息/Positioning
  3. 元素尺寸/Dimensions
  4. 邊距邊框/Margins, Padding, Borders, Outline
  5. 文字排版/Typographic Styles
  6. 背景/Backgrounds
  7. 其他如透明度,游標樣式及衍生內容/Opacity, Cursors, Generated Content

具體到代碼:

el {n display: ;n visibility: ;n float: ;n clear: ;n position: ;n top: ;n right: ;n bottom: ;n left: ;n z-index: ;n width: ;n min-width: ;n max-width: ;n height: ;n min-height: ;n max-height: ;n overflow: ;n margin: ;n margin-top: ;n margin-right: ;n margin-bottom: ;n margin-left: ;n padding: ;n padding-top: ;n padding-right: ;n padding-bottom: ;n padding-left: ;n border: ;n border-top: ;n border-right: ;n border-bottom: ;n border-left: ;n border-width: ;n border-top-width: ;n border-right-width: ;n border-bottom-width: ;n border-left-width: ;n border-style: ;n border-top-style: ;n border-right-style: ;n border-bottom-style: ;n border-left-style: ;n border-color: ;n border-top-color: ;n border-right-color: ;n border-bottom-color: ;n border-left-color: ;n outline: ;n list-style: ;n table-layout: ;n caption-side: ;n border-collapse: ;n border-spacing: ;n empty-cells: ;n font: ;n font-family: ;n font-size: ;n line-height: ;n font-weight: ;n text-align: ;n text-indent: ;n text-transform: ;n text-decoration: ;n letter-spacing: ;n word-spacing: ;n white-space: ;n vertical-align: ;n color: ;n background: ;n background-color: ;n background-image: ;n background-repeat: ;n background-position: ;n opacity: ;n cursor: ;n content: ;n quotes: ;n}n

按字母排序

除了上面這個比較知名的規則,還有一種大部分人用的方式則更加簡單粗暴,那就是上面問卷結果中有出現過的,按屬性的字母排序(Alphabetical),用的人還不少。這種規則簡單明了,寫起來也不用多想,個人覺得沒多大必要,有點為了排序而排序的感覺,並無多大實用之處。

按照重要性的分組排序

來自 Guy Routledge 的這篇文章展示了一種分組及按照重要性排序的方式,或者說基於此種方式下他自己的一種排序規則。

總結起來就是outside in,由外向內,從元素與外界的關係,是否會影響外部布局,到外邊距,內邊距等。

  1. 布局相關(position, float, clear, display),因為元素的布局會對對相鄰元素產生影響,自身甚至會脫離原來的文檔流,所以比較重要
  2. 盒模型相關(width, height, margin, padding)
  3. 外觀 (color, background, border, box-shadow)
  4. 文字排版 (font-size, font-family, text-align, text-transform)
  5. 其他 (cursor, overflow, z-index)

一個示例

按照上面這種重要性分組的順序,來看一個示例。

假若有一個按鈕:

/* <a href="#" class="button">Order now →</a> */n.button { }n

因為想讓按鈕有縱向高度,所以將默認的 displayinline 改成 inline-block.

.button {n display:inline-block;n}n

解決了布局,接下來便是盒模型相關的,內外邊距,根據由外而內的順序,所以先 marginpadding

.button {n display:inline-block;n margin:1em 0;n padding:1em 4em;n}n

然後是外觀展現。

.button {n display:inline-block;n margin:1em 0;n padding:0.5em 3em;n n color:#fff;n background:#196e76;n}n

最後加上對按鈕文字的排版修飾完工。

.button {n display:inline-block;n margin:1em 0;n padding:1em 4em;n n color:#fff;n background:#196e76;n border:0.25em solid #196e76;n box-shadow:inset 0.25em 0.25em 0.5em rgba(0,0,0,0.3), n 0.5em 0.5em 0 #444;n n font-size:3em;n font-family:Avenir, Helvetica, Arial, sans-serif;n text-align:center;n text-transform:uppercase;n text-decoration:none;n}n

這一規則大致與前面的盒模型規則類似。

我眼中的排序規則

就我個人而言,傾向於將比較重要的常用的放在靠前位置,像元素的長寬width height這種,影響尺寸,也很直觀,我認為是比較重要的屬性。

其次是position 這種規定了元素定位的屬性,再然後是 border color 這種次要的外觀屬性等。

雖然在這排序的過程中,會自動將同類的屬性進行分組。但其實要細說下來,同一類別中也不好區分哪條在前,哪條在後比較好,也就是說雖然內心有個大致的重要性分組,但某個分組內再進行排序的話,自己其實也沒有個清晰的準則。

比如 widthheight 誰先誰後?或許在確定了整體排序規則後,同一分組內的排序就沒那麼重要了。

所以,用工具解決就不用那麼糾結。CSS 屬性排序千千萬,我只愛那一種,那一種,用工具解決的那一種。

工具

CSS 屬性本來就沒有一個標來准規定先寫誰後寫誰,怎樣寫都能工作,正是這樣的情況導致你想找一種確定的書寫方式的時候,面臨選擇的困難,每個人會有自己的偏好,這個很難達成統一。

在團隊內,常見的會推 JS 的編碼風格,甚至會推相應的工具來強制檢查。卻很少聽到有為 CSS 來做這樣的風格統一的。我覺得即使不為了考慮團隊代碼風格的一致性問題,從本文開始列的因素中來看,個人至少是需要養成一種屬於自己風格的書寫規範,或者選擇一種規範來始終堅持。養成習慣後,寫起 CSS 下筆如有神,文思如泉湧。

如果覺得手工排序麻煩,那麼也有相應的工作來自動格式化 CSS 代碼的。比如 CSScomb。相應的有編輯器插件,Node CLI 工具。同時 VSCode 的應用市場也有相應實現可以選擇安裝。

當然,該工具有自己的一套排序機制,它主要還是對 CSS 的分組及格式化方面的支持,並沒有使用上面的某種規則來排序。但使用它能夠保證 CSS 屬性按照一定順序恆定輸出。如果你同意他的這種格式化風格的話,使用這個插件會是比較省事的選擇。

通過他提供的在線工具我嘗試了一個示例,大部分是相同的代碼,兩個類名裡面打亂了順序,第二個類裡面進行了屬性的刪減,期望的輸出結果是兩個按鈕類中每個屬性所處的位置不變。

格式化前

.btn {n display: inline-block;n margin: 1em 0;n font-size: 3em;n padding: 1em 4em;n color: #fff;n box-shadow: inset 0.25em 0.25em 0.5em rgba(0, 0, 0, 0.3), 0.5em 0.5em 0 #444;n background: #196e76;n border: 0.25em solid #196e76;n text-decoration: none;n font-family: Avenir, Helvetica, Arial, sans-serif;n text-align: center;n text-transform: uppercase;n}nn.btn2 {n border: 0.25em solid #196e76;n text-transform: uppercase;n padding: 1em 4em;n color: #fff;n box-shadow: inset 0.25em 0.25em 0.5em rgba(0, 0, 0, 0.3), 0.5em 0.5em 0 #444;n background: #196e76;n text-decoration: none;n font-size: 3em;n font-family: Avenir, Helvetica, Arial, sans-serif;n text-align: center;n}n

格式化後

.btnn{n font-family: Avenir, Helvetica, Arial, sans-serif;n font-size: 3em;nn display: inline-block;nn margin: 1em 0;n padding: 1em 4em;nn text-align: center;n text-decoration: none;n text-transform: uppercase;nn color: #fff;n border: .25em solid #196e76;n background: #196e76;n box-shadow: inset .25em .25em .5em rgba(0, 0, 0, .3), .5em .5em 0 #444;n}nn.btn2n{n font-family: Avenir, Helvetica, Arial, sans-serif;n font-size: 3em;nn padding: 1em 4em;nn text-align: center;n text-decoration: none;n text-transform: uppercase;nn color: #fff;n border: .25em solid #196e76;n background: #196e76;n box-shadow: inset .25em .25em .5em rgba(0, 0, 0, .3), .5em .5em 0 #444;n}n

該插件支持自定義樣式規則,通過其提供的在線工具可以方便地生成滿足自己風格的規則。使用VSCode 插件 需要注意,需要在設置中指定一種格式化預設配置才能生效。

{n "csscomb.preset": "csscomb" //其他規則或者自定義規則n}n

除了在編輯器中進行設置,還可以生成一個配置文件,放在項目根目錄中,類似.editorconfig,這樣項目中其他人可以共用同一份配置,達到團隊代碼風格的統一。

結論

港真,按照一定規則格式之後的 CSS 代碼會看起來舒心很多。

選擇一種風格,或者形成並保持自己的風格。程序人生路漫漫,代碼風格常相伴。

「你吃的苦會照亮你未來的路」,你的堅持,不會是白白的付出。

相關資源

  • Poll Results: How do you order your CSS properties?
  • 「Outside In」 — Ordering CSS Properties by Importance
  • Conventional Order of CSS properties
  • CSScomb
  • CSScomb VSCode 插件

推薦閱讀:

知乎上很多前端大佬說,要做好前端的話html和css基礎必須夯實。那麼,達到什麼水平才能叫基礎夯實呢?
Razor 生成的html格式可以調整嗎?
有哪些在伺服器端給網頁截圖的辦法?
這是我的前端學習路線,大家幫忙看看有什麼不好的地方?
前端的清除浮動?

TAG:HTMLCSS | CSS |