前端代码规范

本规范参考Google HTML/CSS Style Guideline和Google Javascript Style Guideline,并加入了作者自身经验进行编写,因作者本身是设计师,前端水平有限,有争见处在该文章下评论或者邮件作者进行讨论。
本文首发于limlift的简书博客LeapDeXign,转载请注明来源及作者。

规范的意义

规范是为了更好的编写代码以及日后的维护。

  • 每个人写代码都有自己的风格规范,在大型团队内同个项目只由个人独立编写完成的情况基本是不存在的,规范好统一的一套代码规范,有益于团队成员之间的交流协作,减少了因为命名或者逻辑奇怪而付出的交流成本;
  • 即使团队中只由个人独立编写完成,也需要遵循一定的代码规范,这是为了在日后的维护重构工作中,维护以及重构人员可以依赖这套代码规范去快速理解整个项目,大大减少了时间成本。

通用规则

协议

在对应链接支持https协议的情况下,使用https安全协议开头,不建议用http协议或者不用协议

<a href="www.zhihu.com">知乎</a> ❌
<a href="http://www.zhihu.com">知乎</a> ❌
<a href="https://www.zhihu.com">知乎</a> ⭕

缩进

缩进用soft tab(两个或者四个半角空格),尽量不要使用tab制表符

字符匹配

HTML/CSS采用小写字母
Javascript中视情况而定
保持单词的独立性,单词与单词之间用下划线或者折线联结

命名规则

命名选词需要明确简洁精准,不要用无意义的英文单词
不要用拼音!不要用拼音!不要用拼音!

<div class="wenzhang"></div> ❌
<div class="article"></div> ⭕
<div class="yee-1992"></div> ❌
<div class="ninty's"></div> ⭕

灵活用缩写,不要滥用缩写!

  <div class="register register-author"></div> ❌
  <div class="reg reg-author"></div> ⭕

单词间的联结,用中折折线,方便编辑器类双击选中当前独立单词修改

  <div class="articleauthor"></div> ❌
  <div class="article_author"></div> ❌
  <div class="article-author"></div> ⭕
  • 驼峰命名法

首单词字母小写,往后每个单词首字母大写,不要加入任何联结符号

function initIndication () {
}
      
function showBox () {
}
  • 下划线与折线

对于多个单词的样式名尽量使用-或者_进行联结,不可用驼峰命名法

文件压缩与加密

上线时需要将对应的css和js文件都压缩一遍,后缀文件名之前加上.min表示这是压缩过的文件
压缩是为了使文件体积更加小巧,提升网页的加载速度
对于js文件而言,除了压缩还需要加密,这是为了防止某些关键js被人扒取直接使用,不涉及到私密性的js可以免除这一个过程。

HTML

HTML5 Doctype

每个HTML页面第一行都应该添加标准模式的声明,确保在每个浏览器中拥有一致的展现。
DOCTYPE声明已经被显著地简化,无须声明无意义的属性。
必须大写。

<!DOCTYPE html>

IE兼容模式

IE支持通过特定的<meta>标签来确定当前页面绘制应该采用的IE版本。一般如果不想兼容低版本IE(edge或者10以下),可以设置为edge mode模式来通知IE采用最新格式。

<meta http-equiv="X-UA-Compatible" content="IE=Edge"> 

逻辑对应

根据元素的功能逻辑选择对应的标签,特殊情况另外处理;

<div onclick="clickFunction()">点击链接</div> ❌
<a onclick="clickFunction()">点击链接</a> ⭕

富媒体说明

需要说明的地方必须说明,可以为img这类标签加载失败的时候给用户提供图像的信息,并且alt属性对于视觉残障人士来说是唯一了解图像内容的方式。

![](images/avatar.jpg) ❌
![](images/avatar.jpg) ⭕

字符转换

特殊符号转换字符需要注意,并非所有的字符都需要转义字符进行转换

The currency symbol for the Euro is “&eur;”. ❌
The currency symbol for the Euro is “€”. ⭕️

引用文件属性

