Less知识整理


Less


介绍

less对于css,很像jquery对于js,让原生内容简化,代码写的少,但是实现的功能却更多。

同时,less的表达,也更像js 。比如变量,嵌套,封装,函数,映射,作用域等等。

所以,学习的时候,可以结合css和js来学习less,更容易理解。同时,在本篇中,我也会不断提醒这一点。

官网

https://less.bootcss.com/

less对于css样式的表达,是通过各种各样的符号来实现的。

比如@ , & , ( ) , { } , [ ] , $等,这让less更像css和js封装的混合体。

本篇就以符号位主线,对less内容进行整理。

安装

less.js是一个js库,需要在node环境下安装和使用。

// node环境下安装
npm install less -g

#or:

yarn global add less

less不能直接被浏览器识别,需要转换为css样式,这要用到less-loader进行编译,

这里有个最大的坑,就是要注意less-loader的版本,一般使用5版本。

npm install less-loader@5

#or:

yarn add less-loader@5

目前,less主要在前端框架中使用,还需要一些额外的webpack配置:

Vue-cli中使用less点击查看

React中配置less点击查看


嵌套

less可以像dom结构一样嵌套书写:

比如当前一组dom结构

<div class="box">
    <div class="box1"></div>
</div>
<div class="box2"></div>

用less给该组dom写样式,就可以这样写:

.box {
    width: 100px;
    heigth: 100px;
    
    .box1 {
        width: 50px;
        height: 50px;
    }
}

.box2 {
    width: 100px;
    heigth: 100px;
}

这样就表示了.box和.box1类样式的父子关系,.box和.box2的兄弟关系。

如果这里把.box2写到.box中,.box2的样式是不会生效的,因为结构错乱了。


注释

注释,分为注释单行和注释多行。这和js的注释方法是一致的。

// 注释单行用//表示

// @width: 100px;

// 注释多行,用/**/表示

/*.box {
    width: @width;
}*/

@

普通变量

// 定义一个宽度变量
@width: 100px;

// 使用变量
.box {
    width: @width; // width: 100px;
}

// 定义一个新变量,值是@width

@height: @width;

.box {
    height: @height; // height: 100px;
}

// 这一点,和js是一致的。

变量插值-选择器

@one-class: btn;

.@{one-class} {
    width: 100px;
}

// 编译结果为

.btn {
    width: 100px;
}

变量插值-urls

@urls: "../images";

.box {
    background: url("@{urls}/huaban.png");
}

// 编译结果为

.box {
    background: url("../images/huaban.png");
}

这里还有个常用的用法。

比如,当前页面中需要用到很多次设置背景图片,图片的地址相同,但是名称不同,

就可以结合mixins 这样来做:

.setbg(@url) {
    background-image: url("../images/@{url}");
}

假如此时.box元素需要设置一个“huaban.png”的图片:

.box {
    .setbg("huaban.png");
}

// 编译结果为:

.box {
    background-image: url("../images/huaban.png");
}

变量插值-import

@themes: "../../src/themes";

@import "@{themes}/tidal-wave.less";

// 编译结果为

@import "../../src/themes/tidal-wave.less";

变量插值-属性

@property: color;

.widget {
  @{property}: #0ee;
  background-@{property}: #999;
}

// 编译结果为

.widget {
  color: #0ee;
  background-color: #999;
}

可变变量

就是通过@的叠加,实现深层次的变量赋值

@primary: pink;

.box {
    @color: primary;
    
    .box1 {
        color: @@color; // color: pink;
    }
}

延迟计算

less中的变量,可以先使用,后定义和赋值。

.box {
    color: @primary;
}

@primary: pink;

// 编译结果为

.box {
    color: pink;
}

这里有一个类似于js的作用域和变量提升的问题,

一个{ }就相当于一个局部作用域,

当同一个变量名称被多次赋值,那么该变量最终的值,

就是在该作用域下的最后被赋予的那个值。

比如:

@var: 0;
.class {
  @var: 1;
  .brass {
    @var: 2;
    three: @var;
    @var: 3;
  }
  one: @var;
}

// 编译结果为

.class {
  one: 1;
}
.class .brass {
  three: 3;
}

这有点像css的自定义属性,

顺便延申阅读:css自定义属性

$ 变量属性

$会把已经存在的属性当作变量来使用。

通过属性,获取到对应的属性值。

比如:

.box {
    width: 100px;
    height: $width; // height: 100px;
}

// or:

.box {
    width: 100px;
    
    .box1 {
        width: $width; // width: 100px;
    }
}

变量属性同样存在同个作用域的取值问题:

它会使用该作用域内的最后一个该属性的值作为自己的值。

