2

前言

前端朋友圈经常讨论的less是个什么鬼?我做前端开发竟然没有耳闻是不是太out了?本篇博客将会详细描述less的常见用法,适合入门的新手。

学习less,Why?

  1. 等你用了之后你就会发现它用起来确实比原生CSS方便很多。比如说:能够大量的简化重复的代码、通过定义全局变量的方法方便日后代码维护。
  2. 前端流行的很多UI框架比如说bootstrape(V4之前的版本),iview等等,CSS的源码都是用的less。
旺财:"less能够大量的简化重复的代码能举个例子?"
问渠:"阅读bootstrape源码,按钮样式的实现用less语法只需要168行,而用CSS语法写需要439行"

less这玩意怎么开始用呢

方式一:在浏览器里面直接引入可以解析less语法的js文件,来瞧瞧下面一个例子;less.min.js文件请到官网下载

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>less001</title>
<!-- 注意type="text/less"依赖的js才能正确解析 -->
<style type="text/less">
    @width: 100px;
    @height: @width + 10px;

    .header {
      width: @width;
      height: @height;
      background-color:red;
    }
</style>
</head>
 
<body>
    <div class="header">
        1234567890
    </div>
</body>
<!-- 依赖的less.min.js文件必须放在要解析的less语法后面才能有效 -->
<script src="./less.min.js"></script>
</html>

方式二:通过开发工具自身的支持,比如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文件查看效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>less003</title>
<link type="text/css" rel="stylesheet" href="./001.css" />
</head>
 
<body>
    <div class="header">
        方式三:1234567890
    </div>
</body>

</html>

方式四:在webpack打包工具中使用;

npm i less less-loader --save-dev

less变量

//让我们先看一段less编译前的代码:
@color:red;
@selector: .header;
@srcName: width;
@{selector}{
  @{srcName}: 200px;
  height: 200px;
  background-color:@color;
}

//以下是编译后的代码:
.header {
  width: 200px;
  height: 200px;
  background-color: red;
}

由此我们需要知道如下用法:

  1. CSS语法在less文件中都支持
  2. 变量的声明方式:@变量名 【例如@color】
  3. 变量的声明一般用于属性值,例如上例中的@color用于声明background-color的属性值
  4. 变量也可以声明属性名和选择器等(但一般不会这么用),使用方式是@{变量名}【例如上例中的@selector,@srcName】

less中的注释

编译前的less文件:
//开头的注释,不会编译到css文件中
/*包裹的注释,编译到css文件中*/ 
.header{ 
  height: 200px;
}

编译后的css文件:
/*包裹的注释,编译到css文件中*/
.header {
  height: 200px;
}
  1. less文件中, //开头的注释,不会编译到css文件中
  2. less文件中, /**/包裹的注释,可以编译到css文件中

less中的嵌套规则

//假设有如下HTML片段
<div class="header">
    <div class="nav">123</div>>
    <div class="logo">456</div>>
</div>
    
//对应的有如下css代码:
.header {
  font-size: 12px;
}
.header .nav {
  float: left;
  background-color: red;
}
//.nav { //没有.header的前缀
//  float: left;
//  background-color: red;
//}
.header .logo {
  float: left;
  width: 300px;
}

以上代码存在嵌套关系,即类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. 混合的基本使用
  2. 不带输出的混合
  3. 混合的参数用法
  4. 混合的参数添加默认值
  5. 命名参数
  6. 匹配模式
//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;
}

由此案例总结出继承的用法:

  1. 使用方法为:继承者:extend(定义的继承名称)
  2. 继承的定义和混合相同,但是不能带有参数(带上参数,所有继承者就不能获取相同属性了)
  3. 注意继承所有属性的情况(如伪类选择器),使用方法为:继承者: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;
}

结束语

内容有点啰嗦,但是工作中会遇到什么以及面试官的心情谁能知道呢?


吴小风
24 声望1 粉丝