Less基础速学 —— 混入、运算、继承

 Less 混合

        在上一篇内容中就已经简单的了解了关于CSS预处理器 —— Less,本篇就往下讲Less中的混合,什么是混合?就是将一系列属性从一个规则集引入到另外一个规则集的方式。下面来看一下它的混合方式有哪些?

普通混合 

<div id="content">
    <div id="main1"></div>
    <div id="main2"></div>
</div>

        如上HTML代码中,main1 和 main2 的样式相同,但名称不同,如按之前的方式编写Less代码则向下面这样,但我们会发现#main1 和 #main2的样式代码同样,那么可以使用混合的方式将相同内容的代码进行提取出来,不同的则可以仍然保留。

#content{
    margin: 0 auto;
    padding: 0;
    width: 200px;
    height: 60px;
    #main1{
        width: 80px;
        height: 30px;
        background: red;
    }
    #main2{
        width: 80px;
        height: 30px;
        background: red;
    }
}

        使用普通混合的方式编写Less代码:

.mixins{
    width: 80px;
    height: 30px;
    background: red;
}
#content{
    #main1{
        .mixins   
    }
    #main2{
        .mixins
    }
}

        通过Koala编译工具进行编译Less文件之后会得到如下CSS代码:

.mixins{
    width: 80px;
    height: 30px;
    background: red;
}
#content #main1 {
  width: 80px;
  height: 30px;
  background: red;
}
#content #main2 {
  width: 80px;
  height: 30px;
  background: red;
}

        聪明的你可能发现不对劲了,这个.mixins这个提取混合的部分怎么也被编译输出了呢?我们想要的是仅仅是输出 #content #main1 和 #content #main2 这两块代码即可,那么如何解决呢?用不带输出的混合方式。


不带输出的混合

        只需要在混合名称后面加上()即可。如下:

.mixins(){
    width: 80px;
    height: 30px;
    background: red;
}
#content{
    #main1{
        .mixins   
    }
    #main2{
        .mixins
    }
}

        这样通过Koala编译工具编译Less文件之后转成的CSS代码如下:

#content #main1 {
  width: 80px;
  height: 30px;
  background: red;
}
#content #main2 {
  width: 80px;
  height: 30px;
  background: red;
}

带参数的混合

        参数即是变量,在上一篇内容就已经讲过了如何声明一个变量以及声明的变量可以用作什么,如果还不清楚的或者已然忘记了的,可以翻阅一下上一篇内容;加上()则是不带输出的混合,在()内容来添加参数则表示带参的混合。如下:

.mixins(@w,@h,@bgc){
    width: @w;
    height: @h;
    background: @bgc;
}

        分别有了@w,@和,@bgc 三个参数了,那么这三个的值怎么来的,是不是很像函数里面当中的实参和形参,这里不同的是它不是一个函数,而是混合Mixins,长的像函数这般罢了。那么下面来完整的传入:

.mixins(@w,@h,@bgc){
    width: @w;
    height: @h;
    background: @bgc;
}
#content{
    #main1{
        .mixins(80px,30px,red)   
    }
    #main2{
        .mixins(20px,40px,yellow)
    }
}

        通过Koala编译工具编译Less文件之后查看CSS代码,符合预期效果:

#content #main1 {
  width: 80px;
  height: 30px;
  background: #ff0000;
}
#content #main2 {
  width: 20px;
  height: 40px;
  background: #ffff00;
}

带参数且有默认值的混合

        上述带参数的混合需要在使用的时候进行赋值 .mixins(20px,40px,yellow),如果少传或者没用会导致使用Koala编译工具无法编译完整会出现错误无法达到预期效果,所以如果没有传入的,可以设置默认的值,那么应该如何编写?为设置的形参进行赋值,如下:

.mixins(@w:80px,@h:20px,@bgc:red){
    width: @w;
    height: @h;
    background: @bgc;
}

        这样一来,假设使用 .mixins() 传入缺少参数或者没有传入时则会由默认值进行代替然后进行编译。


带多个参数的混合

        上述的就是多个参数的混合,.mixins中有3个参数,分别为 @w,@h,@bgc


命名参数

        有的行动者已经尝试了上述的带参数且有默认值的混合,发现了这样的一个问题,就是参数不匹配的问题,如下:

