很久以前,我试图整理一个CSS命名和编写规范,CSSWritingRules[1]。基于以上,本文提供了一些更多的建议。可以根据团队情况和业务特点,选择跟随使用或者部分跟随使用。大部分规则翻译自CSLint--Wiki[2]。从CSSLint的规则中,我们可以窥探到很多有趣的CSS细节,可以帮助我们更好地理解CSS,编写出兼容性更好的CSS代码。这只是一个指南,不是标准。Possible/PotentialMiswriting以下规则是可能导致意外错误的CSS书写示例。小心盒子模型大小这个规则主要针对盒子的高度和宽度,考虑以下情况:.mybox{border:1pxsolidblack;padding:5px;width:100px;}mybox的元素宽度可能会被误认为是100px.但实际上,宽度是112px。这是因为框的宽度最终是由content、padding、border的宽度相加得到的。建议写法:.mybox{box-sizing:border-box;border:1pxsolidblack;padding:5px;width:100px;}建议规则:width与border组合,border-left,border-right,padding,padding-left,同时使用padding-right属性时,指定box-sizing;当height与border、border-top、border-bottom、padding、padding-top、padding-bottom属性一起使用时,指定box-sizing。显示匹配属性(display-property-grouping)当元素设置不同的显示时,一些规则可能会失效。当display:inline时,width、height、margin-top、margin-bottom和float属性将不起作用,因为内联元素盒模型不是标准的盒模型,这些属性将不起作用。当然,不仅是上面的display:inline,还有一些特别建议的规则:display:inline不适用于width、height、margin、margin-top、margin-bottom、float;display:inline-block不与float一起使用;display:block不与垂直对齐一起使用;display:table-*不与margin或float一起使用。很好理解,duplicate-property是不允许的,在相同的样式规则中不允许重复定义的属性。例如:.mybox{width:100px;width:120px;}当然也有例外。定义相同的属性可以用来实现一些渐进增强的功能。例如:.mybox{background:#fff;background:rgba(255,255,255,0.5);}对于不支持RGBA颜色显示的浏览器,fallback会使用第一个定义的规则background:#fff。不推荐写法:/*propertieswiththesamevalue*/.mybox{border:1pxsolidblack;border:1pxsolidblack;}/*propertiesseparatedbyanotherproperty*/.mybox{border:1pxsolidblack;color:green;border:1pxsolidred;}允许写法:/*oneafteranotherwithdifferentvalues*/.mybox{border:1pxsolidblack;border:1pxsolidred;}建议规则:不允许出现两次且值相同的属性;同一属性不允许出现两次并至少被一个其他属性分隔。不允许使用空规则(empty-rules)。空规则不包含任何属性(没有定义样式属性),如下:.foo{}空规则的出现可能是重构样式,忘记删除冗余代码导致的。消除空规则可减少样式文件大小并简化浏览器必须处理的样式信息。建议规则:1.代码不包含空样式规则使用已知属性(known-properties)CSS可以使用越来越多的属性,这个规则检查属性名是否正确。此规则将检查用于确保它是已知属性的每个属性名称。当然,以-前缀开头的特定于浏览器的属性将被忽略,因为前缀被添加到没有单个引用的各个浏览器版本属性中。该规则不仅检查属性名称,还检查属性对应的值是否与其匹配。建议规则:2.在样式中使用标准属性和属性值兼容性Disallownegativetextindent(Disallownegativetextindent)该规则旨在识别在CSS代码中使用text-indent的潜在问题。负文本缩进通常用于次要目的,以隐藏屏幕上的文本。一个用例是作为一种图像替换技术,使用负文本缩进来确保屏幕阅读器可以阅读文本,即使它没有显示在屏幕上。这种技术通常使用较大的负单位值,例如-999px或-9999px,如下:.mybox{background:url(bg.png)no-repeat;text-indent:-9999px;}这个有技术上的缩进这个允许背景图像显示给普通用户,同时确保屏幕阅读器可以流畅地解析内联文本信息。当在横向视图页面中使用文本的负缩进时,会造成一些麻烦,因为会有很长的水平滚动条。这个问题可以通过添加direction:ltr来解决,如下:.mybox{background:url(bg.png)no-repeat;+direction:ltr;text-indent:-9999px;}建议规则:1.使用负数时文本缩进时,与direction:ltr一起使用。Usingbrowsercompatibleprefixes(Requirecompatiblevendorprefixes)浏览器兼容前缀是一个属性从提案到标准的演进过程中引起的问题。以渐变为例。2011年12月,CSS渐变的标准定义尚未最终确定。也就是说,在那个时候,要想实现跨浏览器的颜色渐变,需要使用很多不同的浏览器前缀。CSS渐变有五种不同的浏览器前缀。-ms-linear-gradient和-ms-radial-gradient用于InternetExplorer10+-moz-linear-gradient和-moz-radial-gradient用于Firefox3.6+-o-linear-gradient和-o-radial-gradient用于Opera11.10+-webkit-linear-gradient和-webkit-radial-gradientforSafari5+andChrome-webkit-gradientforSafari4+andChrome(aka"OldWebKit")这个规则要求我们包括所有浏览器的定义使用渐变设备前缀。当然,现在标准已经统一了,到今天,我们写CSS、加浏览器前缀几乎都不再人为了。都应该使用autoprefixer来解放生产力,还有一些类似的前缀兼容问题,比如display:flex等,可以点击查看:展开查看,建议添加多核前缀。随着CSS的发展,这张表无法涵盖所有??的内容。所以最好的办法还是autoprefixer,利用工具添加浏览器前缀。建议规则:1.尽量使用autoprefixer来编译你的CSS代码,使用工具代替手动添加浏览器前缀。使用后备颜色(Requirefallbackcolors)这条规则旨在确保所有浏览器都能显示合适的颜色。建议在使用CSS3颜色表示法rgba()、hsl()、hsla()时,使用备用颜色,以保证颜色值在低版本浏览器上能正确显示,像这样:.mybox{color:red;color:rgba(255,0,0,0.5);}建议规则:指定color属性,当rgba()、hsl()、hsla()颜色值使用时,使用颜色colorforolder属性定义Format之前的浏览器。不再使用旧版IE的hack方法。早些年,老版本的IE浏览器还是要兼容的。我们的CSS代码会有很多*、_等,像这样:{background-color:yellow\0;/*ie8*/+background-color:pink;/*ie7*/*background-color:pink;/*ie7*/_background-color:orange;/*ie6*/}在IE8-逐渐退出历史舞台的今天,如果业务已经彻底放弃IE8-,那么这些针对IE的hack应该不会再用了。建议规则:1.不要使用+、_、*、\0等这些提高IECSS性能的hack。不要使用过多的网络字体(Don'tusetoomanywebfonts),这个很好理解,@font-face的出现让我们可以让用户使用任何字体,而不必拘泥于其中一种“网络安全”字体。但是字体文件本身非常大,有些浏览器在下载字体文件的时候并没有实时渲染,这给使用网页字体时的显示性能带来了隐患。所以建议使用@font-face不易使用过多的web-fonts。建议规则:使用少于5个网络字体@font-face引用。5这个数字是CSLint的建议,个人认为在实际使用中这个值应该低一些。不要使用@import@import命令用于在CSS文件中引用其他CSS文件,如下:@importurl(more.css);@importurl(andmore.css);a{color:black;}当浏览器解析这段代码,每次@import后都会下载指定的文件,从而停止后面代码的执行。也就是说,在@import指定的文件下载完成之前,浏览器不会同时下载其他样式文件,从而失去并行下载CSS的优势,导致页面闪烁。建议规则:1.不要在CSS代码中使用@import当然,这里的@import表示编译后的CSS文件不出现,未编译的CSS文件不受此限制。谨慎使用属性选择器(Disallowselectorsthatlooklikeregularexpressions)CSS3属性选择器更新后,CSS具有类似正则匹配的能力。属性选择器详见:深入挖掘CSS属性选择器[3],像这样:[attr|=val]:选择attr属性值为val或以val-开头的元素(注意“-”这里不是报错,是用来处理语言编码的)。[attr^=val]:选择attr属性值以val开头(包括val)的元素。[attr$=val]:选择attr属性值以val结尾的元素(包括val)。[attr*=val]:选择attr属性值包含子串val的元素(子串只是字符串的一部分,例如“cat”是字符串“caterpillar”的子串)选择一个img标签,其中包含一个title属性,包含一个类名logo的元素,img[title][class~=logo]{...}属性选择器为匹配带来了方便,因为这些复杂的属性选择器是必须要反复计算的来匹配对应的属性值,从而保证最终的显示效果是正确的。为此,CSS需要消耗更多的时间来计算整个页面的显示效果。建议规则:1.尽可能少的使用属性选择器,如果你决定使用它,你应该意识到选择器比一些常规选择器带来更多的开销。谨慎使用通配符*(Disallowuniversalselector)来匹配所有元素。虽然每次都选择一个非常方便元素组,但如果作为选择器的核心部分(选择器最右边的位置),则会造成性能问题。比如下面的规则形式应该避免:.mybox*{background:#fff;color:#000;background:rgba(255,255,255,0.5);}浏览器解析CSS规则是从右到左选择器解析的,所以这个规则将首先匹配文档中的所有元素。然后检查这些元素是否匹配从右开始的下一级规则,即是否具有祖先样式mybox。包含*的选择器越复杂,解析所需的时间就越长。建议规则:1.万能选择器*慎用,如果一定要用,尽量避免放在选择器的最右边。小心未定义的属性选择器(Disallowunqualifiedattributeselectors)HTML5允许在HTML标签中创建自定义属性。但是,与前面的规则类似,例如[type=text],首先匹配所有元素,然后检查个别属性。这意味着未定义的属性选择器与通用选择器具有相同的性能问题。与通用选择器类似,未定义的属性选择器在选择器的核心部分(选择器最右边的部分)时会导致性能问题。像这样:.mybox[type=text]{background:#fff;color:#000;background:rgba(255,255,255,0.5);}建议规则:1.尽量避免将属性选择器放在选择器的末尾对.Useshorthandproperties(Requireshorthandproperties)这个规则建议当可以使用速记属性来减小文件大小时,你应该尽可能使用速记,像这样:.mybox{margin-left:10px;margin-right:10px;margin-top:20px;margin-bottom:30px;}应该替换为:.mybox{margin:20px10px30px;}建议规则:1.当文件大小可以通过速记属性减小时,你应该尝试使用速记属性的方法和不允许重复的背景图像定义(Disallowduplicatebackgroundimages)如果你有多个样式需要使用同一个背景图像,最好声明一个通用的样式类,其中包含这个图像的URL。然后将这个类添加到需要使用的元素中。请看下面代码:.heart-icon{background:url(sprite.png)-16px0no-repeat;}.task-icon{background:url(sprite.png)-32px0no-repeat;}在两个类中重复定义背景图像的URL。这会产生冗余代码并增加修改成本。如果需要修改图片名称,很容易忘记同时修改文件中两张图片的地址。更好的方法是提取一个图像地址类作为重用类,然后将这个类添加到原始HTML元素中。像这样:.icons{background:url(sprite.png)no-repeat;}.heart-icon{background-position:-16px0;}.task-icon{background-position:-32px0;}