一般css以及javacript文件的引用默认属性是定好的,无须重定义,在一些老旧的浏览器也是有默认的
除非特殊情况(使用的不是js文件),无须定义引用文件格式

<link src="css/dayoo-system.min.css" rel="stylesheet" type="text/style"> ❌
<link src="css/dayoo-system.min.css" rel="stylesheet"> ⭕
<script src="js/dayoo-system.min.js" type="text/javascript"></script> ❌
<script src="js/dayoo-system.min.js"></script> ⭕

元素间独立性

除了<em>``<b>等修饰型标签之外,独立的元素型标签尽量用独立隔开,并且注意缩进

<blockquote> 
   <p><em>Space</em>, the final frontier.</p> 
</blockquote>
<ul> 
   <li>Moe 
   <li>Larry 
   <li>Curly 
</ul>

引号

使用双引号,不要用单引号,作用是统一标准并且避免单双引号混用造成的问题。

![](images/avatar.jpg) ❌
![](images/avatar.jpg) ⭕

加载顺序

  • css文件需要在HTML文件一开始就引入,可以避免网页内容加载缓慢的时候出现一瞬间的丢失样式的问题
  • js文件需要在HTML文件结尾引入,等待HTML框架加载完毕后再执行对HTML元素的操作

代码整洁性

同级元素在缩进上严格执行对齐,方便查找以及浏览整体架构

<div class="wrap">
  <p class="title">知乎,分享你刚编的经历</p>
  <div class="content">
      ![](images/example.jpg)
      <p>文章标题</p>
  </div>
</div>
<div class="pop-box">
<div class="box">
   <p class="title">弹出框标题</p>
   <span class="desc">弹出框内容</span>
   <a href="hideBox()" class="btn btn-cancel">关闭</a>
</div>

属性顺序

HTML元素属性应该按照以下顺序排列编写,确保代码的易读性

class
id, name
data-*
src, for, type, href, value
titile, alt
role, aria-*

class用于标识高复用性组件因此排在首位,而id用于唯一性标识组件,排在第二位(谨慎使用id)。

按钮用<a>还是用<button>

HTML编写过程中经常遇到这个问题,答案并不是统一的,往往需要看后台开发人员的习惯以及网页本身的应用场景下的功能,我的建议是,实在不确定用哪一个的时候,你可以将两种标签的样式都统一写好,毕竟你也不知道开发过程中会出什么幺蛾子导致两种标签需要混用

  • 一般情况下,涉及到信息表单的提交时,最好使用<button>标签;只涉及到跳转/功能函数时,推荐使用<a>标签

代码简洁性(减少标签数量)

非必要增加的标签结构不需要增加,否则会造成结构复杂甚至结构冲突或者样式冲突

<span class="avatar">
   ![](...)
</span>  ❌
    
![](...)⭕

CSS

加载样式表

从外部文件加载css,尽可能减少加载的文件数量。
LINK标签加载,永远不要在css文件里用@import的方式引入
非必要情况下不要在文件中使用內联引入的样式。

命名

class名称只可用小写字符和折线-
选择有意义的英文单词,杜绝拼音。
命名法可参照「模块」-「类型」-「标题」-「属性」类似的层级命名法,该方法也适用于项目文件/设计稿图层的整理命名:(可基于最近的父级class或者基础class作为新class的前缀。)

.header {}
.header .userinfo {}
.header .userinfo .avatar {}

或者

.header {}
.header-user-avatar {}
.header-user-name {}

.icon {}
.icon-home-outline {}
.icon-home-full {}
.btn {}
.btn-default {}
.btn-cancel {}
.btn-alert {}

多属性囊括

  • 一般情况下,对于多属性囊括的css属性统一写在一起
.btn {
  border-top-style: none; 
  font-family: palatino, georgia, serif; 
  font-size: 100%; 
  line-height: 1.6; 
  padding-bottom: 2em; 
  padding-left: 1em; 
  padding-right: 1em; 
  padding-top: 0;
}❌

