前言
这是一份旨在增强团队的开发协作,提高代码质量和打造开发基石的编码风格规范,其中包含了 HTML, JavaScript 和 CSS/SCSS 这几个部分。我们知道,当一个团队开始指定并实行编码规范的话,错误就会变得更加显而易见。如果一段特定的代码不符合规范的话,它有可能只是代码风格错误,而也有可能会是
bug。早期指定规范就使得代码审核得以更好的开展,并且可以更精确的地定位到错误。只要开发者们能够保证源代码源文件都严格遵循规范,那接下去所使用的混淆、压缩和编译工具则可投其所好不尽相同。
要讲的依次为:
- 前端编码规范(1)—— 一般规范
- 前端编码规范(2)—— HTML规范
- 前端编码规范(3)—— JavaScript规范
- 前端编码规范(4)—— CSS规范
一般规范
以下章节列举了一些可应用在 HTML, JavaScript 和 CSS/SCSS 上的通用规则。
文件/资源命名
- 使用点分隔符(.)来区分文件名中带有清晰意义的元数据(如 .min.js, .min.css)
- 使用减号(-)是用来分隔文件名(如 big-black-background.jpg)
- 文件命名总是以字母开头而不是数字
- 资源的字母名称必须全为小写
在 web 项目中,所有的文件名应该都遵循同一命名约定。以可读性而言,减号(-)是用来分隔文件名的不二之选。同时它也是常见的 URL 分隔符(i.e. //example.com/blog/my-blog-entry
or //s.example.com/images/big-black-background.jpg),所以理所当然的,减号应该也是用来分隔资源名称的好选择。
请确保文件命名总是以字母开头而不是数字。而以特殊字符开头命名的文件,一般都有特殊的含义与用处(比如 compass[1] 中的下划线就是用来标记跳过直接编译的文件用的)。
资源的字母名称必须全为小写,这是因为在某些对大小写字母敏感的操作系统中,当文件通过工具压缩混淆后,或者人为修改过后,大小写不同而导致引用文件不同的错误,很难被发现。
还有一些情况下,需要对文件增加前后缀或特定的扩展名(比如 .min.js, .min.css),抑或一串前缀(比如 3fa89b.main.min.css)。这种情况下,建议使用点分隔符来区分这些在文件名中带有清晰意义的元数据。
不推荐
MyScript.js |
推荐
my-script.js |
协议
不要指定引入资源所带的具体协议。
当引入图片或其他媒体文件,还有样式和脚本时,URLs 所指向的具体路径,不要指定协议部分(http:, https:),除非这两者协议都不可用。
不指定协议使得 URL 从绝对的获取路径转变为相对的,在请求资源协议无法确定时非常好用,而且还能为文件大小节省几个字节。
不推荐
|
推荐
|
文本缩进
一次缩进两个空格。
<ul>
<li>Fantastic</li>
<li>Great</li>
<li>
<a href="#">Test</a>
</li>
</ul>
CSS 代码
@media screen and (min-width: 1100px) {
body {
font-size: 100%;
}
}
JavaScript 代码
注释
注释是你自己与你的小伙伴们了解代码写法和目的的唯一途径。特别是在写一些看似琐碎的无关紧要的代码时,由于记忆点不深刻,注释就变得尤为重要了。
编写自解释代码只是一个传说,没有任何代码是可以完全自解释的。而代码注释,则是永远也不嫌多。
当你写注释时一定要注意:不要写你的代码都干了些什么,而要写你的代码为什么要这么写,背后的考量是什么。当然也可以加入所思考问题或是解决方案的链接地址。
不推荐 | 推荐 |
一些注释工具可以帮助你写出更好的注释。JSDoc 或 YUIDoc 就是用来写 JavaScript 注释用的。你甚至可以使用工具来为这些注释生成文档,这也是激励开发者们写注释的一个好方法,因为一旦有了这样方便的生成文档的工具,他们通常会开始花更多时间在注释细节上。
HTML规范
文档类型
推荐使用 HTML5 的文档类型申明:<!DOCTYPE html>.
(建议使用 text/html 格式的 HTML。避免使用 XHTML。XHTML 以及它的属性,比如 application/xhtml+xml 在浏览器中的应用支持与优化空间都十分有限)。
HTML 中最好不要将无内容元素的标签闭合,例如:使用 <br> 而非 <br />.
属性顺序
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="...">
HTML 验证
一般情况下,建议使用能通过标准规范验证的 HTML 代码,除非在性能优化和控制文件大小上不得不做出让步。
使用诸如 W3C HTML validator 这样的工具来进行检测。
规范化的 HTML 是显现技术要求与局限的显著质量基线,它促进了 HTML 被更好地运用。
不推荐
<title>Test</title> |
推荐
<!DOCTYPE html> |
语义化
根据元素(有时被错误地称作“标签”)其被创造出来时的初始意义来使用它。打个比方,用 heading 元素来定义头部标题,p 元素来定义文字段落,用 a 元素来定义链接锚点,等等。
HTML元素的排序规则,一般我们使用的HTML元素包括:div, p, ul, table, span, input, select。 基本上div, table,
ul, p都属于结构性比较强的元素,而span, input则是比较弱的元素,因此不允许有span嵌套div, table等等的情况出现, span可以嵌套input,
可以嵌套span。程序员在写页面的时候可以先不考虑界面呈现,按照这样的规则,把数据直接绑定到HTML元素的节点上。
有根据有目的地使用 HTML 元素,对于可访问性、代码重用、代码效率来说意义重大。
HTML注释
1.每一独立部分都要表明注释。例如:
<!--右边 begin--> <!--右边end-->
<!--左边 begin--><!--左边end-->
<!--头部 begin--> <!--头部end-->
<!--讲师列表 begin--> <!--讲师列表end-->
2.注释要用描述性语言,能够清楚的表达每一部分的意思
<!--页面标头 begin-->
<div id="top_frame">
</div>
<!--页面内容 begin-->
<div id="main_frame">
<!--菜单区域 begin-->
<div id="menu_zone">
<%=GetMenuHtml()%>
</div>
<!--菜单区域 end-->
<!--折叠区域 begin-->
<div id="switch">
<span class="_switch"></span>
</div>
<!--折叠区域 end-->
<!--内容区域 begin-->
<div id="right_frame">
<div id="main_zone">
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
</div>
</div>
<!--内容区域 end-->
</div>
<!--页面内容 end-->
关注点分离
为了使文档成为可维护的干净整洁的代码,我们要尽可能的将信息(HTML 结构)、外观(CSS)和行为(JavaScript)分离开来,并使三者之间没有太多的交互和联系。
即在文档和模板中只包含结构性的 HTML;而将所有表现代码,移入样式表中;将所有动作行为,移入脚本之中。 为使得它们之间的联系尽可能的小,在文档和模板中也尽量少地引入样式和脚本文件。
清晰的分层意味着:
- 不使用超过一到两张样式表(i.e. main.css, vendor.css)
- 不使用超过一到两个脚本(学会用合并脚本)
- 不使用行内样式(<style>.no-good {}</style>)
- 不在元素上使用 style 属性(<hr style="border-top: 5px solid black">)
- 不使用行内脚本(<script> alert('no good')</script>)
- 不使用表象元素(i.e. <b>, <u>, <center>, <font>, <b>)
- 不使用表象 class 名(i.e. red, left, center)
不推荐
<!DOCTYPE html> |
推荐
<!DOCTYPE html> |
HTML 内容至上
不要让非内容信息污染了你的 HTML。现在貌似有一种倾向:通过 HTML 来解决设计问题,这是显然是不对的。HTML 就应该只关注内容。
不要引入一些特定的 HTML 结构来解决一些视觉设计问题 不要将 img 元素当做专门用来做视觉设计的元素 以下例子展示了误将 HTML 用来解决设计问题的这两种情况:
不推荐
<!-- We should not introduce an additional element just to solve a design problem --> .text-box > .square { |
推荐
<!-- That's clean markup! --> /* We use a :before pseudo element to solve the design problem of placing a colored square in front of the text content */ |
图片和 SVG 图形能被引入到 HTML 中的唯一理由是它们呈现出了与内容相关的一些信息。
不推荐
<!-- Content images should never be used for design elements! --> |
推荐
<!-- That's clean markup! --> /* We use a :before pseudo element with a background image to solve the problem */ |
HTML注意事项
Type 属性
省略样式表与脚本上的 type 属性。鉴于 HTML5 中以上两者默认的 type 值就是 text/css 和 text/javascript,所以 type
属性一般是可以忽略掉的。甚至在老旧版本的浏览器中这么做也是安全可靠的。
不推荐
<link rel="stylesheet" href="main.css" type="text/css"> |
推荐
<link rel="stylesheet" href="main.css"> |
HTML 引号
使用双引号(“”) 而不是单引号(”) 。
不推荐
<div class='news-article'></div> |
推荐
<div class="news-article"></div> |
属性值
属性一率小写,宽度、高度等要带上“px”
<img height="60px" width="760px" src="data:images/logo.gif"/>
给所有的属性赋值
不推荐
<input „„ checked /> |
推荐
<input „„ checked= "checked"/> |
网页中图片优化: 一定要加alt属性,alt属性指定了当图片不能显示的时候就显示供替换文本。 内容最好与关键词相关。
<img src="data:images/gxseo_logo.gif" alt="中英商务合作"/>
一些小图标最好用.gif格式图片,比如说箭头,文章列表前的图标等,在CSS中做成背景。 这些小图标最好做一张图片,用CSS来定位。
语言属性
根据 HTML5 规范: 强烈建议为 html 根元素指定 lang 属性,从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音,有助于翻译工具确定其翻译时所应遵守的规则等等。
<html lang="zh-CN">
<!-- ... -->
</html>
IE 兼容模式
IE 支持通过特定的
标签来确定绘制当前页面所应该采用的 IE 版本。除非有强烈的特殊需求,否则最好是设置为 edge mode,从而通知 IE 采用其所支持的最新的模式。
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
字符编码
通过明确声明字符编码,能够确保浏览器快速并容易的判断页面内容的渲染方式。这样做的好处是,可以避免在 HTML 中使用字符实体标记(character entity),从而全部与文档编码一致(一般采用
UTF-8 编码)。
<head>
<meta charset="UTF-8">
</head>
JavaScript规范
变量声明
总是使用 var 来声明变量。如不指定 var,变量将被隐式地声明为全局变量,这将对变量难以控制。如果没有声明,变量处于什么定义域就变得不清(可以是在 Document
或 Window 中,也可以很容易地进入本地定义域)。所以,请总是使用 var 来声明变量。
采用严格模式带来的好处是,当你手误输入错误的变量名时,它可以通过报错信息来帮助你定位错误出处。
不推荐 | 推荐 |
变量名
- 变量名推荐使用驼峰法来命名(camelCase)
- 全局变量为大写 (UPPERCASE )
- 常量 (如 PI) 为大写 (UPPERCASE )
- 函数: 构造函数始终以大写字母开头,非构造函数以一个小写字母开头
- 变量名不要以 $ 作为开始标记,避免与很多 JavaScript 库冲突
全局命名空间污染与 IIFE
总是将代码包裹成一个 IIFE(Immediately-Invoked Function Expression),用以创建独立隔绝的定义域。这一举措可防止全局命名空间被污染。
IIFE 还可确保你的代码不会轻易被其它全局命名空间里的代码所修改(i.e. 第三方库,window 引用,被覆盖的未定义的关键字等等)。
不推荐 | 推荐 |
IIFE(立即执行的函数表达式)
无论何时,想要创建一个新的封闭的定义域,那就用 IIFE。它不仅避免了干扰,也使得内存在执行完后立即释放。
所有脚本文件建议都从 IIFE 开始。
立即执行的函数表达式的执行括号应该写在外包括号内。虽然写在内还是写在外都是有效的,但写在内使得整个表达式看起来更像一个整体,因此推荐这么做。
不推荐 | 推荐 |
加上严格验证,用下列写法来格式化你的 IIFE 代码:
如果你想引用全局变量或者是外层 IIFE 的变量,可以通过下列方式传参:
CSS规范
CSS盒模型
選擇器針對性
针对性由 a b c d 四组数字组成,按照以下的方式计算:
- 如果样式是在 HTML 代码中以 'style=...' 的内联样式的方式设置的,则将 a 组记为 1,b c d 三组均记为 0,否则 a 组为 0。
- 将选择器中 ID 属性的数量总合计入 b 组。
- 将选择器中其他属性(类/属性选择器)及伪类的数量总合计入 c 组。
- 将选择器中元素名及伪元素的数量总合计入 d 组。
- 伪元素如:first-line、:first-letter、:before、:after
- 伪类如anchor伪类(:link、:visited、hover、active)、:first-child、:lang
确定针对性的强弱时,根据各组的数字来计算。a 组数字大的针对性更强,当 a 组的数字相同时,比较 b 组数字的大小,以此类推,最终比较结果更大的针对性更强。
某一元素的多个规则集中,选择器的针对性越高,该规则集的权重也就越高。针对性相同的,后出现的规则集的权重更高。
* {} /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 *[id=ok] {} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
#xyz {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
style="..." /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
声明顺序
这是一个选择器内书写CSS属性顺序的大致轮廓。这是为了保证更好的可读性和可扫描重要。
作为最佳实践,我们应该遵循以下顺序(应该按照下表的顺序):
- 结构性属性:
- display
- position, left, top, right etc.
- overflow, float, clear etc.
- margin, padding
- 表现性属性:
- background, border etc.
- font, text
不推荐
.box {font-family: 'Arial', sans-serif;border: 3px solid #ddd;left: 30%;position: absolute;text-transform: uppercase;background-color: #eee;right: 30%;isplay: block;font-size: 1.5rem;overflow: hidden;padding: 1em;margin: 1em;} |
推荐
.box {display: block;position: absolute;left: 30%;right: 30%;overflow: hidden;margin: 1em;padding: 1em;background-color: #eee;border: 3px solid #ddd;font-family: 'Arial', sans-serif;font-size: 1.5rem;text-transform: uppercase;} |
ID和Class命名
ID和class(类)名总是使用可以反应元素目的和用途的名称,或其他通用名称。代替表象和晦涩难懂的名称。
尽管class(类)名和ID 的语义化对于计算机解析来说没有什么实际的意义,语义化的名称通常是正确的选择,因为它们所代表的信息含义,不包含表现的限制。
不推荐
.fw-800 { font-weight: 800;} |
推荐
.heavy { font-weight: 800; } |
合理的使用ID
应该始终考虑使用Class,而不是ID,除非只使用一次。 ID的样式不能被复用并且每个页面中你只能使用一次ID。
不推荐
#content .title { font-size: 2em; } |
推荐
.content .title { font-size: 2em; } |
另一个反对使用ID的观点是含有ID选择器权重很高。 一个只包含一个ID选择器权重高于包含1000个class(类)名的选择器,这使得它很奇怪。
/*这个选择器权重高于下面的选择器*/
#content .title { color: red; }
/*than this selector!*/
html body div.content.news-content .title.content-title.important { color: blue; }
缩写属性
CSS提供了各种缩写属性(如 font 字体)应该尽可能使用, 使用缩写属性对于代码效率和可读性是有很有用的。
常见的简写属性声明:padding、margin、font、background、border、border-radius,如下所示
padding margin
一般形式
margin-top: 10px; margin-right: 5px; margin-bottom: 10px; margin-left: 5px; |
缩写形式
margin: 10px 5px 10px 5px; |
font
一般形式
font-style: italic; font-weight: bold; font-size: .8em; line-height: 1.2; font-family: Arial, sans-serif; |
缩写形式
font: italic bold .8em/1.2 Arial, sans-serif; |
background
一般形式
background-color: #000; d-image: url(images/bg.gif); background-repeat: no-repeat; background-position: top right; |
缩写形式
background: #000 url(images/bg.gif) no-repeat top right; |
border
一般形式
border-width: 1px; border-style: solid; border-color: #000; |
缩写形式
border: 1px solid #000; |
border-radius
一般形式
border-top-left-radius: 1px; border-top-right-radius: 0; border-bottom-right-radius: 3px; border-bottom-left-radius: 4px; |
缩写形式
border-radius: 1px 0 3px 4px; |
- 和CSS盒模型边相关的属性 border-style, margin or padding
- 属性值为1个时,代表所有边属性值相同
- 属性值为2个时,代表顺序为上(下)、右(左)
- 属性值为3个时代表顺序为上、右(左)、下
- 属性值为4个时代表顺序为上、右、下、左
- 和CSS盒模型角相关的属性 border-radius
- 属性值为1个时,代表所有角属性值相同
- 属性值为2个时,代表顺序为上左(下右)、上右(下左)
- 属性值为3个时代表顺序为上左、上右(下左)、下右
- 属性值为4个时代表顺序为上左、上右、下左、下右
带前缀的属性
当使用特定厂商的带有前缀的属性时,通过缩进的方式,让每个属性的值在垂直方向对齐,这样便于多行编辑。
/* 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引号
属性选择器或属性值用双引号(””),而不是单引号(”)括起来。
URI值(url())不要使用引号。
不推荐
@import url('//cdn.com/foundation.css'); |
推荐
@import url(//cdn.com/foundation.css); |
CSS合法颜色值
CSS的颜色可以通过以下方法指定:
- 十六进制颜色:#RRGGBB,其中RR(红色),GG(绿色)和BB(蓝色),其值必须介于0和FF之间
- RGB颜色:RGB(红,绿,蓝)。每个参数(红色,绿色和蓝色)定义颜色的亮度,可在0和255之间,或一个百分比值(从0%到100%)之间的整数。
- RGBA颜色:RGBA(红,绿,蓝,alpha)。 Alpha参数是一个介于0.0(完全透明)和1.0(完全不透明)之间的参数。
- HSL色彩:HSL(色调,饱和度,明度)。色相是在色轮上的程度(从0到360)-0(或360)是红色的,120是绿色的,240是蓝色的。饱和度是一个百分比值;0%意味着灰色和100%的阴影,是全彩。亮度也是一个百分点;0%是黑色的,100%是白色的。
- HSLA颜色:HSLA(色调,饱和度,亮度,α),α是Alpha参数定义的不透明度。 Alpha参数是一个介于0.0(完全透明)和1.0(完全不透明)之间的参数。
- 预定义/跨浏览器的颜色名称
CSS注意事项
- 不要在 rgb()、rgba()、hsl()、hsla() 或 rect() 值的内部的逗号后面插入空格。这样利于从多个属性值(既加逗号也加空格)中区分多个颜色值(只加逗号,不加空格)。
- 对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,.5 代替 0.5;-.5px 代替 -0.5px)。
- 十六进制值应该全部小写,例如,#fff。在扫描文档时,小写字符易于分辨,因为他们的形式更易于区分。
- 尽量使用简写形式的十六进制值,例如,用 #fff 代替 #ffffff。
- 为选择器中的属性添加双引号,例如,input[type="text"]。只有在某些情况下是可选的,但是,为了代码的一致性,建议都加上双引号。
- 避免为 0 值指定单位,例如,用 margin: 0; 代替 margin: 0px;。
CSS Sprites技术
它是把网页中一些背景图片整合到一张图片文件中,再利用CSS的背景图片定位到要显示的位置。这样做可以减少文件体积,减少对服务器的请求次数,提高效率。
CSS hack
针对不同的浏览器写不同的CSS code的过程,就叫。这种形式是应用我们常用的代码来解决不兼容问题,也会用到添加一些特殊符号的形式,它本身没有意义,只是针对不同浏览器是否对它识别来实现的
自适应高度
height:auto !important; min-height:35px; height:35px;/*(兼容IE6\7)*/
阴影效果
filter:progid:DXImageTransform.Microsoft.Shadow(color='black', Direction=135, Strength=4);} opacity:0.5; filter:alpha(opacity=50);
-webkit-box-shadow: 5px 5px 5px #333333;
-moz-box-shadow: 5px 5px 5px #333333;
box-shadow: 5px 5px 5px #333333;
文字过多,以省略号代替
.ecllipse{ white-space:nowrap; text-overflow:ellipsis; -o-text-overflow: ellipsis; text-indent:20px; overflow:hidden; width:50px; }
浮动元素和非浮动元素:IE6 3px Bug
*margin-left:-3px;
浮动后父容器高度自适应
当一个容器内元素都浮动后,它将高度将不会随着内部元素高度的增加而增加,所以造成内容元素的显示超出了容器。
overflow:auto; zoom:1;
IE6的双倍边距bug
当浮动后设置左侧外边距时后,最左侧将显示为双倍边距,比如设置为20,而在IE6下却显示40px,解决这个问题只需应用一个样式。
display:inline;
渐变效果
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#FF000000', EndColorStr='#FFFFFFFF');
background-image: -webkit-gradient(linear,0% 0%, 0% 100%, from(#000000), to(#FFFFFF));
background-image: -moz-webkit-gradient(linear,0% 0%, 0% 100%, from(#000000), to(#FFFFFF));
background-image: -o-webkit-gradient(linear,0% 0%, 0% 100%, from(#000000), to(#FFFFFF));
Chrome的margin
兄弟浮动元素设置 'float:left' 同时自身元素设置 'margin-left'和overflow:hidden 为自身元素指定一个固定值的宽度
overflow:hidden;/*去掉*/
元素位置固定
不随着滚动条滚动
*html{ background-image:url(about:blank); background-attachment:fixed; }
.headers {position:fixed;top:20px;left:0;width:100%;z-index:30;
_position: absolute;_top: expression(eval(document.documentElement.scrollTop+20));
/*_top:top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)));*/
}