最佳实践系列:前端代码标准
@窝窝商城前端(刘轶/李晨/徐利/穆尚)翻译于2012年 版本0.55 @郑昀校对
isobar的这个前端代码标准和最佳实践文档,涵盖了Web应用开发的方方面面,我们翻译了大部分章节,并做了注解。请仔细阅读用标记的段落。
关键词列表:
渐进增强;Combo Handler;Quirks Mode;浏览器盒子模型;选择器特殊性;Spacer Image;CSS Sprites;PNG8;
编写此文档的目的主要有两方面,第一,如何保持代码的一致性;第二,什么才是最佳实践。我们通过编码风格和约定保持一致,可以减轻代码维护的工作量,并降低风险,在将来代码出现问题的时候,方便我们排查错误。我们要保持最佳的编码习惯和做法,确保优化页面的加载和性能,并能更好地维护代码。
普遍性准则
前端开发的核心
1、 结构、表现、行为应该分离。
2、 结构良好的、语义化和有效的HTML标记。
3、 Javascript脚本的渐进增强!
注:渐进增强(Progressive Enhancement)
名词定义:渐进增强是从一个功能可用的基本版本出发,然后逐步增加用户体验的丰富程度,并在应用增强功能之前先测试对该功能的支持性;最基本的可用性出发,在保证站点页面在低级浏览器中的可用性和可访问性的基础上,逐步增加功能及提高用户体验。辅助阅读:http://www.ryanbay.com/?p=97
一般性实践
缩进
对于所有代码语言,我们需要通过TAB缩进进行代码排版(使用空格字符),在文本编辑器击中TAB应相当于四个空格。
可读性 vs 压缩
我们在代码可读性和文件大小的取舍中,更倾向于良好的可读性。
在合适的地方,我们鼓励使用大量的缩进、换行来维持文件代码的可读性。开发者不需要刻意地压缩文件的体积大小,也不需要混淆使用JavaScript。
我们将使用服务器端或发布过程中自动minify和gzip的所有静态客户端文件,如CSS和JavaScript。
注:一般采用服务端的 Combo Handler 来对服务器端上传的未压缩、未混淆的JS和CSS文件做统一合并、压缩和混淆。
标签
标记定义了结构和轮廓的文档,并提供了一个结构化内容。
标记并不打算定义的外观和视觉表现,只用于感知网页的基本概念,如标题、段落、列表。HTML标记中表现样式的属性都应被弃用,样式的表现应该包含在样式表里。
HTML5
我们将在适当的时候使用HTML5 Doctype和HTML5特性。
我们将用W3C验证器测试我们的标记,以确保格式良好。100%有效的代码并不是我们的目标,但W3C验证确实有助于编写更易于维护的网站以及调试代码。Isobar不保证代码是100%有效,而是确保跨浏览器有统一的浏览体验。
模板
对于HTML5文档,我们将定制 H5BP。
文档类型
应该始终使用一个合适的 Doctype 来触发浏览器的标准模式。
我们应该始终避免Quirks Mode(怪异模式或兼容模式)。
HTML5的一个好的方面是,它简化了所需的代码量。无意义的属性已经有所下降,而且已大大简化了 Doctype 声明。因此建议文档类型应声明为HTML5的形式。
HTML5 Doctype
1.
注:怪异模式(quirks mode)
名词定义:指在计算机领域中,一些网页浏览器为了维持对较旧的网页设计的向后兼容性,而使用的一种技术,有别于严格遵循万维网联盟(W3C)与互联网工程任务组(IETF)标准而设计的「标准模式」。
为了与可能数量众多的网页维持兼容,现代的网页浏览器一般具有多种渲染模式:在「标准模式」(standards mode) 页面按照 HTML 与 CSS 的定义渲染,而在「quirks 模式」中则尝试模拟更旧的浏览器的行为。
在 quirks 模式和标准模式之间一个突出的不同是对 CSS IE盒模型缺陷的处理。
参考资料:What happens in Quirks Mode?
DOCTYPE声明 |
说明 |
IE8 |
FF |
Chrome |
|
HTML5推荐的方式 |
CSS1Compat |
CSS1Compat |
|
|
严格模式声明并给出DTD URL |
CSS1Compat |
CSS1Compat |
|
|
严格模式声明但不给出DTD URL |
CSS1Compat |
CSS1Compat |
|
|
过渡模式并给出DTD URL |
CSS1Compat |
CSS1Compat |
|
|
过渡模式但不给出DTD URL |
BackCompat |
BackCompat |
字符编码
所有标记都应设置为utf – 8。它应该同时指定在 HTTP 报头和文档头部。
1.
<
meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
/>
In HTML5, just do:
1.
<
meta
charset
=
"utf-8"
>
通用标记指南
以下是一般指南,用于构建你的HTML标记。
- 使用实际的P元素分隔符而不是多段BR标签。
- 在适当的时候,利用DL(定义列表)和 BLOCKQUOTE。
- 使用UL,OL,DL 来表示一个项目列表,不要使用多个DIV嵌套模拟一个项目列表。
- 使用label 字段来标记表单中每一个字段,它的for属性把这个label与input field关联起来,使得用户可以点击这个label。设置cursor:pointer给label也是明智之举 !!
- 不要使用size属性来控制你输入框的大小,应该使用CSS来定义。
- 在一些闭合div后面加上html注释,以标示你关闭的是什么元素。有大量嵌套和缩进时这会很有帮助。
- 不要使用 tables来完成你的页面布局。
- 在适当的时候合理的运用table中的thead 、tbody、tfoot以及th等标签。
正确的表格:
引号属性
虽然HTML5规范定义了在那些可以自动识别空格的属性周围添加引号作为可选属性,但是所有的属性都应该添加引号。
1.
<
p
class
=
"line note"
data-attribute
=
"106"
>This is my paragraph of special text.
p
>
CSS
Web页面的第二个组件是包含在样式表(Cascading Style Sheet,CSS)里的展示信息。
一般性编码原则
- 通过外部文件来添加CSS。CSS文件里尽可能不要用 # 。CSS总是应该在文档头部之间。
- 使用 link 标记来引用外部CSS文件,永远不要使用 @import导入CSS。
- 不要使用内联样式(inline styling),因为维护的时候很难跟踪样式的规则。
- 确保同一个CSS文件文档只引用一次。
- 请用一个字体标准化文件,如YUI fonts.css,来定义各个标记的字体在不同浏览器中有统一表现!
- 文档中仅出现一次的元素,应使用ID,否则,使用class。
- 理解层叠和选择器特性,这样你就可以编写非常简洁、有效的代码。
- 编写CSS代码时,使用高效的选择器。如果可能,要避免使用运行效率低下的选择器。比如,我们应该避免 * 通配符选择器,避免不适当的ID选择器(如
div#myid
)或类选择器(如table.results
.)。这些之所以特别重要,是因为在Web应用程序中速度是至关重要的,可能有数以千计甚至数以万计的DOM元素需要被渲染。更多细节请参考: 在MDC上编写高效的CSS。
浏览器盒子模型
深入了解CSS和浏览器盒子模型(browser-based box model)是做好CSS布局非常必要的一个条件。
CSS校验
我们不使用 w3c的css校验器。
CSS格式化
我们应该保证,至少每一个选择器应该在单独的一行。声明应该是缩进的。
Classes vs. IDs
如果一些元素是文档中独一无二的,那么你应该只给他们一个ID属性。CLASS则是应用在具备同样属性样式的多个元素上。
选择器的命名规范
无论是ID选择器还是类选择器,我们应该遵循“它是什么(what it is)”而不是“它是什么样子的(what it looks like)”的原则进行命名。例如:一个class命名为 bigBlueText,如果它后来被改为了红色的小字体,那么该class命名就失去了意义,让人不好理解。
如果我们命名为 noteText,无论如何改变外观,它仍然是一个文本框,仍然有意义。
选择器(Selectors)
CSS Selectors Level 3规格说明书里介绍了一整套CSS选择器,非常有用。
Pseudo-classes
伪类(Pseudo-classes)能动态化样式内容。一些伪类从CSS1就存在了,如:visited, :hover
,有些从CSS2就存在了,如:first-child, :lang
。CSS3引入了16个伪类,都非常有用,请深入学习一下它们的用法。
特殊性(Specificity)
浏览器会计算一个选择器的权重,来决定应用哪一个CSS规则。如果两个选择器都要应用到一个元素上,那么特殊性更高的选择器胜出。
ID的特殊性比属性选择器的更高;属性选择器则比类选择器高。所以你可以尝试用id来增加特殊性。
计算特殊性
当你遇到一个又大又复杂的样式表时,你最好知道怎么计算特殊性,这样能让你的选择器更有效率。
特殊性的值可以看作是一个由四个数组成的一个组合,用 a,b,c,d 来表示它的四个位置。 依次比较 a,b,c,d 这个四个数比较其特殊性的大小。比如,a 值相同,那么 b 值大的组合特殊性会较大,以此类推。注意,W3C 中并不是把它作为一个 4 位数来看待的。
a,b,c,d 值的确定规则:
- 如果 HTML 标签的 'style' 属性中该样式存在,则记 a 为 1;
- 数一下选择器中 ID 选择器的个数作为 b 的值。比如,以上样式中包含 '#c1' 和 '#c2' 的选择器;
- 其他属性以及伪类(pseudo-classes)的总数量是 c 的值。比如,上面例子中的 '.con',':hover' 等;
- 元素名和伪元素的数量是 d 的值;比如上面例子中的 ‘div’。
(注:原文为:
- Element, Pseudo Element: d = 1 – (0,0,0,1)
- Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
- Id: b = 1 – (0,1,0,0)
- Inline Style: a = 1 – (1,0,0,0)
此处没有直接翻译。)
下面举一个实际例子:
使用!important将覆盖所有特殊性,无论它们值有多高。因此尽量不要用 !important。大多数情况下它都是不必要的。
Pixels vs. Ems
我们使用px计量单位来定义字体大小,因为它对文本提供了绝对控制。在IE6浏览器中,如果是用px为单位,那么在页面放大缩小的时候,就不会根据页面缩放的大小来调整基础文本的大小。当今所有主要浏览器(包括IE7和IE8)现在支持文本的像素单位 和/或 整版的缩放。在不考虑IE6的情况下,像素大小是首选。此外,没有单位的行高(line-height)是首选的,因为它不继承它的父元素一个百分比值,而是基于一个乘数的字体大小。
正确的写法:
错误的写法:
IE的那些BUG
不可避免的,当其他浏览器都工作正常时,IE的各个版本有可能会引入一些荒谬的BUG,搞得你措手不及。最后我们只好用CSS hooks加一些条件判断单独设置IE下的表现。更多详情请阅读paulirish的文章。
举例:
如果你使用HTML5(以及HTML5 Boilerplate),那推荐你使用Modernizer Javascript 库以及下面这个模式:
简写(CSS Shorthand)
一般来说,CSS简写是首选的,因为简洁。开发人员应该意识到TRBL(Top Right Bottom Left)缩略词,按顺时针“上、右、下、左”进行定义。例如:
padding-left:10px;padding-right:15px;padding-top:20px;padding-bottom:10px;
可将其简写为:padding:20px 15px 10px 10px;
参考阅读:
- http://qrayg.com/journal/news/css-background-shorthand
- http://sonspring.com/journal/css-redundancy
- http://dustindiaz.com/css-shorthand
图片
- 当需要使用重复平铺的图片时,图片尺寸大小应该大于 1x1像素。
- 注:链接给出了一个例子,他用了一个1×1的透明PNG图片作为div的重复背景,样式为:background:transparent url('images/transparent-bg.png') repeat left;,但发现在IE7和IE8下显示有问题,最后只好用了一个1×2的透明图片。
- 不要使用Spacer Images(空白图片)!
- 注:spacer image,指的是1×1的透明图片,用以填充表格的空白区域,以便撑住表格不变形。
- 请大量使用CSS sprites技术!这样做可以大大的减少图片的HTTP请求次数,从而加快网页的加载时间。
- 所有的切片图像应具有透明背景(PNG8)。切图应该紧着图片边缘切。
- 但是 logo 图片文件应该在切图时保留一个padding,这样便于其他人加热链。
文本和字体样式
标题
- 定义标题的默认样式为h1~h6。推荐做法是,在你的CSS文件顶部声明这些默认样式,必要时修改它们使得它们在网站中保持一致性。
- 标题的显示根据页面层级的不同和标题的重要性,从顶部开始,自上而下。h1为最大字体,h6为最小字体。
- SEO提示:请务必保证你的页面在失去CSS支持的时候,依然能够保证一个清晰的一个页面结构,因为搜索引擎对一个结构清晰的页面会特别关照。
链接
应确保链接的默认样式与主要文本的样式有所区分,鼠标悬停状态的样式也应该有所区分。
JavaScript
JavaScript是web页面中的第三个主要的组件。
JavaScript库
目前,我们主要使用jQuery开发新的web应用程序。
一般的编码规则
- 99%的代码应该放在外联JavaScript文件里。这些外联JavaScript文件的声明都应该放在body标记的底部,即