基本原则

  • 结构、样式、行为分离 尽量确保文档和模板只包含 HTML 结构,样式都放到样式表里,行为都放到脚本里。

  • 缩进 统一使用4个空格缩进

  • 文件编码 使用UTF-8编码:<meta charset="utf-8">

  • 一律使用小写字母 省略外链资源(图片及其它媒体资源)URL 中的 http / https 协议,使 URL 成为相对地址,避免 Mixed Content 问题,减小文件字节数。其它协议(ftp 等)的 URL 不省略。

HTML

  • Class与ID

    • class 与 id 单词字母小写,多个单词组成时,采用中划线-分隔
    • 使用唯一的 id 作为 Javascript hook, 同时避免创建无样式信息的 class
  • 属性顺序

    • id
    • class
    • name
    • data-xxx
    • src,for,type,href
    • title,alt
    • aria-xxx,role
  • 引号 属性的定义,统一使用双引号。

  • 嵌套

语义嵌套约束:

  • <li> 用于 <ul><ol> 下;
  • <dd>, <dt> 用于 <dl> 下;
  • <thead>, <tbody>, <tfoot>, <tr>, <td> 用于 <table> 下;

严格嵌套约束:

    • inline-Level 元素,仅可以包含文本或其它 inline-Level 元素;
    • <a>里不可以嵌套交互式元素<a><button><select>等;
    • <p>里不可以嵌套块级元素<div><h1>~<h6><p><ul>/<ol>/<li><dl>/<dt>/<dd><form>等。
    • HEAD
    <!-- 中文 -->
    <html lang="zh-Hans">
    
    <!-- 简体中文 -->
    <html lang="zh-cmn-Hans">
    
    <!-- 繁体中文 -->
    <html lang="zh-cmn-Hant">
    
    <!-- English -->
    <html lang="en">
    • 字符编码 以无BOM的utf-8编码作为文件格式。

    • IE兼容模式 优先使用最新版本的IE和Chrome内核。

    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    • SEO优化
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <!-- SEO -->
        <title>Style Guide</title>
        <meta name="keywords" content="your keywords">
        <meta name="description" content="your description">
        <meta name="author" content="author,email address">
    </head>
    • viewport <meta name="viewport" content="width=device-width, initial-scale=1.0">

    • IOS图标

      • apple-touch-icon 图片自动处理成圆角和高光等效果;
      • apple-touch-icon-precomposed 禁止系统自动添加效果,直接显示设计原图;
    <!-- iPhone 和 iTouch,默认 57x57 像素,必须有 -->
    <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png">
    
    <!-- iPad,72x72 像素,可以没有,但推荐有 -->
    <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-72x72-precomposed.png" sizes="72x72">
    
    <!-- Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有 -->
    <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-114x114-precomposed.png" sizes="114x114">
    
    <!-- Retina iPad,144x144 像素,可以没有,但推荐有 -->
    <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-144x144-precomposed.png" sizes="144x144">
    • favicon 在未指定 favicon 时,大多数浏览器会请求 Web Server 根目录下的 favicon.ico 。为了保证 favicon 可访问,避免404,必须遵循以下两种方法之一:

      • 在Web Server根目录放置favicon.ico文件;
      • 使用 link 指定 favicon; <link rel="shortcut icon" href="path/to/favicon.ico">

    • HEAD模板
    <!DOCTYPE html>
    <html lang="zh-cmn-Hans">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>Style Guide</title>
        <meta name="description" content="不超过150个字符">
        <meta name="keywords" content="">
        <meta name="author" content="name, email@gmail.com">
    
        <!-- 为移动设备添加 viewport -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
        <!-- iOS 图标 -->
        <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png">
    
        <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml" />
        <link rel="shortcut icon" href="path/to/favicon.ico">
    </head>

    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;;
    /*  Not recommended  */
    .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
    }
    
    /* Recommended */
    .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;
    }
    • 声明顺序 相关属性应为一组,推荐的样式编写顺序

    1.Positioning 2.Box model 3.Typographic 4.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;
      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;
    }
    • 引号使用 url() 、属性选择符、属性值使用双引号

    • 媒体查询(Media query)的位置 将媒体查询放在尽可能相关规则的附近。不要将他们打包放在一个单一样式文件中或者放在文档底部。

    • 不要使用 @import 与 <link> 相比,@import 要慢很多,不光增加额外的请求数,还会导致不可预料的问题。

    • 链接的样式顺序 a:link -> a:visited -> a:hover -> a:active

    • 无需添加浏览器厂商前缀 使用Autoprefixer 自动添加浏览器厂商前缀,编写 CSS 时不需要添加浏览器前缀,直接使用标准的 CSS 编写。Autoprefixer 通过 Can I use,按兼容的要求,对相应的 CSS 代码添加浏览器厂商前缀。

    • 模块组织

      • 以 Components 的角度思考,以两个单词命名(.screenshot-image)
      • Components 中的 Elements,以一个单词命名(.blog-post .title)
      • Variants,以中划线-作为前缀(.shop-banner.-with-icon)
      • Components 可以互相嵌套
      • 使用继承
    • 性能优化

      1. 慎用高消耗的样式 高消耗属性在绘制前需要浏览器进行大量计算

        • box-shadows
        • border-radius
        • transparency
        • transforms
        • CSS filters(性能杀手)
      2. 避免过分重排 当发生重排时,浏览器需要重新计算布局位置与大小

      常见的重排元素:

      • width
      • height
      • padding
      • margin
      • display
      • border-width -position

      • top
      • left
      • right
      • bottom
      • font-size
      • float
      • text-align
      • overflow-y
      • font-weight
      • overflow
      • font-family
      • line-height
      • vertical-align
      • clear
      • white-space
      • min-height
    • 正确使用Display属性 Display属性会影响页面的渲染,要合理使用。

      • display: inline后不应该再使用 width、height、margin、padding 以及 float;
      • display: inline-block 后不应该再使用 float;
      • display: block 后不应该再使用 vertical-align;
      • display: table-* 后不应该再使用 margin 或者 float;
    • 不滥用Float Float在渲染时计算量比较大,尽量减少使用。

    • 提升CSS选择器性能 CSS选择器是从右到左进行规则匹配。

      • 避免使用通用选择器*
      • 避免使用标签或class选择器限制id选择器
      • 避免使用标签限制class选择器
      • 避免使用多层标签选择器。使用 class 选择器替换,减少css查找
      • 避免使用子选择器
      • 使用继承

    JavaScript

    • 注释

      • 原则:

        • As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性、可读性。
        • As long as necessary(如有必要,尽量详尽):合理的注释、空行排版等,可以让代码更易阅读、更具美感。
    • 命名

      • 变量、函数、函数的参数、类的方法/属性,使用 Camel 命名法。
      • 私有属性、变量和方法以下划线 _ 开头。
      • 常量, 使用全部字母大写,单词间下划线分隔的命名方式。
      • 类、枚举变量,使用Pascal命名法。
      • 枚举的属性,全部使用字母大写,单词间下划线分隔的命名方式。
      • 由多个单词组成的 缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。
    • 命名语法

      • 类名,使用名词。
      • 函数名,使用动宾短语。
      • boolean 类型的变量使用 is 或 has 开头。
      • Promise 对象用动宾短语的进行时表达。
    • 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 进行遍历, 而是所有出现在对象及其原型链的键值。

    • 二元和三元操作符 操作符始终写在前一行, 以免分号的隐式插入产生预想不到的问题。

    var x = a ? b : c;
    
    var y = a ?
        longButSimpleOperandB : longButSimpleOperandC;
    
    var z = a ?
            moreComplicatedB :
            moreComplicatedC;

    .操作符也是如此:

    var x = foo.bar().
        doSomething().
        doSomethingElse();
    • 条件(三元)操作符 (?:) 三元操作符用于替代 if 条件判断语句。

    • jQuery规范

      • 使用最新版本的jQuery
      • jQuery变量 1.存放jQuery对象的变量以$开头;

      2.将jQuery选择器返回的对象缓存到本地变量中复用; 3.使用驼峰命名变量;

      • 选择器 1.尽可能的使用 ID 选择器,因为它会调用浏览器原生方法 document.getElementById 查找元素。当然直接使用原生 document.getElementById 方法性能会更好;

      2.在父元素中选择子元素使用 .find() 方法性能会更好, 因为 ID 选择器没有使用到 Sizzle 选择器引擎来查找元素;

      • DOM操作 1.当要操作DOM元素的时候,尽量将其分离节点,操作结束后,再插入节点。

      2.使用字符串链接或array.join要比.append()性能更好。

    var $myList = $("#list-container > ul").detach();
    //...a lot of complicated things on $myList
    $myList.appendTo("#list-container");
    // Not recommended
    var $myList = $("#list");
    for(var i = 0; i < 10000; i++){
        $myList.append("<li>"+i+"</li>");
    }
    
    // Recommended
    var $myList = $("#list");
    var list = "";
    for(var i = 0; i < 10000; i++){
        list += "<li>"+i+"</li>";
    }
    $myList.html(list);
    
    // Much to recommended
    var array = [];
    for(var i = 0; i < 10000; i++){
        array[i] = "<li>"+i+"</li>";
    }
    $myList.html(array.join(''));
    • 事件 1.如果需要,对事件使用自定义的 namespace,这样容易解绑特定的事件,而不会影响到此 DOM 元素的其他事件监听; 2.对 Ajax 加载的 DOM 元素绑定事件时尽量使用事件委托。事件委托允许在父元素绑定事件,子代元素可以响应事件,也包括 Ajax 加载后添加的子代元素;

    $("#myLink").on("click.mySpecialClick", myEventHandler);
    $("#myLink").unbind("click.mySpecialClick");
    // Not recommended
    $("#list a").on("click", myClickHandler);
    
    // Recommended
    $("#list").on("click", "a", myClickHandler);
    • 链式写法 1.尽量使用链式写法而不是用变量缓存或者多次调用选择器方法; 2.当链式写法超过三次或者因为事件绑定变得复杂后,使用换行和缩进保持代码可读性;

    $("#myLink")
      .addClass("bold")
      .on("click", myClickHandler)
      .on("mouseover", myMouseOverHandler)
      .show();
    • 性能优化

      • 避免不必要的DOM操作 浏览器遍历 DOM 元素的代价是昂贵的。最简单优化 DOM 树查询的方案是,当一个元素出现多次时,将它保存在一个变量中,就避免多次查询 DOM 树了。

      • 避免使用jQuery实现动画 1.禁止使用 slideUp/Down() fadeIn/fadeOut() 等方法;

      2.尽量不使用 animate() 方法;

    移动端优化

    • click 的 300ms 延迟响应 通用办法:FastClick

    window.addEventListener( "load", function() {
        FastClick.attach( document.body );
    }, false );
    • 快速回弹滚动 如果想要为某个元素拥有 Native 般的滚动效果,可以这样操作:

    .element {
        overflow: auto; /* auto | scroll */
        -webkit-overflow-scrolling: touch;
    }
    • 获取滚动条值 PC 端滚动条的值是通过 document.scrollTop 和 document.scrollLeft 获得,但在 iOS 中并没有滚动条的概念,所以仅能通过 windows.scroll 获取,同时也能兼容 Android 。

    window.scrollY
    window.scrollX
    • 清除输入框内阴影 在 iOS 上,输入框默认有内部阴影,但无法使用 box-shadow 来清除,如果不需要阴影,可以这样操作:

    input,
    textarea {
        border: 0; /* 方法1 */
        -webkit-appearance: none; /* 方法2 */
    }
    • 页面窗口自动调整到设备宽度,并禁止用户缩放页面
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    • 电话号码识别 iOS Safari ( Android 或其他浏览器不会) 会自动识别看起来像电话号码的数字,将其处理为电话号码链接

    <!-- 关闭电话号码识别: -->
    <meta name="format-detection" content="telephone=no" />
    
    <!-- 开启电话功能: -->
    <a href="tel:123456">123456</a>
    
    <!-- 开启短信功能: -->
    <a href="sms:123456">123456</a>
    • 邮箱地址的识别 在 Android ( iOS 不会)上,浏览器会自动识别看起来像邮箱地址的字符串,不论有你没有加上邮箱链接,当你在这个字符串上长按,会弹出发邮件的提示。

    <!-- 关闭邮箱地址识别: -->
    <meta name="format-detection" content="email=no" />
    
    <!-- 开启邮件发送: -->
    <a mailto:>mobile@gmail.com">mobile@gmail.com</a>
    

    标签: none

    添加新评论