.box {
    color: blue;
    
    .box1 {
        background-color: $color; // background-color: pink;
    }
    
    color: pink;
}

Mixins

mixin,就是混合,或者混入。在整个前端的内容中,会时不时的看到这个概念。

它的作用是,把一些公用的内容抽取出来进行封装,供别的内容调用。

别的地方来调用,就会把这些公用的内容插入到调用元素的内容中,这个过程,就叫混合。

基础mixins

比如我们定义一个.bordered类:

.bordered {
    border: 1px solid red;
    border-radius: 4px;
}

现在.box类中也要用到.bordered里的属性,就可以在.box中调用.bordered:

.box {
    width: 100px;
    height: 100px;
    .bordered();
}

此时.box经过编译,就会变成:

.box {
    width: 100px;
    height: 100px;
    border: 1px solid red;
    border-radius: 4px;
}

分组和封装

当混入样式多了之后,需要对这些样式进行分组,方便分开调用。

而且为了混入样式表达不那么混乱,还需要把它们封装在一起。

比如有下面两个mixins样式:

.btn {
    width: 70px;
    height: 30px;
    border: 1px solid #333;
    outline: none;
}

.colors {
    color: #fff;
    background-color: red;
}

把上面两个mixins都封装在==#mixins==类下面:

#mixins() { // 注意这里有个(), 并且下面的内容之间没有分号或者逗号
    .btn {
        width: 70px;
        height: 30px;
        border: 1px solid #333;
        outline: none;
    }

    .colors {
        color: #fff;
        background-color: red;
    }
}

接下来,.box类中需要使用到.colors中的所有样式,那么就可以这样使用了:

.box {
    width: 100px;
    height: 100px;
    #mixins.colors();
}

映射[]

从less@3.5开始,还可以把单个属性变量放入mixins中。

#colors() {
    primary: blue;
    secondary: red;
}

// 在.box类中使用mixins中的属性:

.box {
    color: #colors[primary]; // color: blue;
    background-color: #colors[secondary]; // background-color: red;
}

带参数的mixins

创建一个mixins:

.set-color(@my-color) {
    color: @my-color;
}

使用:

.box {
    .set-color(#fff);
}

// 编译为

.box {
    color: #fff
}

如果是多个参数,要用==;==隔开。这一点注意和函数的区别。

.set-color(@color1; @color2; ...) {
    ...
}

还可以给参数设定默认值:

.set-color(@my-color: pink) { 
    color: @my-color;
}

.box {
    .set-color(); // 不传参的时候,就执行默认值
}

// 编译为

.box {
    color: pink;
}

和插值变量结合的带参数的mixins 可以参考插值变量 urls中的例子。

mixins中存放选择器

存放普通选择器:

.mixins {
    .box1 {
        color: pink;
    }
}

.box {
    .mixins();
}

// 编译为

.box .box1 {
    color: pink;
}

和&结合:

.mixins {
    &:hover {
        background-color: pink;
    }
}

.btn {
    .mixins();
}

// 编译为
.btn:hover {
    background-color: pink;
}

@arguments

当某个属性会用到所有参数时,把参数都写一遍会很麻烦, 可以直接用@arguments代替。

.shadow(@x: 0; @y: 0; @blur: 2px; @color: #000) {
    box-shadow: @arguments;
}

.box {
    .shadow();
}

// 编译为

.box {
    box-shadow: 0 0 2px #000;
}

!important

当!important作用到mixins的执行时,会给它里面的所有属性都加上!important

.my-color {
    color: pink;
    font-size: 16px;
}

.box {
    .my-color() !important;
}

// 编译为

.box {
    color: pink !important;
    font-size: 16px !important;
}

函数mixins

类似于vue的computed,就是为了得到某个值而创建

.averge(@x, @y) {
    @result: ((@x + @y) / 2); // 取平均值
}

.box {
    width: .averge(16px, 50px)[@result];
}

// 编译为

.box {
    width: 33px;
}

when

用来完成判断和循环,类似js的when语法(写法上会有区别)。

// 创建一个带when的mixins

.generate-columns(@n, @i: 1) when (@i =< @n) {
  .column-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}

// 使用

.generate-columns(4);

// 输出结果

.column-1 {
  width: 25%;
}
.column-2 {
  width: 50%;
}
.column-3 {
  width: 75%;
}
.column-4 {
  width: 100%;
}

判断相等

.number-check(@a) when (@a = 5) { ... }

判断大小

.max(@a; @b) when (@a > @b) {width: @a}

且判断

.mixin(@a) when (@a > 0) and (@a < 5) { ... }

或判断

.mixin(@a) when (@a = 1) , (@a = 3) { ... }

非判断

.mixin(@a) when not (@a < 0) { ... }

&

在less嵌套结构中,用&表示用{ }包裹住当前选择器的那个选择器。

.box {
    &.box1 {
        width: 100px;
    }
}

此时,当前选择器是.box1,包裹住.box1的是.box,所以&就表示.box

而&.box1就是css中的.box.box1,即同时具有.box和.box1的那个元素

和伪类结合使用:

.btn {
    color: #fff;
    
    &:hover {
        color: pink;
    }
}

此时,当前选择器是:hover,包裹住:hover的是.btn,所以&就表示.btn

.btn:hover就表示.btn元素悬浮时的样式

/************************************/

// 清除浮动

.clearfix {
  display: block;
  zoom: 1;

  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

既然&能够作为父级选择器存在,那么它就可以这样使用:

.box {
    width: 100px;
    
    &1 {
        width: 50px;
    }
}

// 相当于:

.box {
    width: 100px;
    
    .box1 {
        width: 50px;
    }
}

+ - * /

计算以加减法为主。

单位相同的加减计算,会先计算出数字,然后给数字加上该计量单位,得出最终结果:

@width: 20px + 50px; // 70px

less的计量单位遵循以左为主

单位不同的加减计算,如果有能转换成相同单位的,则先转换为相同单位,再进行计算;

如果不能转换成相同单位的,则先计算出数字,再把左边第一个计量单位作为最终的计量单位。

@long-unit: 5cm + 10mm; // 6cm

@new-unit: 5 - 2cm - 5mm; // 2.5cm

@other: 2 + 5px -3cm; // 4px

对于乘除运算,以简单计算为主。毕竟复杂的单位换算,意义不大。

@base: 5% * 2; // 10%

calc()

执行一些简单的计算。

@leng: 50vh/2;

.box {
    width: calc(50% + (@leng - 20px));
}

~

是转义符。符号后面的内容,在编译时,会保持原样进行输出。

~"(min-width: 768px)" 会被编译为 (min-width: 768px)

less@3.5版本后,有直接简写方式,这种转义符号就不需要了。


导入

导入.css文件

@import 'demo.css'; // 分号不要忘记写

导入.less文件

@import 'demo.less';

// 当导入.less文件时,.less后缀可以省略

@import 'demo';

内置函数

if

语法:

if(判断条件, a, b)

// 如果判断条件得到的结果为true,则执行a值。 否则,执行b值

// 类似于js中的if(判断条件) {return a} else {return b}

如果判断条件只有1个,那么就用==()==包裹住判断条件。不然可能会在某些less版本中报错。

.box {
    width: if((2 > 1), 10px, 20px);
}

// 编译为

.box {
    width: 10px;
}

if中的且判断:

if((true) and (2 > 1), a, b)

if中的或判断:

if((2 > 1) or (3 > 2), a, b)

if中的非判断:

if(not (true), a, b)

escape

用于url编码,通俗点讲就是把特殊符号转换成乱码的形式。

escape('a=1')

// 编码结果:

a%3D1

e

用于去除引用,简单说就是去掉引号,引号中是啥就输出啥

@mscode: "ms:alwaysHasItsOwnSyntax.For.Stuff()" 
filter: e(@mscode);

// 结果

filter: ms:alwaysHasItsOwnSyntax.For.Stuff();

% format

==%(string, arguments …)==用于格式化字符串。

第一个参数是一个包含占位符的字符串。占位符以百分号 % 开头,

后面跟着字母 sSdDaA。后续的参数用于替换这些占位符。

如果你需要输出百分号,可以多用一个百分号来转义 %%

使用大写的占位符可以将特殊字符按照 UTF-8 编码进行转义。

此函数将会对所有的特殊字符进行转义,除了 ()'~! 。空格会被转义为 %20

小写的占位符将原样输出特殊字符,不进行转义。

format-a-d: %("repetitions: %a file: %d", 1 + 2, "directory/file.less");
format-a-d-upper: %('repetitions: %A file: %D', 1 + 2, "directory/file.less");
format-s: %("repetitions: %s file: %s", 1 + 2, "directory/file.less");
format-s-upper: %('repetitions: %S file: %S', 1 + 2, "directory/file.less");

// 格式化结果:

format-a-d: "repetitions: 3 file: "directory/file.less"";
format-a-d-upper: "repetitions: 3 file: %22directory%2Ffile.less%22";
format-s: "repetitions: 3 file: directory/file.less";
format-s-upper: "repetitions: 3 file: directory%2Ffile.less";

replace

用来替换字符串中的字符。

有4个参数,原字符串要被替换的字符用来替换的字符串匹配规则

replace("Hello, Mars?", "Mars\?", "Earth!");
replace("One + one = 4", "one", "2", "gi");
replace('This is a string.', "(string)\.$", "new $1.");
replace(~"bar-1", '1', '2');

// 替换结果

"Hello, Earth!";
"2 + 2 = 4";
'This is a new string.';
bar-2;

@list

列表,数组。

@list: "banana", "tomato", "potato", "peach";
n: length(@list);

// 结果

n: 4

extract

获取list列表中的数据

@list: apple, pear, coconut, orange;
value: extract(@list, 3);

// 结果

value: coconut;

range

获取范围值。

有3个参数:

开始的值 :比如1或者1px,可选,默认为1

结束的值 :比如5或者5px,必须

增加幅度 :每次增加的值,可选,默认为1

value: range(4); // 从1开始,每次增加1,一直增加到4

// 结果:

value: 1 2 3 4;
value: range(10px, 30px, 10); // 开始值为10px,结束值为30px,每次增加10

// 结果:

value: 10px 20px 30px;

each

枚举,遍历

有2个参数:

list :可枚举对象,如数组,对象等

枚举规则 :枚举时执行的内容

@selectors: blue, green, red;

each(@selectors, {
  .sel-@{value} {
    a: b;
  }
});

// 编译为:

.sel-blue {
  a: b;
}
.sel-green {
  a: b;
}
.sel-red {
  a: b;
}

如果list是对象

@set: {
  one: blue;
  two: green;
  three: red;
}
.set {
  each(@set, {
    @{key}-@{index}: @value;
  });
}

// 结果:

.set {
  one-1: blue;
  two-2: green;
  three-3: red;
}

ceil

类似于js的Math.ceil()

ceil(2.4)

// 结果

3

floor

类似于js的Math.floor()

floor(2.4)

// 结果

2

percentage

把数字变成百分比

percentage(0.5)

// 结果

50%

round

四舍五入。有2个参数:

1. 数字

2. 要保留的小数点后几位,默认为0,即结果取整数

round(1.67)

// 结果

2
round(1.67, 1)

// 结果

1.7

sqrt

开平方,取正数平方根

sqrt(25cm)

// 结果

5cm

abs

取绝对值

abs(25cm)

// 结果

25cm
abs(-1)

// 结果

1

pow

语法:pow(a, b) 表示a的b次幂

pow(0cm, 0px)
pow(25, -2)
pow(25, 0.5)
pow(-25, 0.5)
pow(-25%, -0.5)

// 结果

1cm
0.0016
5
NaN
NaN%

mod

取余。语法:mod(a, b) 表示a % b的值

mod(0cm, 0px)
mod(11cm, 6px);
mod(-26%, -5);

// 结果

NaNcm;
5cm
-1%;

min

取最小值

min(5, 10)
min(3px, 42px, 1px, 16px)

// 结果

5
1px

max

取最大值

max(5, 10)
max(3%, 42%, 1%, 16%)

// 结果

10
42%

isnumber

去掉符号后,是否为number类型

isnumber(#ff0);     // false
isnumber(blue);     // false
isnumber("string"); // false
isnumber(1234);     // true
isnumber(56px);     // true
isnumber(7.8%);     // true
isnumber(keyword);  // false
isnumber(url(...)); // false

isstring

是否为字符串类型

isstring(#ff0);     // false
isstring(blue);     // false
isstring("string"); // true
isstring(1234);     // false
isstring(56px);     // false
isstring(7.8%);     // false
isstring(keyword);  // false
isstring(url(...)); // false

iscolor

是否为颜色值

iscolor(#ff0);     // true
iscolor(blue);     // true
iscolor("string"); // false
iscolor(1234);     // false
iscolor(56px);     // false
iscolor(7.8%);     // false
iscolor(keyword);  // false
iscolor(url(...)); // false

isunit

验证单位

isunit(11px, px);  // true
isunit(2.2%, px);  // false
isunit(33px, rem); // false
isunit(4rem, rem); // true
isunit(56px, "%"); // false
isunit(7.8%, '%'); // true
isunit(1234, em);  // false
isunit(#ff0, pt);  // false
isunit("mm", mm);  // false

image-size

获取图片尺寸

包含两个宽高字段,image-width , image-height

image-size("file.png")

// 结果

10px 10px

data-uri

转化资源地址

data-uri('../data/image.jpg')

// 结果

url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg==')

// 在浏览器看到的结果为

url('../data/image.jpg')

还可以设置转化后的图片类型等参数

data-uri('image/jpeg;base64', '../data/image.jpg')
data-uri('image/svg+xml;charset=UTF-8', 'image.svg')

// 结果

url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg==')
url("data:image/svg+xml;charset=UTF-8,%3Csvg%3E%3Ccircle%20r%3D%229%22%2F%3E%3C%2Fsvg%3E")
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值