css预处理器:less

1、什么是less

LESS是一种动态样式语言,属于CSS预处理语言的一种,它使用类似CSS的语法,为CSS的赋予了动态语言的特性,如变量、继承、运算、函数等,更方便CSS的编写和维护。我们编写的less文件最终会编译成css文件

2、如何使用less

  • less官网

    http://lesscss.cn/#download-options

  • 使用CDN

    //cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js

  • 如果使用vsCode的童靴可以使用插件

    Easy LESS

3、less的语法规则

less中的注释

我们编写的less文件最终会被编译成css文件去执行,那么在less中注释分两种,一种是会被编译的注释,另一种是不会被编译的注释

在这里插入图片描述
左边是我们编写的less文件右边是编译后的css文件

变量的使用及语法规则

  • 定义变量
    	@变量名 :;
    	@wit : 200px;
    
  • 使用变量
    	.content{
    		width: @wit;
    	}
    
    这样给我们的class设置了一个宽为200px的样式
    如果将属性名,或者选择器作为变量使用的话需要使用@{}
    	//将选择器作为变量
    	@d : div;
    	//将属性名作为变量
    	@w : width;
    	
    	@{d}{
        	@{w}: 50px;
        }
    
    编译后的css样式
    在这里插入图片描述

less中的嵌套

我们使用css写选择器的时候通常使用 .a .b{} 这样去选择具有父子关系的DOM元素,但在less中我们可以使用嵌套来表示这种父子级关系
  • 基本嵌套
    	//变量
    	@wit : 200px;
    	@hei : 200px;
    	.content{
    		width: @wit;
    		
    		div{
       			height: @hei;
    		}
    	}
    
    这样我们的层次关系非常清晰,给.content设置宽度200px,给content的子级div设置高度为200px
    编译后的css样式

    但是这样使用伪类样式的时候会出问题,我们给div加一个hover伪类
    	//变量
    	@wit : 200px;
    	@hei : 200px;
    	.content{
    		width: @wit;
    		
    		div{
       			height: @hei;
    		}
    		:hover{
    			background-color: black;
    		}
    	}
    
    在这里插入图片描述
    有没有发现div跟hover中间有空格,怎么去解决这个问题让中间的空格去掉
  • &符号使用
    	&:hover{
    			background-color: black;
    	}
    
    在样式前面加一个&符
    在这里插入图片描述
    如果说嵌套是交集选择器的话那我们的&就是并集选择器

less中的混合