.mixins(@w:80px,@h:20px,@bgc:red){
    width: @w;
    height: @h;
    background: @bgc;
}
#content{
    #main1{
        .mixins(red)   
    }
}

        通过Koala编译工具编译Less文件之后查看CSS代码:

#content #main1 {
  width: #ffff00;
  height: 20px;
  background: #ff0000;
}

        这个width宽度怎么成了red的十六进制颜色代码,我们所预期的是width和height都是使用默认值,而background的值为red红色,所以就需要对传入参数进行命名出来,即命名参数。

.mixins(@w:80px,@h:20px,@bgc:red){
    width: @w;
    height: @h;
    background: @bgc;
}
#content{
    #main1{
        .mixins(@bgc:red)   
    }
}

        这样使用Koala编译之后就能够达到预期效果了。


匹配模式

        现在要完成这样的一个三角形的标签样式,它有着不同的箭头朝向,如下,那么当我们需要用到哪一个就可以用哪一个,怎么来做呢?

        先来讲它原生的CSS样式进行编写:

<div id="content">
    <div class="triangle"></div>
</div>
// CSS3写法测试注意浏览器兼容性
// 箭头朝下
#content .triangle{
    width: 0px;
    height: 0px;
    border-width: 20px;
    border-style: solid dashed dashed dashed;
    border-color: red transparent transparent transparent;
    overflow: hidden;
}
// 箭头朝左
#content .triangle{
    width: 0px;
    height: 0px;
    border-width: 20px;
    border-style: dashed solid dashed dashed;
    border-color: transparent red transparent transparent;
    overflow: hidden;
}
// 箭头朝上
#content .triangle{
    width: 0px;
    height: 0px;
    border-width: 20px;
    border-style: solid dashed dashed dashed;
    border-color: transparent transparent red transparent;
    overflow: hidden;
}
// 箭头朝右
#content .triangle{
    width: 0px;
    height: 0px;
    border-width: 20px;
    border-style: solid dashed dashed dashed;
    border-color: transparent transparent transparent red;
    overflow: hidden;
}

        下面就是要将这个三角形标签4个朝向的样式代码进行编写,然后在用的时候进行匹配使用哪一个,这就很像将它做成一个库,然后来使用这个库,下面先来进行混合,创建一个名为triangle.less 的文件:

/*
    B-bottom; L-left; R-right; T-top;
    @w : width 
    @c : color
*/ 
.triangle(B,@w,@c){
    width: 0px;
    height: 0px;
    border-width: @w;
    border-style: solid dashed dashed dashed;
    border-color: @c transparent transparent transparent;
    overflow: hidden;
}
.triangle(L,@w,@c){
    width: 0px;
    height: 0px;
    border-width: @w;
    border-style: dashed solid dashed dashed;
    border-color: transparent @c transparent transparent;
    overflow: hidden;
}
.triangle(T,@w,@c){
    width: 0px;
    height: 0px;
    border-width: @w;
    border-style: dashed dashed solid dashed;
    border-color: transparent transparent @c transparent;
    overflow: hidden;
}
.triangle(R,@w,@c){
    width: 0px;
    height: 0px;
    border-width: @w;
    border-style: dashed dashed dashed solid;
    border-color: transparent transparent transparent @c;
    overflow: hidden;
}

        从上面编写的样式代码来看显然还可以再进行抽取混合,将width,height 和 overflow 再拿出来,整理成如下这样:

.triangle(){
    width: 0px;
    height: 0px;
    overflow: hidden;
}
/*
    B-bottom; L-left; R-right; T-top;
    @w : width 
    @c : color
*/ 
.triangle(B,@w,@c){
    border-width: @w;
    border-style: solid dashed dashed dashed;
    border-color: @c transparent transparent transparent;
}
.triangle(L,@w,@c){
    border-width: @w;
    border-style: dashed solid dashed dashed;
    border-color: transparent @c transparent transparent;
}
.triangle(T,@w,@c){
    border-width: @w;
    border-style: dashed dashed solid dashed;
    border-color: transparent transparent @c transparent;
}
.triangle(R,@w,@c){
    border-width: @w;
    border-style: dashed dashed dashed solid;
    border-color: transparent transparent transparent @c;
}

        这样我们再回到原来要编写的样式代码的文件当中来引入这个“库”,这个库里面有这个三角形标签的4个朝向,我们要来编写 HTML代码中 #content .triangle 中的样式代码,这里同样引入的不是less文件,而是使用Koala编译工具编译得到的CSS样式代码文件(引入less文件则为运行时处理,在上一篇内容已经讲过了):

