Less —— 一种CSS预处理器,可编程化书写CSS

148 阅读10分钟

less

前言

less是什么

Less —— Leaner Style Sheets —— 更精简的样式表, 是一门向后兼容的CSS语言,是一种CSS预处理器,CSS预处理器还有Sass、Stylus等

什么是CSS预处理器?

CSS预处理器是一种专门的编程语言,为CSS增加了一些编程特性,使CSS的编写具备一些编程特性,可以更便于对CSS代码进行组织和维护、减少CSS冗余问题

CSS预处理器是用一种编程语言进行Web网页样式设计,然后再编译为正常的CSS文件

使用预处理器,可以在编写CSS时使用变量、加入简单代码逻辑、函数等,让CSS代码适应性、可维护性更强

less介绍

less基于JS,是CSS的超集,less文件后缀是.less

前往less的GitHub

优点:

  • 嵌套编写,代码更可读,组织性更好
  • 变量的使用使代码更容易维护
  • 缩短开发时间
  • 定义样式,方便复用,减少代码量和开发时间

缺点:

  • 框架少
  • 模块之间紧密耦合

安装

首先需要安装Node.js,然后npm install -g less全局安装

将less文件编译为css文件:cmd:lessc fileName.less fileName.css,less文件修改后,重新运行此命令,会自动更新文件

CDN: <script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.11.1/less.min.js" ></script>

记得引入自己的less文件:<link rel="stylesheet/less" type="text/css" href="lessFile.less" />

语法

变量Variables

声明和赋值: @name: value

 /*声明以及赋值*/
 @myWidth: 100px;
 @yourWidth: @myWidth + 10px;
 ​
 /*使用*/
 tag{
     width: @myWidth;
 }
 ​
 //转化之后
 tag{
     width: 100px;
 }

嵌套规则

先展示原本的html和css,注意css的写法

 <html>
     <div class="container">
         <p id="myP">我是container里的文字</p>
         <div id="myDiv">
             <p id="otherP">其他内容</p>
         </div>
     </div>
     
     <style>
         .container #myP{
             font-size: 20px;
             color: #060606;
         }
         .container #myDiv{
             background: skyblue;
             border-radius: 50%;
             background-color: grey;
         }
         .container #myDiv:hover{
             opcacity: 0.7;
         }
         .container #myDiv #otherP{
             color: yellow;
             font-size: 10px;
         }
     </style>
 </html>

less使用层叠之后的写法,可以发现不同选择器的层次性特别清晰,父子元素嵌套关系一目了然。

当代码量多起来后,编写代码时嵌套的优势就会比较明显,代码的可读性会好很多

 .container{
     #myP{
         font-size: 20px;
         color: #060606;
     }
     
     #myDiv{
         background: skyblue;
         border-radius: 50%;
         background-color: grey;
         
         #otherP{
             color: yellow;
             font-size: 10px;
         }
     }
     
     /*在less中有更优雅的写法*/
     #myDiv:hover{
         opacity: 0.7;
     }
 }

嵌套中的伪类选择器

在less的嵌套中,可以使用&代表当前选择器的父级,从而在嵌套中对父级设置伪类

基于这点,上面的#myDiv:hover就可写为:

 .container{
     #myDiv{
         background: skyblue;
         border-radius: 50%;
         background-color: grey;
         
         /*&代表#myDiv*/
         &:hover{
             opacity: 0.7;
         }
         /*同样的,还可以写myDiv的其他伪类,嵌套关系所属关系非常明确*/
         &:after{}
         &:before{}
         &:active{}
         /*...*/
     }
 }

@规则嵌套和冒泡

css3中的@规则也可以和选择器进行嵌套

冒泡:统一规则集合中,其他元素的相对顺序保持不变,嵌套关系的@规则,编译为css时以and连接在一起

 .container{
     width: 300px;
     height: 400px;
     @media(min-width: 200px){
         @media(min-height: 300px){
             background-color: orange;
         }
     }
     @media ....
 }

