CSS重构:样式表性能调优
这两天窝在家里又看了本CSS相关的书:《CSS重构:样式表性能调优》。重构是指在不改变代码行为的前提下,重写代码,使其更加简洁、易于复用。
这本书读起来比较快,可挑自己感兴趣的读,前面三章是基础知识的介绍,都了解的话可直接跳过。第四章是为样式分类,我比较感兴趣的是第四章(测试)和第五章(代码的组织和重构策略)。
一、测试
测试时需要考虑很多因素,其中包括以下几点:
1、正在用什么浏览器测试网页?
2、如何在不同的操作系统上测试各种各样的浏览器?
3、正在多大的窗口浏览网页?
4、如何快速测试大量网页?
5、如何验证你所看到的效果是正确的?
6、如果你无法获得某些设备,如何测试网站在这些设备上的效果?
1)测试多个浏览器
最常用的测试 CSS 在不同浏览器中显示效果的方法是人工测试,主流浏览器包括Chrome、Firefox、Safari、Microsoft Edge等。
为了测试 CSS 在移动端的效果,需要从合适的应用市场下载适合于设备的各种浏览器。
1、要用iOS系统的Safari浏览器测试, 可以使用iOS原生设备或Xcode的iOS模拟器。
2、安卓设备可以用 Android Studio 的模拟器测试。
2)第三方测试服务
除了自己测试,还可以使用第三方提供的种类丰富的测试服务。它们能够满足测试网站在任意浏览器或其他配置环境中的效果的需求,同时还提供类似共享测试阶段信息、人工测试多种浏览器和截图等功能。
下面列出的几种第三方服务,有些可免费试用一段时间或提供几种级别的免费服务:
1、BrowserStack
2、Sauce Labs
3、Browserling
4、Litmus
3)视觉回归测试
视觉回归测试是一种测试方法,它通过比较作为基准的用户界面图像和开发过程同一用户界面的图像,来检测不符合预期的改动(回归)。视觉回归测试非常耗时,因为需要测试的浏览器很多,一有改动就进行这种测试,测试工作量很大。此外,肉眼难以确定元素在空间位置上的变化。视觉回归测试有如下技巧:
1、测试重要的点,例如一旦基础样式定义好,就不大可能因为改动它们而引入错误;但是更为复杂、更加脆弱的可用性组件则是需要重点测试的。
2、保持足够细致的粒度,每次只测单个组件。
3、用多种浏览器进行视觉回归测试,因为不同浏览器之间可能存在不一致现象,即不要尝试比较不同浏览器的截图。
Gemini项目是Yandex团队开发的视觉回归测试工具。使用该工具,可以编写脚本,自动截取网站在主流浏览器中的截图,然后将其与基准图像比较,不同之处将以高亮形式标记出来。
除了 Gemini, 还有多种视觉回归测试工具, 其中最常用的两个是Wraith和PhantomCSS。前者由BBC开发,后者由Huddle公司的James Cryer带领开发团队编写,它们能打开网站,能用PhantomJS(基于WebKit的无头浏览器)或 SlimerJS(基于Gecko的无头浏览器)截图,能对比网页现有元素的截图跟元素基准图像之间的差异。
二、维护代码
代码的测试跟编写同等重要。不断维护已有代码,提高其质量,其重要性不亚于编写新代码。
1)编码规范
编码规范是指将良好的代码编写方法记录下来形成指南,以鼓励团队所有成员以相同的方式编写代码。CSS 编码规范通常指定了注释、格式、命名和选择器用法方面的规范,其详略程度可根据实际情况自行调整。
(1)注释
A. 应该在每个文件的开头添加注释,说明文件的内容。
/** * 该文件包含选项卡组的样式。 * 选项卡组应仅包含拥有tab类的元素。 */
B. 易于混淆的属性,应用注释予以说明。
.tab-group-flush { display: block; margin-left: -12px; /* 清除父容器的padding值 */ margin-right: -12px; /* 清除父容器的padding值 */ }
(2)格式
A. 规则集应该满足下列要求。
1、有多个属性时,每个属性占一行。
2、规则集声明块中的每条声明缩进 4 个空格。
.selector { property1: value; property2: value; }
B. 声明语句应该满足下列要求。
1、冒号后面加1个空格。
2、必须以分号结尾。
.selector { property1: value; }
C. background-position各个属性值不同时,可以将两个属性值放在一行。
.selector1 { background-position: 0 0; } .selector2 { background-position: 0 -10px; } .selector3 { background-position: 0 -10px; }
D. 规则集和声明末尾的空格必须删除。
(3)选择器命名规范
A. 只允许使用小写字母。
.selector {}
B. 包含多个单词的选择器必须使用脊柱状形式(用连字符连接单词)。
.selector-with-multiple-words {}
C. 禁止用ID为元素添加样式,应该使用类。
.element-to-style {}
D. 用JavaScript修改样式(不管用什么框架),都必须通过增加或删除CSS类来完成。
/** * 正确:用 JavaScript 为元素添加类,修改元素的样式。 */ $(".js-menu-item").on("click", function(e) { $(this).addClass("highlighted"); });
E. 用作 JavaScript 选择器的类和 ID ,必须添加 js- 前缀,并严禁在样式表中使用。
/** * 正确:在JavaScript中,用专门用作JavaScript选择器的类选择元素。 */ $(".js-menu-item").on("click", function() { $(this).addClass("highlighted"); });
F. 必须使用有意义的类名。
/* 正确:类的命名有意义且描述清楚。 */ .resident {}
G. 类名必须描述为什么元素添加样式,而不是怎样添加样式。
/* 正确:类的命名描述的是为什么元素添加样式。 */ .sidebar-important {}
(4)属性
A. 属性的简写形式只可用于border、margin和padding。
/* 正确:仅border属性使用了简写形式。 */ .selector { border: 1px solid #000000; font-family: Arial, sans-serif; font-size: 12px; }
B. 属性必须按照字母顺序排列。
.selector { border: 1px solid #000000; margin: 24px; padding: 12px; }
C. 属性值为0时,必须省略单位。
.selector { border: 1px solid #000000; margin: 0; padding: 0; }
更多编码规范方面的启示,请见下面这些规范:
1、Google CSS编码规范
2、18F前端指南
2)模式库
模式库 (有时也称样式指南)是网站使用的一组用户界面模式,它展示了每种模式相关的重要信息,其中包括以下几点:
1、何时(不)使用模式的指导。
2、解释模式使用方式的示例代码。
3、使用某一模式而不用另一模式的原因。
模式库有如下几个优点。
1、首先,模式库将网站所有组件汇集到一起。参与项目的所有成员都能了解到搭建网站的各个模块,确保他们熟悉其背后的原理。让每个人都熟悉一组可复用的模式,还能加快开发速度,因为开发新项目时,无需从头重新开发这些构建模块。
2、模式库将所有组件汇集到一起,还有助于保证用户界面的一致性。使用模式库对设计团队也能起到帮助作用,因为需要修改组件的样式时,在现有模式的基础上做修改即可。模式库为设计工作提供约束条件,鼓励设计师在现有模式的基础上设计新的元素,这进一步强化了用户界面应该保持一致的设计理念。
3、最后,模式库将网站的所有组件都汇集到一起,使识别不一致的组件变得更加容易。编写的新代码可能影响到用户界面效果,在提交代码之前,借助模式库,可从视觉上快速识别错误。修改模式后,若网页看起来有问题,有了模式库,诊断问题将更加容易,因为模式库是模式的最简单应用形式。
Yelp和MailChimp的模式库在各个方面都做得非常出色。关于模式库的更多资源,请见styleguides.io, 该网站提供相关示例、文章、图书和播客。
三、代码的组织和重构策略
1)按照样式从最不精确到最精确组织 CSS
CSS 样式根据选择器的特指度和样式的顺序产生作用。因此,有必要按照样式产生作用的顺序组织 CSS 代码。
1、通用样式,用来设定基准,以消除不同浏览器之间的不一致性。
2、基础样式,为网站的所有元素提供基本的样式。留白( margin、padding和line-height等)、字体及其大小等样式。
3、组件及其容器的样式,满足网站范围内的大多数应用场景,样式上的任何调整都应该交由父容器处理。
4、结构化样式,包括组件及其容器的样式。 该类样式用来创建网页的布局,并常用于定义尺寸。
5、功能性样式,所有样式中最精确的样式。 JavaScript所使用的添加 !important 语句的类就属于这类样式,其他为满足单一目的而实现的样式也属于该类。
6、浏览器特定样式(如果一定需要),只对特定的浏览器生效。通常不够优雅,因此不再使用时,一定要将其删除。
按照以上顺序添加 CSS, 随着声明块选择器的精确度提高,更为复杂的选择器将与已经添加的更加宽泛的选择器区分开来。
2)多个文件还是一个大文件
代码的组织方式有两种,即将代码置于多个文件或只用一个大文件。代码放置位置要易于开发人员查找,这一点很重要,并且同样非常重要的是,这样做有助于网站快速加载以满足终端用户的需要。
1、尽可能地使需要下载的 CSS 文件缩小,以便提高加载速度。
2、小型项目用一个 CSS 文件完全可以接受,合理地将 CSS 文件内容划分为几个大块,每个大块下再恰当安排小块内容,并合理添加注释。
/** * 通用样式 * --------------------------------------------- */ /** * 基础样式 * --------------------------------------------- */ /* 基础样式:表单 */ /* 基础样式:标题 */ /* 基础样式:图像 */
3、开发网站时使用多个 CSS 文件,各个文件所包含的样式可以分别服务于网站的某一部分功能,从而可以避免将 CSS 添加到不恰当的位置。
|-css/ | |-normalizing-styles | | |- normalize.css | | | |-base-styles | | |- forms.css | | |- headings.css | | |- images.css | | |- lists.css | | |- tables.css | | |- etc. | | | |-component-styles | | |- alerts.css | | |- buttons.css | | |- carousel.css | | |- dropdowns.css | | |- modals.css | | |- etc. | | | |- structural-styles | | |- layout-checkout.css | | |- layout-sidebar.css | | |- layout-primary.css | | |- layout-settings.css | | |- etc. | | | |- utility-styles | | |- utility.css | | | |- browser-specific-styles | | |-ie8.css
3)重构前审查CSS
从以下更高的角度来审查 CSS,将非常有助于重构:
1、所用到的属性列表
2、使用某一特定属性的声明块列表
3、使用的颜色数量
4、使用的最高和最低特指度
5、拥有最高和最低特指度的选择器
6、选择器的长度
CSS Dig是 Google Chrome 浏览器的一款免费插件, 你可以用它获取到以上信息。
4)重构策略
条件允许的话, 应该只对你能够维护的小块代码进行重构,并做到经常评审和发布。
1、保持规则集结构的一致性可以使开发更容易。请确定好声明块的格式和声明语句的顺序。 每条声明语句可以各占一行,并尽可能按照字母顺序排列。
2、删除僵尸代码,僵尸代码是指存在但没有使用的代码,包括没有使用的声明块、重复的声明块和声明语句。
3、分离CSS和JavaScript,搜索JavaScript代码, 找到选取元素的位置, 然后在选择器前面添加 js- ,同时将该选择器添加到HTML代码中定义该元素的位置。
4、分离基础样式,将基础样式分为以下不同类别:
- 标题(
–
)
- 文本(例如:
、和
)
- 超链接()
- 列表(
- 、
- 表格(例如:、、、、和
) - 表单(例如:
- 媒体(例如:
- 和
- )
- 表格(例如:、、、、和