写CSS的人都有这样的困扰:CSS是一门描述性的样式语言,语法简单,但写起来很繁琐。
第一,没有变量。同一个颜色(如主题色),在CSS里要写很多遍,如果要改颜色,得全局搜索替换,容易遗漏。同一个字体、同一个间距、同一个圆角,都是重复写。
第二,没有嵌套。CSS的选择器要一层层写,比如.nav .nav-item .nav-link,重复写父选择器,代码冗长,而且层级关系不直观。
第三,没有函数和运算。CSS不能做计算,比如宽度要根据某个值计算,只能手动算好写死。不能定义函数复用一段样式逻辑。
第四,代码重复多。很多样式是重复的,比如清除浮动、居中、圆角、阴影,每个地方都要写一遍,代码冗余,维护困难。
CSS预处理器(CSS Preprocessor)就是为了解决这些问题而生的。它扩展了CSS的语法,增加了变量、嵌套、混合(Mixin)、函数、继承、运算等编程语言的特性,让CSS写起来更高效、更简洁、更易维护。写好的预处理器代码,会被编译成标准的CSS,浏览器才能识别。
目前最流行的CSS预处理器有两个:Sass(Syntactically Awesome Style Sheets)和Less(Leaner Style Sheets)。两者功能类似,语法略有不同。今天就来介绍它们的基本用法,并做一个对比。
Sass入门
Sass是最早的CSS预处理器,诞生于2007年,用Ruby编写。Sass有两种语法格式:
.sass:缩进语法,用缩进代替大括号,用换行代替分号,简洁但和CSS差异大。.scss:Sassy CSS,是CSS的超集,语法和CSS几乎一样,大括号和分号都保留,学习成本低。现在主流用的是SCSS语法。
变量
Sass用$符号定义变量:
// 定义变量
$primary-color: #3498db;
$font-size-base: 14px;
$spacing: 10px;
// 使用变量
.button {
background-color: $primary-color;
font-size: $font-size-base;
padding: $spacing;
}变量可以是颜色、数字、字符串、列表、映射等类型。变量有作用域,在选择器内定义的变量是局部变量,外部访问不到。可以用!global声明全局变量。
嵌套
Sass支持选择器嵌套,让层级关系更清晰:
// 普通嵌套
.nav {
background: #333;
.nav-item {
display: inline-block;
.nav-link {
color: #fff;
text-decoration: none;
&:hover {
color: $primary-color;
}
}
}
}&符号表示父选择器的引用,常用于伪类(:hover、:active)和伪元素(::before、::after)。
Sass还支持属性嵌套:
.button {
font: {
family: Arial, sans-serif;
size: 14px;
weight: bold;
}
border: {
width: 1px;
style: solid;
color: #ccc;
}
}混合(Mixin)
Mixin是可复用的样式块,用@mixin定义,@include引用:
// 定义mixin
@mixin border-radius($radius: 5px) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
@mixin clearfix {
&::after {
content: "";
display: table;
clear: both;
}
}
// 使用mixin
.button {
@include border-radius(8px);
@include clearfix;
}Mixin可以传参数,参数可以有默认值。Mixin是Sass最强大的功能之一,能大幅减少重复代码。
继承(Extend)
继承让一个选择器可以继承另一个选择器的所有样式,用@extend:
// 基础样式
.message {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
// 继承基础样式
.success {
@extend .message;
border-color: green;
background: #dff0d8;
}
.error {
@extend .message;
border-color: red;
background: #f2dede;
}继承和Mixin的区别:Mixin是把样式复制到引用处(会有重复代码),继承是把选择器合并(如.message, .success, .error共享样式),生成的CSS更简洁。但继承有一些限制(不能在@media中继承外部选择器),使用时要注意。
函数
Sass内置了很多函数,也可以自定义函数:
// 内置函数
.container {
width: percentage(960px / 1200px); // 百分比
color: lighten(#3498db, 20%); // 变亮
background: darken(#fff, 5%); // 变暗
padding: ceil(10.2px); // 向上取整
}
// 自定义函数
@function calculate-width($cols, $total: 12) {
@return percentage($cols / $total);
}
.col-6 {
width: calculate-width(6); // 50%
}Sass的内置函数非常丰富,包括颜色函数(lighten、darken、mix、opacify等)、字符串函数、数字函数、列表函数、映射函数等,能满足各种复杂的样式计算需求。
运算
Sass支持数字运算:
$base-size: 16px;
.title {
font-size: $base-size * 1.5; // 24px
margin: $base-size / 2; // 8px
padding: $base-size + 4px; // 20px
}颜色也可以运算:
$color: #3498db;
.box {
background: $color + #111; // 颜色相加
border-color: $color * 1.2; // 颜色相乘
}导入和模块化
Sass用@import导入其他Sass文件:
// 主文件style.scss
@import "variables"; // 导入_variables.scss
@import "mixins"; // 导入_mixins.scss
@import "base"; // 导入_base.scss
@import "components"; // 导入_components.scss以开头的Sass文件(如variables.scss)是局部文件,不会被单独编译成CSS,只会被导入。这样可以把样式模块化,分成变量、混合、基础样式、组件等不同文件,便于维护。
Less入门
Less诞生于2009年,受Sass启发,但用JavaScript编写,可以在浏览器端或Node.js环境编译。Less的语法和SCSS类似,也是CSS的超集,学习成本低。
变量
Less用@符号定义变量(和Sass的$不同):
// 定义变量
@primary-color: #3498db;
@font-size-base: 14px;
// 使用变量
.button {
background-color: @primary-color;
font-size: @font-size-base;
}Less的变量是懒加载的,可以在使用之后定义,变量会提升到作用域顶部。
嵌套
Less的嵌套和Sass几乎一样:
.nav {
background: #333;
.nav-item {
display: inline-block;
.nav-link {
color: #fff;
&:hover {
color: @primary-color;
}
}
}
}混合(Mixin)
Less的Mixin更简单,直接用类选择器定义,引用时直接写类名:
// 定义mixin(就是一个类选择器)
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
.clearfix() {
&::after {
content: "";
display: table;
clear: both;
}
}
// 使用mixin
.button {
.border-radius(8px);
.clearfix();
}Less的Mixin不带括号时,定义的样式会输出到CSS中;带括号时,只作为mixin使用,不输出。Less的Mixin还支持条件判断(when关键字)和循环(recursive mixin)。
继承
Less的继承用&:extend()语法:
.message {
padding: 10px;
border: 1px solid #ccc;
}
.success {
&:extend(.message);
border-color: green;
}Less的继承功能不如Sass强大,但基本够用。
函数
Less也有内置函数,包括颜色函数、数学函数、字符串函数等:
.container {
width: percentage(960px / 1200px);
color: lighten(#3498db, 20%);
background: darken(#fff, 5%);
}Less也可以用JavaScript表达式(在反引号中),但不推荐使用,因为可移植性差。
运算
Less的运算和Sass类似:
@base-size: 16px;
.title {
font-size: @base-size * 1.5;
margin: @base-size / 2;
}导入
Less用@import导入文件:
@import "variables.less";
@import "mixins.less";
@import "base.less";Less的导入比Sass灵活,可以导入CSS文件、可以设置导入选项(如@import (reference) "file.less"只引用不输出)。
Sass和Less对比
| 特性 | Sass | Less |
|---|---|---|
| 诞生时间 | 2007年 | 2009年 |
| 编写语言 | Ruby(也有Node.js版本node-sass) | JavaScript |
| 变量符号 | $ | @ |
| 语法格式 | .sass(缩进)和.scss(CSS超集) | .less(CSS超集) |
| Mixin定义 | @mixin + @include | 类选择器 + 直接引用 |
| 继承 | @extend | &:extend() |
| 函数 | 强大,内置函数丰富,支持自定义函数 | 一般,内置函数较少 |
| 逻辑控制 | 支持@if、@for、@each、@while | 支持when条件,循环需用递归mixin |
| 编译环境 | Ruby或Node.js | Node.js或浏览器端 |
| 社区和生态 | 更成熟,Compass等框架丰富 | 较大,Bootstrap用Less |
| 学习曲线 | 稍陡(功能多) | 平缓(语法简单) |
怎么选?
两者功能类似,选哪个主要看项目需求和个人偏好:
- 如果项目用Ruby on Rails,选Sass(Rails原生支持Sass)。
- 如果项目用Bootstrap 3,选Less(Bootstrap 3用Less,Bootstrap 4改用Sass)。
- 如果需要强大的函数和逻辑控制(如复杂的样式计算、循环生成样式),选Sass(Sass的函数和控制流更强大)。
- 如果需要在浏览器端实时编译(如在线主题定制),选Less(Less可以在浏览器端用less.js编译)。
- 如果团队熟悉JavaScript,选Less(Less用JS编写,生态和Node.js更契合)。
- 如果是新项目,没有特殊约束,推荐Sass(更成熟、功能更强大、社区更活跃,而且Bootstrap 4已经改用Sass,说明Sass是趋势)。
我个人用的是Sass(SCSS语法),因为它的函数和控制流更强大,能处理复杂的样式需求,而且社区生态更成熟。
编译工具
写好的Sass/Less代码需要编译成CSS才能用。常用的编译工具有:
- 命令行工具:Sass的
sass命令,Less的lessc命令。适合简单项目。 - 构建工具:Grunt、Gulp、Webpack等,配合对应的插件(grunt-sass、gulp-sass、sass-loader等),可以自动编译、压缩、加前缀。适合中大型项目。
- 编辑器插件:Sublime Text、VS Code、WebStorm等编辑器都有Sass/Less插件,可以保存时自动编译。适合个人项目。
- GUI工具:Koala、Prepros、CodeKit等图形化工具,拖拽文件就能编译,适合不熟悉命令行的开发者。
我个人用的是Gulp + gulp-sass,配合gulp-autoprefixer(自动加浏览器前缀)和gulp-clean-css(压缩CSS),构建流程自动化,效率很高。
总结
CSS预处理器是前端开发的必备工具,它让CSS写起来更高效、更简洁、更易维护。变量、嵌套、混合、函数、继承、运算这些特性,能大幅提升CSS的开发效率,减少重复代码。
Sass和Less是最流行的两个CSS预处理器,功能类似,语法略有不同。选哪个主要看项目需求和个人偏好,没有绝对的好坏。如果你还在用纯CSS写样式,建议试试CSS预处理器,它会改变你写CSS的方式,让你爱上写样式。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录