<link rel="stylesheet" href="../css/01.css">
...
<div id="content">
    <div class="triangle"></div>
</div>

        下面继续来编写编译为 01.css 的 less样式文件,首先要来引入刚刚编写的这个“库”:

// 01.less

@import "./triangle.less";

#content .triangle{
    // 箭头朝下 - B
    .triangle(B,20px,red)
}

        通过Koala编译工具进行编译之后得到如下的CSS代码:

#content .triangle {
  border-width: 20px;
  border-style: solid dashed dashed dashed;
  border-color: #ff0000 transparent transparent transparent;
}

        少了后来抽取的部分代码,那么再来调整执行:

// 01.less  
@import "./triangle.less";

#content .triangle{
    // 箭头朝下
    .triangle();
    .triangle(B,20px,red)
}

        这样一来就可以得到编译后完整的CSS代码:

#content .triangle {
  width: 0px;
  height: 0px;
  overflow: hidden;
  border-width: 20px;
  border-style: solid dashed dashed dashed;
  border-color: #ff0000 transparent transparent transparent;
}

        如不添加 .triangle() 则会缺少 width,height 和 overflow,或者放弃抽取这四个样式代码中的相同代码,又或者执行 先.triangle()然后再执行 .triangle(B,20px,red),这两种好像都不能得以满足我们,我们预期的是在执行 .triangle(B,20px,red) 的时候能够把 .triangle() 也带上,那么就需要给 .triangle() 带上参数,让它来自行的匹配是 B / T / L / R

// triangle.less
/*
    @_ 匹配 B/L/T/R
*/ 
.triangle(@_,@w,@c){
    width: 0px;
    height: 0px;
    overflow: hidden;
}
/*
    B-bottom; L-left; R-right; T-top;
    @w : width 
    @c : color
*/ 
.triangle(B,@w,@c){
    border-width: @w;
    border-style: solid dashed dashed dashed;
    border-color: @c transparent transparent transparent;
}
.triangle(L,@w,@c){
    border-width: @w;
    border-style: dashed solid dashed dashed;
    border-color: transparent @c transparent transparent;
}
.triangle(T,@w,@c){
    border-width: @w;
    border-style: dashed dashed solid dashed;
    border-color: transparent transparent @c transparent;
}
.triangle(R,@w,@c){
    border-width: @w;
    border-style: dashed dashed dashed solid;
    border-color: transparent transparent transparent @c;
}
// 01.less  
@import "./triangle.less";

#content .triangle{
    // 箭头朝下
    .triangle(B,20px,red)
}

         下面来使用 Koala编译器工具编译会得到如下的CSS样式代码:

/*
    @_ 匹配 B/L/T/R
*/
/*
    B-bottom; L-left; R-right; T-top;
    @w : width 
    @c : color
*/
#content .triangle {
  width: 0px;
  height: 0px;
  overflow: hidden;
  border-width: 20px;
  border-style: solid dashed dashed dashed;
  border-color: #ff0000 transparent transparent transparent;
}

        需要用到哪一个,比如箭头向上,就在01.less文件中来使用 .triangle(T,20px,red)即可。


arguments变量

        在上篇内容讲到了使用@声明一个变量的作用,作为普通属性值:@red: red,那么当它有三个或以上的属性值呢?一个一个变量定义吗?显然不太合适,下面我们来看一下:

.border(@w,@l,@c){
    border: @w @l @c; 
}

#content .main{
    .border(1px solid black);
}

        Koala编译之后得到的CSS代码: 

#content .main {
  border: 1px solid #000000;
}

        这样一来传递三个参数同时还需要这样写 border: @w @l @c ,这样一来好像不方便啊,怎么弄?使用arguments变量,如下:

.border(@w,@l,@c){
    border: @arguments;
}

