# 前言
# 为什么进行开发规范约定
旨在增强团队开发协作、提高代码质量和打造稳固的开发基础。参看各种优秀项目源码可以发现大佬的代码很多时候并没有非常华丽,但是他们一定严格遵守着代码规范保证代码的可读性及可维护性。而且越是大厂对于代码规范越是推崇因为这是构建健壮项目的坚定基石。如果你也许成为一个强大的开发者,那么请仔细阅读并遵守它们。
# 益处:
- 减少不必要的错误
- 方便维护交接
- 易于扩展
- 提高编码速度,减少焦虑,延长寿命
- 以下省略一万条
# 缺点:
- 需要花时间学习并在实践中反复使用才能熟练快速的进行使用
- 增加了初次书写代码时的时间,在快速迭代中可能会增加压力
# 总览
本开发规范包含以下几个主要构成部分
- HTML规范
- 图片规范
- CSS规范
- 命名规范
- JavaScript规范
- VUE规范
- Git commit规范
- Git 工作流规范
- 项目上线规范
- 常用工具配置
- 项目基础模板
# HTML规范
# 代码规范
# DOCTYPE 声明
一个DOCTYPE必须包含以下部分,并严格按照顺序出现:
- A string that is an ASCII case-insensitive match for the string “<!DOCTYPE”.
- One or more space characters.
- A string that is an ASCII case-insensitive match for the string “html”.
- Optionally, a DOCTYPE legacy string or an obsolete permitted DOCTYPE string (defined below).
- Zero or more space characters.
- A “>” (U+003E) character.
- 一个ASCII字符串 “<!DOCTYPE” ,大小写不敏感
- 一个或多个空白字符
- 一个ASCII字符串”html”,大小写不敏感
- 一个可选的历史遗留的DOCTYPE字符串 (DOCTYPE legacy string),或者一个可选的已过时但被允许的DOCTYPE字符串 (obsolete permitted DOCTYPE string) 字符串
- 一个或多个空白字符
- 一个编码为 U+003E 的字符 “>”
# 团队约定
HTML文件必须加上 DOCTYPE 声明,并统一使用 HTML5 的文档声明:
<!DOCTYPE html>
# 更多关于 DOCTYPE声明
# 页面语言LANG
Lang属性的取值应该遵循互联网工程任务组–IETF(The Internet Engineering Task Force)制定的关于语言标签的文档 BCP 47 - Tags for Identifying Languages
# 团队约定
推荐使用属性值 cmn-Hans-CN
(简体, 中国大陆),但是考虑浏览器和操作系统的兼容性,目前仍然使用 zh-CN
属性值
<html lang="zh-CN">
更多地区语言参考:
zh-SG 中文 (简体, 新加坡) 对应 cmn-Hans-SG 普通话 (简体, 新加坡)
zh-HK 中文 (繁体, 香港) 对应 cmn-Hant-HK 普通话 (繁体, 香港)
zh-MO 中文 (繁体, 澳门) 对应 cmn-Hant-MO 普通话 (繁体, 澳门)
zh-TW 中文 (繁体, 台湾) 对应 cmn-Hant-TW 普通话 (繁体, 台湾)
# 已废弃不推荐使用的 Languages Tags
以下写法已于 2009 年废弃,请勿使用(cmn、wuu、yue、gan 等已由 2005 年的 extlang 升级到 2009 年的 language):
zh-cmn, zh-cmn-Hans, zh-cmn-Hant, zh-wuu, zh-yue, zh-gan
以下写法已于 2009 年废弃,不推荐使用:
zh-Hans, zh-Hans-CN, zh-Hans-SG, zh-Hans-HK, zh-Hans-MO, zh-Hans-TW,
zh-Hant, zh-Hant-CN, zh-Hant-SG, zh-Hant-HK, zh-Hant-MO, zh-Hant-TW
更多已废弃 Languages Tags 参考 IANA Language Subtag Registry 里面的 “Type: redundant“”
# 更多关于 Languages Tags :
W3C Language tags in HTML and XML
网页头部的声明应该是用 lang=”zh” 还是 lang=”zh-cn”?
# CHARSET
Because the character sets in ISO-8859 was limited in size, and not compatible in multilingual environments, the Unicode Consortium developed the Unicode Standard.
The Unicode Standard covers (almost) all the characters, punctuations, and symbols in the world.
Unicode enables processing, storage, and transport of text independent of platform and language.
The default character encoding in HTML-5 is UTF-8.
因为 ISO-8859 中字符集大小是有限的,且在多语言环境中不兼容,所以 Unicode 联盟开发了 Unicode 标准。
Unicode 标准覆盖了(几乎)所有的字符、标点符号和符号。
Unicode 使文本的处理、存储和运输,独立于平台和语言。
HTML-5 中默认的字符编码是 UTF-8
参阅 HTML Unicode (UTF-8) Reference
# 团队约定
一般情况下统一使用 “UTF-8” 编码
<meta charset="UTF-8">
请尽量统一写成标准的 “UTF-8”,不要写成 “utf-8” 或 “utf8” 或 “UTF8”。根据 IETF对UTF-8的定义,其编码标准的写法是 “UTF-8”;而 UTF8 或 utf8 的写法只是出现在某些编程系统中,如 .NET framework 的类 System.Text.Encoding 中的一个属性名就叫 UTF8。
# 更多关于
UTF-8写法: UTF8 or UTF-8?
GBK:Application of IANA Charset Registration for GBK
Charset :character-encoding-declaration
# 元素及标签闭合
HTML元素共有以下5种:
- 空元素:area、base、br、col、command、embed、hr、img、input、keygen、link、meta、param、source、track、wbr
- 原始文本元素:script、style
- RCDATA元素:textarea、title
- 外来元素:来自MathML命名空间和SVG命名空间的元素。
- 常规元素:其他HTML允许的元素都称为常规元素。
元素标签的闭合应遵循以下原则:
Tags are used to delimit the start and end of elements in the markup. Raw text, escapable raw text, and normal elements have a start tag to indicate where they begin, and an end tag to indicate where they end. The start and end tags of certain normal elements can be omitted, as described below in the section on optional tags. Those that cannot be omitted must not be omitted. Void elements only have a start tag; end tags must not be specified for void elements. Foreign elements must either have a start tag and an end tag, or a start tag that is marked as self-closing, in which case they must not have an end tag.
- 原始文本元素、RCDATA元素以及常规元素都有一个开始标签来表示开始,一个结束标签来表示结束。
- 某些元素的开始和结束标签是可以省略的,如果规定标签不能被省略,那么就绝对不能省略它。
- 空元素只有一个开始标签,且不能为空元素设置结束标签。
- 外来元素可以有一个开始标签和配对的结束标签,或者只有一个自闭合的开始标签,且后者情况下该元素不能有结束标签。
# 团队约定
为了能让浏览器更好的解析代码以及能让代码具有更好的可读性,有如下约定:
- 所有具有开始标签和结束标签的元素都要写上起止标签,某些允许省略开始标签或和束标签的元素亦都要写上。
- 空元素标签都不加 “/” 字符
推荐:
<div>
<h1>我是h1标题</h1>
<p>我是一段文字,我有始有终,浏览器能正确解析</p>
</div>
<br>
不推荐:
<div>
<h1>我是h1标题</h1>
<p>我是一段文字,我有始无终,浏览器亦能正确解析
</div>
<br/>
更多关于元素及标签关闭:#Elements
# 书写风格
# HTML代码大小写
HTML标签名、类名、标签属性和大部分属性值统一用小写
推荐:
<div class="demo"></div>
不推荐:
<div class="DEMO"></div>
<DIV CLASS="DEMO"></DIV>
HTML文本、CDATA、JavaScript、meta标签某些属性等内容可大小写混合
<!-- 优先使用 IE 最新版本和 Chrome Frame -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<!-- HTML文本内容 -->
<h1>I AM WHAT I AM </h1>
<!-- JavaScript 内容 -->
<script type="text/javascript">
var demoName = 'demoName';
...
</script>
<!-- CDATA 内容 -->
<script type="text/javascript"><![CDATA[
...
]]></script>
# 类型属性
不需要为 CSS、JS 指定类型属性,HTML5 中默认已包含
推荐:
<link rel="stylesheet" href="" >
<script src=""></script>
不推荐:
<link rel="stylesheet" type="text/css" href="" >
<script type="text/javascript" src="" ></script>
# 元素属性
- 元素属性值使用双引号语法
- 元素属性值可以写上的都写上
推荐:
<input type="text">
<input type="radio" name="name" checked="checked" >
不推荐:
<input type=text>
<input type='text'>
<input type="radio" name="name" checked >
更多关于元素属性:#Attributes
# 特殊字符引用
In certain cases described in other sections, text may be mixed with character references. These can be used to escape characters that couldn’t otherwise legally be included in text.
文本可以和字符引用混合出现。这种方法可以用来转义在文本中不能合法出现的字符。
在 HTML 中不能使用小于号 “<” 和大于号 “>”特殊字符,浏览器会将它们作为标签解析,若要正确显示,在 HTML 源代码中使用字符实体
推荐:
<a href="#">more>></a>
不推荐:
<a href="#">more>></a>
更多关于符号引用:#Character references
# 代码缩进
统一使用四个空格进行代码缩进,使得各编辑器表现一致(各编辑器有相关配置)
<div class="jdc">
<a href="#"></a>
</div>
# 纯数字输入框
使用 type="tel"
而不是 type="number"
<input type="tel">
# 代码嵌套
元素嵌套规范,每个块状元素独立一行,内联元素可选
推荐:
<div>
<h1></h1>
<p></p>
</div>
<p><span></span><span></span></p>
不推荐:
<div>
<h1></h1><p></p>
</div>
<p>
<span></span>
<span></span>
</p>
段落元素与标题元素只能嵌套内联元素
推荐:
<h1><span></span></h1>
<p><span></span><span></span></p>
不推荐:
<h1><div></div></h1>
<p><div></div><div></div></p>
# 注释规范
# 遵循标准
HTML注释规范写法应该遵循以下标准:
Comments must start with the four character sequence U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS (<!–). Following this sequence, the comment may have text, with the additional restriction that the text must not start with a single “>” (U+003E) character, nor start with a U+002D HYPHEN-MINUS character (-) followed by a “>” (U+003E) character, nor contain two consecutive U+002D HYPHEN-MINUS characters (–), nor end with a U+002D HYPHEN-MINUS character (-). Finally, the comment must be ended by the three character sequence U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN (–>).
- 必须以4个有序字符开始:编码为 U+003C LESS-THAN SIGN 的小于号, 编码为 U+0021 EXCLAMATION MARK 的感叹号, 编码为 U+002D HYPHEN-MINUS 横线, 编码为 U+002D HYPHEN-MINUS横线 ,即 “<!–”
- 在此之后是注释内容,注释的内容有以下限制:
- 不能以单个 “>” (U+003E) 字符开始
- 不能以由 “-“(U+002D HYPHEN-MINUS)和 ”>” (U+003E) 组合的字符开始,即 “->”
- 不能包含两个连续的 U+002D HYPHEN-MINUS 字符,即 “–”
- 不能以一个 U+002D HYPHEN-MINUS 字符结束,即 “-”
- 必须以3个有序字符结束:U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN,即 “–>”
标准写法:
<!--Comment Text-->
错误的写法:
<!-->The Wrong Comment Text-->
<!--->The Wrong Comment Text-->
<!--The--Wrong--Comment Text-->
<!--The Wrong Comment Text--->
# 团队约定
# 单行注释
一般用于简单的描述,如某些状态描述、属性描述等
注释内容前后各一个空格字符,注释位于要注释代码的上面,单独占一行
推荐:
<!-- Comment Text -->
<div>...</div>
不推荐:
<div>...</div><!-- Comment Text -->
<div><!-- Comment Text -->
...
</div>
# 模块注释
一般用于描述模块的名称以及模块开始与结束的位置
注释内容前后各一个空格字符,<!-- S Comment Text -->
表示模块开始,<!-- E Comment Text -->
表示模块结束,模块与模块之间相隔一行
推荐写法:
<!-- S Comment Text A -->
<div class="mod_a">
...
</div>
<!-- E Comment Text A -->
<!-- S Comment Text B -->
<div class="mod_b">
...
</div>
<!-- E Comment Text B -->
不推荐写法:
<!-- S Comment Text A -->
<div class="mod_a">
...
</div>
<!-- E Comment Text A -->
<!-- S Comment Text B -->
<div class="mod_b">
...
</div>
<!-- E Comment Text B -->
# 嵌套模块注释
当模块注释内再出现模块注释的时候,为了突出主要模块,嵌套模块不再使用
<!-- S Comment Text -->
<!-- E Comment Text -->
而改用
<!-- /Comment Text -->
注释写在模块结尾标签底部,单独一行。
<!-- S Comment Text A -->
<div class="mod_a">
<div class="mod_b">
...
</div>
<!-- /mod_b -->
<div class="mod_c">
...
</div>
<!-- /mod_c -->
</div>
<!-- E Comment Text A -->
# 文件模版
HTML模版指的是团队使用的初始化HTML文件,里面会根据不同平台而采用不一样的设置,一般主要不同的设置就是 mata 标签的设置,以下是 PC 和移动端的 HTML 模版。
# HTML5标准模版
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>HTML5标准模版</title>
</head>
<body>
</body>
</html>
# 团队约定
# 移动端
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no" >
<meta name="format-detection" content="telephone=no" >
<title>移动端HTML模版</title>
<!-- S DNS预解析 -->
<link rel="dns-prefetch" href="">
<!-- E DNS预解析 -->
<!-- S 线上样式页面片,开发请直接取消注释引用 -->
<!-- #include virtual="" -->
<!-- E 线上样式页面片 -->
<!-- S 本地调试,根据开发模式选择调试方式,请开发删除 -->
<link rel="stylesheet" href="css/index.css" >
<!-- /本地调试方式 -->
<link rel="stylesheet" href="http://srcPath/index.css" >
<!-- /开发机调试方式 -->
<!-- E 本地调试 -->
</head>
<body>
</body>
</html>
# PC端
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="keywords" content="your keywords">
<meta name="description" content="your description">
<meta name="author" content="author,email address">
<meta name="robots" content="index,follow">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="ie-stand">
<title>PC端HTML模版</title>
<!-- S DNS预解析 -->
<link rel="dns-prefetch" href="">
<!-- E DNS预解析 -->
<!-- S 线上样式页面片,开发请直接取消注释引用 -->
<!-- #include virtual="" -->
<!-- E 线上样式页面片 -->
<!-- S 本地调试,根据开发模式选择调试方式,请开发删除 -->
<link rel="stylesheet" href="css/index.css" >
<!-- /本地调试方式 -->
<link rel="stylesheet" href="http://srcPath/index.css" >
<!-- /开发机调试方式 -->
<!-- E 本地调试 -->
</head>
<body>
</body>
</html>
# WebApp Meta
# WebApp Meta 标签设置(iOS)
A web application is designed to look and behave in a way similar to a native application—for example, it is scaled to fit the entire screen on iOS. You can tailor your web application for Safari on iOS even further, by making it appear like a native application when the user adds it to the Home screen. You do this by using settings for iOS that are ignored by other platforms.
WebApp目的在于使其界面和行为在某种程度上类似于原生APP应用。例如,WebApp 可以在 iOS 设备上通过缩放去适配设备屏幕。当用户将WebApp程序添加到主屏幕后,会使得它看上去像原生APP一样,以此,你可以进一步为 Safari 定制自己的 WebApp,而使用某些专为 iOS 平台设定的设置就可以做到。
WebApp可以通过设置 meta 标签来改变页面的一些表现,有些 meta 设置在 Safari 应用或原生 App 的内嵌网页中都可以生效,而有些设置侧需要将应用添加到主屏幕的时候才会生效。
# Viewport Meta Tag
# 通用类设置
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no">
- width – viewport的宽度
- height – viewport的高度
- initial-scale – 初始的缩放比例
- minimum-scale – 允许用户缩放到的最小比例
- maximum-scale – 允许用户缩放到的最大比例
- user-scalable – 是否允许用户缩放
# Safari on iOS viewport
The width of the viewport in pixels. The default is 980. The range is from 200 to 10,000.
The minimum-scale and maximum-scale properties also affect the behavior when changing orientations. The range of these property values is from >0 to 10.0. The default value for minimum-scale is 0.25 and maximum-scale is 5.0
user-scalable – The default is yes. Setting user-scalable to no also prevents a webpage from scrolling when entering text in an input field.
- 默认宽度是 980px,范围从 200px 到 10000px
- initial-scale 缩放比例范围值是 从 >0 到 10 之间
- minimum-scale 默认值是 0.25
- maximum-scale 默认值是 5
- user-scalable – 默认值是 yes,设置 no 还可以在文本框输入文本的时候阻止页面滚动
更多关于 Safari on iOS viewport 的设置:
Configuring the Viewport Safari HTML Reference
# Apple-Specific Meta Tag Keys
# apple-mobile-web-app-capable
设置 WebApp 是否进入全屏模式,该设置需要添加到主屏幕才生效
<meta name="apple-mobile-web-app-capable" content="yes">
If content is set to yes, the web application runs in full-screen mode;otherwise, it does not. The default behavior is to use Safari to display web content.You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone read-only Boolean JavaScript property.
- content设置 yes 进入全屏模式
- 默认会启动 Safari 应用,使用 Safari 应用浏览
- 通过检测 window.navigator.standalone 的 Boolean 值可以判断 web 应用是否处于全屏模式
# apple-mobile-web-app-status-bar-style
为 webapp 设置状态栏样式
<meta name="apple-mobile-web-app-status-bar-style" content="black">
This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable.
If content is set to default, the status bar appears normal. If set to black, the status bar has a black background. If set to black-translucent, the status bar is black and translucent. If set to default or black, the web content is displayed below the status bar. If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar. The default value is default.
- 此 meta 设置只在全屏模式生效
- 默认值是 default
- content=”black”,状态栏背景黑色,网页内容在状态栏下面
- content=”black-translucent”,状态栏半透明,背景黑色,网页内容占满全屏
该设置在 iOS6 和 iOS7 表现还可以,但到了 iOS8 后会出现各种问题,而且在 iOS9 中并没有生效。参阅:iOS 8: web app status bar position and resizing problems
# format-detection
自动识别页面中有可能是电话格式的数字
<meta name="format-detection" content="telephone=no">
By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number. Specifying telephone=no disables this feature.
iOS中的 Safari 会默认识别与电话格式相似的数字并生成一个可以拉起电话应用并将该数字作为电话号码拨打的链接。定义 telephone=no 可以屏蔽该功能
更多 WebApp 设置参考 Configuring Web Applications
# 图片规范
# 图片格式
常见的图片格式有 GIF、PNG8、PNG24、JPEG、WEBP,根据图片格式的特性和场景需要选取适合的图片格式。
# GIF
GIF图象是基于颜色列表的(存储的数据是该点的颜色对应于颜色列表的索引值),最多只支持8位(256色)。GIF文件内部分成许多存储块,用来存储多幅图象或者是决定图象表现行为的控制块,用以实现动画和交互式应用。GIF文件还通过LZW压缩算法压缩图象数据来减少图象尺寸
# 特性
- 优秀的压缩算法使其在一定程度上保证图像质量的同时将体积变得很小。
- 可插入多帧,从而实现动画效果。
- 可设置透明色以产生对象浮现于背景之上的效果。
- 由于采用了8位压缩,最多只能处理256种颜色,故不宜应用于真彩色图片。
更多关于GIF:
# PNG
PNG是20世纪90年代中期开始开发的图像文件存储格式,其目的是企图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。流式网络图形格式(Portable Network Graphic Format,PNG)名称来源于非官方的“PNG’s Not GIF”,是一种位图文件(bitmap file)存储格式,读成“ping”。PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且还可存储多到16位的α通道数据。PNG使用从LZ77派生的无损数据压缩算法。
# 特性
- 支持256色调色板技术,文件体积小。
- 无损压缩
- 最高支持48位真彩色图像以及16位灰度图像。
- 支持Alpha通道的透明/半透明特性。
- 支持图像亮度的Gamma校准信息。
- 支持存储附加文本信息,以保留图像名称、作者、版权、创作时间、注释等信息。
- 渐近显示和流式读写,适合在网络传输中快速显示预览效果后再展示全貌。
- 使用CRC防止文件出错。
- 最新的PNG标准允许在一个文件内存储多幅图像。
更多关于PNG:
PNG官方站 - PNG General Information
# JPEG
JPEG是一种针对照片视频而广泛使用的一种有损压缩标准方法。这个名称代表Joint Photographic Experts Group(联合图像专家小组)。此团队创立于公元1986年,1992年发布了JPEG的标准而在1994年获得了ISO 10918-1的认定
# 特性
- 适用于储存24位元全采影像
- 采取的压缩方式通常为有损压缩
- 不支持透明或动画
- 压缩比越高影像耗损越大,失真越严重
- 压缩比在10左右肉眼无法辨出压缩图与原图的差别
更多关于JPEG:
# WEBP
WebP,是一种同时提供了有损压缩与无损压缩的图片文件格式,派生自视频编码格式 VP8,是由Google在购买On2 Technologies后发展出来。WebP最初在2010年发布,2011年11月8日,Google开始让WebP支持无损压缩和透明色的功能,而在2012年8月16日的参考实做libwebp 0.2.0中正式支持
# 特性
- 同时提供有损压缩和无损压缩两种图片文件格式
- 文件体积小,无损压缩后,比 PNG 文件少了 45% 的文件大小;有损压缩后,比 JPEG 文件少了 25% - 34% 文件大小
- 浏览器兼容差,目前只支持客户端 Chrome 和 Opera 浏览器以及安卓原生浏览器(Andriod 4.0+),WebP兼容性
更多关于WebP:
# 团队约定
# 内容图
内容图多以商品图等照片类图片形式存在,颜色较为丰富,文件体积较大
- 优先考虑 JPEG 格式,条件允许的话优先考虑 WebP 格式
- 尽量不使用PNG格式,PNG8 色位太低,PNG24 压缩率低,文件体积大
# 背景图
背景图多为图标等颜色比较简单、文件体积不大、起修饰作用的图片
- PNG 与 GIF 格式,优先考虑使用 PNG 格式,PNG格式允许更多的颜色并提供更好的压缩率
- 图像颜色比较简单的,如纯色块线条图标,优先考虑使用 PNG8 格式,避免不使用 JPEG 格式
- 图像颜色丰富而且图片文件不太大的(40KB 以下)或有半透明效果的优先考虑 PNG24 格式
- 图像颜色丰富而且文件比较大的(40KB - 200KB)优先考虑 JPEG 格式
- 条件允许的,优先考虑 WebP 代替 PNG 和 JPEG 格式
# 图片大小
# 全国网速现状
# 固定网络
据文章 《2015年Q3中国宽带速率状况报告》,2015第三季全国平均速度整体情况:
中国固定宽带互联网网络平均网络下载速率达到7.90 Mbit/s,用户进行网页浏览的平均首屏呈现时间为2.18s,平均视频下载速率为6.41Mbit/s
# 移动网络
3G网络传输速率理论峰值在3.5Mbps,4G网络传输速率理论上可达到20Mbps,最高可以达到100Mbps。根据 128KB/s=128×8(Kb/s)=1024Kb/s=1Mb/s
的转换来算,3G网络的理论传输速率可达到450KB/s,4G网络的理论传输速率可达到 2.5MB/s ~ 12.5MB/s
受用户计算机性能、网络设备质量、资源使用情况、网络高峰期、网站服务能力、线路衰耗、信号衰减等多因素影响,3G和4G的实际平均传输速率约为:
- 3G:最高值100KB/s,平均值40~50KB/s
- 4G:最高值2.75MB/s,平均500~1000KB/s
# 3G/4G用户占比
2015年8月移动宽带(3G/4G)用户占比各省分布情况:
据文章 《工信部:2015年7月底中国4G用户累计超过2.5亿》 介绍:
截至2015年7月底,中国4G用户累计超过2.5亿(全球LTE用户超过7.9亿,全球TD-LTE用户超过2.78亿),已建设4G基站超过153万个,其中完成TD-LTE基站建设超过100万个,多载波聚合等TD-LTE演进技术逐步商用,4G智能手机已经占到国内智能手机市场的82.7%。
# 团队约定
中国普通家庭的宽带基本能达到8Mbps,实际速率大约为500—900KB/s,全国3G/4G用户占有比超过了50%,为了保证图片能更好地加载展示给用户看,团队约定:
PC平台单张的图片的大小不应大于 200KB。
移动平台单张的图片的大小不应大于 100KB。
(图片的大小约定标准随全国网速的改变而改变)
# 图片质量
- 上线的图片都应该经过压缩处理,压缩后的图片不应该出现肉眼可感知的失真区域
- 60质量的JPEG格式图片与质量大于60的相比,肉眼已看不出明显的区别,因此保存 JPEG 图的时候,质量一般控制在60,若保真度要求高的图片可适量提高到 80,图片大小控制在 200KB 以内
# 图片引入
HTML 中图片引入不需添加 width、height 属性,alt 属性应该写上
推荐:
<img src="" alt="" >
不推荐:
<img src="" width="" height="" >
CSS 中图片引入不需要引号
.jdc {
background-image: url(icon.png);
}
# CSS Sprites VS Data URIs
# CSS Sprites特点
- 减少请求数
- 加速图片的显示
- 维护更新成本大
- 更多的内存消耗,特别是大体积或有过多空白的 Sprites 图
- 图片渗漏,相邻的不需展示的图片有可能出现在展示元素中,特别是在高清设备移动设备上
# Data URIs(base64编码)
- 减少请求数
- 转换文件体积大,大约比原始的二进制大33%
- IE6 / IE7 不支持
- 图片显示相对较慢,需要更多的CPU消耗
更多关于 CSS Sprites 和 Data URIs 可以阅读:
《When to Base64 Encode Images (and When Not To)》
CSS Sprites vs. Data URIs: Which is Faster on Mobile?
# 团队约定
# CSS Sprites 使用建议
- 适合使用频率高更新频率低的小图标
- 尽量不留太多的空白
- 体积较大的图片不合并
- 确保要合并的小图坐标数值和合并后的 Sprites 图尺寸均为偶数
# Data URIs(base64编码)使用建议
- 适合更新频率高的小图片,如某些具备自定义功能的标题icon等
- 转换成 Base64 编码的图片应小于 2KB
- 移动端不使用 Base64 编码
- 要兼容 IE6/IE7 的不使用
# CSS规范
# 代码规范
# 编码规范
CSS样式表是一个序列通用字符集,传输和存储过程中,这些字符必须由支持 US-ASCII(例如 UTF-8, ISO 8859-x, SHIFT JIS 等)字符编码方式编译
# 文档内嵌样式表编码
When a style sheet is embedded in another document, such as in the STYLE element or “style” attribute of HTML, the style sheet shares the character encoding of the whole document.
当样式出现在其它文档,如 HTML 的 STYLE 标签或标签属性 “style”,样式的编码由文档的决定。
# 文档外链样式表编码
When a style sheet resides in a separate file, user agents must observe the following priorities when determining a style sheet’s character encoding (from highest priority to lowest):
- An HTTP “charset” parameter in a “Content-Type” field (or similar parameters in other protocols)
- BOM and/or @charset
- or other metadata from the linking mechanism (if any)
- charset of referring style sheet or document (if any)
- Assume UTF-8
文档外链样式表的编码可以由以下各项按照由高到低的优先级顺序决定:
- HTTP “Content-Type” 字段参数 “charset”(或其它协议相似的参数)
- BOM(byte-order mark)和(或)@charset
- Link 中的元数据设置(如果有的话)
- 引用样式表字符集或文档编码(如果有的话)
- 假定为 UTF-8 编码
# 样式表编码
Authors using an @charset rule must place the rule at the very beginning of the style sheet, preceded by no characters. (If a byte order mark is appropriate for the encoding used, it may precede the @charset rule.)
@charset must be written literally, i.e., the 10 characters ‘@charset “‘ (lowercase, no backslash escapes), followed by the encoding name, followed by ‘“;’.
- @charset规则一定要在样式文件的第一行首个字符位置开始,否则的话就会有机会让 BOM 设置生效(如果有设置 BOM 的话)而优于 @charset 作为样式表的编码
@charset "";
一定要写上,并且用小写字母,不能出现转义符
# 团队约定
- 样式文件必须写上 @charset 规则,并且一定要在样式文件的第一行首个字符位置开始写,编码名用 “UTF-8”
- 字符 @charset “”; 都用小写字母,不能出现转义符,编码名允许大小混写
- 考虑到在使用“UTF-8”编码情况下 BOM 对代码的污染和编码显示的问题,在可控范围下,坚决不使用 BOM。(更多关于 BOM 可参考 BOM的介绍 和 「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别? )
推荐:
@charset "UTF-8";
.jdc{}
不推荐:
/**
* @desc File Info
* @author Author Name
* @date 2015-10-10
*/
/* @charset规则不在文件首行首个字符开始 */
@charset "UTF-8";
.jdc{}
@CHARSET "UTF-8";
/* @charset规则没有用小写 */
.jdc{}
/* 无@charset规则 */
.jdc{}
更多关于样式编码:CSS style sheet representation
# 代码风格
# 代码格式化
样式书写一般有两种:一种是紧凑格式 (Compact)
.jdc{ display: block;width: 50px;}
一种是展开格式(Expanded)
.jdc{
display: block;
width: 50px;
}
团队约定
统一使用展开格式书写样式
# 代码大小写
样式选择器,属性名,属性值关键字全部使用小写字母书写,属性字符串允许使用大小写。
/* 推荐 */
.jdc{
display:block;
}
/* 不推荐 */
.JDC{
DISPLAY:BLOCK;
}
# 选择器
- 尽量少用通用选择器
*
- 不使用 ID 选择器
- 不使用无具体语义定义的标签选择器
/* 推荐 */
.jdc {}
.jdc li {}
.jdc li p{}
/* 不推荐 */
*{}
#jdc {}
.jdc div{}
# 代码缩进
统一使用四个空格进行代码缩进,使得各编辑器表现一致(各编辑器有相关配置)
.jdc {
width: 100%;
height: 100%;
}
# 分号
每个属性声明末尾都要加分号;
.jdc {
width: 100%;
height: 100%;
}
# 代码易读性
左括号与类名之间一个空格,冒号与属性值之间一个空格
推荐:
.jdc {
width: 100%;
}
不推荐:
.jdc{
width:100%;
}
逗号分隔的取值,逗号之后一个空格
推荐:
.jdc {
box-shadow: 1px 1px 1px #333, 2px 2px 2px #ccc;
}
不推荐:
.jdc {
box-shadow: 1px 1px 1px #333,2px 2px 2px #ccc;
}
为单个css选择器或新申明开启新行
推荐:
.jdc,
.jdc_logo,
.jdc_hd {
color: #ff0;
}
.nav{
color: #fff;
}
不推荐:
.jdc,jdc_logo,.jdc_hd {
color: #ff0;
}.nav{
color: #fff;
}
颜色值 rgb()
rgba()
hsl()
hsla()
rect()
中不需有空格,且取值不要带有不必要的 0
推荐:
.jdc {
color: rgba(255,255,255,.5);
}
不推荐:
.jdc {
color: rgba( 255, 255, 255, 0.5 );
}
属性值十六进制数值能用简写的尽量用简写
推荐:
.jdc {
color: #fff;
}
不推荐:
.jdc {
color: #ffffff;
}
不要为 0
指明单位
推荐:
.jdc {
margin: 0 10px;
}
不推荐:
.jdc {
margin: 0px 10px;
}
# 属性值引号
css属性值需要用到引号时,统一使用单引号
/* 推荐 */
.jdc {
font-family: 'Hiragino Sans GB';
}
/* 不推荐 */
.jdc {
font-family: "Hiragino Sans GB";
}
# 属性书写顺序
建议遵循以下顺序:
- 布局定位属性:display / position / float / clear / visibility / overflow
- 自身属性:width / height / margin / padding / border / background
- 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
- 其他属性(CSS3):content / cursor / border-radius / box-shadow / text-shadow / background:linear-gradient …
.jdc {
display: block;
position: relative;
float: left;
width: 100px;
height: 100px;
margin: 0 10px;
padding: 20px 0;
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: #333;
background: rgba(0,0,0,.5);
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-o-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}
# CSS3浏览器私有前缀写法
CSS3 浏览器私有前缀在前,标准前缀在后
.jdc {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-o-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}
更多关于浏览器私有前辍写法:#Vendor-specific extensions
# 注释规范
Comments begin with the characters
/*
and end with the characters*/
. They may occur anywhere outside other tokens, and their contents have no influence on the rendering. Comments may not be nested.
- 注释以字符
/*
开始,以字符*/
结束 - 注释不能嵌套
/*Comment Text*/
# 团队约定
# 单行注释
注释内容第一个字符和最后一个字符都是一个空格字符,单独占一行,行与行之间相隔一行
推荐:
/* Comment Text */
.jdc{}
/* Comment Text */
.jdc{}
不推荐:
/*Comment Text*/
.jdc{
display: block;
}
.jdc{
display: block;/*Comment Text*/
}
# 模块注释
注释内容第一个字符和最后一个字符都是一个空格字符,/*
与 模块信息描述占一行,多个横线分隔符-
与*/
占一行,行与行之间相隔两行
推荐:
/* Module A
---------------------------------------------------------------- */
.mod_a {}
/* Module B
---------------------------------------------------------------- */
.mod_b {}
不推荐:
/* Module A ---------------------------------------------------- */
.mod_a {}
/* Module B ---------------------------------------------------- */
.mod_b {}
# 文件信息注释
在样式文件编码声明 @charset
语句下面注明页面名称、作者、创建日期等信息
@charset "UTF-8";
/**
* @desc File Info
* @author Author Name
* @date 2015-10-10
*/
更多关于CSS注释:#Comments
# SASS规范
# 语法选用
SASS有两种语法格式,一种是 SCSS (Sassy CSS),另一种是缩进格式(Indented Syntax),有时称之为 Sass。
# SCSS
SCSS语法基于 CSS 语法扩展,每一个有效的 CSS 文件都是一个有效的具有相同含义的 SCSS 文件,换种说法就是 SCSS 能识别大多数的 CSS hacks 写法和浏览器前缀写法以及早期的 IE 滤镜写法,这种格式以 .scss 作为扩展名。
# Sass
Sass 使用 “缩进” 代替 “花括号” 表示属性属于某个选择器,用 “换行” 代替 “分号” 分隔属性,很多人认为这样做比 SCSS 更容易阅读,书写也更快速。缩进格式也可以使用 Sass 的全部功能,只是与 SCSS 相比个别地方采取了不同的表达方式,具体请查看 the indented syntax reference。这种格式以 .sass 作为拓展名。
更详细的用法请阅读 SASS 官网文档:DOCUMENTATION
# 团队约定
考虑到 SCSS 语法对 CSS 语法友好的兼容性和扩展性,我们在使用 SASS 编写样式的时候,统一使用 SCSS 语法
# 编码格式
When running on Ruby 1.9 and later, Sass is aware of the character encoding of documents. Sass follows the CSS spec to determine the encoding of a stylesheet, and falls back to the Ruby string encoding. This means that it first checks the Unicode byte order mark, then the @charset declaration, then the Ruby string encoding. If none of these are set, it will assume the document is in UTF-8.
当在 Ruby1.9或更新的版本运行的时候,SASS 能识辨文档的字符编码。SASS 遵循 CSS 规范去确定样式文件的编码,进而转回 Ruby 字符串编码。这意味着SASS编译的时候会首先检测 BOM,然后到 @charset 声明,再到 Ruby 字符串编码,如果以上都没有设置,SASS 会认为文档的编码为 UTF-8
# 团队约定
严格遵守上面 “CSS规范” 中的 “编码规范”
更多关于 SASS 编码:SASS Encodings
# SASS注释规范
SASS支持 CSS 标准的多行注释 /* */
,同时也支持单行注释 //
。
- 多行注释在使用非 Compressed 模式进行编译后的输出文件中会保留下来,单行注释
//
侧会被移除 - 多行注释和单行注释在 SASS 编译后输出的压缩 CSS 文件都会被移除
- 当多行注释内容第一个字符是感叹号 “!” 的时候,即
/*! */
,SASS 无论用哪一种编译方式编译注释都会保留 - 注释内容可以加入 SASS 变量
# 团队约定
SCSS 文件内
- 全部遵循 CSS 注释规范
- 不使用
/*! */
注释方式 - 注释内不放 SASS 变量
标准的注释规范如下:
@charset "UTF-8";
/**
* @desc File Info
* @author liqinuo
* @date 2015-10-10
*/
/* Module A
----------------------------------------------------------------*/
.mod_a {}
/* module A logo */
.mod_a_logo {}
/* module A nav */
.mod_a_nav {}
/* Module B
----------------------------------------------------------------*/
.mod_b {}
/* module B logo */
.mod_b_logo {}
/* module B nav */
.mod_b_nav {}
# 嵌套规范
# 选择器嵌套
/* CSS */
.jdc {}
body .jdc {}
/* SCSS */
.jdc {
body & {}
}
/* CSS */
.jdc {}
.jdc_cover {}
.jdc_info {}
.jdc_info_name {}
/* SCSS */
.jdc {
&_cover {}
&_info {
&_name {}
}
}
# 属性嵌套
/* CSS */
.jdc {
background-color: red;
background-repeat: no-repeat;
background-image: url(/img/icon.png);
background-position: 0 0;
}
/* SCSS */
.jdc {
background: {
color: red;
repeat: no-repeat;
image: url(/img/icon.png);
position: 0 0;
}
}
# 变量
可复用属性尽量抽离为页面变量,易于统一维护
// CSS
.jdc {
color: red;
border-color: red;
}
// SCSS
$color: red;
.jdc {
color: $color;
border-color: $color;
}
# 混合(mixin)
根据功能定义模块,然后在需要使用的地方通过 @include
调用,避免编码时重复输入代码段
// CSS
.jdc_1 {
-webkit-border-radius: 5px;
border-radius: 5px;
}
.jdc_2 {
-webkit-border-radius: 10px;
border-radius: 10px;
}
// SCSS
@mixin radius($radius:5px) {
-webkit-border-radius: $radius;
border-radius: $radius;
}
.jdc_1 {
@include radius; //参数使用默认值
}
.jdc_2 {
@include radius(10px);
}
// CSS
.jdc_1 {
background: url(/img/icon.png) no-repeat -10px 0;
}
.jdc_2 {
background: url(/img/icon.png) no-repeat -20px 0;
}
// SCSS
@mixin icon($x:0, $y:0) {
background: url(/img/icon.png) no-repeat $x, $y;
}
.jdc_1 {
@include icon(-10px, 0);
}
.jdc_2 {
@include icon(-20px, 0);
}
# 占位选择器 %
如果不调用则不会有任何多余的 css 文件,占位选择器以 %
标识定义,通过 @extend
调用
//scss
%borderbox {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.jdc {
@extend %borderbox;
}
# extend 继承
// CSS
.jdc_1 {
font-size: 12px;
color: red;
}
.jdc_2 {
font-size: 12px;
color: red;
font-weight: bold;
}
// SCSS
.jdc_1 {
font-size: 12px;
color: red;
}
.jdc_2 {
@extend .jdc_1;
font-weight: bold;
}
// 或者
%font_red {
font-size: 12px;
color: red;
}
.jdc_1 {
@extend %font_red;
}
.jdc_2 {
@extend %font_red;
font-weight: bold;
}
# for 循环
// CSS
.jdc_1 {background-position: 0 -20px;}
.jdc_2 {background-position: 0 -40px;}
.jdc_3 {background-position: 0 -60px;}
// SCSS
@for $i from 1 through 3 {
.jdc_#{$i} {
background-position: 0 (-20px) * $i;
}
}
注意:#{}
是连接符,变量连接使用时需要依赖
# each 循环
// CSS
.jdc_list {
background-image: url(/img/jdc_list.png);
}
.jdc_detail {
background-image: url(/img/jdc_detail.png);
}
// SCSS
@each $name in list, detail {
.jdc_#{$name} {
background-image: url(/img/jdc_#{$name}.png);
}
}
// CSS
.jdc_list {
background-image: url(/img/jdc_list.png);
background-color: red;
}
.jdc_detail {
background-image: url(/img/jdc_detail.png);
background-color: blue;
}
// SCSS
@each $name, $color in (list, red), (detail, blue) {
.jdc_#{$name} {
background-image: url(/img/jdc_#{$name}.png);
background-color: $color;
}
}
# function 函数
@function pxToRem($px) {
@return $px / 10px * 1rem;
}
.jdc {
font-size: pxToRem(12px);
}
# 运算规范
运算符之间空出一个空格
.jdc {
width: 100px - 50px;
height: 30px / 5;
}
注意运算单位,单位同时参与运算,所以 10px 不等于 10,乘除运算时需要特别注意
// 正确的运算格式
.jdc {
width: 100px - 50px;
width: 100px + 50px;
width: 100px * 2;
width: 100px / 2;
}
# 重置样式
# 移动端
* { -webkit-tap-highlight-color: transparent; outline: 0; margin: 0; padding: 0; vertical-align: baseline; }
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin: 0; padding: 0; vertical-align: baseline; }
img { border: 0 none; vertical-align: top; }
i, em { font-style: normal; }
ol, ul { list-style: none; }
input, select, button, h1, h2, h3, h4, h5, h6 { font-size: 100%; font-family: inherit; }
table { border-collapse: collapse; border-spacing: 0; }
a { text-decoration: none; color: #666; }
body { margin: 0 auto; min-width: 320px; max-width: 640px; height: 100%; font-size: 14px; font-family: -apple-system,Helvetica,sans-serif; line-height: 1.5; color: #666; -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; }
input[type="text"], textarea { -webkit-appearance: none; -moz-appearance: none; appearance: none; }
# PC端
html, body, div, h1, h2, h3, h4, h5, h6, p, dl, dt, dd, ol, ul, li, fieldset, form, label, input, legend, table, caption, tbody, tfoot, thead, tr, th, td, textarea, article, aside, audio, canvas, figure, footer, header, mark, menu, nav, section, time, video { margin: 0; padding: 0; }
h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal }
article, aside, dialog, figure, footer, header, hgroup, nav, section, blockquote { display: block; }
ul, ol { list-style: none; }
img { border: 0 none; vertical-align: top; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: none; }
table { border-collapse: collapse; border-spacing: 0; }
strong, em, i { font-style: normal; font-weight: normal; }
ins { text-decoration: underline; }
del { text-decoration: line-through; }
mark { background: none; }
input::-ms-clear { display: none !important; }
body { font: 12px/1.5 \5FAE\8F6F\96C5\9ED1, \5B8B\4F53, "Hiragino Sans GB", STHeiti, "WenQuanYi Micro Hei", "Droid Sans Fallback", SimSun, sans-serif; background: #fff; }
a { text-decoration: none; color: #333; }
a:hover { text-decoration: underline; }
# 媒体查询
设备尺寸参考 :Mobile devices
媒体查询类型浏览器支持情况:CSS3 Media Queries overview
# 常用查询语句
判断设备横竖屏
/* 横屏 */
@media all and (orientation :landscape) {
}
/* 竖屏 */
@media all and (orientation :portrait) {
}
判断设备宽高
/* 设备宽度大于 320px 小于 640px */
@media all and (min-width:320px) and (max-width:640px) {
}
判断设备像素比
/* 设备像素比为 1 */
@media only screen and (-webkit-min-device-pixel-ratio: 1), only screen and (min-device-pixel-ratio: 1) {
}
/* 设备像素比为 1.5 */
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
}
/* 设备像素比为 2 */
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
}
# 常用设备设置
# iPhones
/* ----------- iPhone 4 and 4S ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (-webkit-min-device-pixel-ratio: 2) {
}
/* Portrait */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: portrait) {
}
/* Landscape */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: landscape) {
}
/* ----------- iPhone 5 and 5S ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 568px)
and (-webkit-min-device-pixel-ratio: 2) {
}
/* Portrait */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 568px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: portrait) {
}
/* Landscape */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 568px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: landscape) {
}
/* ----------- iPhone 6 ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (-webkit-min-device-pixel-ratio: 2) {
}
/* Portrait */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: portrait) {
}
/* Landscape */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: landscape) {
}
/* ----------- iPhone 6+ ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 414px)
and (max-device-width: 736px)
and (-webkit-min-device-pixel-ratio: 3) {
}
/* Portrait */
@media only screen
and (min-device-width: 414px)
and (max-device-width: 736px)
and (-webkit-min-device-pixel-ratio: 3)
and (orientation: portrait) {
}
/* Landscape */
@media only screen
and (min-device-width: 414px)
and (max-device-width: 736px)
and (-webkit-min-device-pixel-ratio: 3)
and (orientation: landscape) {
}
# Galaxy Phones
/* ----------- Galaxy S3 ----------- */
/* Portrait and Landscape */
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 2) {
}
/* Portrait */
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 2)
and (orientation: portrait) {
}
/* Landscape */
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 2)
and (orientation: landscape) {
}
/* ----------- Galaxy S4 ----------- */
/* Portrait and Landscape */
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3) {
}
/* Portrait */
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: portrait) {
}
/* Landscape */
@media screen
and (device-width: 320px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: landscape) {
}
/* ----------- Galaxy S5 ----------- */
/* Portrait and Landscape */
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3) {
}
/* Portrait */
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: portrait) {
}
/* Landscape */
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: landscape) {
}
# HTC Phones
/* ----------- HTC One ----------- */
/* Portrait and Landscape */
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3) {
}
/* Portrait */
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: portrait) {
}
/* Landscape */
@media screen
and (device-width: 360px)
and (device-height: 640px)
and (-webkit-device-pixel-ratio: 3)
and (orientation: landscape) {
}
# iPads
/* ----------- iPad mini ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (-webkit-min-device-pixel-ratio: 1) {
}
/* Portrait */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 1) {
}
/* Landscape */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: landscape)
and (-webkit-min-device-pixel-ratio: 1) {
}
/* ----------- iPad 1 and 2 ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (-webkit-min-device-pixel-ratio: 1) {
}
/* Portrait */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 1) {
}
/* Landscape */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: landscape)
and (-webkit-min-device-pixel-ratio: 1) {
}
/* ----------- iPad 3 and 4 ----------- */
/* Portrait and Landscape */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (-webkit-min-device-pixel-ratio: 2) {
}
/* Portrait */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 2) {
}
/* Landscape */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: landscape)
and (-webkit-min-device-pixel-ratio: 2) {
}
# 移动端常用私有属性
目前两大主流移动平台为 iOS
和 Android
,有不少带 -webkit-
前辍的 CSS 私有属性以及一些 iOS only 属性,当中好些属性在日常需求中经常应用到。
WebKit
CSS 属性中的一部分已经被包含在 CSS 规范草案中,并且可能成为最后的推荐标准,但目前仍然是试验性的属性,还有一些属性是不规范的属性,它们没有出现在跟踪规范中。
# -webkit-scrollbar
-webkit-scrollbar
是-webkit-私有的伪元素,用于对拥有overflow属性的区域 自定义滚动条的样式。
譬如,为了隐藏滚动条,你可以这么做:
.scroll::-webkit-scrollbar {
width: 0;
height: 0;
}
除了对整个滚动条的控制外,Webkit还提供了控制对滚动条各组成部分的表现渲染的伪元素,甚至具体到滚动条的各种状态行为的伪类。
# 滚动条各块组成表现渲染的伪元素
一般而言,滚动条的主要组成部分包括:
- 滚动按钮 — 滚动按钮的夹角则被称为滚动角(corner)。
- 轨道 — 轨道(track)可以进一步分为轨枕(track pieces) 和滑块(thumb)。
Webkit则根据滚动条各组成部分,提供了不同的伪元素来自定义样式。
::-webkit-scrollbar { /* 1 */ }
::-webkit-scrollbar-button { /* 2 */ }
::-webkit-scrollbar-track { /* 3 */ }
::-webkit-scrollbar-track-piece { /* 4 */ }
::-webkit-scrollbar-thumb { /* 5 */ }
::-webkit-scrollbar-corner { /* 6 */ }
::-webkit-resizer { /* 7 */ }
下图则是各伪元素对应的滚动条各部分:
::-webkit-scrollbar
:滚动条整体部分。可设置width、height、background、border等。
::-webkit-scrollbar-button
:滚动条两端的按钮。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。
::-webkit-scrollbar-track
:轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。
::-webkit-scrollbar-track-piece
:轨枕,也就是除去滚动滑块的部分。
::-webkit-scrollbar-thumb
:滚动滑块,也就是滚动条里面可以拖动的那部分。
::-webkit-scrollbar-corner
:滚动按钮的夹角则被称为滚动角。
::-webkit-resizer
:用于定义右下角拖动块的样式。
需要注意的是:若是水平滚动条,则width属性不起作用,height属性用来控制滚动条相应部分竖直方向高度;若是竖直滚动条,则height属性不起作用,width属性用来控制相应部分的宽度。
# 滚动条各块组成的伪元素
下面的伪类可以应用到上面的伪元素中。
:horizontal
:选择水平方向的滚动条。
:vertical
:选择垂直方向的滚动条。
:decrement
:适用于滚动按钮和轨枕。选择能够使得视窗位置递减状态(例如,垂直滚动条向上滚动,水平滚动条向左滚动。)的滚动按钮或轨枕。
:increment
:适用于滚动按钮和轨枕。选择能够使得视窗位置递增状态(例如,垂直滚动条向下滚动,水平滚动条向右滚动。)的滚动按钮或轨枕。
:start
:适用于滚动按钮和轨枕。选择位于滚动滑块前边的滚动按钮和轨枕。
:end
:适用于滚动按钮和轨枕。选择位于滚动滑块后边的滚动按钮和轨枕。
:double-button
:适用于滚动按钮和轨枕。选中紧挨着一对按钮的轨枕以及位于滚动条某一端的一对按钮中的其中一个滚动按钮。
:single-button
:适用于滚动按钮和轨枕。选中紧挨着仅一个按钮的轨枕以及位于滚动条某一端的仅它本身一个的滚动按钮。
:no-button
:适用于轨枕。选中轨道结束位置没有按钮的轨枕。
:corner-present
:适用于选中滚动角不存在的滚动条。
:window-inactive
:适用于所有滚动条,选中焦点不在该视窗的滚动区域。
另外,:enabled、:disabled、:hover、和:active等伪类同样在滚动条中适用。 为了更好地理解,以下是几个伪元素组合伪类的应用例子:
::-webkit-scrollbar-track-piece:start {
/\*滚动条上半边或左半边\*/
}
::-webkit-scrollbar-thumb:window-inactive {
/\*当焦点不在当前区域滑块的状态\*/
::-webkit-scrollbar-button:horizontal:decrement:hover {
/\*当鼠标在水平滚动条下面的按钮上的状态\*/
或者,读者可以去阅读官方例子
# 参考资料:
# -webkit-touch-callout
-webkit-touch-callout
是一个不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
当你触摸并按住触摸目标时候,禁止或显示系统默认菜单。在iOS上,当你触摸并按住触摸的目标,比如一个链接,Safari浏览器将显示链接有关的系统默认菜单,这个属性可以让你禁用系统默认菜单。
# 属性值
none
:系统默认菜单被禁用inherit
:系统默认菜单不被禁用
# 兼容性
- iOS 2.0及更高版本的 Safari 浏览器可用
- Android 尚不明确
# -webkit-tap-highlight-color
-webkit-tap-highlight-color
是一个不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
在 iOS Safari 上,当用户点击链接或具有 JavaScript 可点击脚本的元素,系统会为这些被点击元素加上一个默认的透明色值,该属性可以覆盖该透明值。
# 属性值
# 兼容性
- iOS 1.1.1及更高版本的Safari浏览器可用
- 大部分安卓手机
# -webkit-overflow-scrolling
定义在具 overflow:scroll
属性的元素内是否采用原生样式滚动行为
# 属性值
auto
:默认值,单手滚动,滚动没有惯性效果touch
:原生样式滚动,应用此属性值会产生层叠上下文(会影响定位参照物的属性,类似opacity
、masks
、transforms
属性,影响到position
的效果,甚至影响到position:fixed
的定位参照物,)
# 兼容性
- iOS 5.0 及更高版本
- 大部分安卓机
# -webkit-line-clamp
-webkit-line-clamp
是一个不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他外来的WebKit属性。
常见结合属性:
display: -webkit-box
:必须结合的属性,将对象作为弹性伸缩盒子模型显示。-webkit-box-orient
:必须结合的属性,设置或检索伸缩盒对象的子元素的排列方式。text-overflow
:可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本。
# 属性值
# 兼容性
- iOS
- Andriod
# -webkit-appearance
-webkit-appearance
是一个不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。
改变按钮和其他控件的外观,使其类似于原生控件。
# 属性值
none
:去除系统默认 appearance 的样式,常用于 iOS 下移除原生样式button
:渲染成 button 的风格checkbox
:渲染成 input checkbox 样式的复选框按钮radio
:渲染成 radio 的风格- …
更多属性值参考 mozilla:-webkit-appearance 属性
# 兼容性
- iOS 2.0及更高版本的Safari浏览器可用
- Android 尚不明确
# -webkit-font-smoothing
字体平滑,该属性定义文本的平滑属性,但要注意以下说明:
非标准属性,不建议用于网页上,这个属性不能保证所有用户都能看到相同效果,这会使网站的字体渲染造成不一致,而此属性的渲染行为日后也有可能会改变
# 属性值
none
:去掉字体平滑效果,使字体带锯齿antialiased
:使字体在像素级别更平滑更轻细subpixel-antialiased
:在多数非 Retina 显示设备中字体将会更锐利。
注意:以上属性在 Retina 设备上会有明显的效果,在非 Retina 设备上看不出差异
# 兼容性
- 部分高清设备,如 Retina Mac
# -webkit-backface-visibility
backface-visibility
在 W3文档 有定义描述
定义转换元素的背面是否显示
# 属性值
visible
:显示(默认值)hidden
:隐藏
# 兼容性
- iOS 2.0 及更高版本的 Safari 浏览器可用
- 大部分 Android
# -webkit-mask
定义多样的蒙板效果属性(缩写属性,类似 margin
)
# 使用语法
<mask-image> [<mask-repeat> || <mask-attachment> || <mask-position> || <mask-origin> || <mask-clip> || <mask-composite>]*
where
<mask-position> = [ <percentage> | <length> | left | center | right ] [ <percentage> | <length> | top | center | bottom ]?
默认值:
-webkit-mask: none repeat scroll 0% 0% padding border add;
# 属性值
:为元素设置蒙板图片,蒙板图片会根据图片的透明区域对元素可视部分进行裁剪 :图片链接作为蒙板图片 :渐变函数 -webkit-gradient
作为蒙板图片none
:去掉蒙板图片
:定义蒙板图片是否平铺或平铺的方式 repeat
:默认值,水平和垂直方向平铺repeat-x
:水平方向平铺repeat-y
:垂直方向平铺no-repeat
:不平铺
:如果 `-webkit-mask-image` 属性有设置,`attachment` 决定该图片是否相对视窗固定或随着其容器滚动 scroll
:默认值,随容器滚动fixed
:相地视窗固定
:定义蒙板图片的初始位置,书写格式类似 `background-position`—-` [, ]*` left
right
center
:定义蒙板图片定位相对起点,与 `webkit-mask-position` 属性相关。当 `-webkit-mask-attachment:fixed` 的时候,该属性不生效。 padding
:默认值,蒙板定位相对边距border
:蒙板定位相对边框content
:蒙板定位相对元素盒子内容
:如果 `-webkit-mask-image` 属性有设置,`-webkit-mask-clip` 将定义蒙板图片的裁剪区域 border
:默认值,蒙板图片延伸到容器的边框padding
:蒙板图片延伸到容器的边距content
:蒙板图片裁剪到元素盒子内容范围text
:蒙板图片裁剪到元素文本范围
:定义蒙板图片重合的裁剪显示方式 add
:默认值,图片重合不裁剪subtract
:去掉层级低的图形以及图片重合部分图形,只留层级高非重合部分图形intersect
:只留重合部分图形exclude
:只去掉重合部分图形
有关属性更详细描述请参考:
# 兼容性
- Safari 4.0 及更高版本
- iOS 4.0 及更高版本
- Android 2.1 及更高版本
# -webkit-user-select
定义用户是否能选中元素内容
# 属性值
auto
:可选中元素内容none
:不能选中任何内容text
:可选中元素内的文本
# 兼容性
- iOS 3.0 及更高版本的 Safari
- 大部分安卓手机
# -webkit-user-modify
定义用户是否可编辑元素内容
# 属性值
read-only
:只读read-write
:可读可写,粘贴内容会保留富文本格式( Android 机不保留富文本格式 )read-write-plaintext-only
:可读可写,粘贴内容所有富文本格式都会丢失
注意:使用这个属性的时候,请不要出现 -webkit-user-select: none
,文本无法选中的情况下,在 Safari 该属性不生效,不过在 Chrome 依然生效
# 兼容性
- iOS 5.0 及更高版本
- Safari 3.0 及更高版本
- 大部分安卓手机
# -webkit-text-stroke
定义文本描边,可以设计描边的宽和颜色,一般与文本填充属性 -webkit-text-fill-color
共用。
# 属性值
:长度单位 :颜色值
# 兼容性
- iOS 2.0 及更高版本
- Safari 3.0 及更高版本
- 安卓尚不明确
# -webkit-text-fill-color
定义文本填充,一般与文本描边属性 -webkit-text-stroke
共用。
# 属性值
:颜色值 currentcolor
:元素color
属性值-webkit-activelink
:链接被点击时系统的默认颜色
更多属性值参考:Safari CSS Reference -webkit-text-fill-color
# 兼容性
- iOS 2.0 及更高版本
- Safari 3.0 及更高版本
- 安卓尚不明确
# -webkit-text-size-adjust
定义 iOS Safari 网页文本大小调整属性
# 属性值
:百分比值,字体显示调整值 auto
:字体自动调整none
:字体不能自动调整
# 兼容性
- iOS 1.0 及更高版本
- Safari on iOS only
- 安卓尚不明确
# -webkit-marquee
定义滚动文本内容属性(缩写属性,类似margin
)。
# 使用语法
-webkit-marquee: direction increment repetition style speed
# 属性值
:滚动方向 ahead
:从下到上滚动auto
:默认滚动方向backwards
:从右到左滚动down
:从上到下滚动forwards
:从左到右滚动left
:从右到左滚动reverse
:从上到下滚动right
:从左到右滚动up
:从下到上滚动
:每次移动的距离 - [
| ] large
:距离常量medium
:距离常量small
:距离常量
- [
:文字滚动的重复次数 - 非负整数
infinite
:无限次
:滚动或滑动的速度 - 非负整数(毫秒单位)或带时间单位的非负整数
fast
normal
slow
# 兼容性
- iOS 1.0 及更高版本
- Safari 3.0 及更高版本
- 大部分安卓手机
# -webkit-filter
滤镜属性可以让元素本身内容(文本、背景等)及其子元素加上滤镜效果
# 属性值
blur(<length>)
:模糊,原始效果值为0px
,不接受负值brightness([ <number> | <percentage> ])
:亮度,原始效果值为1
或100%
,不接受负值contrast([ <number> | <percentage> ])
:对比度,原始效果值为1
或100%
,不接受负值drop-shadow( <length>{2,4} <color>?)
:投影,原始效果值为所有长度值为0
,长度值至少2个,最多4个,grayscale([ <number> | <percentage> ] )
:灰度,原始效果值为0
,最大值为1
或100%
,不接受负值hue-rotate( <angle>)
:相位,原始效果值为0deg
invert( [ <number> | <percentage> ])
:反相,原始效果值为0
,最大值为1
或100%
,不接受负值opacity([ <number> | <percentage> ] )
:透明度,原始效果值为1
,最大值为1
或100%
,不接受负值saturate([ <number> | <percentage> ])
:饱和度,原始效果值为1
,不接受负值sepia([ <number> | <percentage> ])
:乌贼墨,原始效果值为0
,最大值为1
或100%
,不接受负值
关于 -webkit-filter
与 -webkit-backdrop-filter
的属性对比可以参考:
What’s New in Safari 9.0 - backdrop-filter
# 兼容性
- iOS 8.0 及更高版本
- Safari 8.0 及更高版本
- Android 4.4 及更高版本
# -webkit-backdrop-filter
背景滤镜属性可以让元素的背景或元素层级以下的元素加上滤镜效果
# 属性值
blur(<length>)
:模糊,原始效果值为0px
,不接受负值brightness([ <number> | <percentage> ])
:亮度,原始效果值为1
或100%
,不接受负值contrast([ <number> | <percentage> ])
:对比度,原始效果值为1
或100%
,不接受负值drop-shadow( <length>{2,3} <color>?)
:投影,原始效果值为所有长度值为0
,长度值至少2个,最多3个,注意:不支持投影扩展值和混合投影grayscale([ <number> | <percentage> ] )
:灰度,原始效果值为0
,最大值为1
或100%
,不接受负值hue-rotate( <angle>)
:相位,原始效果值为0deg
invert( [ <number> | <percentage> ])
:反相,原始效果值为0
,最大值为1
或100%
,不接受负值opacity([ <number> | <percentage> ] )
:透明度,原始效果值为1
,最大值为1
或100%
,不接受负值saturate([ <number> | <percentage> ])
:饱和度,原始效果值为1
,不接受负值sepia([ <number> | <percentage> ])
:乌贼墨,原始效果值为0
,最大值为1
或100%
,不接受负值
关于 -webkit-filter
与 -webkit-backdrop-filter
的属性对比可以参考:
# 兼容性
- iOS 9.0 及更高版本
- Safari 9.0 及更高版本
- 安卓尚未明确
# position:-webkit-sticky
可以使得元素在页面没有滚动的情况下表现得像relative,在滚动条滚到该元素区域的时候根据top值的设置使元素固定离顶部的距离,表现像 position:fixed
,也就是常见的吸顶需求效果。
# 特性
- 依赖父级元素滚动区域
- 定位参考物始终是 viewport,
transform
等可以改变position:fixed
定位参考物的属性也没办法改变position:-webkit-sticky
的定位参考物 position:-webkit-sticky
属性的元素固定区域只依赖其父元素的可滚动高度,如果其父元素高度小于元素本身的高度,fixed效果失效。
# 兼容性
- iOS 6.1 及更高版本
- iOS only
# -apple-system
苹果操作系统会从两种不同外观和大小的字体进行自动转换去调节系统新字体 “San Francisco”,可以通过 CSS 规则
font-family: -apple-system , sans-serif;
让系统智能选择适配操作系统的字体,添加 -apple-system
可以使字体变得更圆润锐利。
关于 -apple-system
更详细的介绍可以参考:
# 兼容性
- iOS 9.0 及更高版本
- Safari 9.0 及更高版本
- iOS / OS X only
# 更多 WebKit CSS 属性
更多 -webkit-
CSS 属性介绍请参考:
# 命名规范
由历史原因及个人习惯引起的 DOM 结构、命名不统一,导致不同成员在维护同一页面时,效率低下,迭代、维护成本极高。
# 目录命名
- 项目文件夹:projectname
- 样式文件夹:css
- 脚本文件夹:js
- 样式类图片文件夹:img
- 网络接口封装文件夹:api
- 工具类封装文件夹:utils
- 模块文件夹:modules
- 混合模块文件夹:mixins
# 图片命名
# 命名顺序
图片命名建议以以下顺序命名:
图片业务(可选) +(mod_)图片功能类别(必选)+ 图片模块名称(可选) + 图片精度(可选)
图片业务:
- dsj_:大数据
- wx_:微信小程序
- sq_:智慧社区
- st_:智慧食堂
- …
图片功能类别:
- mod_:是否公共,可选
- icon:模块类固化的图标
- logo:LOGO类
- spr:单页面各种元素合并集合
- btn:按钮
- bg:可平铺或者大背景
- …
图片模块名称:
- goodslist:商品列表
- goodsinfo:商品信息
- userava tar:用户头像
- …
图片精度:
- 普清:@1x
- Retina:@2x | @3x
- …
如下面例子:
公共模块:
wx_mod_btn_goodlist@2x.png
wx_mod_btn_goodlist.png
mod_btn_goodlist.png
非公共模块:
wx_btn_goodlist@2x.png
wx_btn_goodlist.png
btn_goodlist.png
# 交叉业务协作
业务交叉协作的时候,为了避免图片命名冲突,建议图片名加上业务和模块前辍,如拍拍侧和手Q侧的业务交叉合作时,侧栏导航icon雪碧图命名:
推荐:
sq_icon_mod_sidenav.png
不推荐:
icon_mod_sidenav.png
处理高清图片的时候,命名应该加上图片相应的精度说明
推荐:
sq_logo@1x.png
sq_logo@2x.png
不推荐:
sq_logo.png
sq_logo_retina.png
# HTML/CSS文件命名
确保文件命名总是以字母开头而不是数字,且字母一律小写,以下划线连接且不带其他标点符号,如:
<!-- HTML -->
jdc.html
jdc_list.html
jdc_detail.html
<!-- SASS -->
jdc.scss
jdc_list.scss
jdc_detail.scss
# ClassName命名
ClassName的命名应该尽量精短、明确,必须以字母开头命名,且全部字母为小写,单词之间统一使用中划线 “-” 连接
# 命名原则
基于姓氏命名法(继承 + 外来),
祖先模块不能出现中划线,除了是全站公用模块,如 mod-
系列的命名:
推荐:
<div class="modulename">
<div class="modulename-info">
<div class="modulename-son"></div>
<div class="modulename-son"></div>
...
</div>
</div>
<!-- 这个是全站公用模块,祖先模块允许直接出现中划线 -->
<div class="mod-info">
<div class="mod-info-son"></div>
<div class="mod-info-son"></div>
...
</div>
不推荐:
<div class="modulename-info">
<div class="modulename-info-son"></div>
<div class="modulename-info-son"></div>
...
</div>
在子孙模块数量可预测的情况下,严格继承祖先模块的命名前缀
<div class="modulename">
<div class="modulename-cover"></div>
<div class="modulename-info"></div>
</div>
当子孙模块超过4级或以上的时候,可以考虑在祖先模块内具有识辨性的独立缩写作为新的子孙模块
推荐:
<div class="modulename">
<div class="modulename-cover"></div>
<div class="modulename-info">
<div class="modulename-info-user">
<div class="modulename-info-user-img">
<img src="" alt="">
<!-- 这个时候 miui 为 modulename-info-user-img 首字母缩写-->
<div class="miui-tit"></div>
<div class="miui-txt"></div>
...
</div>
</div>
<div class="modulename-info-list"></div>
</div>
</div>
不推荐:
<div class="modulename">
<div class="modulename-cover"></div>
<div class="modulename-info">
<div class="modulename-info-user">
<div class="modulename-info-user-img">
<img src="" alt="">
<div class="modulename-info-user-img-tit"></div>
<div class="modulename-info-user-img-txt"></div>
...
</div>
</div>
<div class="modulename-info-list"></div>
</div>
</div>
# 模块命名
全站公共模块:以 mod-
开头
<div class="mod-yours"></div>
业务公共模块:以 业务名-mod-
开头
<div class="paipai-mod-yours"></div>
# 常用命名推荐
注意:ad、banner、gg、guanggao 等有机会和广告挂勾的字眠不建议直接用来做ClassName,因为有些浏览器插件(Chrome的广告拦截插件等)会直接过滤这些类名,因此
<div class="ad"></div>
这种广告的英文或拼音类名不应该出现
另外,敏感不和谐字眼也不应该出现,如:
<div class="fuck"></div>
<div class="jer"></div>
<div class="sm"></div>
<div class="gcd"></div>
<div class="ass"></div>
<div class="KMT"></div>
...
ClassName | 含义 |
---|---|
about | 关于 |
account | 账户 |
arrow | 箭头图标 |
article | 文章 |
aside | 边栏 |
audio | 音频 |
avatar | 头像 |
bg,background | 背景 |
bar | 栏(工具类) |
branding | 品牌化 |
crumb,breadcrumbs | 面包屑 |
btn,button | 按钮 |
caption | 标题,说明 |
category | 分类 |
chart | 图表 |
clearfix | 清除浮动 |
close | 关闭 |
col,column | 列 |
comment | 评论 |
community | 社区 |
container | 容器 |
content | 内容 |
copyright | 版权 |
current | 当前态,选中态 |
default | 默认 |
description | 描述 |
details | 细节 |
disabled | 不可用 |
entry | 文章,博文 |
error | 错误 |
even | 偶数,常用于多行列表或表格中 |
fail | 失败(提示) |
feature | 专题 |
fewer | 收起 |
field | 用于表单的输入区域 |
figure | 图 |
filter | 筛选 |
first | 第一个,常用于列表中 |
footer | 页脚 |
forum | 论坛 |
gallery | 画廊 |
group | 模块,清除浮动 |
header | 页头 |
help | 帮助 |
hide | 隐藏 |
hightlight | 高亮 |
home | 主页 |
icon | 图标 |
info,information | 信息 |
last | 最后一个,常用于列表中 |
links | 链接 |
login | 登录 |
logout | 退出 |
logo | 标志 |
main | 主体 |
menu | 菜单 |
meta | 作者、更新时间等信息栏,一般位于标题之下 |
module | 模块 |
more | 更多(展开) |
msg,message | 消息 |
nav,navigation | 导航 |
next | 下一页 |
nub | 小块 |
odd | 奇数,常用于多行列表或表格中 |
off | 鼠标离开 |
on | 鼠标移过 |
output | 输出 |
pagination | 分页 |
pop,popup | 弹窗 |
preview | 预览 |
previous | 上一页 |
primary | 主要 |
progress | 进度条 |
promotion | 促销 |
rcommd,recommendations | 推荐 |
reg,register | 注册 |
save | 保存 |
search | 搜索 |
secondary | 次要 |
section | 区块 |
selected | 已选 |
share | 分享 |
show | 显示 |
sidebar | 边栏,侧栏 |
slide | 幻灯片,图片切换 |
sort | 排序 |
sub | 次级的,子级的 |
submit | 提交 |
subscribe | 订阅 |
subtitle | 副标题 |
success | 成功(提示) |
summary | 摘要 |
tab | 标签页 |
table | 表格 |
txt,text | 文本 |
thumbnail | 缩略图 |
time | 时间 |
tips | 提示 |
title | 标题 |
video | 视频 |
wrap | 容器,包,一般用于最外层 |
wrapper | 容器,包,一般用于最外层 |
# JavaScript规范
# 类型
1.1 基本类型: 直接存取基本类型。
字符串
数值
布尔类型
null
undefined
const foo = 1; let bar = foo; bar = 9; console.log(foo, bar); // => 1, 9
1.2 复杂类型: 通过引用的方式存取复杂类型。
对象
数组
函数
const foo = [1, 2]; const bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9
# 引用
2.1 对所有的引用使用
const
;不要使用var
。为什么?这能确保你无法对引用重新赋值,也不会导致出现 bug 或难以理解。
// bad var a = 1; var b = 2; // good const a = 1; const b = 2;
2.2 如果你一定需要可变动的引用,使用
let
代替var
。为什么?因为
let
是块级作用域,而var
是函数作用域。// bad var count = 1; if (true) { count += 1; } // good, use the let. let count = 1; if (true) { count += 1; }
2.3 注意
let
和const
都是块级作用域。// const 和 let 只存在于它们被定义的区块内。 { let a = 1; const b = 1; } console.log(a); // ReferenceError console.log(b); // ReferenceError
# 对象
3.1 使用字面值创建对象。
// bad const item = new Object(); // good const item = {};
3.2 如果你的代码在浏览器环境下执行,别使用 保留字 作为键值。这样的话在 IE8 不会运行。 更多信息。 但在 ES6 模块和服务器端中使用没有问题。
// bad const superman = { default: { clark: 'kent' }, private: true, }; // good const superman = { defaults: { clark: 'kent' }, hidden: true, };
3.3 使用同义词替换需要使用的保留字。
// bad const superman = { class: 'alien', }; // bad const superman = { klass: 'alien', }; // good const superman = { type: 'alien', };
3.4 创建有动态属性名的对象时,使用可被计算的属性名称。
为什么?因为这样可以让你在一个地方定义所有的对象属性。
function getKey(k) { return `a key named ${k}`; } // bad const obj = { id: 5, name: 'San Francisco', }; obj[getKey('enabled')] = true; // good const obj = { id: 5, name: 'San Francisco', [getKey('enabled')]: true, };
3.5 使用对象方法的简写。
// bad const atom = { value: 1, addValue: function (value) { return atom.value + value; }, }; // good const atom = { value: 1, addValue(value) { return atom.value + value; }, };
3.6 使用对象属性值的简写。
为什么?因为这样更短更有描述性。
const lukeSkywalker = 'Luke Skywalker'; // bad const obj = { lukeSkywalker: lukeSkywalker, }; // good const obj = { lukeSkywalker, };
3.7 在对象属性声明前把简写的属性分组。
为什么?因为这样能清楚地看出哪些属性使用了简写。
const anakinSkywalker = 'Anakin Skywalker'; const lukeSkywalker = 'Luke Skywalker'; // bad const obj = { episodeOne: 1, twoJedisWalkIntoACantina: 2, lukeSkywalker, episodeThree: 3, mayTheFourth: 4, anakinSkywalker, }; // good const obj = { lukeSkywalker, anakinSkywalker, episodeOne: 1, twoJedisWalkIntoACantina: 2, episodeThree: 3, mayTheFourth: 4, };
# 数组
4.1 使用字面值创建数组。
// bad const items = new Array(); // good const items = [];
4.2 向数组添加元素时使用 Arrary#push 替代直接赋值。
const someStack = []; // bad someStack[someStack.length] = 'abracadabra'; // good someStack.push('abracadabra');
4.3 使用拓展运算符
...
复制数组。// bad const len = items.length; const itemsCopy = []; let i; for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // good const itemsCopy = [...items];
4.4 使用 Array#from 把一个类数组对象转换成数组。
const foo = document.querySelectorAll('.foo'); const nodes = Array.from(foo);
# 解构
5.1 使用解构存取和使用多属性对象。
为什么?因为解构能减少临时引用属性。
// bad function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `${firstName} ${lastName}`; } // good function getFullName(obj) { const { firstName, lastName } = obj; return `${firstName} ${lastName}`; } // best function getFullName({ firstName, lastName }) { return `${firstName} ${lastName}`; }
5.2 对数组使用解构赋值。
const arr = [1, 2, 3, 4]; // bad const first = arr[0]; const second = arr[1]; // good const [first, second] = arr;
5.3 需要回传多个值时,使用对象解构,而不是数组解构。
为什么?增加属性或者改变排序不会改变调用时的位置。
// bad function processInput(input) { // then a miracle occurs return [left, right, top, bottom]; } // 调用时需要考虑回调数据的顺序。 const [left, __, top] = processInput(input); // good function processInput(input) { // then a miracle occurs return { left, right, top, bottom }; } // 调用时只选择需要的数据 const { left, right } = processInput(input);
# Strings
6.1 字符串使用单引号
''
。// bad const name = "Capt. Janeway"; // good const name = 'Capt. Janeway';
6.2 字符串超过 80 个字节应该使用字符串连接号换行。
6.3 注:过度使用字串连接符号可能会对性能造成影响。jsPerf 和 讨论.
// bad const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.'; // bad const errorMessage = 'This is a super long error that was thrown because \ of Batman. When you stop to think about how Batman had anything to do \ with this, you would get nowhere \ fast.'; // good const errorMessage = 'This is a super long error that was thrown because ' + 'of Batman. When you stop to think about how Batman had anything to do ' + 'with this, you would get nowhere fast.';
6.4 程序化生成字符串时,使用模板字符串代替字符串连接。
为什么?模板字符串更为简洁,更具可读性。
// bad function sayHi(name) { return 'How are you, ' + name + '?'; } // bad function sayHi(name) { return ['How are you, ', name, '?'].join(); } // good function sayHi(name) { return `How are you, ${name}?`; }
# 函数
7.1 使用函数声明代替函数表达式。
为什么?因为函数声明是可命名的,所以他们在调用栈中更容易被识别。此外,函数声明会把整个函数提升(hoisted),而函数表达式只会把函数的引用变量名提升。这条规则使得箭头函数可以取代函数表达式。
// bad const foo = function () { }; // good function foo() { }
7.2 函数表达式:
// 立即调用的函数表达式 (IIFE) (() => { console.log('Welcome to the Internet. Please follow me.'); })();
7.3 永远不要在一个非函数代码块(
if
、while
等)中声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但它们的解析表现不一致。7.4 注意: ECMA-262 把
block
定义为一组语句。函数声明不是语句。阅读 ECMA-262 关于这个问题的说明。// bad if (currentUser) { function test() { console.log('Nope.'); } } // good let test; if (currentUser) { test = () => { console.log('Yup.'); }; }
7.5 永远不要把参数命名为
arguments
。这将取代原来函数作用域内的arguments
对象。// bad function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }
7.6 不要使用
arguments
。可以选择 rest 语法...
替代。为什么?使用
...
能明确你要传入的参数。另外 rest 参数是一个真正的数组,而arguments
是一个类数组。// bad function concatenateAll() { const args = Array.prototype.slice.call(arguments); return args.join(''); } // good function concatenateAll(...args) { return args.join(''); }
7.7 直接给函数的参数指定默认值,不要使用一个变化的函数参数。
// really bad function handleThings(opts) { // 不!我们不应该改变函数参数。 // 更加糟糕: 如果参数 opts 是 false 的话,它就会被设定为一个对象。 // 但这样的写法会造成一些 Bugs。 //(译注:例如当 opts 被赋值为空字符串,opts 仍然会被下一行代码设定为一个空对象。) opts = opts || {}; // ... } // still bad function handleThings(opts) { if (opts === void 0) { opts = {}; } // ... } // good function handleThings(opts = {}) { // ... }
7.8 直接给函数参数赋值时需要避免副作用。
为什么?因为这样的写法让人感到很困惑。
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
# 箭头函数
8.1 当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。
为什么?因为箭头函数创造了新的一个
this
执行环境(译注:参考 Arrow functions - JavaScript | MDN 和 ES6 arrow functions, syntax and lexical scoping),通常情况下都能满足你的需求,而且这样的写法更为简洁。为什么不?如果你有一个相当复杂的函数,你或许可以把逻辑部分转移到一个函数声明上。
// bad [1, 2, 3].map(function (x) { const y = x + 1; return x * y; }); // good [1, 2, 3].map((x) => { const y = x + 1; return x * y; });
8.2 如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和
return
都省略掉。如果不是,那就不要省略。为什么?语法糖。在链式调用中可读性很高。
为什么不?当你打算回传一个对象的时候。
// good [1, 2, 3].map(x => x * x); // good [1, 2, 3].reduce((total, n) => { return total + n; }, 0);
# 构造器
9.1 总是使用
class
。避免直接操作prototype
。为什么? 因为
class
语法更为简洁更易读。// bad function Queue(contents = []) { this._queue = [...contents]; } Queue.prototype.pop = function() { const value = this._queue[0]; this._queue.splice(0, 1); return value; } // good class Queue { constructor(contents = []) { this._queue = [...contents]; } pop() { const value = this._queue[0]; this._queue.splice(0, 1); return value; } }
9.2 使用
extends
继承。为什么?因为
extends
是一个内建的原型继承方法并且不会破坏instanceof
。// bad const inherits = require('inherits'); function PeekableQueue(contents) { Queue.apply(this, contents); } inherits(PeekableQueue, Queue); PeekableQueue.prototype.peek = function() { return this._queue[0]; } // good class PeekableQueue extends Queue { peek() { return this._queue[0]; } }
9.3 方法可以返回
this
来帮助链式调用。// bad Jedi.prototype.jump = function() { this.jumping = true; return true; }; Jedi.prototype.setHeight = function(height) { this.height = height; }; const luke = new Jedi(); luke.jump(); // => true luke.setHeight(20); // => undefined // good class Jedi { jump() { this.jumping = true; return this; } setHeight(height) { this.height = height; return this; } } const luke = new Jedi(); luke.jump() .setHeight(20);
9.4 可以写一个自定义的
toString()
方法,但要确保它能正常运行并且不会引起副作用。class Jedi { constructor(options = {}) { this.name = options.name || 'no name'; } getName() { return this.name; } toString() { return `Jedi - ${this.getName()}`; } }
# 模块
10.1 总是使用模组 (
import
/export
) 而不是其他非标准模块系统。你可以编译为你喜欢的模块系统。为什么?模块就是未来,让我们开始迈向未来吧。
// bad const AirbnbStyleGuide = require('./AirbnbStyleGuide'); module.exports = AirbnbStyleGuide.es6; // ok import AirbnbStyleGuide from './AirbnbStyleGuide'; export default AirbnbStyleGuide.es6; // best import { es6 } from './AirbnbStyleGuide'; export default es6;
10.2 不要使用通配符 import。
为什么?这样能确保你只有一个默认 export。
// bad import * as AirbnbStyleGuide from './AirbnbStyleGuide'; // good import AirbnbStyleGuide from './AirbnbStyleGuide';
10.3 不要从 import 中直接 export。
为什么?虽然一行代码简洁明了,但让 import 和 export 各司其职让事情能保持一致。
// bad // filename es6.js export { es6 as default } from './airbnbStyleGuide'; // good // filename es6.js import { es6 } from './AirbnbStyleGuide'; export default es6;
# Iterators and Generators
11.1 不要使用 iterators。使用高阶函数例如
map()
和reduce()
替代for-of
。为什么?这加强了我们不变的规则。处理纯函数的回调值更易读,这比它带来的副作用更重要。
const numbers = [1, 2, 3, 4, 5]; // bad let sum = 0; for (let num of numbers) { sum += num; } sum === 15; // good let sum = 0; numbers.forEach((num) => sum += num); sum === 15; // best (use the functional force) const sum = numbers.reduce((total, num) => total + num, 0); sum === 15;
11.2 现在还不要使用 generators。
为什么?因为它们现在还没法很好地编译到 ES5。 (译者注:目前(2016/03) Chrome 和 Node.js 的稳定版本都已支持 generators)
# 属性
12.1 使用
.
来访问对象的属性。const luke = { jedi: true, age: 28, }; // bad const isJedi = luke['jedi']; // good const isJedi = luke.jedi;
12.2 当通过变量访问属性时使用中括号
[]
。const luke = { jedi: true, age: 28, }; function getProp(prop) { return luke[prop]; } const isJedi = getProp('jedi');
# 变量
13.1 一直使用
const
来声明变量,如果不这样做就会产生全局变量。我们需要避免全局命名空间的污染。地球队长已经警告过我们了。(译注:全局,global 亦有全球的意思。地球队长的责任是保卫地球环境,所以他警告我们不要造成「全球」污染。)// bad superPower = new SuperPower(); // good const superPower = new SuperPower();
13.2 使用
const
声明每一个变量。为什么?增加新变量将变的更加容易,而且你永远不用再担心调换错
;
跟,
。// bad const items = getItems(), goSportsTeam = true, dragonball = 'z'; // bad // (compare to above, and try to spot the mistake) const items = getItems(), goSportsTeam = true; dragonball = 'z'; // good const items = getItems(); const goSportsTeam = true; const dragonball = 'z';
13.3 将所有的
const
和let
分组为什么?当你需要把已赋值变量赋值给未赋值变量时非常有用。
// bad let i, len, dragonball, items = getItems(), goSportsTeam = true; // bad let i; const items = getItems(); let dragonball; const goSportsTeam = true; let len; // good const goSportsTeam = true; const items = getItems(); let dragonball; let i; let length;
13.4 在你需要的地方给变量赋值,但请把它们放在一个合理的位置。
为什么?
let
和const
是块级作用域而不是函数作用域。// good function() { test(); console.log('doing stuff..'); //..other stuff.. const name = getName(); if (name === 'test') { return false; } return name; } // bad - unnecessary function call function(hasName) { const name = getName(); if (!hasName) { return false; } this.setFirstName(name); return true; } // good function(hasName) { if (!hasName) { return false; } const name = getName(); this.setFirstName(name); return true; }
# Hoisting
14.1
var
声明会被提升至该作用域的顶部,但它们赋值不会提升。let
和const
被赋予了一种称为「暂时性死区(Temporal Dead Zones, TDZ)」的概念。这对于了解为什么 type of 不再安全相当重要。// 我们知道这样运行不了 // (假设 notDefined 不是全局变量) function example() { console.log(notDefined); // => throws a ReferenceError } // 由于变量提升的原因, // 在引用变量后再声明变量是可以运行的。 // 注:变量的赋值 `true` 不会被提升。 function example() { console.log(declaredButNotAssigned); // => undefined var declaredButNotAssigned = true; } // 编译器会把函数声明提升到作用域的顶层, // 这意味着我们的例子可以改写成这样: function example() { let declaredButNotAssigned; console.log(declaredButNotAssigned); // => undefined declaredButNotAssigned = true; } // 使用 const 和 let function example() { console.log(declaredButNotAssigned); // => throws a ReferenceError console.log(typeof declaredButNotAssigned); // => throws a ReferenceError const declaredButNotAssigned = true; }
14.2 匿名函数表达式的变量名会被提升,但函数内容并不会。
function example() { console.log(anonymous); // => undefined anonymous(); // => TypeError anonymous is not a function var anonymous = function() { console.log('anonymous function expression'); }; }
14.3 命名的函数表达式的变量名会被提升,但函数名和函数函数内容并不会。
function example() { console.log(named); // => undefined named(); // => TypeError named is not a function superPower(); // => ReferenceError superPower is not defined var named = function superPower() { console.log('Flying'); }; } // the same is true when the function name // is the same as the variable name. function example() { console.log(named); // => undefined named(); // => TypeError named is not a function var named = function named() { console.log('named'); } }
14.4 函数声明的名称和函数体都会被提升。
function example() { superPower(); // => Flying function superPower() { console.log('Flying'); } }
想了解更多信息,参考 Ben Cherry 的 JavaScript Scoping & Hoisting。
# 比较运算符和等号
15.1 优先使用
===
和!==
而不是==
和!=
.15.2 条件表达式例如
if
语句通过抽象方法ToBoolean
强制计算它们的表达式并且总是遵守下面的规则:- 对象 被计算为 true
- Undefined 被计算为 false
- Null 被计算为 false
- 布尔值 被计算为 布尔的值
- 数字 如果是 +0、-0、或 NaN 被计算为 false, 否则为 true
- 字符串 如果是空字符串
''
被计算为 false,否则为 true
if ([0]) { // true // An array is an object, objects evaluate to true }
15.3 使用简写。
// bad if (name !== '') { // ...stuff... } // good if (name) { // ...stuff... } // bad if (collection.length > 0) { // ...stuff... } // good if (collection.length) { // ...stuff... }
15.4 想了解更多信息,参考 Angus Croll 的 Truth Equality and JavaScript。
# 代码块
16.1 使用大括号包裹所有的多行代码块。
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function() { return false; } // good function() { return false; }
16.2 如果通过
if
和else
使用多行代码块,把else
放在if
代码块关闭括号的同一行。// bad if (test) { thing1(); thing2(); } else { thing3(); } // good if (test) { thing1(); thing2(); } else { thing3(); }
# 注释
17.1 使用
/** ... */
作为多行注释。包含描述、指定所有参数和返回值的类型和值。// bad // make() returns a new element // based on the passed in tag name // // @param {String} tag // @return {Element} element function make(tag) { // ...stuff... return element; } // good /** * make() returns a new element * based on the passed in tag name * * @param {String} tag * @return {Element} element */ function make(tag) { // ...stuff... return element; }
17.2 使用
//
作为单行注释。在评论对象上面另起一行使用单行注释。在注释前插入空行。// bad const active = true; // is current tab // good // is current tab const active = true; // bad function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this._type || 'no type'; return type; } // good function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this._type || 'no type'; return type; }
17.3 给注释增加
FIXME
或TODO
的前缀可以帮助其他开发者快速了解这是一个需要复查的问题,或是给需要实现的功能提供一个解决方式。这将有别于常见的注释,因为它们是可操作的。使用FIXME -- need to figure this out
或者TODO -- need to implement
。17.4 使用
// FIXME
: 标注问题。class Calculator { constructor() { // FIXME: shouldn't use a global here total = 0; } }
17.5 使用
// TODO
: 标注问题的解决方式。class Calculator { constructor() { // TODO: total should be configurable by an options param this.total = 0; } }
# 空白
18.1 使用 2 个空格作为缩进。
// bad function() { ∙∙∙∙const name; } // bad function() { ∙const name; } // good function() { ∙∙const name; }
18.2 在花括号前放一个空格。
// bad function test(){ console.log('test'); } // good function test() { console.log('test'); } // bad dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog', }); // good dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog', });
18.3 在控制语句(
if
、while
等)的小括号前放一个空格。在函数调用及声明中,不在函数的参数列表前加空格。// bad if(isJedi) { fight (); } // good if (isJedi) { fight(); } // bad function fight () { console.log ('Swooosh!'); } // good function fight() { console.log('Swooosh!'); }
18.4 使用空格把运算符隔开。
// bad const x=y+5; // good const x = y + 5;
18.5 在文件末尾插入一个空行。
// bad (function(global) { // ...stuff... })(this);
// bad (function(global) { // ...stuff... })(this);↵ ↵
// good (function(global) { // ...stuff... })(this);↵
18.5 在使用长方法链时进行缩进。使用前面的点
.
强调这是方法调用而不是新语句。// bad $('#items').find('.selected').highlight().end().find('.open').updateCount(); // bad $('#items'). find('.selected'). highlight(). end(). find('.open'). updateCount(); // good $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount(); // bad const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led); // good const leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .classed('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led);
18.6 在块末和新语句前插入空行。
// bad if (foo) { return bar; } return baz; // good if (foo) { return bar; } return baz; // bad const obj = { foo() { }, bar() { }, }; return obj; // good const obj = { foo() { }, bar() { }, }; return obj;
# 逗号
19.1 行首逗号:不需要。
// bad const story = [ once , upon , aTime ]; // good const story = [ once, upon, aTime, ]; // bad const hero = { firstName: 'Ada' , lastName: 'Lovelace' , birthYear: 1815 , superPower: 'computers' }; // good const hero = { firstName: 'Ada', lastName: 'Lovelace', birthYear: 1815, superPower: 'computers', };
19.2 增加结尾的逗号: 需要。
为什么? 这会让 git diffs 更干净。另外,像 babel 这样的转译器会移除结尾多余的逗号,也就是说你不必担心老旧浏览器的尾逗号问题。
// bad - git diff without trailing comma const hero = { firstName: 'Florence', - lastName: 'Nightingale' + lastName: 'Nightingale', + inventorOf: ['coxcomb graph', 'modern nursing'] } // good - git diff with trailing comma const hero = { firstName: 'Florence', lastName: 'Nightingale', + inventorOf: ['coxcomb chart', 'modern nursing'], } // bad const hero = { firstName: 'Dana', lastName: 'Scully' }; const heroes = [ 'Batman', 'Superman' ]; // good const hero = { firstName: 'Dana', lastName: 'Scully', }; const heroes = [ 'Batman', 'Superman', ];
# 分号
20.1 使用分号
// bad (function() { const name = 'Skywalker' return name })() // good (() => { const name = 'Skywalker'; return name; })(); // good (防止函数在两个 IIFE 合并时被当成一个参数) ;(() => { const name = 'Skywalker'; return name; })();
# 类型转换
21.1 在语句开始时执行类型转换。
21.2 字符串:
// => this.reviewScore = 9; // bad const totalScore = this.reviewScore + ''; // good const totalScore = String(this.reviewScore);
21.3 对数字使用
parseInt
转换,并带上类型转换的基数。const inputValue = '4'; // bad const val = new Number(inputValue); // bad const val = +inputValue; // bad const val = inputValue >> 0; // bad const val = parseInt(inputValue); // good const val = Number(inputValue); // good const val = parseInt(inputValue, 10);
21.4 如果因为某些原因 parseInt 成为你所做的事的瓶颈而需要使用位操作解决性能问题时,留个注释说清楚原因和你的目的。
// good /** * 使用 parseInt 导致我的程序变慢, * 改成使用位操作转换数字快多了。 */ const val = inputValue >> 0;
21.5 注: 小心使用位操作运算符。数字会被当成 64 位值,但是位操作运算符总是返回 32 位的整数(参考)。位操作处理大于 32 位的整数值时还会导致意料之外的行为。关于这个问题的讨论。最大的 32 位整数是 2,147,483,647:
2147483647 >> 0 //=> 2147483647 2147483648 >> 0 //=> -2147483648 2147483649 >> 0 //=> -2147483647
21.6 布尔:
const age = 0; // bad const hasAge = new Boolean(age); // good const hasAge = Boolean(age); // good const hasAge = !!age;
# 命名规则
22.1 避免单字母命名。命名应具备描述性。
// bad function q() { // ...stuff... } // good function query() { // ..stuff.. }
22.2 使用驼峰式命名对象、函数和实例。
// bad const OBJEcttsssss = {}; const this_is_my_object = {}; function c() {} // good const thisIsMyObject = {}; function thisIsMyFunction() {}
22.3 使用帕斯卡式命名构造函数或类。
// bad function user(options) { this.name = options.name; } const bad = new user({ name: 'nope', }); // good class User { constructor(options) { this.name = options.name; } } const good = new User({ name: 'yup', });
22.4 不要使用下划线
_
结尾或开头来命名属性和方法。// bad this.__firstName__ = 'Panda'; this.firstName_ = 'Panda'; this._firstName = 'Panda'; // good this.firstName = 'Panda';
22.5 别保存
this
的引用。使用箭头函数或 Function#bind。// bad function foo() { const self = this; return function() { console.log(self); }; } // bad function foo() { const that = this; return function() { console.log(that); }; } // good function foo() { return () => { console.log(this); }; }
22.6 如果你的文件只输出一个类,那你的文件名必须和类名完全保持一致。
// file contents class CheckBox { // ... } export default CheckBox; // in some other file // bad import CheckBox from './checkBox'; // bad import CheckBox from './check_box'; // good import CheckBox from './CheckBox';
22.7 当你导出默认的函数时使用驼峰式命名。你的文件名必须和函数名完全保持一致。
function makeStyleGuide() { } export default makeStyleGuide;
22.8 当你导出单例、函数库、空对象时使用帕斯卡式命名。
const AirbnbStyleGuide = { es6: { } }; export default AirbnbStyleGuide;
# 存取器
23.1 属性的存取函数不是必须的。
23.2 如果你需要存取函数时使用
getVal()
和setVal('hello')
。// bad dragon.age(); // good dragon.getAge(); // bad dragon.age(25); // good dragon.setAge(25);
23.3 如果属性是布尔值,使用
isVal()
或hasVal()
。// bad if (!dragon.age()) { return false; } // good if (!dragon.hasAge()) { return false; }
23.4 创建
get()
和set()
函数是可以的,但要保持一致。class Jedi { constructor(options = {}) { const lightsaber = options.lightsaber || 'blue'; this.set('lightsaber', lightsaber); } set(key, val) { this[key] = val; } get(key) { return this[key]; } }
# 事件
24.1 当给事件附加数据时(无论是 DOM 事件还是私有事件),传入一个哈希而不是原始值。这样可以让后面的贡献者增加更多数据到事件数据而无需找出并更新事件的每一个处理器。例如,不好的写法:
// bad $(this).trigger('listingUpdated', listing.id); ... $(this).on('listingUpdated', function(e, listingId) { // do something with listingId });
更好的写法:
// good $(this).trigger('listingUpdated', { listingId : listing.id }); ... $(this).on('listingUpdated', function(e, data) { // do something with data.listingId });
# jQuery
25.1 使用
$
作为存储 jQuery 对象的变量名前缀。// bad const sidebar = $('.sidebar'); // good const $sidebar = $('.sidebar');
25.2 缓存 jQuery 查询。
// bad function setSidebar() { $('.sidebar').hide(); // ...stuff... $('.sidebar').css({ 'background-color': 'pink' }); } // good function setSidebar() { const $sidebar = $('.sidebar'); $sidebar.hide(); // ...stuff... $sidebar.css({ 'background-color': 'pink' }); }
25.3 对 DOM 查询使用层叠
$('.sidebar ul')
或 父元素 > 子元素$('.sidebar > ul')
。 jsPerf25.4 对有作用域的 jQuery 对象查询使用
find
。// bad $('ul', '.sidebar').hide(); // bad $('.sidebar').find('ul').hide(); // good $('.sidebar ul').hide(); // good $('.sidebar > ul').hide(); // good $sidebar.find('ul').hide();
# ECMAScript 5 兼容性
# ECMAScript 6 规范
- 以下是ES6 各个特性的名称
# VUE规范
# Git commit规范
# 提交规范
每完成一个功能进行一次提交不要将多个功能混合在一次提交中,如果无法避免请详尽描述更改内容
# 格式规范
采用插件:git-commit-plugin 进行提交模式规范
# commit标准格式
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
# 1. type
type
为必填项,用于指定commit的类型,约定了feat
、fix
两个主要type
,以及docs、style、build、refactor、revert五个特殊type
,其余type
暂不使用。
# 主要type
feat: 增加新功能
fix: 修复bug
# 特殊type
docs: 只改动了文档相关的内容
style: 不影响代码含义的改动,例如去掉空格、改变缩进、增删分号
build: 构造工具的或者外部依赖的改动,例如webpack,npm
refactor: 代码重构时使用
revert: 执行git revert打印的message
# 暂不使用type
test: 添加测试或者修改现有测试
perf: 提高性能的改动
ci: 与CI(持续集成服务)有关的改动
chore: 不修改src或者test的其余修改,例如构建过程或辅助工具的变动
当一次改动包括主要type
与特殊type
时,统一采用主要type
。
# 2. scope
scope
也为必填项,用于描述改动的范围,格式为项目名/模块名,例如: node-pc/common
rrd-h5/activity
,而we-sdk
不需指定模块名。如果一次commit修改多个模块,建议拆分成多次commit,以便更好追踪和维护。
# 3. body
body
填写详细描述,主要描述改动之前的情况
及修改动机
,对于小的修改不作要求,但是重大需求、更新等必须添加body来作说明。
# 4. break changes
break changes
指明是否产生了破坏性修改,涉及break changes的改动必须指明该项,类似版本升级、接口参数减少、接口删除、迁移等。
# 5. footer
可用于填写affect issues
指明是否影响了某个问题。例如我们使用jira时,我们在commit message
中可以填写其影响的JIRA_ID
填写方式例如:
re #JIRA_ID
fix #JIRA_ID
# Git 工作流规范
# 项目上线规范
- 如无必要禁止进行任何控制台输出
- 项目上线包名称:
项目名_打包时间_打包人
# 常用工具配置
# eslint配置
采用了eslint进行代码格式化,请删除或禁用其他格式插件以免产生冲突导致意外的报错问题.
# 常用配置项含义
{
// 环境定义了预定义的全局变量。
"env": {
//环境定义了预定义的全局变量。更多在官网查看
"browser":true,
"node":true,
"commonjs":true,
"amd":true,
"es6":true,
"mocha":true
},
// JavaScript 语言选项
"parserOptions": {
// ECMAScript 版本
"ecmaVersion":6,
"sourceType":"script",//module
// 想使用的额外的语言特性:
"ecmaFeatures": {
// 允许在全局作用域下使用 return 语句
"globalReturn":true,
// impliedStric
"impliedStrict":true,
// 启用 JSX
"jsx":true
}
},
/**
* "off" 或 0 - 关闭规则
* "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出),
* "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
*/
"rules": {
// 可能的错误 //
// 禁止条件表达式中出现赋值操作符
"no-cond-assign":2,
// 禁用 console
"no-console":0,
// 禁止在条件中使用常量表达式
// if (false) {
// doSomethingUnfinished();
// } //cuowu
"no-constant-condition":2,
// 禁止在正则表达式中使用控制字符 :new RegExp("\x1f")
"no-control-regex":2,
// 数组和对象键值对最后一个逗号, never参数:不能带末尾的逗号, always参数:必须带末尾的逗号,
// always-multiline:多行模式必须带逗号,单行模式不能带逗号
"comma-dangle": [1,"always-multiline"],
// 禁用 debugger
"no-debugger":2,
// 禁止 function 定义中出现重名参数
"no-dupe-args":2,
// 禁止对象字面量中出现重复的 key
"no-dupe-keys":2,
// 禁止重复的 case 标签
"no-duplicate-case":2,
// 禁止空语句块
"no-empty":2,
// 禁止在正则表达式中使用空字符集 (/^abc[]/)
"no-empty-character-class":2,
// 禁止对 catch 子句的参数重新赋值
"no-ex-assign":2,
// 禁止不必要的布尔转换
"no-extra-boolean-cast":2,
// 禁止不必要的括号 //(a * b) + c;//报错
"no-extra-parens":0,
// 禁止不必要的分号
"no-extra-semi":2,
// 禁止对 function 声明重新赋值
"no-func-assign":2,
// 禁止在嵌套的块中出现 function 或 var 声明
"no-inner-declarations": [2,"functions"],
// 禁止 RegExp 构造函数中无效的正则表达式字符串
"no-invalid-regexp":2,
// 禁止在字符串和注释之外不规则的空白
"no-irregular-whitespace":2,
// 禁止在 in 表达式中出现否定的左操作数
"no-negated-in-lhs":2,
// 禁止把全局对象 (Math 和 JSON) 作为函数调用 错误:var math = Math();
"no-obj-calls":2,
// 禁止直接使用 Object.prototypes 的内置属性
"no-prototype-builtins":0,
// 禁止正则表达式字面量中出现多个空格
"no-regex-spaces":2,
// 禁用稀疏数组
"no-sparse-arrays":2,
// 禁止出现令人困惑的多行表达式
"no-unexpected-multiline":2,
// 禁止在return、throw、continue 和 break语句之后出现不可达代码
/*
function foo() {
return true;
console.log("done");
}//错误
*/
"no-unreachable":2,
// 要求使用 isNaN() 检查 NaN
"use-isnan":2,
// 强制使用有效的 JSDoc 注释
"valid-jsdoc":1,
// 强制 typeof 表达式与有效的字符串进行比较
// typeof foo === "undefimed" 错误
"valid-typeof":2,
//
// 最佳实践 //
//
// 定义对象的set存取器属性时,强制定义get
"accessor-pairs":2,
// 强制数组方法的回调函数中有 return 语句
"array-callback-return":0,
// 强制把变量的使用限制在其定义的作用域范围内
"block-scoped-var":0,
// 限制圈复杂度,也就是类似if else能连续接多少个
"complexity": [2,9],
// 要求 return 语句要么总是指定返回的值,要么不指定
"consistent-return":0,
// 强制所有控制语句使用一致的括号风格
"curly": [2,"all"],
// switch 语句强制 default 分支,也可添加 // no default 注释取消此次警告
"default-case":2,
// 强制object.key 中 . 的位置,参数:
// property,'.'号应与属性在同一行
// object, '.' 号应与对象名在同一行
"dot-location": [2,"property"],
// 强制使用.号取属性
// 参数: allowKeywords:true 使用保留字做属性名时,只能使用.方式取属性
// false 使用保留字做属性名时, 只能使用[]方式取属性 e.g [2, {"allowKeywords": false}]
// allowPattern: 当属性名匹配提供的正则表达式时,允许使用[]方式取值,否则只能用.号取值 e.g [2, {"allowPattern": "^[a-z]+(_[a-z]+)+$"}]
"dot-notation": [2, {"allowKeywords":false}],
// 使用 === 替代 == allow-null允许null和undefined==
"eqeqeq": [2,"allow-null"],
// 要求 for-in 循环中有一个 if 语句
"guard-for-in":2,
// 禁用 alert、confirm 和 prompt
"no-alert":0,
// 禁用 arguments.caller 或 arguments.callee
"no-caller":2,
// 不允许在 case 子句中使用词法声明
"no-case-declarations":2,
// 禁止除法操作符显式的出现在正则表达式开始的位置
"no-div-regex":2,
// 禁止 if 语句中有 return 之后有 else
"no-else-return":0,
// 禁止出现空函数.如果一个函数包含了一条注释,它将不会被认为有问题。
"no-empty-function":2,
// 禁止使用空解构模式no-empty-pattern
"no-empty-pattern":2,
// 禁止在没有类型检查操作符的情况下与 null 进行比较
"no-eq-null":1,
// 禁用 eval()
"no-eval":2,
// 禁止扩展原生类型
"no-extend-native":2,
// 禁止不必要的 .bind() 调用
"no-extra-bind":2,
// 禁用不必要的标签
"no-extra-label:":0,
// 禁止 case 语句落空
"no-fallthrough":2,
// 禁止数字字面量中使用前导和末尾小数点
"no-floating-decimal":2,
// 禁止使用短符号进行类型转换(!!fOO)
"no-implicit-coercion":0,
// 禁止在全局范围内使用 var 和命名的 function 声明
"no-implicit-globals":1,
// 禁止使用类似 eval() 的方法
"no-implied-eval":2,
// 禁止 this 关键字出现在类和类对象之外
"no-invalid-this":0,
// 禁用 __iterator__ 属性
"no-iterator":2,
// 禁用标签语句
"no-labels":2,
// 禁用不必要的嵌套块
"no-lone-blocks":2,
// 禁止在循环中出现 function 声明和表达式
"no-loop-func":1,
// 禁用魔术数字(3.14什么的用常量代替)
"no-magic-numbers":[1,{"ignore": [0,-1,1] }],
// 禁止使用多个空格
"no-multi-spaces":2,
// 禁止使用多行字符串,在 JavaScript 中,可以在新行之前使用斜线创建多行字符串
"no-multi-str":2,
// 禁止对原生对象赋值
"no-native-reassign":2,
// 禁止在非赋值或条件语句中使用 new 操作符
"no-new":2,
// 禁止对 Function 对象使用 new 操作符
"no-new-func":0,
// 禁止对 String,Number 和 Boolean 使用 new 操作符
"no-new-wrappers":2,
// 禁用八进制字面量
"no-octal":2,
// 禁止在字符串中使用八进制转义序列
"no-octal-escape":2,
// 不允许对 function 的参数进行重新赋值
"no-param-reassign":0,
// 禁用 __proto__ 属性
"no-proto":2,
// 禁止使用 var 多次声明同一变量
"no-redeclare":2,
// 禁用指定的通过 require 加载的模块
"no-return-assign":0,
// 禁止使用 javascript: url
"no-script-url":0,
// 禁止自我赋值
"no-self-assign":2,
// 禁止自身比较
"no-self-compare":2,
// 禁用逗号操作符
"no-sequences":2,
// 禁止抛出非异常字面量
"no-throw-literal":2,
// 禁用一成不变的循环条件
"no-unmodified-loop-condition":2,
// 禁止出现未使用过的表达式
"no-unused-expressions":0,
// 禁用未使用过的标签
"no-unused-labels":2,
// 禁止不必要的 .call() 和 .apply()
"no-useless-call":2,
// 禁止不必要的字符串字面量或模板字面量的连接
"no-useless-concat":2,
// 禁用不必要的转义字符
"no-useless-escape":0,
// 禁用 void 操作符
"no-void":0,
// 禁止在注释中使用特定的警告术语
"no-warning-comments":0,
// 禁用 with 语句
"no-with":2,
// 强制在parseInt()使用基数参数
"radix":2,
// 要求所有的 var 声明出现在它们所在的作用域顶部
"vars-on-top":0,
// 要求 IIFE 使用括号括起来
"wrap-iife": [2,"any"],
// 要求或禁止 “Yoda” 条件
"yoda": [2,"never"],
// 要求或禁止使用严格模式指令
"strict":0,
//
// 变量声明 //
//
// 要求或禁止 var 声明中的初始化(初值)
"init-declarations":0,
// 不允许 catch 子句的参数与外层作用域中的变量同名
"no-catch-shadow":0,
// 禁止删除变量
"no-delete-var":2,
// 不允许标签与变量同名
"no-label-var":2,
// 禁用特定的全局变量
"no-restricted-globals":0,
// 禁止 var 声明 与外层作用域的变量同名
"no-shadow":0,
// 禁止覆盖受限制的标识符
"no-shadow-restricted-names":2,
// 禁用未声明的变量,除非它们在 /*global */ 注释中被提到
"no-undef":2,
// 禁止将变量初始化为 undefined
"no-undef-init":2,
// 禁止将 undefined 作为标识符
"no-undefined":0,
// 禁止出现未使用过的变量
"no-unused-vars": [2, {"vars":"all","args":"none"}],
// 不允许在变量定义之前使用它们
"no-use-before-define":0,
//
// Node.js and CommonJS //
//
// require return statements after callbacks
"callback-return":0,
// 要求 require() 出现在顶层模块作用域中
"global-require":1,
// 要求回调函数中有容错处理
"handle-callback-err": [2,"^(err|error)$"],
// 禁止混合常规 var 声明和 require 调用
"no-mixed-requires":0,
// 禁止调用 require 时使用 new 操作符
"no-new-require":2,
// 禁止对 __dirname 和 __filename进行字符串连接
"no-path-concat":0,
// 禁用 process.env
"no-process-env":0,
// 禁用 process.exit()
"no-process-exit":0,
// 禁用同步方法
"no-sync":0,
//
// 风格指南 //
//
// 指定数组的元素之间要以空格隔开(, 后面), never参数:[ 之前和 ] 之后不能带空格,always参数:[ 之前和 ] 之后必须带空格
"array-bracket-spacing": [2,"never"],
// 禁止或强制在单行代码块中使用空格(禁用)
"block-spacing":[1,"never"],
//强制使用一致的缩进 第二个参数为 "tab" 时,会使用tab,
// if while function 后面的{必须与if在同一行,java风格。
"brace-style": [2,"1tbs", {"allowSingleLine":true}],
// 双峰驼命名格式
"camelcase":2,
// 控制逗号前后的空格
"comma-spacing": [2, {"before":false,"after":true}],
// 控制逗号在行尾出现还是在行首出现 (默认行尾)
// http://eslint.org/docs/rules/comma-style
"comma-style": [2,"last"],
//"SwitchCase" (默认:0) 强制 switch 语句中的 case 子句的缩进水平
// 以方括号取对象属性时,[ 后面和 ] 前面是否需要空格, 可选参数 never, always
"computed-property-spacing": [2,"never"],
// 用于指统一在回调函数中指向this的变量名,箭头函数中的this已经可以指向外层调用者,应该没卵用了
// e.g [0,"that"] 指定只能 var that = this. that不能指向其他任何值,this也不能赋值给that以外的其他值
"consistent-this": [1,"that"],
// 强制使用命名的 function 表达式
"func-names":0,
// 文件末尾强制换行
"eol-last":2,
"indent": [2,4, {"SwitchCase":1}],
// 强制在对象字面量的属性中键和值之间使用一致的间距
"key-spacing": [2, {"beforeColon":false,"afterColon":true}],
// 强制使用一致的换行风格
"linebreak-style": [1,"unix"],
// 要求在注释周围有空行 ( 要求在块级注释之前有一空行)
"lines-around-comment": [1,{"beforeBlockComment":true}],
// 强制一致地使用函数声明或函数表达式,方法定义风格,参数:
// declaration: 强制使用方法声明的方式,function f(){} e.g [2, "declaration"]
// expression:强制使用方法表达式的方式,var f = function() {} e.g [2, "expression"]
// allowArrowFunctions: declaration风格中允许箭头函数。 e.g [2, "declaration", { "allowArrowFunctions": true }]
"func-style":0,
// 强制回调函数最大嵌套深度 5层
"max-nested-callbacks": [1,5],
// 禁止使用指定的标识符
"id-blacklist":0,
// 强制标识符的最新和最大长度
"id-length":0,
// 要求标识符匹配一个指定的正则表达式
"id-match":0,
// 强制在 JSX 属性中一致地使用双引号或单引号
"jsx-quotes":0,
// 强制在关键字前后使用一致的空格 (前后腰需要)
"keyword-spacing":2,
// 强制一行的最大长度
"max-len":[1,200],
// 强制最大行数
"max-lines":0,
// 强制 function 定义中最多允许的参数数量
"max-params":[1,7],
// 强制 function 块最多允许的的语句数量
"max-statements":[1,200],
// 强制每一行中所允许的最大语句数量
"max-statements-per-line":0,
// 要求构造函数首字母大写 (要求调用 new 操作符时有首字母大小的函数,允许调用首字母大写的函数时没有 new 操作符。)
"new-cap": [2, {"newIsCap":true,"capIsNew":false}],
// 要求调用无参构造函数时有圆括号
"new-parens":2,
// 要求或禁止 var 声明语句后有一行空行
"newline-after-var":0,
// 禁止使用 Array 构造函数
"no-array-constructor":2,
// 禁用按位运算符
"no-bitwise":0,
// 要求 return 语句之前有一空行
"newline-before-return":0,
// 要求方法链中每个调用都有一个换行符
"newline-per-chained-call":1,
// 禁用 continue 语句
"no-continue":0,
// 禁止在代码行后使用内联注释
"no-inline-comments":0,
// 禁止 if 作为唯一的语句出现在 else 语句中
"no-lonely-if":0,
// 禁止混合使用不同的操作符
"no-mixed-operators":0,
// 不允许空格和 tab 混合缩进
"no-mixed-spaces-and-tabs":2,
// 不允许多个空行
"no-multiple-empty-lines": [2, {"max":2}],
// 不允许否定的表达式
"no-negated-condition":0,
// 不允许使用嵌套的三元表达式
"no-nested-ternary":0,
// 禁止使用 Object 的构造函数
"no-new-object":2,
// 禁止使用一元操作符 ++ 和 --
"no-plusplus":0,
// 禁止使用特定的语法
"no-restricted-syntax":0,
// 禁止 function 标识符和括号之间出现空格
"no-spaced-func":2,
// 不允许使用三元操作符
"no-ternary":0,
// 禁用行尾空格
"no-trailing-spaces":2,
// 禁止标识符中有悬空下划线_bar
"no-underscore-dangle":0,
// 禁止可以在有更简单的可替代的表达式时使用三元操作符
"no-unneeded-ternary":2,
// 禁止属性前有空白
"no-whitespace-before-property":0,
// 强制花括号内换行符的一致性
"object-curly-newline":0,
// 强制在花括号中使用一致的空格
"object-curly-spacing":0,
// 强制将对象的属性放在不同的行上
"object-property-newline":0,
// 强制函数中的变量要么一起声明要么分开声明
"one-var": [2, {"initialized":"never"}],
// 要求或禁止在 var 声明周围换行
"one-var-declaration-per-line":0,
// 要求或禁止在可能的情况下要求使用简化的赋值操作符
"operator-assignment":0,
// 强制操作符使用一致的换行符
"operator-linebreak": [2,"after", {"overrides": {"?":"before",":":"before"} }],
// 要求或禁止块内填充
"padded-blocks":0,
// 要求对象字面量属性名称用引号括起来
"quote-props":0,
// 强制使用一致的反勾号、双引号或单引号
"quotes": [2,"single","avoid-escape"],
// 要求使用 JSDoc 注释
"require-jsdoc":1,
// 要求或禁止使用分号而不是 ASI(这个才是控制行尾部分号的,)
"semi": [2,"always"],
// 强制分号之前和之后使用一致的空格
"semi-spacing":0,
// 要求同一个声明块中的变量按顺序排列
"sort-vars":0,
// 强制在块之前使用一致的空格
"space-before-blocks": [2,"always"],
// 强制在 function的左括号之前使用一致的空格
"space-before-function-paren": [2,"always"],
// 强制在圆括号内使用一致的空格
"space-in-parens": [2,"never"],
// 要求操作符周围有空格
"space-infix-ops":2,
// 强制在一元操作符前后使用一致的空格
"space-unary-ops": [2, {"words":true,"nonwords":false}],
// 强制在注释中 // 或 /* 使用一致的空格
"spaced-comment": [2,"always", {"markers": ["global","globals","eslint","eslint-disable","*package","!"] }],
// 要求或禁止 Unicode BOM
"unicode-bom":0,
// 要求正则表达式被括号括起来
"wrap-regex":0,
//
// ES6.相关 //
//
// 要求箭头函数体使用大括号
"arrow-body-style":2,
// 要求箭头函数的参数使用圆括号
"arrow-parens":2,
"arrow-spacing":[2,{"before":true,"after":true}],
// 强制在子类构造函数中用super()调用父类构造函数,TypeScrip的编译器也会提示
"constructor-super":0,
// 强制 generator 函数中 * 号周围使用一致的空格
"generator-star-spacing": [2, {"before":true,"after":true}],
// 禁止修改类声明的变量
"no-class-assign":2,
// 不允许箭头功能,在那里他们可以混淆的比较
"no-confusing-arrow":0,
// 禁止修改 const 声明的变量
"no-const-assign":2,
// 禁止类成员中出现重复的名称
"no-dupe-class-members":2,
// 不允许复制模块的进口
"no-duplicate-imports":0,
// 禁止 Symbol 的构造函数
"no-new-symbol":2,
// 允许指定模块加载时的进口
"no-restricted-imports":0,
// 禁止在构造函数中,在调用 super() 之前使用 this 或 super
"no-this-before-super":2,
// 禁止不必要的计算性能键对象的文字
"no-useless-computed-key":0,
// 要求使用 let 或 const 而不是 var
"no-var":0,
// 要求或禁止对象字面量中方法和属性使用简写语法
"object-shorthand":0,
// 要求使用箭头函数作为回调
"prefer-arrow-callback":0,
// 要求使用 const 声明那些声明后不再被修改的变量
"prefer-const":0,
// 要求在合适的地方使用 Reflect 方法
"prefer-reflect":0,
// 要求使用扩展运算符而非 .apply()
"prefer-spread":0,
// 要求使用模板字面量而非字符串连接
"prefer-template":0,
// Suggest using the rest parameters instead of arguments
"prefer-rest-params":0,
// 要求generator 函数内有 yield
"require-yield":0,
// enforce spacing between rest and spread operators and their expressions
"rest-spread-spacing":0,
// 强制模块内的 import 排序
"sort-imports":0,
// 要求或禁止模板字符串中的嵌入表达式周围空格的使用
"template-curly-spacing":1,
// 强制在 yield* 表达式中 * 周围使用空格
"yield-star-spacing":2
}
}