.btn {
  border-top: 0; 
  font: 100%/1.6 palatino, georgia, serif; 
  padding: 0 1em 2em;
}⭕️
   
  • 特殊情况下,例如需要对某个属性进行操作的时候,才需要拆开属性来写
.click {
  background-color:#fff;
  background-image:url(../images/icon.png);
  background-position:0 0;
  background-repeat:no-repeat;
}
.click:hover {
  background-color:#eee;
  background-position:-44px 0;
}

0与1之间

取值0和1之间的数值时,省略0不写

.btn-cancel {
   font-size:0.875rem;
}❌
    
.btn-cancel {
   font-size:.875rem;
}⭕️

缩写色值

某些可以缩写的色值(aabbcc型或者aaaaaa型)使用缩写

.btn-cancel {
   background-color:#eebbcc;
}❌ 
    
.btn-cancel {
   background-color:#ebc;
}⭕️

多级联结

class名的英文单词用折线-连接

.popupboxcontent {} ❌
.popup-box-content {} ⭕️

id命名用驼峰命名法

#my-canvas {} ❌
#myCanvas {} ⭕️

选择器权重

权重计算规则:

id选择器:1.0.0
class选择器:0.1.0
元素选择器:0.0.1

  1. 当选择器选到当前元素的时候,遵循权重计算规则;
  2. 当选择器没有选到当前元素的时候,遵循就近原则;
  3. 1和2冲突的时候,1的优先度高。

第一种情况:

<style>
  #box1 .spec2 p {
    color: red;
  }
  div idv #box3 p {
    color: blue;
  }
  div.spec1 div.spec2 div.spec3 p{
    color: green;
  }
</style>

<div id="box1" class="spec1">
  <div id="box2" class="spec2">
    <div id="box3" class="spec3">
      <p>文字</p>
    </div>
  </div>
</div>

第二种情况:

<style>
  div p {
    color: red;
  }
  #box{
    color: blue;
  }
</style>

<div id="box">
  <p id="para" class="spec">
    <span>文字</span>
  </p>
</div>

第三种情况:

<style>
  span {
    color: green;
  }
  .nav {
    color: red;
  }
  .nav ul li {
    color: blue;
  }
</style>

<div class="nav">
  <ul>
    <li><span>文字</span></li>
    <li><span>文字</span></li>
    <li><span>文字</span></li>
    <li><span>文字</span></li>
  </ul>
</div>

css-hack

针对IE各种低版本的兼容,使用属性前(后)缀法:

hack 写法 兼容
* *color 标准模式:IE6/7;quirk模式:IE All;
+ +color 标准模式:IE6/7;quirk模式:IE All;
- -color 标准模式:IE6;quirk模式:IE 6;
_ _color 标准模式:IE6;quirk模式:IE6/7/8/9;
# #color 标准模式:IE6/7;quirk模式:IE All;
\0 color:red\0 标准模式:IE8/9/10;quirk模式: none;
\9\0 color:red\9\0 标准模式:IE9/10;quirk模式:none;
!important color:red !important; 标准模式:IE7/8/9/10;quirk模式:IE10;

属性独立性

除非是压缩过后的css文件,否则建议每个属性保持独立换行。

