2

Less是什么

再说less之前,先说一下大家都知道的css;css作为撑起前端领域的3大基石之一,他的一举一动都是时刻牵动着开发者们的小心脏,css和html一样,都是一种标记性语言,并不像js那样具有逻辑性,而且每当有新的特性出来的时候,一定绕不过兼容问题;在一个就是重复性及其恼火,同样的一个相似样式在一个页面可能要写几次甚至十来次,简直是一种折磨,同样的还有一些难以记忆的色彩,每次可能都要找好久才能找到你上一次写的那个色号;所以就涌现了一些有趣的预编译语言,less就是其中一个佼佼者.

神奇的预编译语言

什么是预编译语言呢,就我的理解就是一种浏览器不能直接识别语言,浏览器只html,js,css,所以一些特殊的语言需要经过编译处理才能被浏览器识别;

Sass(scss)

诞生于2007年,基于ruby,所以使用sass(scss)的话需要先装上ruby.sass和scss这两个十分相似,在百度上搜索scss 下面的第一个却是sass,说的简单的可以理解scss是sass的一个升级版本,完全兼容sass之前的功能,又有了些新增能力,在语法上有些出入.

Stylus

诞生于2010年,来源于node社区的一款预编译语言,跟sass有些相近

Less

诞生于2009年,受Sass的影响创建的一个开源项目。 Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。
Less 可以运行在 Node 或浏览器端。(引用于官网)。

萝卜青菜

萝卜青菜,各有所爱,市面上的css预处理语言很多,上面3个只是其中一部分,在选择上也是有点儿纠结的,就个人而言,虽然sass和stylus在功能上要比less强,但是说到学习时间和成本那肯定是less最优的,只要会css.那么就可以在很短事件里面了解掌握less常用精华部分了,掌握这些就足以应对日常工作中所需要的情况了;

Less常用

还是上面那句话,less的功能很多,但是其实我们只需要掌握其中最常用的那部分就足以应对工作中的问题了;

变量

less的变量跟一般语言的变量没什么区别,主要用在一些十分重复的值上,比方色彩,路径;

语法

定义: @变量名:变量值;
使用: 属性: @变量

常见场景

色号使用
 @grey-text:grey;
 div{
     color:@grey-text; //不需要加""
 }
 //编译之后得到:
 div{
     color:grey;
 }

这主要用在页面上的一些色号上,每次都重复复制一个色号,而且有时候代码多了又要翻上去找那个色号,让人心烦(☄ฺ◣ω◢)☄ฺ,以后就可以在页面顶部先定义好页面上重复次数多的色号,方便使用;

文件路径

这个主要重在背景图或者其他一些有路径文件的处理上;比方依据起点项目的文件目录来说,给一个div设置背景图是这样路径

div1{
    background-image:url(../../images/web3.0/xx/xxx.png);
}
div2{
    background-image:url(../../images/web3.0/aa/aaa.png);
}

写多了感觉想吐,((유∀유|||)) ,在起点项目里面都是这样的目录,虽说这个文件目录不会轻易更改,但是保不准那一天变更了就惨了,现在有了less的变量我们就可以这样

//1,先在less文件顶部定义好全局路径,就是前面那一段重复的
@base-url:"../../images/web3.0/";//加上了引号
//2,然后使用
div1{
    background-image:url("@{base-url}xx/xxx.png");
}
div2{
    background-image:url("@{base-url}aa/aaa.png");//这里也加上了引号,并且使用大括号包裹
}
//以后即使项目路径变更了我们只需要改最上面的@base-url就可以一次性全部更改了;

好吧,上面的这个文件路径加不加引号还有些奇怪的地方;举个例子

@base-url:img/; //这里没加引号
@base-url-l:"../../qidianv3.0/assets/images/web3.0/";  //加上了引号
@bg-img:background-image; //把属性名当做变量存放也是可以的