混合就是将一系列属性从一个规则中引入到另一个规则的方式
  • 普通混合
    先来看一段代码

    	.content{
    		width: 200px;
    		height: 200px;
    		background-color: red;
    
    		.inner1{
        		width: 100px;
        		height: 100px;
        		border: 1px solid black;
    		}
    		.inner2{
        		width: 100px;
        		height: 100px;
       			border: 1px solid black;
    		}
    	}
    

    这是我们的嵌套对吧,大家有没有发现一个问题,在inner1和inner2中的样式是重复的,我们写代码要避免这种重复性的工作,对于这种重复性的东西我们一般就是将它公共的东西抽取出来,在我们的Less中就是将这种事情称之为混合

    	.innerT{
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       	}
       .inner1{
       		.innerT
       }
       .inner2{
     		.innerT
       }
    

    但是这样做有个问题,我们来看一下编译后的css文件

    	.a {
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       	}
       .content {
       		width: 200px;
       		height: 200px;
       		background-color: red;
       }
       .content .inner1 {
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       }
       .content .inner2 {
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       }
    

    它将我们混合的部分也编译出来了,这是我们不想要的,怎么解决这个问题呢,看下一个混合。

  • 不带输出的混合
    我们给他加一个括号

    	.a(){
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       	}
    

    来看一下编译后的css文件

      .innerT{
      		width: 100px;
      		height: 100px;
      		border: 1px solid black;
      	}
      .inner1{
      		.innerT
      }
      .inner2{
    		.innerT
      }
    

    但是这样做有个问题,我们来看一下编译后的css文件

       .content {
       		width: 200px;
       		height: 200px;
       		background-color: red;
       }
       .content .inner1 {
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       }
       .content .inner2 {
       		width: 100px;
       		height: 100px;
       		border: 1px solid black;
       }
    

    我们公共部分的样式没有输出出来吧,但是随即而来又一个问题,inner1和inner2里面的属性值都是写死的,我想要在inner1和inner2里面的数值不一样怎么办呢,用参数解决。

  • 带参数的混合

    	.innerT(@w, @h){
    		width: @w;
    		height: @h;
    		border: 1px solid black;
    	}
    	
    	.content{
    		.inner1{
      			.innerT(100px, 200px)
    	    }
    		.inner2{
        		.innerT(200px, 100px)
    		}
    	}
    

    用@符声明我们的形参,使用他的时候输入实参,再来看下编译后的css文件

    	.content .inner1 {
    		width: 100px;
    		height: 200px;
    		border: 1px solid black;
    	}
    	.content .inner2 {
    		width: 200px;
    		height: 100px;
    	 	border: 1px solid black;
    	}
    

    完美解决是吧,但是如果我想调用他的时候不给他传入实参怎么办呢。

  • 带参数且有默认值的混合
    我们使用@参数名 : 默认值,这种形式给他赋默认值

    	.innerT(@w:1px, @h:1px){
    		width: @w;
    		height: @h;
    		border: 1px solid black;
    	}
    	.content{
    		 .inner1{
       			.innerT()
    		 }
    		.inner2{
       	 		.innerT(200px, 100px)
    		}
    	}
    

    在我们调用他的时候,可以选择传参或不传参,来看一下编译后的css文件

    	.content .inner1 {
    		width: 1px;
    		height: 1px;
    		border: 1px solid black;
    	}
    	.content .inner2 {
    		width: 200px;
    		height: 100px;
    		border: 1px solid black;
    	}
    

    但是问题又来了,当我有多个参数的时候我想给指定参数赋值怎么办。

  • 命名参数
    我们在调用他的时候直接写出来形参名称然后赋值就好了。

    	.inner1{
       		.innerT(@h:500px)
    	}
    

    我们来看编译后的css文件

    	.content .inner1 {
    		width: 1px;
    		height: 500px;
    		border: 1px solid black;
    	}
    

    这样我们没有给参数的值使用的是默认值,我们指定的参数值已经是我们填入的值

  • 匹配模式
    我们用一个小Demo来理解匹配模式,用html+css写一个三角形

    	<div id="wrap">
        	<div class="sjx">
            
        	</div>
    	</div>
    
    	.triangle(){
    		width: 0px;
    		height: 0px;
    		border-width: 40px;
    		border-style: solid;
    		border-color: black  transparent transparent transparent;
    	}
    	#wrap{
    		.sjx{
       			 .triangle()
    		}
    	}
    

    来看一下效果

    这样是不是不够理想,我所有的数值都是死的,我想改变这个三角形的大小,颜色,都不能改变对吧,我们来进行优化一下。

    	.triangle(@w:40px, @c:block){
    		 width: 0px;
    		height: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: @c  transparent transparent transparent;
    	}
    

    这样将我们控制三角形大小,颜色换成了参数,在我们调用他的时候传参就可以控制三角形的大小颜色了对吧。那么我们的需求又变了,现在不单单要求他可以控制他的颜色,大小,我还要能控制三角形的方向。
    有人说了,那简单啊我写四份改改他的方向不就完了吗,但是这样真的可以吗,我们来看一下。

    	//上
    	.triangle(@w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: @c transparent transparent transparent;
    	}
    
    	//右
    	.triangle(@w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent @c   transparent transparent;
    	}
    
    	//下
    	.triangle(@w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent transparent @c  transparent;
    	}
    
    	//左
    	.triangle(@w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent transparent transparent @c;
    	}
    	#wrap{
    		.sjx{
        		.triangle()
    		}
    	}
    

    我们来看一下编译后的css文件

    	#wrap .sjx {
    	  	height: 0px;
    		width: 0px;
    		border-color: pink transparent transparent transparent;
    		border-color: transparent pink transparent transparent;
    		border-color: transparent transparent pink transparent;
    		border-width: 40px;
    		border-style: solid;
    	    border-color: transparent transparent transparent pink;
    	}
    

    瓦特,是什么鬼这是,他将我们所有控制方向的代码都编译到了一起,这样写肯定是有问题的,我们写了四个同名方法他不知道该调用哪个了。这时候我们的匹配模式该出来了,我们需要一个匹配符,来匹配我们要调用的到底是哪个方法。
    我们通过在参数列表前面加一个自定义匹配符来区分这四个方法

       //上
       .triangle(T, @w:40px, @c:pink){
       	height: 0px;
       	width: 0px;
       	border-width: @w;
       	border-style: solid;
       	border-color: @c transparent transparent transparent;
       }
    
       //右
       .triangle(R, @w:40px, @c:pink){
       	height: 0px;
       	width: 0px;
       	border-width: @w;
       	border-style: solid;
       	border-color: transparent @c   transparent transparent;
       }
    
       //下
       .triangle(B, @w:40px, @c:pink){
       	height: 0px;
       	width: 0px;
       	border-width: @w;
       	border-style: solid;
       	border-color: transparent transparent @c  transparent;
       }
    
       //左
       .triangle(L, @w:40px, @c:pink){
       	height: 0px;
       	width: 0px;
       	border-width: @w;
       	border-style: solid;
       	border-color: transparent transparent transparent @c;
       }
       
       #wrap{
       	.sjx{
       		.triangle(B)
       	}
       }
    

    我们在调用方法的时候就用自定义的匹配符当参数传递进去,它就知道我们要调用的是哪个方法了,我们来看一下编译后的css

    	#wrap .sjx {
    		height: 0px;
    		width: 0px;
    		border-width: 40px;
    		border-style: solid;
    		border-color: transparent transparent pink transparent;
    	}
    

    已经成功解决掉了对不对,但是我们的代码是不是显得太冗余了,我们可以将混合抽取出来成模块,单独写一个less文件放进去,然后在通过@impor引进来

    	@import "triangle.less";
    	#wrap{
    		.sjx{
        		.triangle(B)
    		}
    	}
    

    我们来回头看一下我们抽取出来的模块

    	//上
    	.triangle(T, @w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: @c transparent transparent transparent;
    	}
    
    	//右
    	.triangle(R, @w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent @c   transparent transparent;
    	}
    
    	//下
    	.triangle(B, @w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent transparent @c  transparent;
    	}
    
    	//左
    	.triangle(L, @w:40px, @c:pink){
    		height: 0px;
    		width: 0px;
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent transparent transparent @c;
    	}
    

    看似很完美对不对,但是其中还是有一些代码冗余了比如height,width,对于我们冗余的这些代码我们在进行混合

    	.triangle(@_, @w, @c){
    		width: 0px;
    		 height: 0px;
    	}
    
    	//上
    	.triangle(T,@w:40px, @c:block){
    			border-width: @w;
    			border-style: solid;
    			border-color: @c transparent transparent transparent;
    	}
    
    	//右
    	.triangle(R, @w:40px, @c:block){
    		border-width: @w;
    		border-style: solid;
    		border-color: transparent @c   transparent transparent;
    	}
    	
    	//下
    	.triangle(B, @w:40px, @c:block){
    			border-width: @w;
    			border-style: solid;
    			border-color: transparent transparent @c  transparent;
    	}
    
    	//左
    	.triangle(L, @w:40px, @c:block){
    			border-width: @w;
    			border-style: solid;
    			border-color: transparent transparent transparent @c;
    	}
    

    我们在公共部分添加的@_是一个通配符,在调用的时候先执行里面的代码
    这里有一个个小点大家注意一下,我们将三角形的匹配模式抽取出去单独写一个triangle.less这个文件不会编译成单独的这个文件的css文件

arguments变量

  • @argument参数列表
    	.variable(@w, @style, @c){
    		border: @arguments;
    	}
    	.content{
    		.variable(1px, solid, black);
    	}
    
    用arguments变量省去了挨个写参数的事情,我们来看一下编译后的css文件
    	.content {
    		border: 1px solid black;
    	}
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值