良好的 CSS 架构目标
- 可预测性:可预见性的 CSS 意味着你的规则行为正如你所想,当你添加或更新一条规则,他不应该影响你网站上不想要受影响的部分。对于一个小型网站很少的修改,并不是很重要。但是对于一个有着几十或几百个页面的大型网站,可预见性的 CSS 就是一种必要。
- 可重用:CSS 规范应该是足够抽象的和耦合的,这样你可以根据现有代码部分很快创建出新的组件,而不需要重新编写你已经处理过的样式和问题。
- 可维护:当你的网站需要添加、更新或重新安排一些新的组件和特性,这样做不应该重构现有的 CSS。给页面添加 X 组件不应该破坏已经存在的组件 Y。
- 可扩展:随着你的网站的规模和复杂程度的增长,它往往需要更多的开发人员来维护。可扩展的 CSS 意味着可以轻松的由有一个人或一个大型的技术团队管理你的网站。他也意味着你的网站的 CSS 架构容易掌握不需要很陡的学习曲线,仅仅因为你是如今唯一接触 CSS 的开发人员,但是并不意味着永远是这种情况。
CSS 分类
- 基本样式(Base): 网站的全局默认样式
- 对象(Object):只关注解构和布局,不被允许修饰类的样式
- 组件(Components):分离的、自成一体的 UI 零件
- 状态(Status):隐藏/显示,展开/收起
- 主题(Themes):只改变一个组件,使用唯一的颜色、字体等
- 工具集(Utilities):应用一个特殊样式规则改变间隙、增加字体大小、居中文本、添加一个浮动清除、隐藏等,对现有组件进行微调
- JavaScript Hook:JavaScript 与 CSS 解耦
CSS 预处理器
预处理器作为工具,可以实现模块化编写 CSS
目前流行的预处理器有 Less,Sass,Stylus
Less 没有循环,但可以用递归实现,而 Sass 和 Stylus 有真循环
无论是工作还是自己写项目,都要搭建一个项目环境,也就是安装一系列的 npm 包。相比刀耕火种的开发方式,使用工具开发的前期准备过程稍显麻烦,然而一旦环境建好,后期的开发将会游刃有余。
编写框架大致会用到的 npm 如下:
1 | --autoprefixer |
前端框架对比
以 Bootstrap、Semantic、UIkit 为主
选择轻量级框架反倒不如自己实现一个框架。因为大多轻量级框架就像是工作总结,是根据自己的业务需求实现的。所以大多不具有通用性。
大多数的轻量级框架只是 CSS 框架,不涉及 JS 部分,主要用于网页的布局。
模块划分:编写框架的第一步就是要确定框架应该包含哪些模块。因为是轻量级框架,所以模块肯定没有重量级框架那么全面,只有核心的一些组件。通过比较一些轻量级框架以及工作总结,大致常用的模块包括栅格、媒体、按钮、排版、表单、表格、面板以及辅助工具。
在常用的这几个组件中,需要重点关注的是栅格、表单及面板,媒体组件也很重要,但是自由发挥的空间不大,我直接用了 Bootstrap 的媒体组件。
命名策略:首先是类命名的层次与结构。类命名一直是我比较纠结的地方,刚开始工作的时候为了起一个见名知意又简洁的类名总是抓耳挠腮。我在编写框架时尽量避免与 Bootstrap 的类名重叠,但也不能完全避免。对比其他框架会发现,这种情况不可避免的会出现,毕竟类名会有一定的规律性以及层次性。在这一点上我比较喜欢 Bootstrap 的风格。
CSS 样式书写规范
1. 规则声明块
当规则声明块中有多个样式声明时,每条样式独占一行。
在规则声明块的左大括号 { 前加一个空格。
在样式属性的冒号 : 后面加上一个空格,前面不加空格。
在每条样式后面都以分号 ; 结尾。
规则声明块的右大括号 } 独占一行。
每个规则声明间用空行分隔。
所有最外层引号使用单引号 ‘ 。
当一个属性有多个属性值时,以逗号 , 分隔属性值,每个逗号后添加一个空格,当单个属性值过长时,每个属性值独占一行。
1 | .g-footer, |
2. 样式属性顺序
单个样式规则下的属性在书写时,应按功能进行分组,并以 Positioning Model > Box Model > Typographic > Visual 的顺序书写,提高代码的可读性。
如果包含 content 属性,应放在最前面;
Positioning Model 布局方式、位置,相关属性包括:position / top / right / bottom / left / z-index / display / float / …
Box Model 盒模型,相关属性包括:width / height / padding / margin / border / overflow / …
Typographic 文本排版,相关属性包括:font / line-height / text-align / word-wrap / …
Visual 视觉外观,相关属性包括:color / background / list-style / transform / animation / transition / …
Positioning 处在第一位,因为他可以使一个元素脱离正常文本流,并且覆盖盒模型相关的样式。盒模型紧跟其后,因为他决定了一个组件的大小和位置。其他属性只在组件内部起作用或者不会对前面两种情况的结果产生影响,所以他们排在后面。
3. SASS 使用建议
1) 使用 SASS 、 LESS 等预处理器时,建议嵌套层级不超过 3 层。
2) 组件/公用类的使用方法
组件/公用类使用 %placeholders 定义,使用 @extend 引用。如:
1 | %clearfix { |
3) 组件类的思考
使用 SASS ,经常会预先定义好一些常用公用组件类,譬如清除浮动,水平垂直居中,文字 ellipsis。又或者多个元素具有同样的样式,我们希望能够少写这部分代码,公共部分抽离出来只写一次,达到复用。
但是复用的方式在 SASS 中有多种,那么是使用单独使用一个类定义,给需要的标签添加,还是使用 @include 或者 @extend在定义的类中引入一个 @mixin,或者一个 @function 呢?
基于让 CSS 更简洁以及代码的复用考虑,采用上面的使用 %placeholders 定义,使用 @extend 引用的方案。
%placeholders,只是一个占位符,只要不通过 @extend 调用,编译后不会产生任何代码量
使用 @extend 引用,则是因为每次调用相同的 %placeholders 时,编译出来相同的 CSS 样式会进行合并(反之,如果使用 @include 调用定义好的 @mixin,编译出来相同的 CSS 样式不会进行合并)
这里的组件类特指那些不会动态改变的 CSS 样式,注意与那些可以通过传参生成不同数值样式的 @mixin 方法进行区分
4) 尽量避免使用标签名
基于 CSS 选择器的解析规则(从右向左),建议避免使用通用标签名作为选择器的一环可以提高 CSS 匹配性能。