less预编译

1 初见less

less是一门向后兼容的 CSS 扩展语言。

HTML标签不能直接识别less样式,需要引入less.js来编译

引入样式文件

<link rel="stylesheet/less" type="text/css" href="styles.less" />

引入编译脚本

<script src="less.js" type="text/javascript"></script>

但是,这种方式是运行时编译,不是预编译,在VSCode插件商店中搜索less下载对应的编译插件

image-20200802101317365

每次保存less文件时就可以自动编译出css文件

2 less语法

2.1 注释

less有两种注释

  • 常规的css注释

    /* 可见注释,会被编译到css文件中 */
    
  • 编译后不可见注释

    // 不可见注释,不会被编译到css文件中
    

image-20200802101850122

2.2 变量

使用@符号声明变量,样式中可以引用,less的变量都是块级作用域,直接上代码,一目了然

less块级作用域:首先在本地查找变量和混合(mixins),如果找不到,则从“父”级作用域继承

@width: 10px;
@height: @width + 10px;

.box {
    width: @width;
    height: @height;
}

编译结果为

image-20200802102414254

属性名和选择器也可以用变量,但是在引用的时候需要用 {}包裹起来,上代码

@width: 10px;
@height: @width + 10px;
@m: margin;
@selector: #nav;

.box {
    @{m}: 10px;
    width: @width;
    height: @height;
}
@{selector} {
    color: red;
}

来看下编译后的,属性和选择器引用很少使用

image-20200802103306532

变量延迟加载

.over {
    @var: 1;
    .three {
        @var: 2;
        three: @var;
        @var: 3;
    }
    one: @var;
}

one属性是在over作用域中的,跟brass无关,所以one的值是1;在brass作用域中,要等变量先加载完再引用,这就是延迟加载,所以three的值是3

image-20200802104154490

2.3 嵌套

前面的代码已经能够体现嵌套规则了,可以根据HTML的层级关系来嵌套css样式,伪类选择器也是可以嵌套的

.box {
    width: @width;
    height: @height;
    background-color: pink;
    :hover {
        background-color: deeppink;
    }
}

编译结果是这样的

image-20200802112646945

注意这里多了一个空格,这样是不生效的,那怎么样去掉这个空格呢,使用&取消父子关系,让两个类挨在一起

.box {
    width: @width;
    height: @height;
    background-color: pink;
    &:hover {
        background-color: deeppink;
    }
}

再来看结果

image-20200802112826627

空格没了

2.3.1 @嵌套和冒泡

@ 规则(例如 @media@supports)可以与选择器以相同的方式进行嵌套。@ 规则会被放在前面,同一规则集中的其它元素的相对顺序保持不变

例如

.component {
    width: 600px;
    @media (min-width: 768px) {
        width: 300px;
        @media (min-resolution: 192dpi) {
            background-image: url(/img/retina2x.png);
        }
    }
    @media (min-width: 1280px) {
        width: 800px;
    }
}

这段代码在component类中嵌套了三个媒体查询,编译之后media会编译到最外层

image-20200802114843175

2.4 混合

2.4.1 混合

混合就是将一系列属性从一个规则集引用到另一个规则集的方式,简单来说已定义的类可以在另一个类中进行引用

.border {
    border-bottom: solid 2px #000;
}
.border-2 {
    .border();
    color: red;
}

结果

image-20200802114037991

引用混合的时候,混合没有参数时,括号可以加也可以不加;混合需要使用默认参数时,括号必须加

2.4.2 不编译的混合

如果只想定义一个混合,在选择其后面加一个括号,那么这个混合不会被编译

.border() {
    border-bottom: solid 2px #000;
}
.border-2 {
    .border();
    color: red;
}

编译结果只有.border-2这个类

2.4.3 带参数的混合

类似于js定义方法一样接收参数,然后进行编译(但是,他不叫函数,叫混合

.bar(@w, @h, @color) {
    width: @w;
    height: @h;
    color: @color;
}

.nav-bar {
    .bar(100px, 200px, #409eff);
}

在引用bar的时候将参数填入,然后进行编译

image-20200802121333778

可以设置参数的默认值,可以传递命名参数

.bar(@w: 10px, @h:10px, @color:green) {
    width: @w;
    height: @h;
    color: @color;
}

.nav-bar {
    .bar(@color: #409eff);
}

结果

image-20200802123431310

当引用混合的时候不加任何参数就会全部使用默认值

2.4.4 匹配模式

根据标识匹配混合,下面定义了4种样式,分别是上右下左边框

.border-style(@_, @w, @h, @c) {
    border-style: solid;
}
.border-style(T, @w, @h, @c) {
    width: @w;
    height: @h;
    border-color: @c transparent transparent transparent;
}
.border-style(R, @w, @h, @c) {
    width: @w;
    height: @h;
    border-color: transparent @c transparent transparent;
}
.border-style(B, @w, @h, @c) {
    width: @w;
    height: @h;
    border-color: transparent transparent @c transparent;
}
.border-style(L, @w, @h, @c) {
    width: @w;
    height: @h;
    border-color: transparent transparent transparent @c;
}

.border-3 {
    .border-style(B, 100px, 100px, #000);
}

匹配效果如图

image-20200802130704309

注意代码开始的地方

.border-style(@_, @w, @h, @c) {
    border-style: solid;
}

这一段,@_用来匹配L、R、B、T标识,每次使用匹配模式时自动带上这段公共代码

2.4.5 @arguments

@arguments包含传进来的所有参数

.border_arg(@w:30px,@c:red,@sty:solid){
    border:@arguments;
}
 
.test_arguments{
    .border_arg();
}

结果如图

image-20200802132730158

2.5 运算

算术运算符 +-*/ 可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换

@color: #224488 / 2; //结果是 #112244
background-color: #112244 + #111; // 结果是 #223355,#111->#111111

2.6 转义

当需要引入无效的CSS语法或Less不能识别的字符,就需要使用转义字符,在字符串前面加一个 ~,并将需要转义的字符串放在 “” 中

@min768: ~"(min-width: 768px)";
.element {
    @media @min768 {
        color: pink;
    }
}

// 结果
@media (min-width: 768px) {
  .element {
    color: pink;
  }
}

使用计算的时候less会自动计算结果

image-20220727140311733

使用转义来避免自动编译

.no {
    height: ~"100 + 20px";
}

image-20220727140406165

2.7 映射

Less 3.5 版本开始,可以将混合和规则集作为一组值的映射(map)使用

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

.button {
  color: #colors[primary];
  border: 1px solid #colors[secondary];
}
// 结果
.button {
  color: blue;
  border: 1px solid green;
}

2.8 导入

less文件导入可以省略后缀名

@import "main"; // mian.less
@import "style.css";

2.9 继承

使用extend函数继承一个类

.middle {
    margin: 0 auto;
}
.footer:extend(.middle) {
    color: pink;
}

编译之后的middle类将会变成两个类公共部分,用逗号连接

image-20200802135813855


前端小白