前端普適性規范
黃金定律
不論有多少人共同參與同一項目,一定要確保每一行代碼都像是同一個人編寫的。
永遠一致同一套編碼規范,可以是這里列出的,也可以是你自己總結的。如果您發現本規范中有任何錯誤,敬請在問題中指正。
前端普適性規范
項目命名
項目名全部采用小寫方式,以中划線分隔,禁止駝峰式命名。例如:my-project-name
文件命名
文件命名參照項目命名規則。示例:error-report.html
有復數結構時,要采用復數命名法,例如:腳本,樣式,圖像,數據模型
文件名中只規范小寫英文字母az,排序數字09或間隔符-組成,禁止包含特殊符號,某些空格,$等
為了醒目,某些說明文件的文件名,可以使用大寫字母,例如:README,LICENSE
為更好的表達語義,文件名使用英文名詞命名,或英文簡寫。
永久命名帶有廣告等英文的單詞,例如ad,adv,adver,advertising,防止該模塊被瀏覽器當成垃圾廣告過濾掉。任何文件的命名均如此。
文件常用命名:
-
index.shtml引導頁&首頁
-
main.shtml主頁
-
download.shtml下載頁面
-
act.html活動列表頁面
-
video.html視頻
-
cdkey.html CDKEY頁面
-
base.css基本樣式
-
layout.css框架布局
-
module.css模塊樣式
-
global.css局部樣式
-
font.css字體樣式
-
index.css首頁樣式
-
link.css鏈接樣式
-
print.css打印樣式
HTML 規范
語法
使用四個空格的縮進,這是保證代碼在各種環境下顯示一致的唯一方式。
嵌套的節點應該縮進(四個空格)。
在屬性上,使用雙引號,不要使用單引號。
不要在自動閉合標簽結尾處使用斜線 / - HTML5 規范 指出他們是可選的。
<img src="images/logo.png" alt="Company">
不要忽略可選的關閉標簽(例如,</li> 和 </body>)。
HTML5 doctype
在每個 HTML 頁面開頭使用這個簡單地 doctype 來啟用標准模式,使其每個瀏覽器中盡可能一致的展現。
雖然 doctype 不區分大小寫,但是按照慣例,doctype 大寫
<!DOCTYPE html>
語言屬性
<html lang="en">
</html>
字符編碼
通過明確聲明字符編碼,能夠確保瀏覽器快速並容易的判斷頁面內容的渲染方式。這樣 做的好處是,可以避免在 HTML 中使用字符實體標記(character entity),從而全部與 文檔編碼一致(一般采用 UTF-8 編碼)。
<meta charset="UTF-8">
IE 兼容模式
IE 支持通過特定的 標簽來確定繪制當前頁面所應該采用的 IE 版本。除非有強烈 的特殊需求,否則最好是設置為 edge mode,從而通知 IE 采用其所支持的最新的模 式。
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
響應式
<meta name="viewport" content="width=device-width, initial-scale=1">
引入 CSS 和 JavaScript
根據 HTML5 規范, 通常在引入 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 標准和語義,但是不應該以浪費實用性作為代價。任何時候都要用盡量小的復雜度和盡量少的標簽來解決問題。
減少標簽數量
在編寫 HTML 代碼時,需要盡量避免多余的父節點。很多時候,需要通過迭代和重構來使 HTML 變得更少。參考下面的示例:
<!-- Not so great -->
<span class="avatar">
<img src="...">
</span>
<!-- Better -->
<img class="avatar" src="...">
屬性順序
HTML 屬性應該按照特定的順序出現以保證易讀性。
-
class
-
id
-
name
-
data-*
-
src, for, type, href, value , max-length, max, min, pattern
-
placeholder, title, alt
-
aria-*, role
-
required, readonly, disabled
class 是為高可復用組件設計的,理論上他們應處在第一位。id 更加具體而且應該盡量少使用(例如, 頁內書簽),所以他們處在第二位。
Boolean 屬性
Boolean 屬性指不需要聲明取值的屬性。XHTML 需要每個屬性聲明取值,但是 HTML5 並不需要。
一個元素中 Boolean 屬性的存在表示取值 true,不存在則表示取值 false。
簡而言之,不要為 Boolean 屬性添加取值。
<input type="text" disabled>
JavaScript 生成標簽
在 JavaScript 文件中生成標簽讓內容變得更難查找,更難編輯,性能更差。應該盡量避免這種情況的出現。
CSS 規范
語法
使用四個空格的縮進,這是保證代碼在各種環境下顯示一致的唯一方式。
使用組合選擇器時,保持每個獨立的選擇器占用一行。
為了代碼的易讀性,在每個聲明的左括號前增加一個空格。
聲明塊的右括號應該另起一行。
每條聲明 : 后應該插入一個空格。
每條聲明應該只占用一行來保證錯誤報告更加准確。
所有聲明應該以分號結尾。雖然最后一條聲明后的分號是可選的,但是如果沒有他,你的代碼會更容易出錯。
逗號分隔的取值,都應該在逗號之后增加一個空格。
不要在顏色值 rgb() rgba() hsl() hsla()和 rect() 中增加空格,並且不要帶有取值前面不必要的 0 (比如,使用 .5 替代 0.5)。
所有的十六進制值都應該使用小寫字母,例如 #fff。因為小寫字母有更多樣的外形,在瀏覽文檔時,他們能夠更輕松的被區分開來。
盡可能使用短的十六進制數值,例如使用 #fff 替代 #ffffff。
為選擇器中的屬性取值添加引號,例如 input[type="text"]。他們只在某些情況下可有可無,所以都使用引號可以增加一致性。
不要為 0 指明單位,比如使用 margin: 0; 而不是 margin: 0px;。
/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
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"] {
margin-bottom: 15px;
background-color: rgba(0,0,0,.5);
box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}
聲明順序
相關的屬性聲明應該以下面的順序分組處理:
Positioning
Box model 盒模型
Typographic 排版
Visual 外觀
Positioning 處在第一位,因為他可以使一個元素脫離正常文本流,並且覆蓋盒模型相關的樣式。盒模型緊跟其后,因為他決定了一個組件的大小和位置。
其他屬性只在組件內部起作用或者不會對前面兩種情況的結果產生影響,所以他們排在后面。
.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;
}
Don't use @import
與<link>相比,@import較慢,增加額外的頁面請求,並可能導致其他不可預見的問題。
<!-- Use link elements -->
<link rel="stylesheet" href="core.css">
<!-- Avoid @imports -->
<style>
@import url("more.css");
</style>
媒體查詢位置
盡量將媒體查詢的位置靠近他們相關的規則。不要將他們一起放到一個獨立的樣式文件中,或者丟在文檔的最底部。這樣做只會讓大家以后更容易忘記他們。這里是一個典型的案例。
.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 驗證程序顯示你在 183 行有一個語法錯誤,如果是一個單條聲明的行,那就是他了。在多個聲明的情況下,你必須為哪里出錯了費下腦子。
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }
屬性簡寫
盡量不使用屬性簡寫的方式,屬性簡寫需要你必須顯式設置所有取值。常見的屬性簡寫濫用包括:
-
padding
-
margin
-
font
-
background -border -border-radius
大多數情況下,我們並不需要設置屬性簡寫中包含的所有值。例如,HTML 頭部只設置上下的 margin,所以如果需要,只設置這兩個值。過度使用屬性簡寫往往會導致更混亂的代碼,其中包含不必要的重寫和意想不到的副作用。
/* 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;
}
Less 和 Sass 中的嵌套
避免不必要的嵌套。可以進行嵌套,不意味着你應該這樣做。只有在需要給父元素增加樣式並且同時存在多個子元素時才需要考慮嵌套。
// Without nesting
.table > thead > tr > th { … }
.table > thead > tr > td { … }
// With nesting
.table > thead > tr {
> th { … }
> td { … }
}
代碼注釋
代碼是由人來編寫和維護的。保證你的代碼是描述性的,包含好的注釋,並且容易被他人理解。好的代碼注釋傳達上下文和目標。不要簡單地重申組件或者 class 名稱。
class 命名
保持 class 命名為全小寫,可以使用短划線(不要使用下划線和 camelCase 命名)。短划線應該作為相關類的自然間斷。(例如,.btn 和 .btn-danger)。
避免過度使用簡寫。.btn 可以很好地描述 button,但是 .s 不能代表任何元素。
class 的命名應該盡量短,也要盡量明確。
使用有意義的名稱;使用結構化或者作用目標相關,而不是抽象的名稱。
命名時使用最近的父節點或者父 class 作為前綴。
使用 .js-* 來表示行為(相對於樣式),但是不要在 CSS 中包含這些 class。
選擇器
使用 class 而不是通用元素標簽來優化渲染性能。
避免在經常出現的組件中使用一些屬性選擇器 (例如,[class^="..."])。瀏覽器性能會受到這些情況的影響。
減少選擇器的長度,每個組合選擇器選擇器的條目應該盡量控制在 3 個以內。
只在必要的情況下使用后代選擇器 (例如,沒有使用帶前綴 classes 的情況).
代碼組織
以組件為單位組織代碼。
制定一個一致的注釋層級結構。
使用一致的空白來分割代碼塊,這樣做在查看大的文檔時更有優勢。
當使用多個 CSS 文件時,通過組件而不是頁面來區分他們。頁面會被重新排列,而組件移動就可以了。
編輯器配置
根據以下的設置來配置你的編輯器,將這些設置應用到項目的 .editorconfig 文件,來避免常見的代碼不一致和丑陋的 diffs。
-
使用四個空格的縮進。
-
在保存時刪除尾部的空白字符。
-
設置文件編碼為 UTF-8。
-
在文件結尾添加一個空白行。
JS 規范
語法
使用四個空格的縮進,這是保證代碼在各種環境下顯示一致的唯一方式。
聲明之后一律以分號結束, 不可以省略
完全避免 == != 的使用, 用嚴格比較條件 === !==
eval 非特殊情況, 禁用!!!
with 非特殊情況, 禁用!!!
單行長度,理論上不要超過80列,不過如果編輯器開啟"自動換行"的話可以不考慮單行長度
接上一條,如果需要換行,存在操作符的情況,一定在操作符后換行,然后換的行縮進4個空格
這里要注意,如果是多次換行的話就沒有必要繼續縮進了,比如說下面這種就是最佳格式。
if (typeof qqfind === "undefined" ||
typeof qqfind.cdnrejected === "undefined" ||
qqfind.cdnrejected !== true) {
url = "http://pub.idqqimg.com/qqfind/js/location4.js";
} else {
url = "http://find.qq.com/js/location4.js";
}
空行
方法之間加
單行或多行注釋前加
邏輯塊之間加空行增加可讀性
變量命名
標准變量采用駝峰標識
使用的ID的地方一定全大寫
使用的URL的地方一定全大寫, 比如說 reportURL
涉及Android的,一律大寫第一個字母
涉及iOS的,一律小寫第一個,大寫后兩個字母
常量采用大寫字母,下划線連接的方式
構造函數,大寫第一個字母
var thisIsMyName;
var goodID;
var AndroidVersion;
var iOSVersion;
var MAX_COUNT = 10;
function Person(name) {
this.name = name
}
字符常量
一般情況下統一使用單引號
null的使用場景
初始化可能以后分配對象值的變量
與一個可能或可能沒有對象值的初始化變量進行比較
傳入一個預期對象的函數
從預期對象的函數返回
不適合null的使用場景
不要使用null來測試是否提供參數
不要測試值為null的未初始化變量
undefined使用場景
永遠不要直接使用undefined進行變量判斷
使用字符串 "undefined" 對變量進行判斷
// Bad
var person;
console.log(person === undefined); //true
// Good
console.log(typeof person); // "undefined"
對象字面量
// Bad
var team = new Team();
team.title = "AlloyTeam";
team.count = 25;
// Good
var team = {
title: "AlloyTeam",
count: 25
};
數組聲明
// Bad
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);
// Good
var colors = [ "red", "green", "blue" ];
var numbers = [ 1, 2, 3, 4 ];
單行注釋
雙斜線后,必須跟注釋內容保留一個空格
與下一行代碼縮進保持一致
可位於一個代碼行的末尾,雙斜線距離分號四個空格
// Good
if (condition) {
// if you made it here, then all security checks passed
allowed();
}
var zhangsan = "zhangsan"; // 雙斜線距離分號四個空格,雙斜線后始終保留一個空格
多行注釋格式
最少三行
前邊留空一行
/**
* 注釋內容與星標前保留一個空格
*/
何時使用多行注釋格式
難於理解的代碼段
可能存在錯誤的代碼段
瀏覽器特殊的HACK代碼
業務邏輯強相關的代碼
想吐槽的產品邏輯, 合作同事
文檔注釋
各類標簽 @param @method 等 參考 http://usejsdoc.org/
用於:方法、構造函數、對象
/**
* here boy, look here , here is girl
* @method lookGril
* @param {Object} balabalabala
* @return {Object} balabalabala
*/
括號對齊
標准示例 括號前后有空格,花括號起始不另換行,結尾新起一行
花括號必須要,即使內容只有一行
涉及 if for while do...while try...catch...finally 的地方都必須使用花括號,即使內容只有一行
if else 前后留有空格
if (condition) { doSomething(); } else { doSomethingElse(); }
switch
switch和括號之間有空格,case需要縮進,break之后跟下一個case中間留一個空白行
花括號必須要, 即使內容只有一行。
switch 的 falling through 一定要有注釋特別說明,no default 的情況也需要注釋特別說明況
switch (condition) { case "first": // code break; case "second": // code break; default: // code }
for
普通for循環, 分號后留有一個空格, 判斷條件等內的操作符兩邊不留空格
前置條件如果有多個,逗號后留一個空格
for-in 一定要有 hasOwnProperty 的判斷, 否則 JSLint 或者 JSHint 都會有一個 warn
for (i=0, len=values.length; i<len; i++) { process(values[i]); } var prop; for (prop in object) { // 注意這里一定要有 hasOwnProperty 的判斷, 否則 JSLint 或者 JSHint 都會有一個 warn ! if (object.hasOwnProperty(prop)) { console.log("Property name is " + prop); console.log("Property value is " + object[prop]); } }
變量聲明
所有函數內變量聲明放在函數內頭部,只使用一個 var(多了JSLint報錯), 一個變量一行, 在行末跟注釋, 注釋啊,注釋啊,親
函數聲明
一定先聲明再使用, 不要利用 JavaScript engine的變量提升特性, 違反了這個規則 JSLint 和 JSHint都會報 warn
function declaration 和 function expression 的不同,function expression 的()前后必須有空格,而function declaration 在有函數名的時候不需要空格,沒有函數名的時候需要空格。
函數調用括號前后不需要空格
立即執行函數的寫法, 最外層必須包一層括號
"use strict" 決不允許全局使用, 必須放在函數的第一行, 可以用自執行函數包含大的代碼段, 如果 "use strict" 在函數外使用, JSLint 和 JSHint 均會報錯
function doSomething(item) { // do something } var doSomething = function (item) { // do something } // Good doSomething(item); // Bad: Looks like a block statement doSomething (item); // Good (function() { "use strict"; function doSomething() { // code } })();