前言

前端朋友圈经常讨论的less是个什么鬼?我做前端开发竟然没有耳闻是不是太out了?本篇博客将会详细描述less的常见用法,适合入门的新手。
学习less,Why?等你用了之后你就会发现它用起来确实比原生CSS方便很多。比如说:能够大量的简化重复的代码、通过定义全局变量的方法方便日后代码维护。前端流行的很多UI框架比如说bootstrape(V4之前的版本),iview等等,CSS的源码都是用的less。
旺财:"less能够大量的简化重复的代码能举个例子?"问渠:"阅读bootstrape源码,按钮样式的实现用less语法只需要168行,而用CSS语法写需要439行"less这玩意怎么开始用呢
方式一:在浏览器里面直接引入可以解析less语法的js文件,来瞧瞧下面一个例子;less.min.js文件请到官网下载
方式二:通过开发工具自身的支持,比如koala;
方式三:node.js晓不晓得?高端玩家都用这个;
第一步:全局环境下安装less编译器npm install -g less第二部:lessc 需要编译的文件名称 编译后的文件名称lessc 001.less 001.css
001.less文件内容:@width: 100px;@height: @width + 10px;.header { width: @width; height: @height; background-color:red;}
用html文件中引入编译后的001.css文件查看效果
方式四:在webpack打包工具中使用;
npm i less less-loader --save-devless变量
//让我们先看一段less编译前的代码:@color:red;@selector: .header;@srcName: width;@{selector}{ @{srcName}: 200px; height: 200px; background-color:@color;}//以下是编译后的代码:.header { width: 200px; height: 200px; background-color: red;}
由此我们需要知道如下用法:
CSS语法在less文件中都支持变量的声明方式:@变量名 【例如@color】变量的声明一般用于属性值,例如上例中的@color用于声明background-color的属性值变量也可以声明属性名和选择器等(但一般不会这么用),使用方式是@{变量名}【例如上例中的@selector,@srcName】less中的注释
编译前的less文件://开头的注释,不会编译到css文件中/*包裹的注释,编译到css文件中*/ .header{ height: 200px;}编译后的css文件:/*包裹的注释,编译到css文件中*/.header { height: 200px;}less文件中, //开头的注释,不会编译到css文件中less文件中, /**/包裹的注释,可以编译到css文件中less中的嵌套规则
//假设有如下HTML片段
以上代码存在嵌套关系,即类nav和类logo是header的子类,但是代码结构却没有体现出来;如果代码是小白写的(注释的那一段),类nav没有加上前缀header,那就更加可怕了,看下面less如何实现
//带有嵌套规则的less代码:.header { font-size: 12px; .nav { float:left; background-color:red; } .logo { float:left; width: 300px; }}
感觉到了吗?less能够允许我们像写html结构代码一样去写css代码。但是在使用嵌套的时候有两种情况需要注意:
一: &代表当前选择器的父级;当你使用伪元素的时候,前面如果没有具体选择器,编译后伪元素前面会有空格,导致样式代码不生效,这个时候可以在伪元素前面加上&。
//:hover、 :after、 :focus...各种伪元素都逃不了在前面加&或者选择器&:hover { background-color:green; }
二: 在前面变量部分我们说过@符号在less语法中是用于定义变量的。但是在实际过程中css自身语法中@就有特定的用法,比如说@media表示媒体查询,这样的话就和less语法冲突了。less解决方案是在编译时把css自身的@语法放到其它语法前面如下:
//less语法.component { width: 300px; @media (min-width: 768px) { width: 600px; @media (min-resolution: 192dpi) { background-image: url(/img/retina2x.png); } } @media (min-width: 1280px) { width: 800px; }}//编译后的css语法.component { width: 300px;}@media (min-width: 768px) { .component { width: 600px; }}@media (min-width: 768px) and (min-resolution: 192dpi) { .component { background-image: url(/img/retina2x.png); }}@media (min-width: 1280px) { .component { width: 800px; }}less中的混合
旺财:"你不是说用less能够大量的简化重复的代码吗?我看着之前的代码咋那么麻烦呢?"问渠:"之前的语法只是铺垫,less混合这个功能十分强大,保证完成简化代码的任务"
混合的作用有点类似于函数,能够通过调用混合名称,获取一堆预先定义的规则属性,而不用再去写重复的代码,具体看下案例。 基本用法如下,我们一一来分析下:
混合的基本使用不带输出的混合混合的参数用法混合的参数添加默认值命名参数匹配模式
//1. 混合的基本使用//假设有如下代码:.div1 { float: left; width: 200px; height: 200px; background-color: green;}.div2 { float: left; width: 200px; height: 200px; background-color: red;}//很明显这段代码中除了背景颜色不一样之外,其它的代码都是相同的,那么就可以达到共用的目标//用less的混合语法可以改写成如下形式.less-mixins{ float:left; width:200px; height:200px;}.div1{ .less-mixins; background-color:green;}.div2{ .less-mixins; background-color:red;}//最终编译后的css代码.less-mixins { float: left; width: 200px; height: 200px;}.div1 { float: left; width: 200px; height: 200px; background-color: green;}.div2 { float: left; width: 200px; height: 200px; background-color: red;}
混合的基本使用如下:
A、定义的混合为.less-mixins,有没有感觉就像定义类一样B、引用定义的混合方式为.less-mixins,即直接写上类名即可C、不用怀疑,你没有看错,编译后的css代码中还有混合.less-mixins(这部分代码是多余的,接下来的案例就是去除这部分无效代码)
//2. 不带输出的混合//less代码改为如下:.less-mixins(){ float:left; width:200px; height:200px;}.div1{ .less-mixins; background-color:green;}.div2{ .less-mixins; background-color:red;}//最终编译后的css代码.div1 { float: left; width: 200px; height: 200px; background-color: green;}.div2 { float: left; width: 200px; height: 200px; background-color: red;}
相对于上述案例,改变的只是在混合名称后面加了一对小括号,再次编译less文件就不会在生成的css文件中包含无效的混合定义
//3. 混合的参数用法.less-mixins(@width,@height,@color){ float:left; width:@width; height:@height; background-color:@color;}.div1{ .less-mixins(200px,200px,yellow); }.div2{ .less-mixins(200px,300px,green);}//编译后的css文件.div1 { float: left; width: 200px; height: 200px; background-color: yellow;}.div2 { float: left; width: 200px; height: 300px; background-color: green;}
就像定义函数参数似的,上述(@width,@height,@color)就是定义的混合参数,在混合内部就可以使用这些参数,调用混合传参就像js语法中调用函数一样
//4. 混合的参数添加默认值.less-mixins(@width:100px,@height:100px,@color:red){ float:left; width:@width; height:@height; background-color:@color;}.div1{ .less-mixins(200px,200px,yellow); }.div2{ .less-mixins();}//编译后的css.div1 { float: left; width: 200px; height: 200px; background-color: yellow;}.div2 { float: left; width: 100px; height: 100px; background-color: red;}
混合的参数默认值添加,只需要在变量名称后面加上:默认值即可。但是有木有发现问题,假设我调用的混合的时候只传入一个参数怎么办?或者入参小于实参怎么办呢?看下面:
//5. 命名参数.less-mixins(@width:100px,@height:100px,@color:red){ float:left; width:@width; height:@height; background-color:@color;}.div1{ .less-mixins(200px,200px,yellow); }.div2{ .less-mixins(@color:green);}//编译后的css.div1 { float: left; width: 200px; height: 200px; background-color: yellow;}.div2 { float: left; width: 100px; height: 100px; background-color: green;}
上述我们在调用混合的时候为.less-mixins(@color:green),通过@color:来指定我要传入的是哪个参数。
//6.匹配模式.less-mixins(L,@width:100px,@height:100px,@color:red){ float:left; width:@width; height:@height; background-color:@color;}.less-mixins(R,@width:100px,@height:100px,@color:red){ float:right; width:@width; height:@height; background-color:@color;}//虽然两次定义的混合名称相同,但是第一个参数不同,根据第一个参数(注意没有加上@定义变量),进行匹配即可.div1{ .less-mixins(L,200px,200px,yellow); }.div2{ .less-mixins(R,@color:green);}//编译后的css文件.div1 { float: left; width: 200px; height: 200px; background-color: yellow;}.div2 { float: right; width: 100px; height: 100px; background-color: green;}
混合.less-mixins定义了两次,这两次的功能除了浮动的方向不一致之外其它都是相同的(当然这里也可以定义成两个变量名),这种情况要想区分调用哪次混合的定义,需要在调用混合的时候,指定第一个参数作为匹配字符串。
less计算
//按照惯例,先来欣赏一段less代码以及编译后的css//less代码@width: 10px;@height: @width + 10px;.header { width: @width; height: @height;}//编译后的css代码.header { width: 10px; height: 20px;}
less语法可以支持计算,进行运算的变量只需一个单位即可。和css自身语法的calc函数一样,calc函数是浏览器自身运行css代码时候进行计算。
less继承
less中混合的作用是复制一堆属性和值,属性和值可以是变量,调用者可以根据自身需要进行传参;less中继承也是复制一堆属性和值,但是属性和值都是常量,所有继承者获取的属性和值都相同,不可以传参。使用继承和我们之前混合的基本使用相同,只是调用的时候不同,来看下案例:
//定义混合如下:.less-mixins(){ float:left; width:200px; height:200px;}.div1{ .less-mixins; background-color:green;}.div2{ .less-mixins; background-color:red;}//编译后的css结果.div1 { float: left; width: 200px; height: 200px; background-color: green;}.div2 { float: left; width: 200px; height: 200px; background-color: red;}//但是有没有思考过,上面编译的css代码不是最好的,其实改成如下形式://.div1,.div2有一段代码是相同的,可以使用逗号进行分割定义,进而节省代码量.div1,.div2 { float: left; width: 200px; height: 200px;}.div1 { background-color: green;}.div2 { background-color: red;}//使用继承语法改写的less代码.less-mixins{ float:left; width:200px; height:200px;}.div1{ &:extend(.less-mixins); background-color:green;}.div2{ &:extend(.less-mixins); background-color:red;}
由此案例总结出继承的用法:
使用方法为:继承者:extend(定义的继承名称)继承的定义和混合相同,但是不能带有参数(带上参数,所有继承者就不能获取相同属性了)注意继承所有属性的情况(如伪类选择器),使用方法为:继承者:extend(定义的继承名称 all),看下面案例:
//less代码//注意增加了:hove的样式,在调用该继承的时候如果没有在继承名称后面加上空格和all,那么编译的css代码是不会包含:hove样式的.less-mixins{ float:left; width:200px; height:200px;}.less-mixins:hover{ font-size:20px;}.div1{ &:extend(.less-mixins all); background-color:green;}.div2{ &:extend(.less-mixins all); background-color:red;}//编译后的css代码.less-mixins,.div1,.div2 { float: left; width: 200px; height: 200px;}.less-mixins:hover,.div1:hover,.div2:hover { font-size: 20px;}.div1 { background-color: green;}.div2 { background-color: red;}less导入
导入css文件方式:@import "文件名";导入less文件方式:@import "文件名";注意此时.less扩展名可以省略
@import "002.css";@import "002";less作用域和懒加载事项
//less代码@width: 200px;.header { @width: 300px; div { color: @width; }}//编译后的css代码.header div { color: 300px;}
作用域注意点:相同的变量定义了两次,里面的变量定义生效了,也就是说变量值优先查找内部作用域。
//less代码//注意@width变量的位置.header { div { color: @width; }}@width: 200px;//渲染后的.header div { color: 200px;}
懒加载:我们可以先使用变量,在后面定义
函数
less官方提供了很多函数,计算出来的值用于css的属性值,举个栗子:
//比如颜色的函数rgb(90, 129, 32)//less代码.header { color: rgb(90, 129, 32); }//css代码.header { color: #5a8120;}