一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情。
背景
CSS 自诞生以来,基本语法和核心机制一直没有本质上的变化,它的发展几乎全是表现力层面上的提升。最开始 CSS 在网页中的作用只是辅助性的装饰,轻便易学是最大的需求;然而如今网站的复杂度已经不可同日而语,原生 CSS 已经让开发者力不从心。
当一门语言的能力不足而用户的运行环境又不支持其它选择的时候,这门语言就会沦为 “编译目标” 语言。开发者将选择另一门更高级的语言来进行开发,然后编译到底层语言以便实际运行。
于是,在前端领域,天降大任于斯人也,CSS 预处理器应运而生。而 CSS 这门古老的语言以另一种方式 “重新适应” 了网页开发的需求。
模块化
把文件切分的思路再向前推进一步,就是 “模块化”。一个大的 CSS 文件在合理切分之后,所产生的这些小文件的相互关系应该是一个树形结构。
树形的根结节一般称作 “入口文件”,树形的其它节点一般称作 “模块文件”。入口文件通常会依赖多个模块文件,各个模块文件也可能会依赖其它更末端的模块,从而构成整个树形。
以下是一个简单的示例:
entry.styl
├─ base.styl
│ ├─ normalize.styl
│ └─ reset.styl
├─ layout.styl
│ ├─ header.styl
│ │ └─ nav.styl
│ └─ footer.styl
├─ section-foo.styl
├─ section-bar.styl
└─ ...
(入口文件 entry.styl 在编译时会引入所需的模块,生成 entry.css,然后被页面引用。)
选择符嵌套
选择符嵌套是文件内部的代码组织方式,它可以让一系列相关的规则呈现出层级关系。在以前,如果要达到这个目的,我们只能这样写:
.nav {margin: auto /* 水平居中 */; width: 1000px; color: #333;}
.nav li {float: left /* 水平排列 */; width: 100px;}
.nav li a {display: block; text-decoration: none;}
这种写法需要我们手工维护缩进关系,当上级选择符发生变化时,所有相关的下级选择符都要修改;此外,把每条规则写成一行也不易阅读,为单条声明写注释也很尴尬(只能插在声明之间了)。
在 CSS 预处理语言中,嵌套语法可以很容易地表达出规则之间的层级关系,为单条声明写注释也很清晰易读:
.nav
margin: auto // 水平居中
width: 1000px
color: #333
li
float: left // 水平排列
width: 100px
a
display: block
text-decoration: none
变量
在变更出现之前,CSS 中的所有属性值都是 “幻数”。你不知道这个值是怎么来的、它的什么样的意义。有了变量之后,我们就可以给这些 “幻数” 起个名字了,便于记忆、阅读和理解。
接下来我们会发现,当某个特定的值在多处用到时,变量就是一种简单而有效的抽象方式,可以把这种重复消灭掉,让你的代码更加 DRY。
我们来比较一下以下两段代码:
strong {
color: #ff4466;
font-weight: bold;
}
/* ... */
.notice {
color: #ff4466;
}
$color-primary = #ff4466
strong
color: $color-primary
font-weight: bold
/* ... */
.notice
color: $color-primary
你可能已经意识到了,变量让开发者更容易实现网站视觉风格的统一,也让 “换肤” 这样的需求变得更加轻松易行。