混合Mixins

将一组css样式封装起来,放到别的css样式中使用,实现一组同样的规则可以在其他多个规则中使用

 /*要封装的*/
 .test{
     border-radius: 10%;
     border: 2px solid grey;
 }
 ​
 //在别的规则里使用
 p{
     display: block;
     /*将规则嵌套进来*/
     .test();   
 }
 ​
 .myDiv{
     position: relative;
     font-size: 3em;
     background-color: #fff;
     /*在别的样式里也使用同样的规则*/
     .test();
 }

less算术运算

less支持简单的四则运算,可以对任何数字、颜色或者变量进行操作,优化css代码编写

 @myFontSize: 10px;
 @myColor: red;
 ​
 #ori{
     font-size: @myFontSize;    
 }
 ​
 #lessAnd{
     font-size: @myFontSize + 10px;
 }
 ​
 #oriColor{
     color: red;
 }
 ​
 #NewColor {
     color: @myColor + blue; //红+蓝
 }

lessc name.less name.css后得到转化后的css文件,可以看到结果为:

 #ori {
   font-size: 10px;
 }
 #lessAnd {
   font-size: 20px;
 }
 #oriColor {
   color: red;
 }
 #NewColor {
   color: #ff00ff;  /*颜色的加减*/
 }

less运算里,参与加减法运算的所有数都会被转换为相同的单位再进行运算

 @parma1: 1cm + 50mm; //结果为6cm

而乘除法中,带单位的数据相乘除不会得到一个区域的面积或者是倍数。而是统一单位,只对纯数字部分进行运算,将计算结果指定明确的单位

 @mul: 6cm * 3mm; //结果为18cm

less的颜色值运算函数

颜色指运算时,单位应当相同(rgb、hsl...),并且参数应当在其相应的范围内,颜色运算时,返回值是运算结果颜色的十六进制

以下函数中,颜色的值都以color代表,增加或减少的值都是百分数

  • saturate(color, 增加的饱和度) :增加某颜色的饱和度,增加的饱和度用百分比表示
 #colorDiv{
     background-color: rgb(226, 158, 158);
     background-color: saturate(rgb(226, 158, 158), 30%);/*给颜色rgb(12,12,12)的饱和度增加30%*/
 }
 ​
 /*编译后的css*/
 #colorDiv{
     background-color: #e29e9e;
     background-color: #f58b8b; /*#e29e9e增加了30%饱和度之后的颜色*/
 }

image.png

  • desaturate(color, 降低的饱和度) :降低某颜色饱和度,用法同saturate(),不再赘述
  • lighten(color, 增加的亮度) :增加某颜色亮度,增加的亮度也是百分数值,类比saturate(),不再赘述
  • darken(color, 降低的亮度) :降低某颜色亮度,类比saturate()
  • fadein(color, 增加的透明度) :增加某颜色的透明度
  • fadeout(color, 降低的透明度) :降低某颜色透明度
  • spin(color, 改变多少色相)旋转颜色色相角度,第二个参数是整型
  • mix(color1, color2) :按比例混合两种颜色,返回混合结果的rgba值
  • greyscale(color) :完全移除颜色饱和度,等效于desaturate(color, 100%)
  • contrast(color, setBlack, setWhite, 百分比界定值(可选项)) :将color与界定值进行对比,若小于界定值就返回setBlack,大于指定值就返回setWhite,界定值是设置的由深色过渡到浅色的转变位置,范围是[0, 100%],默认为43%。setBlack是指定的深色,默认纯黑#000000;setWhite指定的浅色,默认纯白#ffffff,二者均可自己重新设置。可以利用这个函数实现界面主题颜色的切换(白天、夜晚)。

calc(计算式) :特殊,不再向css3那样返回其中数学表达式的计算结果,less里只是计算出其中的变量的值,然后解析出来。v3.0.0开始可用。

 /*less中使用calc()*/
 @myFontSize: 10px;
 #lessAnd{
     font-size: calc((@myFontSize + 20px)*2 - 30px);
 }