.lessa{
    width: 200px;
    height: 200px;
    @{bg-img}:url('@{base-url}bg.png');
}
.lessd{
    width: 200px;
    height: 200px;
    @{bg-img}:url("@{base-url-l}banner@2x.png");

上面两个都得到了正常编译,但是第二个(@base-url-l的属性值)如果不加引号却会出错,得到NameError: variable @base-url-l is undefined的报错,这点让人在意;难道是单节的可以不加,多节的就一定要加嘛?算了..保险起见都加上吧;

属性名定义

上面提到的变量定义还可定义属性名,我觉得这个用在那些较长的属性名上是个不错的注意

background-attachment: fixed;//背景图较小时候是否跟随内部元素滚动,取值:scroll fixed;
//background-attachmen够长,也不好记忆,把他存下来
@bgFixed:background-attachment;
div{
    @{bgFixed}:fixed;
}
//编译得到
div{
    background-attachment:fixed;
}

但是其实这个我觉得用处不大,因为sublime安装Emmet css3等插件之后只需要记得这个属性的几个字母就可以提示了,要敲的单词说不定要比自定义的还要少,而且时间更加省;┐( ̄ヘ ̄)┌,比方上面这个我只需要敲"batf",就可以得到background-attachment:fixed了;

总结:我觉得这个变量还是主要用在色彩和资源路径实用

计算

这个计算还是很管用的,而且很强大

宽高计算

一个很有用处的计算属性,他可以直接对常用的属性值(数字属性)进行四则运算,同样,新提出的css也增加了类似的calc()计算属性;
**加减法时 以第一个数据的单位为基准
乘除法时 注意单位一定要统一**
解释下第一条,第二条注意一下单位就好:

下面红块区域

.main{
    height: 100% - 40px;
    border:1px solid red;
}
//最后编译出来
.main {
    height: 60%;
    border: 1px solid red;
}

可以看到,最后他得到了60%;他是把40px当做40%来处理的,这就是上面说的加减法时 以第一个数据的单位为基准;
现在我们来对比一下css3的calc()的计算结果

.main{
    height:calc( 100% - 40px);
    border:1px solid red;
}
//最后编译出来,(编译个毛线啊,这本身就是原生css啊喂ヽ(`Д´)ノ︵ ┻━┻ ┻━┻ )
.main {
    height: calc(100% - 40px);
    border: 1px solid red;
}

可以看到明显对比,下面的自己占据了剩下所有空间,他没有忽视单位的存在,而是真的如同我们想的进行计算,所以从这一点看来明显是calc()要聪明一些;

色彩计算

这个东西挺有趣的,色彩还可以计算;

@bgcolor:#CB9898; //定义色彩
.main{
    height: calc(100% - 40px);
    box-sizing: border-box;
    border:1px solid red;
    background-color:@bgcolor+#111; //背景色计算
}

;

//编译得到
.main{
    height: calc(100% - 40px);
    box-sizing: border-box;
    border: 1px solid red;
    background-color: #dca9a9;//渲染结果
}

还是上面那个图,可以看到背景色最后渲染成为了#dca9a9;这个计算过程也很简单,首先把#CB9898换成rgb得到203,152,152,
再把#111换成rgb得到 17,17,17 最后两个rgb对应相加,得到 220,169,169 化成hex就是#dca9a9了;
然后我们看看calc支持这东西吗?

emm..ヽ( ̄▽ ̄)ノ无效的属性值,这一点看来还是less更加厉害;
那么这一点用在什么地方更加合适呢?毕竟人脑不是电脑,不可能心算出hex->rgb在相加,除非是那种很简单的#111+#222=#333的这种,所以我暂时也还没找到这东西的使用场景;
总结:所以两种计算方式不存在谁好谁坏的说法,关键看使用场景,就个人来说,外面的布局上用calc比较好,而里面的子元素之间的明确宽高关系还是用less的计算方法,毕竟每一次都要写calc()还是挺讨厌的,不是吗?

嵌套

这个我觉得是less里面最好用的功能之一了,因为他会形成一种类似作用域的东西,所有的属性或者变量值都只在这个范围生效,可以在一定程度上减轻css交叉引用时相同class所带来的影响,极大程度减轻了我们写css选择器的烦躁感( ̄▽ ̄)/

嵌套规则

.alread-selectd{
    margin-top: 36px;
        .alread-selectd-head{
            display: flex;
            .alread-selectd-title{
                font-weight: bold;
                &+span{
                    .MIX-font(14px,#999);
                }
            }
        }
    }
    
//编译得到
.alread-selectd {
  margin-top: 36px;
}
.alread-selectd .alread-selectd-head {
  display: flex;
}
.alread-selectd .alread-selectd-head .alread-selectd-title {
  font-weight: bold;
}
.alread-selectd .alread-selectd-head .alread-selectd-title + span {
  font-size: 14px;
  color: #999;
}

作用域

//作用域(或者说就近原则)
@font-color:pink;//全局定义
.main{
    @font-color:red; //重定义
    color:@font-color;
    .in{
        @font-color:blue;  //重定义
        color:@font-color;
    }
}
.footer{
    @font-color:green;  //重定义
    color:@font-color;
}
.mask{
    color:@font-color; //全局定义
}

;
所以简单的说,这个作用域其实也就是个就近原则,他会去找距离自己最近的那个变量,指导最外层;

"&"的用处

&符号代表的就是当前选择器,他用在自己的特定class(或者说状态下)和伪类:after:before是相当有用的;
我们经常会用到当鼠标点击的时候去切换某个元素的样式,这时候只需要像这样

div{
    background-color:black;
    &.active{
        background-color:red;
    }
}
//然后在点击的时候加上active这个calss就好
//伪类使用
div{
    color:red;
    &:after{
        content:"i'm cute,so please give me money!!"
    }
}

媒体查询器的嵌套

媒体查询器不用写到外面去了,媒体查询器同样可以嵌套在规则层级里面了,只是按照一般习惯,我们会把所有的要根据媒体查询器来写的样式放在一个媒体查询器里面,而这个却会每一个样式都单独生成一个媒体查询区;

div{
    width:300px;
    @media screen and (min-width: 320px) and (max-width: 1200px){
        width:100px;
    }
}
//最后得到
div{
  background-color: pink;
}
@media screen and (min-width: 320px) and (max-width: 1200px){
  div{
    background-color: grey;
  }
}

混合

这也是less里面十分有用的东西,混合(mixture)其实就是一堆预定义的样式的集合;我们可以把一些经常会出现的,一些固定写法抽出来集合在一块儿,然后使用的时候很方便的就可以调用了;

不带参数的混合

.MIX-center{ //这是一个经常用到的让元素内部水平垂直居中的东西;
    display:flex;
    align-items: center;
    justify-content: center;
}
div{
    .MIX-center;//亦可以写成.MIX-center();
}

带参数的混合

我们可能经常会写这种按钮,如果来一个写一个那真的是一种折磨,现在有了less我们可以这样

.MIX-btn(@width,@height,@font-size,@color,@bdr-color){ //使用混合,把样式都写出来;
    width: @width;
    height: @height;
    font-size: @font-size;
    line-height:@height;
    text-align: center;
    border-radius: @height;
    color:@color;
    border:1px solid @bdr-color;
    text-decoration: none;
}
//然后,我们这样使用
button{
    .MIX-btn(100px,30px, 12px, #333,black);
    display: inline-block;
}

//实际编译得到
button{
    width: 100px;
    height: 30px;
    font-size: 12px;
    line-height: 30px;
    text-align: center;
    border-radius: 30px;
    color: #333;
    border: 1px solid black;
    text-decoration: none;
    display: inline-block;
}

以后遇到这种按钮就可以直接调用.MIX-btn(),依次传入参数就好了;

默认参数的混合

混合参数在指定的时候可以带上默认值,如果不给,那么他就采用默认值

.MIX-border(@a:10px,@b:50px,@c:30px,@color:#000){
    border:1px solid  @color;
    box-shadow: @arguments;//指代的是 全部参数
}
div{
    .MIX-border();
}
//得到
div{
    border:solid 1px #000;
    box-shadow: 10px 50px 30px #000;
}

这种混合个人而言不合适用在具体数字很多的时候,因为页面中这些数字很少有一样的,难以做到通吃,这种数字值很多的情况你还不如就放个变量名,然后所有的值都手动传入更好;所以他适合用在一些'变动不多的常见套路'上
比方第一个里面的居中,但是我们有时候只会在x上居中,在y上则是从交叉轴起点对齐,比方左边是圆形头像,右边是个人信息,或者其他的什么对齐方式;所以定死的混合就不大合适;但是每次调用的时候我们都去传参数也是麻烦,毕竟大部分时候我们用flex居中是最常见的;我们这时候采用这种带参数的默认居中混合

.MIX-center(@x:center,@y:center){ //不要加'';
    display:flex;
    align-items: @y;
    justify-content:@x;
}
.div{ //传入了参数他就用你指定的参数
    .MIX-center(@y:flex-start); //注意传参方式
}
.div1{
    .MIX-center(); //不给就默认(song)(`・ω・´);
}
//得到
.div{
    display:flex;
    align-items: @flex-start;//采用我们的设定值
    justify-content:center; //默认值
}

这样是不是感觉好得多了?

混合的命名空间

有些奇怪复杂的使用方式,来一段官网的介绍:

有时候,你可能为了更好组织CSS或者单纯是为了更好的封装,将一些变量或者混合模块打包起来, 你可以像下面这样在.space中定义一些属性集之后可以重复使用:
.MIX-space{
    .base{
        width: 200px;
        height: 200px;
    }
    .color{
        color:red;
        .bgcolor{
            background-color: grey;
        }
    }
    .border{
        border: 1px solid black;
    }
}
//0,直接调用父层
.space{
    .MIX-space(); //啥都没有
}
//1, 调用直系子层
.space{
    .MIX-space .base();//只有宽高生效
}
//2, 调用直系子层
.space{
    .MIX-space .border();//只有边框生效
}
//3, 有爷爷级,跨级调用孙子层
.space{
    .MIX-space .bgcolor();//NameError: .MIX-space.bgcolor is undefined;
}
//4, 调用直系子层(含自己子层)
.space{
    .MIX-space .color(); //只生效字体红色
}
//5, 连续调用
.space{
    .MIX-space>.color>.bgcolor() //生效灰色
}
//6, 子层以及子层调用
.space{
    .MIX-space .color();
    .MIX-space>.color>.bgcolor(); //注意这种用法,不能写成 .MIX-space>.color()>.bgcolor();
}
//7, 多属性调用
.space{
    .MIX-space .base();
    .MIX-space .border();//宽高边框生效
}
// 8, (没有爷爷),越过父层跳跃调用
.space{
    .color(); //NameError: .color is undefined
}

所以从上面的几个例子可以看出这东西的意义和用法了;他和一般的混合有些不一样,感觉更像是其他语言的对象,普通混合是一旦调用,那么就会把这个混合里面所有的样式属性全部应用进去,尽管有时候我们只想要其中一两个;而混合空间则满足了这个需要,你可以在一个复杂的命名空间里面去挑选你需要的几个属性来使用
其中有几个点需要注意一下
1,直接调用父层是不会如同我们想象的那样去自动包含他下面的子层样式,只会得到他自己身上的样式,假如他上面没有任何样式,那么你将什么也得不到(0);
2,混合命名空间是绝对禁止直接调用子层或者孙子层的,第一步一定是把混合空间引入,这样才"有混可调" (8);
2,调用之前必须先调用父层,直接调用子层会得到未定义 (3);
3,需要哪些样式就调用哪些样式,调了几个你就要写几个,千万别忘了第一点;
4,孙层前面的父层不要加();
关于混合的一些写法建议:
1,混合不一定用'.'开头,也可以用'#',所以看起来就像一般的class选择器和id选择器
2,写混合的时候建议在前面加上MIX-用作识别,这样做有个好处,可以避免和一般class,id混淆;
3,尽管混合在调用的时候有时候可以不加(),但是建议还是一直加上吧,把他想想成为函数吧,想着函数调用不带()那是不是很难受?

继承

继承,less的伪类,很明显,意思就是自己(伪类,自己,那么就联想到'&:')从指定的地方去继承样式(又是一个充满玄学的东西٩(º﹃º٩));
先看一个简单例子

.outer{
    background-color:aliceblue;
}
div{
    &:extend(.outer)//继承不用加();
}
//渲染得到
div{
    background-color:aliceblue;
}

继承就基本而言就是这样使用;但是他也有一些注意的点;现在我们以上面的命名空间为被继承者,看一两个小东西就明白了
你要开心我们可以叫他爸爸(● ̄(エ) ̄●);儿子从爸爸那儿继承很正常不是

.MIX-space{
    .base{
        width: 200px;
        height: 200px;
    }
    .color{
        color:red;
        .bgcolor{
            background-color: grey;
        }
    }
    .border{
        border: 1px solid black;
    }
}
//1,继承父
.extend{
    &:extend(.MIX-space)
}
//编译得到
.extend{
    //啥都没得到
}
//2,层级调用
.extend{
    &:extend(.MIX-space .color);
}
//编译得到
.extend{
    color: red;
}
//3,多个继承
.extend{
    &:extend(.MIX-space .color); 
    &:extend(.MIX-space .color .bgcolor); 
}
//编译得到
.MIX-space .color,.extend { //注意这个选择器的变化
  color: red;
}
.MIX-space .color .bgcolor,.extend { //注意这个选择器的变化
  background-color: grey;
}
//跨级继承
.extend{
    &:extend(.color); 
}
//得到警告 extend ' .color' has no matches

从上面几个例子可以看出,继承和命名空间的使用规则其实是基本一致的,只是他不需要调用加括号而已;另外值得注意一点的是继承者在编译出来之后他得到的选择器会变成'父,继承者'这样的形式,在一个就是继承编译出来的并不会在一个大括号里面,这就像上面的嵌套媒体查询器了!

@import 引入

@import引入,这东西在css里面其实也有,作用其实也差不多,都是在一个css里面去引入另一个css,但是两者的功能性却是差的很多;假设在一个页面里面,我想要使用bootstrap的btn样式,但是我又不想把整个bootstrap全部引入,那么这时候我们可以这样做

@import "../bootstrap-3.3.7/less/variables.less"; //注意着两个东西,这是bootstrap的全局变量定义,一些基本单位(颜色,字体大小,padding,margin之内的)都在这个less文件里面
@import "../bootstrap-3.3.7/less/mixins.less"; //所有的混合样式,这两个都必须放在最前面,且必须引入
@import "../bootstrap-3.3.7/less/buttons.less";

<button type="button" class="abtn btn-info">按钮</button>

//使用
.abtn{
    &:extend(.btn);
}
.table{
    &:extend(.table);
}

![](https://static.qidianla.com/1...;
可以看到他就有了基本样式,然后我们再来看看这个文件大小
;
;
至于上面提到的两个less是有这样的描述

bootstrap.less作用是将其他less文件全部引入,但是引入的顺序还是有要求的。比如先引入 variables.less 和 mixins.less,是因为后面的less文件用到的less特性都是来自于这两个文件的,如果不先引入,就会出现编译错误的问题。然后再引入 reset.less 重置原有的样式。接着引入网格系统的相关文件,这是整个网格系统建立的关键所在。然后引入一些公用的组件,特定组件,最后就是一些无家可归但是比较有用的样式样式文件:utilities.less。

less里面的@import引入可以附带多个参数,这几个参数的意义和作用目前还有摸透是几个意思

指令 含义
reference 使用文件,但不会输出其内容(即,文件作为样式库使用)
inline 对文件的内容不作任何处理,直接输出
less 无论文件的扩展名是什么,都将作为LESS文件被输出
css 无论文件的扩展名是什么,都将作为CSS文件被输出
once 文件仅被导入一次 (这也是默认行为)
multiple 文件可以被导入多次
optional 当文件不存在时,继续编译(即,该文件是可选的)

色彩函数

好吧,这东西有涉及到一些色彩上的专业知识,原谅我只晓得个rgba; ╮(・o・)╭ 所以还是找个平时用得上的东西来说
有时候可能拿到个hex,但是明显这东西还有个透明度通道,那就只有转成rgb,在加个a了...难受...香菇,
而less提供几个好用方法使用

.lighten{
    height: 100px;
    width: 100px;
    background-color: fadeout(#4e5b7a, 40%); //fadeout函数
}
//编译得到
.lighten {
    height: 100px;
    width: 100px;
    background-color: rgba(78, 91, 122, 0.6); //上面是淡出值,所以实际应该得到0.6;
}
//其他两个应该用得到的
mix(@color1, @color2,weight);//混合2个不同的颜色,第三个参数为alpha值,默认50%;
fade(@color,alpha) //就是直接设置透明度
fadein(@color,alpha) //其实就是很fadeout相反啦

色彩函数里面还有几个看起来很复杂的东西,涉及到什么hsla,hsv,色彩空间,色彩通道什么的...看不懂看不懂ヘ(* – -)ノ

免编译

还记得上面的计算属性嘛?提到在less中使用calc()会被同一单位计算处理掉,但是这很危险,所以我我们要让less知道这东西你不去动他;
使用 ~''(波浪符号加单引号)这样的格式

div{
    width:~'calc(100% - 80px)'
}
//编译得到
div{
    width: calc(100% - 80px);
}

这样就可以避免一些重要的东西被错误编译了

注释

最后缩一下注释吧
CSS 形式的注释在 LESS 中是依然保留的
Less文件中

Css文件中:

//注释

好吧...关于less的基本用法差不多就是上面这些了,后续再补充吧(滑稽)


墨韵
109 声望0 粉丝