CSS预处器(CSS Preprocessor /ˌpriːˈprəʊsesə/)是基于CSS之上的一种“新”的CSS语言,在CSS基础上添加了一些编程特性。可以认为是CSS的扩展,或CSS的超集,让CSS的编写更简洁、功能更强大。
🔴 那为什么需要CSS预处理器呢?—— 主要是为了加强CSS,解决CSS的一些弊端:
CSS预处器就是为了解决这些问题, 为了像其他编程语言一样,编写简洁、维护更容易、可读性强、适应性强。
🟢 CSS预处器特性:
CSS预处器比较流行的实现语言:Sass/Scss、Less、Stylus
比较 | Less | Sass/Scss |
---|---|---|
变量申明 | @vname: #FFF color : @vname 变量插值:@{XXXX} |
$vname: #FFF color : $vname 变量插值:${XXXX} |
嵌套规则 | 选择器嵌套:div p a{} = div{ p{ a{}}} | 选择器嵌套:同Less |
代码复用 | 混入(Mixin):复用(拷贝)代码 .class{ } { .class() } @extend继承 aclass :extend(pclass) |
混入(Mixin):复用(拷贝)代码 @minxin class{ } { **@include** class} @extend继承:原理是用了并集处理器放公共样式 |
条件语句 | 不支持,用if()函数模拟 | ✅ 支持:if{ } else ,for{}循环 |
运行环境 | JS编写的,可以运行在Node、浏览器环境 | 有Ruby版本、新的dart版本,需要安装对应环境 |
后处理器(post-processor),就是写完CSS后,对CSS进行再加工处理,如cssNext、autoprefixer,用来对CSS代码进行兼容性完善、代码压缩等处理。
中文文档:https://less.bootcss.com/
在线转换工具:http://www.wetools.com/less-to-css
在开发阶段,直接引用less,需引入less的JS文件。
- <link rel="stylesheet/less" type="text/css" href="styles.less" />
- /* less的JS文件 */
- <script src="https://cdn.jsdelivr.net/npm/less@4" ></script>
正式环境肯定是要提前编译输出CSS文件,这就需要安装less包来编译less代码。需要NodeJS环境,然后通过npm指令安装:npm install -g less
这个功能确实很好用,代码结构都清晰了,多用于后代选择器,其他各种(关系)选择器都可以用。
🔸申明:跟HTML结构一样,嵌套使用。
🔸父选择器&:用&符号标识父级,伪元素、属性嵌套必须用&开头。
.less 示例 & 编译结果示例代码:
- /* <p> <span>子曰:</span> <span primary>道听而涂说,德之弃也。</span> </p> */
- @pcolor: gold;
- #quote(@content, @vertical, @padding) {
- content: @content;
- vertical-align: @vertical;
- padding: @padding;
- }
- p {
- background-color: lighten(@pcolor, 30%);
- border:@pcolor solid 10px;
- border-image:repeating-linear-gradient(-45deg,darken(@pcolor, 5%) 5px,lighten(@pcolor, 5%) 10px) 10;
- text-align: center;
- line-height: 3em;
-
- span {
- color: darken(@pcolor, 20%);
- font-size: 1.5em;
- font-weight: 500;
- font-family: '汇文明朝体';
- &[primary] {
- padding: 0 5px;
- &::before {
- #quote("⌈", 4px, 0 6px 0 0);
- }
- &::after {
- #quote("⌋", -4px, 0 0 0 6px);
- }
- }
- }
- }
» 编译结果
- /* <p> <span>子曰:</span> <span primary>道听而涂说,德之弃也。</span> </p> */
- p {
- background-color: #ffef99;
- border: gold solid 10px;
- border-image: repeating-linear-gradient(-45deg, #e6c200 5px, #ffdb1a 10px) 10;
- text-align: center;
- line-height: 3em;
- }
- p span {
- color: #998100;
- font-size: 1.5em;
- font-weight: 500;
- font-family: '汇文明朝体';
- }
- p span[primary] {
- padding: 0 5px;
- }
- p span[primary]::before {
- content: "⌈";
- vertical-align: 4px;
- padding: 0 6px 0 0;
- }
- p span[primary]::after {
- content: "⌋";
- vertical-align: -4px;
- padding: 0 0 0 6px;
- }
同JS,支持单行、多行。
- @import "../css/default.css";
- @import "t2"; /* t2.less */
🔸运算符+、-、*、/
支持任何单位的数值、颜色、变量的运算,结果采用最左边的单位。
@ 开头申明变量,支持表达式。可以定义在外面,也可以定义在规则集内部,这会影响他们的作用域。
🔸作用域:同JS,有提升的效果(同一作用域内,可以先使用后申明),作用域向上查找(继承)。
🔸变量插值:用在类名上,替换为变量值,也是一种变量使用方式,需带花括号:@{vname}
🔸~转义:包含特殊字符,需要引号包起来的变量值,申明格式:@var : ~'value'; @var : ~"value";
- @margin-vertical: 0.5em;
- @line-height: 1.5em + @margin-vertical; /**最好单位一致,px+em会转换失败 **/
- @li-name: li;
- @media768: ~'(min-width: 768px)'; /** 需要引起来的字符 **/
- @border: 1px solide #000;
-
- @media @media768 {
- @{li-name} { /** 变量插值,也是一种使用方式,括起来 **/
- background-color: aliceblue;
- margin: @margin-vertical 0; /** 使用变量 **/
- line-height: @line-height;
- border: @border;
- }
- }
» 编译结果:计算并替换最终值
- @media (min-width: 768px) {
- li {
- background-color: aliceblue;
- margin: 0.5em 0;
- line-height: 2em;
- border: 1px solide #000;
- }
- }
混合(Mixins)就是复用代码,复用一组CSS规则、一条规则值,类似JavaScript的函数调用。复用(复制)代码,直接把一个类里面的代码拷贝过来,命名空间的混入也一样,把类当函数调用。
🔸申明:class(){} 类名一般为#、.开头,括号()可带、可不带。带括号时,编译不会输出该申明代码,so,建议一般都带上括号。
🔸使用:class(),就像函数调用一样,把class{}中的规则代码复制过来。
- .border
- {
- border: 1px solid #66F;
- border-left-width: 3px;
- }
-
- li {
- padding: 0 5px;
- .border(); /*复用(复制)代码*/
- }
» 编译结果:📢 注意上面被复用的类.border也会编译输出,如不需要申明时加上括号()。
- .border {
- border: 1px solid #66F;
- border-left-width: 3px;
- }
- li {
- padding: 0 5px;
- /*复用(复制)代码*/
- border: 1px solid #66F;
- border-left-width: 3px;
- }
按照 命名空间来组织管理复用的(mixins)代码。
🔸申明:就是多层混合的嵌套,类似JavaScript里面的Object对象,可以通过.来链式调用。
🔸使用:使用的时候也是按照嵌套路径调用。
- #namespace() { /** 申明命名空间 **/
- .button-orange { /** 申明了两个子类 **/
- background-color: orange;
- border: @border;
- &:hover {background-color: lighten(orange,20%);}
- }
- .button-blue{
- background-color:skyblue;
- border: @border;
- &:hover {background-color: lighten(skyblue,20%);}
- }
- }
- div{
- button{
- #namespace.button-blue(); /** 使用混入,通过命名空间调用 **/
- }
- }
» 编译结果:
- div button {
- background-color: skyblue;
- border: 1px solide #000;
- /** 使用混入,通过命名空间调用 **/
- }
- div button:hover {
- background-color: #def2fa;
- }
像JavaScript中的Map一样使用,复用规则里面的属性值。
🔸使用:用[]的形式获取css属性值,#map[pname]
- #border(){
- border: 1px solid black;
- color: red;
- }
- div {
- #border();
- border-color: #border[color];
- }
» 编译结果:
- div {
- border: 1px solid black;
- color: red;
- border-color: red;
- }
混入支持带参数,在使用的时候传入参数,参数支持默认值,这个还挺好用的!
- #namespace {
- .button(@color:orange) { /* 带参数,并设置了默认值 */
- background-color: @color;
- border:1px solid @color;
- &:hover {
- background-color: lighten(@color, 20%);
- }
- }
- }
- div {
- button {
- #namespace.button(blue);
- color: #namespace.button[background-color];
- }
- }
继承另外一个类的规则集,效果同混入,使用起来更优雅一点。
🔸使用:class :extend(pclass)
内置了很多函数,用于字符、颜色、算数技术。函数手册
属性 | 描述 |
---|---|
percentage(n) | 转换为百分比值, |
saturate(color, 5%) | 颜色饱和度增加5% |
lighten(color, 5%) | 颜色亮度降低5% |
darken(color, 5%) | 颜色亮度增加5% |
if(condition, tv,fv) | IF函数,同JS的三元运算符? |
replace(str, par, rep) | 字符替换 |
extract(list, index) | 提取集合的值 |
each(list, rules) | 循环输出规则 |
中文文档:https://www.sass.hk/docs/
Less、Scss使用区别并不大,很多用法都比较相似,比较常用的嵌套是一样的,变量、混入的语法稍有不同。相对而言,Less稍简洁,Scss更强大点,学习一个就行了,很多框架是都支持,实际需要的时候看看文档即可。