lessc name.less name.css后再看编译出的css文件

 /*编译出的css文件中的结果*/
 #lessAnd {
     /*对calc()中数学表达式结果的计算由CSS完成*/
     font-size: calc((10px + 20px)*2 - 30px);
 }

可以看到只是把变量的值计算出来了,但less并不负责对整个表达式的计算并返回结果,而是将对数学表达式的计算过程交给css处理

转义

一些情况下,需要引入一些字符作为属性或者变量值,但这些字符对于CSS语法而言是无效的,或对CSS有效但less无法识别,这时候就需要使用less中的转义字符。在less中,转义使用小波浪~符号,用法为:~"需要转义的字符"或者~'需要转义的字符'

举个例子,less中~"/",编译后在css中显示为/。一般,在一些代码不能被正常编译时,才必须用到转义

从less3.5开始,转义可以从~"需要转义的字符"简写为:(需要转义的字符),即将~""简写为()

而less3.5+开始,许多需要引号转义的情况就不再需要

函数

less官方函数手册

命名空间、访问符

将一些会频繁使用的混合(Mixins)进行分组封装,便于组织结构和分类重复使用。

这就像把很多规则封装到一个类(命名空间)中,然后在开发中根据实际需要去调用各种命名空间中的类

格式:

 /*定义一个命名空间,其中存放混合mixin1和混合mixin2*/
 .命名空间名(){
     .mixin1{
         //规则内容
     }
     .mixin2{
         //规则内容
     }
     /*
     *...
     *...
     */
 }

使用:

 .test{
     //格式一
     .命名空间名 > .混合名
     
     //格式2,不用定位符>
     .命名空间名2 格式名2
 }

把一个命名空间的类混合到别的里面:

 #test2 div{
     #命名空间名.mixin1();
 }

使用时在命名空间名后加(),那么其后引用的混合就不会出现在编译后的CSS里:.命名空间名().mixin2(),这块中的mixin2不会出现在输出的CSS文件里

映射Maps

less3.5开始支持

映射是将混合以及规则集作为一组值的映射使用

创建映射

 //不引入参数
 #mapName(){
     key1: value1;
     key2: value2;
     //...
 }
 ​
 //引入参数创建映射
 #mapNane2(@param1, @param2, ...){
     //白天主题
     dayTimeBKColor: @param1;
     dayTimeFontColor: @param2;
     
     //夜晚主题
     nightBKColor: @param3;
     nightFontColor: @param4;
 }

映射的使用:#映射名[key]

 body{
     background-color: #interfaceTheme[daytimeBKColor];
 }

作用域

首先从当前所在局部作用域查找所需变量和混合,若没有找到,再逐级向上从父作用域继承使用响应的变量或混合

导入Import

导入别的less文件,使用其中的所有变量或者其他

格式:

 import (option1, option2, ...) "FileName" //注意,如果是less文件,那么拓展名.less可以省略,其他比如css就不省略拓展名
可选项说明
reference使用一个LESS文件作为参考,但不输出它
inline将CSS复制到输出而不进行处理,当CSS文件不是less兼容的时,可以这样做
css将导入的文件视为常规css文件,不论文件拓展名是什么
less将导入的文件视为常规less文件,不论文件拓展名是什么
once只导入一次文件
multiple多次导入文件
optional若找不到要导入的文件,仍继续编译而不报错

Less Guards

Guards中的5个比较运算符

>>=<<==(注意判断是否相等是一个等号)

Guards中的逻辑运算

  • .mixin(@param) when(check(@param)){}
  • not 用于取否:.mixin(@param) when not(chech(@param)){}
  • and 用于取.mixin(@param) when(check1(@param)) and (check2(@param)){}
  • or 用于取并: .mixin(@param) when(check1(@param)) or (check2(@param)){},另外还可以使用,替代or
  • default() 根据其他已创建好的mixin条件来进行匹配:.mixin(@param) when(default()){}

