黄金定律:永远遵守一套编码规范,确保每一行代码就像一个人编写的一样。
HTML
语法:
- 用两个空格代表制表符(保证所有环境下,获取一致性展现)
- 嵌套元素缩进一次(两个空格)
- 对于属性的定义,全部使用双引号,绝对不要使用单引号。
- 不要在自闭合(self-closing)元素末尾添加斜线(HTML5中说明这是可选的)
- 不要省略可选的结束标签(closing tag)
HTML5 doctype
根据HTML5规范:强烈建议为html根元素设置lang属性,从而为文档设置正确的语言。如下:
<html
lang=
"en-us"
>
<!-- ... -->
</html>
IE兼容模式
IE支持通过特定的<meta>标签来确定绘制当前页面应该采用的IE版本。除非有特别强烈要求,否则最好使用edge mode,从而通知IE采用其所支持的最新模式。
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=Edge"
>
字符编码
通过明确的字符编码能够确保浏览器快速并容易地判断页面内容的渲染方式。好处:避免在HTML中使用字符实体标记(character entity),从而全部与文档编码一致(一般采用UTF-8编码)
<head>
<meta
charset=
"UTF-8"
>
</head>
引入CSS和JavaScript文件
根据HTML5规范,在引入CSS和JavaScript文件时一般不需要指定type属性,因为text/css和type/javascript分别是他们的默认属性
HTML5 spec links
- Using link
- Using style
- Using script
<!-- External CSS -->
<link
rel=
"stylesheet"
href=
"code-guide.css"
>
<!-- In-document CSS -->
<style>
/* ... */
</style>
<!-- JavaScript -->
<script
src=
"code-guide.js"
>
</script>
实用为王
尽量遵循HTML标准和语义,但是不要以牺牲实用性为代价,任何时候都尽量使用最少的标签保持最小的复杂度
属性顺序
HTML属性应当按照以下顺序依次排列确保代码的易读性。
- class
- id, name
- data-*
- src, for, type, href, value
- title, alt
- role, aria-*
class用于标识高度复用组件,因此应该排在首位。id用于标识具体组件,应当谨慎使用(例如页面内的书签),因此排在第二位。
例:
<a
class=
"..."
id=
"..."
data-toggle=
"modal"
href=
"#"
>
Example link
</a>
<input
class=
"form-control"
type=
"text"
>
<img
src=
"..."
alt=
"..."
>
布尔(boolean)型属性
布尔型属性可以在声明时不赋值。XHTML规范要求为其赋值,但是HTML5规范不需要。
元素的布尔型属性如果有值,就是true,如果没有值就是false。
<input
type=
"text"
disabled
>
<input
type=
"checkbox"
value=
"1"
checked
>
<select>
<option
value=
"1"
selected
>
1
</option>
</select>
减少标签数量
编写HTML代码时,尽量避免多余的父元素。很多时候,这需要迭代和重构来实现。例如:
<!-- Not so great -->
<span
class=
"avatar"
>
<img
src=
"..."
>
</span>
<!-- Better -->
<img
class=
"avatar"
src=
"..."
>
JavaScript生成的标签
通过JavaScript生成的标签让内容变得不容易查找、编辑、并且降低性能。因此尽量避免。
CSS
语法
- 用两个空格代表制表符(tab)--这是唯一能够保证在所有环境下获得一致展现
- 为选择器分组时,将单独的选择器单独放一行
- 为了代码的易读性,每一个声明块的左花括号前添加一个空格。
- 声明块的右边花括号应当单独成行
- 每台声明语句的 :后应该插入一个空格
- 为了获取更准确的错误报告,每条声明都应该单独占一行。
- 所有的声明语句都以分号结尾。即使最后一条声明后面的分号是可以省略的
- 对于逗号分隔的属性值,每个逗号后面都应该插入一个空格(如, box-show)
- 不要在rgb(), rgba(), hsl(), hsla()或rect()值的内部的逗号后面插入空格。这样有利于区分。
- 对于属性值或者颜色参数,省略小于1的小数前面的0(如:.5代替0.5)
- 十六进制应该全部小写,例如,#fff。在扫描文档时,小写字符易于分辨
- 尽量使用简写形式的十六进制值,例如用#fff代替#ffffff
- 为选择器的属性添加双引号,例如, input[type="text"]。
- 避免为0值指定单位,例如 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
:
0px
1px
2px
#CCC
,
inset
0
1px
0
#FFFFFF
}
/* Good CSS */
.selector
,
.selector-secondary
,
.selector
[
type
=
"text"
]
{
padding
:
15px
;
margin-bottom
:
15px
;
background-color
: rgba(
0
,
0
,
0
,
.5
);
box-shadow
:
0
1px
2px
#ccc
,
inset
0
1px
0
#fff
;}
声明顺序
相关的属性声明应当归为一组,并按照如下顺序:
- Positioning
- Box model
- Typegraphic
- Visual
由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在首位。盒模型排在第二位,因为他决定了组件的尺寸和位置
其他属性只是影响组件内部(inside)或者是不影响前两组属性,因此排在后面。
.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
;}
不要使用@import
与<link>标签相比,@import指令要慢得多,不光增加了额外的请求次数,还会导致不可预料的问题。替换方法有以下几种
- 使用多个<link>元素
- 通过Sass或者Less类似的CSS预处理器将多个CSS文件编译为一个文件
- 通过Rails、jekyll或者其他系统提供的CSS文件合并功能
<!-- Use link elements -->
<link
rel=
"stylesheet"
href=
"core.css"
>
<!-- Avoid @imports -->
<style>
@import
url("more.css")
;
</style>
媒体查询(Media query)的位置
将媒体查询放在尽可能相关规则的附近。不要将它们打包放在一个单一样式文件中或者文档底部。如果分开了,将来会被大家遗忘。
.element
{
...
}
.element-avatar
{
...
}
.element-selected
{
...
}
@media
(min-width:
480px
) {
.element
{
...
}
.element-avatar
{
...
}
.element-selected
{
...
}}
带前缀的属性
当使用特定厂商的带有前缀的属性时,通过缩进方式,让每个属性的值在垂直方向对齐,便于多行编辑。
在Textmate中,
使用
Text → Edit Each Line in Selection
(⌃⌘A)。在 Sublime Text 2 中,使用
Selection → Add Previous Line
(⌃⇧↑) 和
Selection → Add Next Line
(⌃⇧↓)。
/* Prefixed properties */
.selector
{
-webkit-box-shadow
:
0
1px
2px
rgba(
0
,
0
,
0
,
.15
);
box-shadow
:
0
1px
2px
rgba(
0
,
0
,
0
,
.15
);}
单行规则说明
对于只包含一条声明的样式,为了易读性和快速编辑,建议将语句放在同一行。对于多条声明的样式,还是应当将声明将声明分为多行。
/* 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
- fount
- background
- border
- border-radius
/* 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和Saas中的嵌套
避免不必要的嵌套。虽然我们可以使用嵌套,但并不意味则应该使用嵌套。只有在必须将样式必须限制在父元素内部(后代选择器),并且存在多个需要嵌套元素才能使用嵌套。
Less和Sass操作符
为了提高可读性,在圆括号中的数学表达式的数值和操作符之间均添加一个空格
// Bad example
.element
{
margin
:
10px
0
@
variable
*
2
10px
;}
// Good example
.element
{
margin
:
10px
0
(
@
variable
*
2
)
10px
;}
注释
请确保你的代码可以能够自述。注释良好并易于他人理解。好的注释能够传达上下文消息和代码目的
/* Bad example */
/* Modal header */
.modal-header
{
...
}
/* Good example */
/* Wrapping element for .modal-title and .modal-close */
.modal-header
{
...
}
class命名
- class名称中只能出现小写字符和破折号(dashe)(不是下划线,也不是驼峰命名)。破折号应当用于相关的class命名(类似于命名空间,例如, .btn和 .btn-danger)
- 避免过度简写,如.btn代表button但是.s 不代表任何元素
- class名称应当尽可能的短,并且意义明确
- 使用有意义的名称。使用有组织或者目的明确的名称,不要使用表现形式(presentational)的名称
- 基于最近的父class或基本(base)class作为新的Class前缀
- 使用 .js-* class来标识行为(与样式相对),并且最好不要讲这些样式class包含到css中。
/* Bad example */
.t
{
...
}
.red
{
...
}
.header
{
...
}
/* Good example */
.tweet
{
...
}
.important
{
...
}
.tweet-header
{
...
}
选择器
- 对于通用元素使用class,这样有利于渲染性能的优化
- 对于经常出现的组件,避免使用属性选择器(例如, [class^="..."])。浏览器的性能会受这些因素的影响
- 选择器要尽可能短,并且限制组成选择器的个数,建议不要超过3个
- 只有在必要的时候才将class限制在最近的父元素内(也就是后代选择器)(例如不使用带前缀的clas时--前缀类似于命名空间)
/* Bad example */
span
{
...
}
.page-container
#stream
.stream-item
.tweet
.tweet-header
.username
{
...
}
.avatar
{
...
}
/* Good example */
.avatar
{
...
}
.tweet-header
.username
{
...
}
.tweet
.avatar
{
...
}
代码组织
- 以组件为单位组织代码段
- 指定一致的注释规范
- 使用一致的空白符将代码分割成块,这样有利于扫描较大文档
- 如果使用了多个css文件,将其按照组件而非页面的形式分拆,因为页面会被重组,而组件只会被移动。
/* * 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
{
...
}
编辑器配置
将你的编辑器按照下面的配置进行设置,以免常见的代码不一致和差异:
- 使用两个空格代替制表符(soft-tab即用空格代表tab符)
- 保存文件是,删除尾部的空白符
- 设置文件编码UTF-8
- 在文件为添加空白行
参照文档并将这些配置信息添加到项目的.editorconfig文件中