不管是下面的準則或您自己的準則,只要用同樣的準則即可。如有任何不對之處,請不吝指教。若想新增或貢獻內容,請至 GitHub 來提 issue。
不管有多少個貢獻者,每行程式碼都應該像是同一人所寫。
</li>
或 </body>
)。<!DOCTYPE html>
<html>
<head>
<title>Page title</title>
</head>
<body>
<img src="images/company-logo.png" alt="Company">
<h1 class="hello-world">Hello, world!</h1>
</body>
</html>
每個 HTML 頁面開頭使用這個簡單的 doctype,來啟用標準模式。每個瀏覽器將會有更加一致的 render 結果。
<!DOCTYPE html>
<html>
<head>
</head>
</html>
明確宣告字元編碼來快速簡單地確保內容 render 正確無誤。
<head>
<meta charset="UTF-8">
</head>
根據 HTML5 規範,引用 JavaScript 與 CSS 檔案時,無需指定 CSS 與 JavaScript 的 type
。因為預設值便是 text/css
和 text/javascript
。
<!-- External CSS -->
<link rel="stylesheet" href="code-guide.css">
<!-- In-document CSS -->
<style>
/* ... */
</style>
<!-- JavaScript -->
<script src="code-guide.js"></script>
在不犧牲實用性的前提下,盡力維持 HTML 的標準與語義。盡量使用簡潔、簡單的 Markup。
HTML 屬性應按照特定順序撰寫,確保程式碼的易讀性。
class
id
, name
data-*
src
, for
, type
, href
title
, alt
aria-*
, role
Class 是為了重用的元素而生,應該排第一位。ID 具體得多,應盡量少用(可用場景像是頁內書籤),所以排第二位。
<a class="..." id="..." data-modal="toggle" href="#">
Example link
</a>
<input class="form-control" type="text">
<img src="..." alt="...">
布林屬性是不需要寫值的屬性。XHTML 要求你宣告數值,但 HTML5 不需要。
深入閱讀請查閱 WhatWG 關於布林屬性一節:
元素有布林屬性存在即代表 true value,反之不存在則代表 false value。
如果一定要附上屬性的數值的話,則無需遵守 WhatWG 的這條規則:
如果有寫屬性的話,其數值必須是空字串或是屬性的標準名稱(需符合 ASCII 不分大小寫的規則),且前後不可有空白。
長話短說,不用寫數值。
<input type="text" disabled>
<input type="checkbox" value="1" checked>
<select>
<option value="1" selected>1</option>
</select>
撰寫 HTML 時,盡量避免多餘的父元素。這需要反覆重寫與重構,才能寫出更少的 HTML。看看右邊這個例子:
<!-- Not so great -->
<span class="avatar">
<img src="...">
</span>
<!-- Better -->
<img class="avatar" src="...">
Markup 寫在 JavaScript 裡,不僅難找、也更難編輯,性能更是差。盡量避免在 JavaScript 裡撰寫 Markup。
.navbar
.header
.logo
.workspace
.content
.content__header
.content__body
.sidebar
.footer
.open
: drop-down.hover
: mouseover.selected
: multi-select.active
: slideshow, tab.current
: pager:
後面留一個空白。box-shadow
,inset
前方逗號後有留空白)。.5
,不要寫成 0.5
。#fff
。#fff
來取代 #ffffff
。input[type="text"]
。margin: 0;
而不是 margin: 0px;
。對於這裡使用的術語有任何問題嗎?請參考維基百科上關於層疊樣式表條目裡的語法小節。
/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
padding:15px;
margin:0px 0px 15px;
background-color:rgba(0, 0, 0, 0.5);
box-shadow:0 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}
/* Good CSS */
.selector,
.selector-secondary,
.selector[type="text"] {
padding: 15px;
margin: 0 0 15px;
background-color: rgba(0, 0, 0, .5);
box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}
相關的屬性宣告應以下列順序分組:
Positioning,與位置有關的宣告放最前面,因為這可以從正常文件順序裡移除元素,或是覆寫牽扯到 Box Model 的樣式。Box Model 放下一個。因為它決定元件的位置與尺寸。
其它只在元件內部起作用的屬性放最後,因為這不會影響前兩者。
關於屬性順序的完整列表,請參考 Recess、idiomatic-css #declaration-order。
.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}
將 Media Query 與其最相關的規則放在一起。別把他們放在 CSS 檔案最後面,或是獨立成另外的樣式表。這樣只會讓之後接手的人錯過他們。右邊是個經典範例。
.element { ... }
.element-avatar { ... }
.element-selected { ... }
@media (min-width: 480px) {
.element { ...}
.element-avatar { ... }
.element-selected { ... }
}
使用帶有各家廠商前綴的屬性時,縮排每個屬性、垂直對齊,以便多行編輯。
/* Prefixed properties */
.selector {
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
當一組規則只包含單條宣告的的情況裡,考慮移除換行;寫成單行的可讀性更高、更容易編輯。任何包含多條宣告的一組規則應該要分為多行。
這麼分的關鍵因素是錯誤偵測─比如:CSS Validator 表示 183 行有語法錯誤。如果是單行宣告便就是那行,多條宣告沒分行的話則會找到抓狂。
/* Single declarations on one line */
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }
/* Multiple declarations, one per line */
.sprite {
display: inline-block;
width: 16px;
height: 15px;
background-image: url(../img/sprite.png);
}
.icon { background-position: 0 0; }
.icon-home { background-position: 0 -20px; }
.icon-account { background-position: 0 -40px; }
宣告盡量少用簡寫,最好明確的將所有的值寫出來。過度濫用簡寫的特性包含:
padding
margin
font
background
border
border-radius
通常我們只需設定需要的值,簡寫會設定到多餘的值。舉例來說,HTML 標題只會設定 top 與 bottom margin,所以只要更改這兩個值即可。濫用特性縮寫只會寫出更差的程式碼,也會有無謂的覆寫與不預期的副作用。
Mozilla Developer Network 有篇很好的專文,給不熟悉記法與行為的開發者:特性簡寫。
/* Bad example */
.element {
margin: 0 0 10px;
background: red;
background: url("image.jpg");
border-radius: 3px 3px 0 0;
}
/* Good example */
.element {
margin-bottom: 10px;
background-color: red;
background-image: url("image.jpg");
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
避免無謂的巢狀。可用巢狀不表示都要用巢狀。
只在多元素需要巢狀,或是需要在父元素下增加樣式的場景下使用巢狀。
// Without nesting
.table > thead > tr > th { … }
.table > thead > tr > td { … }
// With nesting
.table > thead > tr {
> th { … }
> td { … }
}
程式碼是由人來撰寫與維護的。
確保程式碼精準描述、有良好的註解,讓別人看起來是很親切。
好的註解傳遞意圖、意境。
註解不要只是重複元件或是 Class 的名稱。
長註解記得使用完整的句子,一般的筆記用簡潔的用語。
/* Bad example */
/* Modal header */
.modal-header {
...
}
/* Good example */
/* Wrapping element for .modal-title and .modal-close */
.modal-header {
...
}
.btn
和 .btn-danger
)。.btn
很好,但 .s
不代表任何元素。.js-*
Class 來標示行為(相對樣式來說),這些類別放在另外的 CSS。/* Bad example */
.t { ... }
.red { ... }
.header { ... }
/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }
[class^="..."]
)。大家都知道這會影響到瀏覽器的性能。延伸閱讀:
/* Bad example */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }
/* Good example */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }
/*
* Component section heading
*/
.element { ... }
/*
* Component section heading
*
* Sometimes you need to include optional context for the entire component. Do that up here if it's important enough.
*/
.element { ... }
/* Contextual sub-component or modifer */
.element-heading { ... }
羅列目前較有 z-index 問題如下:
基本 z-index
= order 數字 * 1000,
有異動需更新文件。
使用下列設定來設定編輯器,避免掉常見的程式碼不一致和醜陋的 diffs:
考慮將以上偏好應用到專案的 .editorconfig
檔案並撰寫文件說明。舉個例子,參考 Bootstrap 的 .editorconfig
。瞭解更多內容,請參考 editorconfig.org。