类型检查函数:函数作用显然是语义化易懂的

  • iscolor(@param)
  • isnumber(@param)
  • isstring(@param)
  • iskeyword(@param)
  • isurl(@param)

类型检查功能:函数作用显然是语义化易懂的

  • ispixel(@param)
  • ispercentage(@param)
  • isem(@param)
  • isunit(@param)

less Mixin Guards —— 混合守卫

Guards守卫通俗说,就是起这样的作用:当满足xxx条件时,混合Mixin包含YYY规则。起到一个根据参数情况动态为混合分配规则的功能

应当注意的是,Guards中只有true是唯一真值

less中使用Guards:

 .mixinName(@param1; @param2; ...) when(check(@param1); check(@param2, @param3); ...){ 
                                         /*
                                         *   这里check(@param1)等只是方便理解的一个表述,意为对变量param1的一个判断条件
                                         *这个判断可以是: @param1 >= 10px,或者是 @param1 = true
                                         *       或者是 function(@param1), 比如 lightness(@param1) <= 30%
                                         */
     //条件满足时加入的样式
     font-size: 16px;
     background-color: skyblue;
     border-radius: 50%;
 }

于是,在使用参数的混合mixin时,mixin中的规则除了使用时手动设置的,还有根据传入的参数和所设置的它的 Mixin Guards 动态添加的

下面是一个例子

     <div class="dayTheme">
         less测试
     </div>
 @myColor: red;
 .theme(@time) when(lightness(@myColor) >= 30%){
     background-color: skyblue;
     border-radius: 10%;
     color: orange;
     //...
 }
 .theme(@myColor){
     border: 3px solid purple;
     font-size: 30px;
 }
 .dayTheme{
     //注意混合使用位置
     .theme(@myColor);
 }
 ​
 //编译成css后
 .dayTheme {
   /*red满足lightness(red) >= 30%, 所以额外加入了混合 .theme 中的样式属性*/
   background-color: skyblue;
   border-radius: 10%;
   color: orange;
     
   //这部分不论是否满足light(red)>=30%,都会有
   border: 3px solid purple;
   font-size: 30px;
 }

image.png

less CSS Guards —— CSS守卫

CSS守卫应用于CSS选择器,可以声明mixin并且立刻调用它

你可以直接作用于在CSS选择器上

 button when(check(@param)){
     //样式属性
 }

也可以使用&获取父级选择器然后作用在其子选择器

 & when(check(@param)){
     div{
         //...
     }
     a{
         //...
     }
     table{
         //...
     }
     &:hover{
         //...
     }
     &-other{
         //...
     }
 }

比如:

 @test: blue;
 .mixin(){
     @param2:mixin;
     .mixin2 when(@param2 = mixin){
         //...
     } 
     color: orange;
 }
 .mixin();

循环Loops

顾名思义。当混合mixin递归,并和Guards、模式匹配组合使用时,将会创建循环结构,格式参考如下:

 //循环mixin创建
 .loops(@i) when(@i > 0){
     //注意这里运算符两边空格
     .loops(@i - 1);
     width: (10px * @i);
 }
 ​
 //使用循环
 #loopDiv{
     .loops(5);
 }
 ​
 //编译后:
 #loopDiv {
   width: 10px;
   width: 20px;
   width: 30px;
   width: 40px;
   width: 50px;
 }

合并

将一个属性的部分值以这种格式属性+: 值封装mixin中,然后在别的样式里调用这个mixin,将值添加到同样的属性中,添加的属性和原本设置的属性之间用,间隔

 .mixin() {
   //格式是属性名+: 属性值;
   box-shadow+: 5px 5px 5px grey;
 }
 .class {
   .mixin();
   //需要合并的属性同样是这种格式
   box-shadow+: 0 0 5px #f78181;
 }
 ​
 //编译为css后
 .class {
   box-shadow: 5px 5px 5px grey, 0 0 5px #f78181;
 }

Less进阶详见less官方文档