相信对于知道前端这个词的人应该都听说过CSS吧。提到CSS我们应该容易想到传统CSS带来的一些局限性,实际上在CSS的整个发展历史上,总共经历了4次的布局革命,从初代的table布局到CSS+DIV布局,再到现在比较流行的的Flex布局和Grid布局。
初代的table布局
实际上这个布局在目前的HTML5的规范中已经不存在了,但是还是可以稍微了解一下的:
This would be some font broken up into columns
table初代布局有一个问题是:它的结构跟表现是混合在一起的。因此在我们需求变更和改动的过程中实际上是很困难的。
CSS+DIV布局:结构和表现分离开来
CSS+DIV也是目前最流行的布局方式。
html { margin-left: 2cm; font-family: "Times", serif;}
h1 { font-size: 24px;}
Flex布局
也就是我们说的一个弹性盒子,它是移动端一个比较主流的布局技术,单一维度的布局。
.flex {
height: calc(100% - 120px);
display: flex;
}
Grid布局
也叫作网格布局,实现了CSS维度的拓展。使用网格布局可以定义它的行和列的一个属性,这也是它的CSS的二维布局。
.container {
height: 100%;
display: grid;
grid-template-columns: 200px auto 200px;
grid-template-rows: 80px auto 40px;
}
总的来说,它们还是有一些共同的特点的:
- 只有一个全局的命名空间,所以无法避免出现选择器的冲突。
- 模块化做的不够好,很容易造成嵌套和样式覆盖混乱,然后导致了一大堆的乱七八糟的文件的产生。
上面两个问题是传统CSS的局限性的两个关键地方所在,也是传统CSS的两个槽点。因此就诞生了CSS预处理器。
预处理器:也就是在我们编写代码的时候,可以不按照传统的CSS的写法来写,然后经过一层预处理器转换成浏览器可以理解的一个传统的CSS,这就是CSS预处理器的作用。
CSS预处理器的几大重要功能:
文件拆分
- css预处理器扩展了@import 指令的能力,比如在es6里面如果要引入一个js文件,一般我们需要用一个import,但是经过了CSS预处理器都会有一个@import的能力。
- 编译环节将切分后的文件重新合并为一个大文件,文件的引入解决了两个问题:
1 解决了大文件不便维护的问题
2 解决了一堆小文件在加载时的性能问题
模块化
- css 文件在合理切分
- 编译环节将切分后的文件重新合并为一个大文件
1 解决了大文件不便维护的问题
2 小文件的相互关系形成一个树形结构
index.css
├─ header.css
│ └─ reset.css
├─ content.css
│ ├─ left.css
│ │ └─ nav.css
│ └─ right.css
├─ fotter.css
└─ ...
选择符嵌套
- 传统嵌套
1 手工维护缩进关系
2 当上级选择符发生变化时,所有相关的下级选择符都要修改
3 注释书写
.header {
margin: auto; /* 水平居中 */
width: 1000px;
color: #333;
}
.header li {
float: left;
width: 100px;
}
.header li a {
display: block;
text-decoration: none;
}
- 预处理器嵌套
1 层级关系清晰
2 注释清晰易读
.header {
margin: auto // 水平居中
width: 1000px
color: #333
li {
float: left // 水平排列
width: 100px
a {
display: block
text-decoration: none
}
}
}
变量(换肤)
- 实现了网站视觉风格的统一
strong {
color: #ff4466;
font-weight: bold;
}
/* ... */
.error {
color: #ff4466;
}
- 换肤
$color-primary = #329FD9;
header {
color: $color-default
}
.footer {
color: $color-default
}
运算
$left: 20px;
.header {
margin-left: $left + 12px;
}
函数
比如说下面的圆角,可以实现一个CSS里面的函数的复用,提供一个可以统一修改元素圆角的css方法。
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}