.click {background-color:#fff;background-image:url(../images/icon.png);background-position:0 0;background-repeat:no-repeat;} ❌
.click {
   background-color:#fff;
   background-image:url(../images/icon.png);
   background-position:0 0;
   background-repeat:no-repeat;
} ⭕️

line-height的重要性

针对某些只包含纯文字的元素容器,文字类标签或者父级标签一定要注意写明line-height,因为在不同浏览器中line-height有不同表现(尤其是低版本IE),而不是去写死height来限制它的高度(特别需求例外),利用文字的line-height把父级容器撑开。
line-height不应该用带单位的数值来写(如24px/2rem等),而是直接写数字系数,系数是基于文字的font-size为基础来计算的,比如font-size为16px的文字,line-height写为1.5,则ling-height为24px。

Javascript

常量,变量与函数

  1. 常量使用大写字母,下划线表示联结
  2. 变量使用小写字母,不要用任何联结符号,使用驼峰命名法
  3. 变量/常量/函数的命名要有意义,不要用拼音!不要用拼音!不要用拼音!
  4. 命名方法参照一下的格式:「动词」+「模块名词」+「修饰」
  5. Boolean变量最好用is开头
  6. 函数名使用驼峰命名法
  7. 变量和常量声明必须放在开头
  8. 函数声明放在文件中间;
  9. 最后才是onload函数来加载文档。
var COUNT_A = 1;

var isTrue = TRUE;

for(var time = 0; time++; time<data.length-1){
  //do someting
}
function createInfo(argument){
  //do someting
}
function popUpBox(title,context,url){
  //make box container pop up
}

函数声明的方式

函数声明一共有三种方式:

  1. 函数声明function abc(){}
  2. 函数表达式abc = function() {}
  3. 构造函数var abc = new function () {}
  • 使用Function构造函数定义函数的方式是一个函数表达式,不推荐使用这种方式定义函数,原因在于这种方式会导致解析两次代码,影响性能(第一次解析常规的JavaScript代码,第二次解析传入构造函数的字符串)
  • 这种语法唯一的特点是:可以直观地理解“函数是对象,函数名是指针”的概念。

对于函数声明和函数表达式两种定义函数的方式而言,解析器并不是一视同仁的。解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);对于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。直接上例子吧。。。

例子1:

alert(sum(10,10)); 
function sum(num1,num2){  
   return num1+num2;  
}

例子2:

alert(sum(10,10));//20  
var sum = function(num1,num2){  
   return num1+num2;  
}; 

浏览器解析器在上述两个例子中的解析情况并不一致,解析器会率先读取函数声明,而对于函数表达式而言它对解析器的意义只不过是一个表达式,因此在上述例子中,例子2会报错,因为例子2的函数表达式解析慢于执行语句,执行语句查找不到对应的函数执行。

函数的封装

何为函数封装,就是讲一个或多个功能的函数封装起来,对内对外只有数据接口。

  • 函数封装的意义在于,对于具有公用性的功能,我们可以不必去重复写同一功能的函数,只需要调用封装好的函数即可,保持代码的简洁性和模块性。

注意函数的封装,尤其适用jQuery库时,需要深刻理解jQ的运行机制

function initDocument(data) {
  //do someting;
}
function popUpBox(ele) {
  //show your popup box;
}
$(function(){
  initDocument(string-data);
  popUpBox('popup-box');
})

以上例子中的popupBox函数就是封装好的函数,只需要传入元素的样式名/id名就可以对该元素进行操作。

灵活运用函数之间的套用关系

根据不同函数之间的关联性以及函数本身的独立性/功能特点上的共有性来封装函数,进行函数的调用,简易模块化js文件,方便日后的维护以及重复参考;

注释

注释都需要写在语句前面
单行注释使用//,在注释语句开头使用

//这是单行注释

多行注释/行内注释使用/**/,包裹住注释语句

/*
这是多行注释
仅供此文档使用
联系方式为xxxxx
/*
    
function fuckThisDoc (argument/*对单个变量的注释*/,number){
   return abc;
}

如何吃透js

研究jQ源码或者下载一个开源的js插件,硬啃,从读码到理解再到优化,基本上就能理解这门语言的运转机制了。

推荐阅读更多精彩内容

  • Web 前端代码规范 最后更新时间:2017-06-25 原始文章链接:https://github.com/bx...
    白小明0927阅读 2,095评论 1 15
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 131,838评论 18 138
  • html语义化 为什么要语义化在没有css的情况下,页面也能呈现出内容结构;有利于SEO有助于爬虫住区更多的有效信...
    漓漾li阅读 413评论 1 4
  • 前段时间在看一些规范性的东西记在了笔记上,今天在这里拿出来给大家分享一下,目前我采用(学习到)的一些规范约束 【后...
    _proto_麻瓜一袁阅读 519评论 1 4
  • 今年已经过了四分之三的时间,早在7月份业界就认为OPPO的出货量可能达到9000万至1亿,近日产业链人士指vivo...
    每日一看阅读 114评论 0 0