前端开发规范
说明
字体颜色
- 红色 标识为 重点
- 绿色 标识为 技巧
- 蓝色 标识为 提示
- 黄色 标识为 警告
通用要求
目的
- 代码一致性
通过保持代码风格和传统的一致性,我们可以减少遗留系统维护的负担,并降低未来系统崩溃的风险。 - 最佳实践
通过遵照最佳实践,我们能确保优化的页面加载、性能以及可维护的代码。
核心
- 表现、内容和行为的分离
- 标记应该是结构良好、语义正确 以及 普遍合法
- Javascript应该起到渐进式增强用户体验的作用
基本原则
- 缩进
统一四个空格缩进(总之缩进统一即可),不要使用 Tab或者Tab、空格混搭。建议设置开发工具一个Tab为四个空格。 - 文件编码
使用不带 BOM 的 UTF-8 编码。- 在 HTML中指定编码
- 使用scss编写css文件头部需设置@charset “utf-8”;,否则添加中文注释报错。一般css文件不用设置。
-
一律使用小写字母
-
统一注释
通过配置编辑器,可以提供快捷键来输出一致认可的注释模式。-
HTML 注释
1.模块注释1
2
3
4
<div class="article-list">
...
</div>2.区块注释
1
2
3
4
5<!--
@name: Drop Down Menu
@description: Style of top bar drop down menu.
@author: Ashu(Aaaaaashu@gmail.com)
--> -
CSS 注释
组件块和子组件块以及声明块之间使用一空行分隔,子组件块之间三空行分隔。1
2
3
4
5
6
7
8
9
10
11
/* ==========================================================================
组件块
========================================================================= */
/* 子组件块
============================================================================ */
.selector-secondary {
display: block; /* 注释*/
} -
Javascript注释
1.单行注释
必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致。
2.多行注释
避免使用 /*…*/ 这样的多行注释。有多行注释内容时,使用多个单行注释。
3.函数/方法要注释- 注释包括函数说明,有参数和返回值时必须使用注释标识。参数和返回值注释必须包含类型信息和说明。
-
当函数是内部函数,外部不可访问时,可以使用 @inner 标识。
Javascript /** * 函数描述 * * @param {string} p1 参数1的说明 * @param {string} p2 参数2的说明,比较长 * 那就换行了. * @param {number=} p3 参数3的说明(可选) * @return {Object} 返回值描述 */ function foo(p1, p2, p3) { var p3 = p3 || 10; return { p1: p1, p2: p2, p3: p3 }; }
-
文件注释
文件注释用于告诉不熟悉这段代码的读者这个文件中包含哪些东西。 应该提供文件的大体内容, 它的作者, 依赖关系和兼容性信息。如下:Javascript /** * @fileoverview Description of file, its uses and information * about its dependencies. * @author user@meizu.com (Firstname Lastname) * Copyright 2015 Meizu Inc. All Rights Reserved. */
-
-
代码验证
- 使用 W3C HTML Validator 来验证你的HTML代码有效性和规范化。
- 使用 W3C CSS Validator 来验证你的CSS代码有效性
HTML
尽量遵循 HTML 标准和语义,但是不要以牺牲实用性为代价。任何时候都要尽量使用最少的标签并保持最小的复杂度。
标签
- 自闭合(self-closing)标签,无需闭合 ( 例如: img input br hr 等 ),img和input标签尾部需加斜杠/以免后台编译出现错误,br标签遵循标准写法<br />。
- 除以上标签其它标签必须闭合,包括可选闭合的标签(例如:</li> 或 </body> )。
- 段落分隔符要使用实际对应的<p>元素,而不是用多个<br>标签。
- 列表中的条目必须总是放置于<ul>、<ol>或<dl> 中,永远不要用一组 <div>或<p> 来表示。
- 给每个表单里的字段加上 <label> 标签,其中的 for 属性必须和对应的输入字段对应,这样用户就可以点击标签。
- 在某些闭合的 </div> 标签旁边加上一段html注释,说明这里闭合的是什么元素。这在有大量嵌套和缩进的情况下会很有用。
- 不要把表格用于页面布局。
- 对于页眉和标题,永远使用首字母大写格式。不要在标记中使用全部大写或小写的标题,而是应用CSS属性
text-transform:uppercase/lowercase
。 - 尽量减少标签数量。
Class 与 ID
- class 应以功能或内容命名,不以表现形式命名。
- class 与 id 单词字母小写,多个单词组成时,采用中划线-分隔,不要采用驼峰命名法和下划线。
- 使用唯一的 id 作为 Javascript hook, 同时避免创建无样式信息的 class。
属性
- 在HTML5规范里并没有严格要求属性值两边加引号。但考虑到一些属性可以接受空白值,为了保持一致性,我们所有属性值必须加上双引号。
- HTML 属性应该按照特定的顺序出现以保证易读性。
- id
- class
- name
- dta-xxx
- src, for, type, href
- title, alt
- aria-xxx, role
嵌套
- 语义嵌套约束
- <li> 用于 <ul> 或 <ol> 下。
- <dd>, <dt> 用于 <dl> 下。
- <thead>, <tbody>, <tfoot>, <tr>, <td> 用于 <table> 下。
- 严格嵌套约束
- a 标签不允许嵌套 div 这种约束属于语义嵌套约束。如果 a 标签若要包含块元素,设置内部容器元素为 span ,样式设置为
diaplay:block
。 - <a>里不可以嵌套交互式元素<a>、<button>、<select>等。
- <p>里不可以嵌套块级元素<div>、<h1>~<h6>、<p>、<ul>、<ol>、<li>、<dl>、<dt>、<dd>、<form>等。
- a 标签不允许嵌套 div 这种约束属于语义嵌套约束。如果 a 标签若要包含块元素,设置内部容器元素为 span ,样式设置为
布尔值属性
HTML5 规范中 disabled、checked、selected 等属性不用设置值。
语义化
没有 CSS 的 HTML 是一个语义系统而不是 UI 系统。语义化的HTML结构有助于搜索引擎理解,利于SEO。
理解HTML以及HTML5的标签的语义化特性,例如:<header>,<nav>,<footer>, <p>, <h1> ~ <h6>,<ul>,<ol>,<article>,<section>…等标签。
HEAD
-
语言属性
1
2
3
4
5
6
7
8
9
10
11<!-- 中文 -->
<html lang="zh-Hans">
<!-- 简体中文 -->
<html lang="zh-cmn-Hans">
<!-- 繁体中文 -->
<html lang="zh-cmn-Hant">
<!-- English -->
<html lang="en"> -
IE 兼容模式
优先使用最新版本的IE 和 Chrome 内核<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
- viewport
为移动端设备优化,设置可见区域的宽度和初始缩放比例<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- favicon
在未指定 favicon 时,大多数浏览器会请求 Web Server 根目录下的 favicon.ico 。为了保证 favicon 可访问,避免404,必须遵循以下两种方法之一:- 在 Web Server 根目录放置 favicon.ico 文件
- 使用 link 指定 favicon
<link rel="shortcut icon" href="path/to/favicon.ico">
CSS
通用约定
- 代码组织
- 以组件为单位组织代码段
- Class 和 ID
- 使用语义化、通用的命名方式
- 使用连字符 - 作为 ID、Class 名称界定符,不要驼峰命名法和下划线
- 避免选择器嵌套层级过多,尽量少于 3 级
- 避免选择器和 Class、ID 叠加使用
- 声明块格式
- 选择器分组时,保持独立的选择器占用一行
- 声明块的左括号 { 前添加一个空格
- 声明块的右括号 } 应单独成行
- 声明语句中的 : 后应添加一个空格
- 声明语句应以分号 ; 结尾
- 一般以逗号分 大专栏 前端开发规范隔的属性值,每个逗号后应添加一个空格
- rgb()、rgba()、hsl()、hsla() 或 rect() 括号内的值,逗号分隔,但逗号后不添加一个空格
- 对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,.5 代替 0.5;-.5px 代替 -0.5px)
- 十六进制值应该全部小写或者大写和尽量简写,不要大小写混用,例如,#fff 代替 #ffffff
- 避免为 0 值指定单位,例如,用 margin: 0; 代替 margin: 0px;
-
声明顺序
- 相关属性应为一组,推荐的样式编写顺序
- Positioning
- Box model
- Typographic
- Visual
-
由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在首位。盒模型决定了组件的尺寸和位置,因此排在第二位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box model */
display: block;
box-sizing: border-box;
width: 100px;
height: 100px;
padding: 10px;
border: 1px solid #e5e5e5;
border-radius: 3px;
margin: 10px;
float: right;
overflow: hidden;
/* Typographic */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
text-align: center;
/* Visual */
background-color: #f5f5f5;
color: #fff;
opacity: .8;
/* Other */
cursor: pointer;
}
注: 根据个人习惯可适度调整,总体属性顺序不能改变。
- z-index的值目前以底部固定导航菜单设置为20为准,弹层遮罩等需盖住底部导航菜单的元素可设置大于20,但不建议超过40,页面中其它元素值要小于20。不允许出现随意设置的情况(例如:z-index:99999)。
- 引号使用
- url() 、属性选择符、属性值使用双引号。
- url()若不加双引号,引用地址文件名如果包含空格,就会引用失败。
- 相关属性应为一组,推荐的样式编写顺序
-
不要使用 @import
-
与 <link> 相比,@import 要慢很多,不光增加额外的请求数,还会导致不可预料的问题。
替代办法:
- 使用多个 元素
- 通过 Sass 或 Less 类似的 CSS 预处理器将多个 CSS 文件编译为一个文件
- 其他 CSS 文件合并工具
参考 don’t use @import
-
- 尽量使用类名,避免使用标签选择器。
- 链接的样式顺序
- a:link -> a:visited -> a:hover -> a:active(LoVeHAte)
- 无需添加浏览器厂商前缀
- 使用 Autoprefixer 自动添加浏览器厂商前缀,编写 CSS 时不需要添加浏览器前缀,直接使用标准的 CSS 编写。
- 尽量使用两个单词及以上的类名命名方法,避免css文件过大时类名重复混乱的情况。
- 一般情况避免使用!important,css样式发生冲突解决办法:
- 添加新的类名设置样式
- 精确查找,添加父元素类名以便区分。
- 注: h1 >=20px; h2 18px; h3 16px; h4 14px; h5 12px; h6 < 12px; 单个页面建议h1标签只出现一次,避免过多出现其它标题标签防止搜索引擎鉴定为作弊。
性能优化
- 注意事项:
- 慎重选择高消耗的样式
- box-shadows
- border-radius
- transparency
- transforms
- CSS filters(性能杀手)
- 避免使用通用选择器
- 避免使用标签或 class 选择器限制 id 选择器
.menu-left#newMenuIcon {…}
//Bad#newMenuIcon {…}
//Good - 避免使用标签限制 class 选择器
treecell.indented {…}
//Bad - 避免使用多层标签选择器。使用 class 选择器替换,减少css查找
treeitem[mailfolder="true"] > treerow > treecell {…}
//Bad.treecell-mailfolder {…}
//Good - 避免使用子选择器
- 使用继承
- 慎重选择高消耗的样式
- CSS 选择器的执行效率从高到低
- id选择器(#myid)
- 类选择器(.myclassname)
- 标签选择器(div,h1,p)
- 子选择器(ul < li)
- 后代选择器(li a)
- 通配符选择器(*)
- 属性选择器(a[rel=”external”]
- 类选择器(a:hover, li:nth-child)
- 正确使用 Display 的属性
- display: inline后不应该再使用 width、height、margin、padding 以及 float。
- display: inline-block 后不应该再使用 float。
- display: block 后不应该再使用 vertical-align。
- display: table-* 后不应该再使用 margin 或者 float。
- 不滥用 Float Float在渲染时计算量比较大,尽量减少使用
-
开启硬件加速,但不能滥用。
1
2
3
4.classname {
-webkit-transform:translateZ(0);
transform:translateZ(0);
}
Javascript
通用约定
注意事项
- 99%的代码必须封装在外部Javascript文件中。这些文件必须在 BODY 标签的尾部引入,让页面的性能最大化。
- 不要使用 document.write()。
- 给变量和函数的命名要有逻辑意义。
- 不要人为缩短命名到最小。除了传统的 for 循环中的计数器 i 等简化的情况,变量命名必须长到有明确意义。
- 常量或配置变量(例如动画持续时间等)必须放在文件的顶部。
- 尽力编写可通用化的函数,让它接受参数并返回值。这样有利于充分的代码重用,而且一旦与引入及外部脚本配合起来,能在脚本需要修改时减少开销。
- 最小化全局变量。给代码添加注释。
- 不要用隐含的类型转换。
- 不要用 eval(),with()和void()。
- 用 parseInt() 进行数字转换。
- 构造器首字母大写。
命名
- 变量, 使用 Camel 命名法。变量名 = 类型 + 对象描述
- Int 整型 i
- Float 浮点 fl
- Boolean 布尔 b
- String 字符串 s
- Array 数组 a
- Object 对象 o
- Function 函数 fn
- Regular Expression 正则 re
- 私有属性、变量和方法以下划线 _ 开头。
- 常量, 使用全部字母大写,单词间下划线分隔的命名方式。
- 函数, 使用 Camel 命名法。
- 函数的参数, 使用 Camel 命名法。
- 类, 使用 Pascal 命名法,首字母大写。
- 类的 方法 / 属性, 使用 Camel 命名法。
- 枚举变量 使用 Pascal 命名法,首字母大写。
- 枚举的属性, 使用全部字母大写,单词间下划线分隔的命名方式。
命名语法
- 类名,使用名词。
- 函数名,使用动宾短语。
- boolean 类型的变量使用 is 或 has 开头。
-
Promise 对象用动宾短语的进行时表达。
1
2var loadingData = ajax.get('url');
loadingData.then(callback);
True 和 False 布尔表达式
- 类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == null。
- 以下的布尔表达式都返回 false:
null / undefined / ‘’ 空字符串 / 0 数字0 - 注意以下类型返回true:
‘0’ 字符串0 / [] 空数组 / {} 空对象
其它注意事项
- 不要在 Array 上使用 for-in 循环
- for-in 循环只用于 object/map/hash 的遍历, 对 Array 用 for-in 循环有时会出错. 因为它并不是从 0 到 length - 1 进行遍历, 而是所有出现在对象及其原型链的键值。
- 二元和三元操作符 .操作符
- 操作符始终写在前一行, 以免分号的隐式插入产生预想不到的问题。
- && 和 || 二元布尔操作符是可短路的, 只有在必要时才会计算到最后一项。
性能优化
总结中…
移动端
总结中…