#content .main{
    .border(1px solid black);
}

        这样就可以了,有的可能觉得很是鸡肋,这里是为了让你知道在less中有这种语法,可能会在某些地方用到。


Less 运算

        在Less中可以进行加减乘除的运算,下面直接来进行使用:

#content .main{
    width: (100 + 100px);
    height: 200 - 100px;
    border: 1*2px solid black;
    border-radius: 20/5%;
}

        通过 Koala 工具编译之后得到如下CSS代码:

#content .main {
  width: 200px;
  height: 100px;
  border: 2px solid #000000;
  border-radius: 4%;
}

        以上就是Less运算中的加减乘除了。


Less 继承

        在讲Less继承之前呢我们先来使用Less混合的方式编写,再使用继承方式编写,然后来感受一下这两种方式的区别:

<div id="content">
    <div class="main">ONE</div>
    <div class="main">TWO</div>
</div>

        完成以上的这个样式效果,原生CSS代码样式如下:

*{
    margin: 0 auto;
    padding: 0;
}
#content{
    position: relative;
    width: 300px;
    height: 300px;
    border: 1px solid;
    margin: 0 auto;
}
#content .main{
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}
#content .main:nth-child(1){
    width: 100px;
    height: 100px;
    background-color: skyblue;
}
#content .main:nth-child(2){
    width: 50px;
    height: 50px;
    background: red;
}

        下面来使用Less编写样式代码:

混合编写 

整体编写:

// 01.less
#content{
    position: relative;
    width: 300px;
    height: 300px;
    border: 1px solid;
    margin: 0 auto;
    .main{
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        margin: auto;
        &:nth-child(1){
            width: 100px;
            height: 100px;
            background: #87ceeb;       
        }
        &:nth-child(2){
            width: 50px;
            height: 50px;
            background: #ff0000;
        }
    }
}

将其中的代码再次提取,进行一个混合为一个center.less文件:

// center.less
.center(@w,@h,@bgc){
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: @w;
    height: @h;
    background: @bgc;
}

然后修改01.less文件:

// 01.less
@import './center.less';
#content{
    position: relative;
    width: 300px;
    height: 300px;
    border: 1px solid;
    margin: 0 auto;
    .main{
        &:nth-child(1){
            .center(100px,100px,skyblue)            
        }
        &:nth-child(2){
            .center(50px,50px,red)
        }
    }
}

        完成之后可以自行打开Koala编译工具进行编译查看CSS代码以及打开01.html查看引入的样式能否正常显示即可。

        以上的这块就是使用前面所讲到的混合,带有参数的混合混合方式,它的灵活性较高。那么下面来看一下Less继承,Less的继承不支持带参,所以在center.less文件的代码,将无法将这个三个不固定的参数进行继承,简单来说就是没用参数的形式,所以center.less调整如下:

// center.less
// 继承
.center{
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

        不固定的这三个参数(width,height,background)要编写回原来的less代码中,这里可能就有些生硬了,不像混合那样只需要我们来传递参数即可,显然没有混合那么的灵活,但继承它就比混合要高效了,那么如何在01.less文件中来使用继承呢?同样通过@import进行引入,引入之后通过extend关键字来使用,如下:

@import './center.less';

#content{
    position: relative;
    width: 300px;
    height: 300px;
    border: 1px solid;
    margin: 0 auto;
    .main:extend(.center){
        &:nth-child(1){
            width: 100px;        
            height: 100px;
            background: skyblue;
        }
        &:nth-child(2){
            width: 50px;
            height: 50px;
            background: red;
        }
    }
}

        下面通过Koala编译工具进行编译为原生CSS代码,然后来看一下编译后的CSS代码:

.center,
#content .main,
#content .main:nth-child(1),
#content .main:nth-child(2) {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}
#content {
  position: relative;
  width: 300px;
  height: 300px;
  border: 1px solid;
  margin: 0 auto;
}
#content .main:nth-child(1) {
  width: 100px;
  height: 100px;
  background: skyblue;
}
#content .main:nth-child(2) {
  width: 50px;
  height: 50px;
  background: red;
}
.center,
#content .main,
#content .main:nth-child(1),
#content .main:nth-child(2) {
   
   

      看完这个CSS代码你会发现其中有块样式代码很“奇妙”,怎么会这样呢?虽然没用错,但感觉跟你写出来原生CSS代码不一样;怎么来调整呢?继承的这块内容是与这个 .main 是平级的,所以可以如下这样来编写:

#content{
    position: relative;
    width: 300px;
    height: 300px;
    border: 1px solid;
    margin: 0 auto;
    // .main:extend(.center){
    .main{
        &:extend(.center);
        &:nth-child(1){
            width: 100px;        
            height: 100px;
            background: skyblue;
        }
        &:nth-child(2){
            width: 50px;
            height: 50px;
            background: red;
        }
    }
}

        再编译的时候就与你编写的原生CSS代码相同了。

        既然继承了,那么是否对应的伪元素是否会被继承呢?再center.less文件当中来编写这个 .center 的伪元素hover被选择的状态是否在被继承的时候会被继承过去。

// center.less
// 继承
.center{
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

.center:hover{
    background: plum;
}

        不改动01.less文件,使用Koala编译工具进行编译查看编译后的01.css文件代码如下:

// 01.css
.center,
#content .main {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}
.center:hover {
  background: plum;
}
#content {
  position: relative;
  width: 300px;
  height: 300px;
  border: 1px solid;
  margin: 0 auto;
}
#content .main:nth-child(1) {
  width: 100px;
  height: 100px;
  background: skyblue;
}
#content .main:nth-child(2) {
  width: 50px;
  height: 50px;
  background: red;
}

        看一下这个编译后的代码,有没有被继承?没有吧!你不会想跟我说 .center:hover{ background: plum } 这个叫继承了吧!那你再仔细看看,是不是应该是 #content .main:hover 这个出现才算被继承了呢?应该怎么处理?如下:

        在原来继承的后面添加 "all",表示有关的所有状态被继承。

...
    .main{
        &:extend(.center all);
...

        编译后就会出现这块代码:

.center:hover,
#content .main:hover {
  background: plum;
}

        小伙伴们测试之后发现怎么没有效果呢?写的没问题啊,怎么会有问题呢?这里涉及了一个 "权重的问题" ,: hover 显示 和 :nth-child() 显示,:nth-child 权重大于 :hover,所以没有显示出来,调整如下代码再编译;(!important最优先)

.center:hover{
    background: plum !important;
}

        测试结果如下:

         以上就是使用 Less混合 和 Less继承,Less混合的灵活性比Less继承高,而性能则Less继承比Less混合要高。


Less避免编译 ~" "

        在上面讲到使用这个Less可以进行一个加减乘除的一个运算,原生CSS中也有这样一个函数可以进行计算 —— cacl() 

        下面在less当中来用这个函数进行计算:

// .less
*{
    margin: 0 auto;
    padding: calc(100px - 20px);
}

        通过Koala工具进行编译之后可以得到如下CSS代码:

// .css文件
* {
  margin: 0;
  padding: calc(80px);
}

        得到 .css文件 的这块内容之前,是less对这个 calc() 中进行了运算,值已经计算好了为什么还要输出calc(),calc这块函数的计算是可以交给浏览器去计算,浏览器是支持的,所以这块内容不需要交给less进行处理需要Less对其进行一个避免编译,可以使用这个 ~" " 来避免编译,如下代码调整:

// 01.less

*{
    margin: 0;
    padding: ~"calc(1000px - 10px)";
}

        编译之后可以得到如下代码:

* {
  margin: 0;
  padding: calc(1000px - 10px);
}

        以上就是本篇目的全部内容,感谢大家的支持!!!


附上Less基础速学:

Less基础速学 —— 嵌套、变量、注释、&本篇讲关于Less预处理器中的嵌套,变量和注释以及"&"的内容,less的嵌套写法通过采用缩进的方式,less还可以设置变量,变量的作用也有很多,比如做普通属性值来使用,作选择器和属性名,作为URL以及变量的延迟,编写less文件通过Koala编译工具可以编译为原生的CSS样式代码,如果对less预处理感兴趣或者在项目中需要使用CSS预处理器的可以看看这篇关于less预处理器的篇目吧!https://blog.csdn.net/weixin_52203618/article/details/130529805?spm=1001.2014.3001.5501

猜你喜欢

转载自blog.csdn.net/weixin_52203618/article/details/130544586
今日推荐