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下载对应的编译插件
每次保存less文件时就可以自动编译出css文件
2 less语法
2.1 注释
less有两种注释
常规的css注释
/* 可见注释,会被编译到css文件中 */
编译后不可见注释
// 不可见注释,不会被编译到css文件中
2.2 变量
使用@
符号声明变量,样式中可以引用,less的变量都是块级作用域,直接上代码,一目了然
less块级作用域:首先在本地查找变量和混合(mixins),如果找不到,则从“父”级作用域继承
@width: 10px;
@height: @width + 10px;
.box {
width: @width;
height: @height;
}
编译结果为
属性名和选择器也可以用变量,但是在引用的时候需要用 {}
包裹起来,上代码
@width: 10px;
@height: @width + 10px;
@m: margin;
@selector: #nav;
.box {
@{m}: 10px;
width: @width;
height: @height;
}
@{selector} {
color: red;
}
来看下编译后的,属性和选择器引用很少使用
变量延迟加载
.over {
@var: 1;
.three {
@var: 2;
three: @var;
@var: 3;
}
one: @var;
}
one属性是在over作用域中的,跟brass无关,所以one的值是1;在brass作用域中,要等变量先加载完再引用,这就是延迟加载,所以three的值是3
2.3 嵌套
前面的代码已经能够体现嵌套规则了,可以根据HTML的层级关系来嵌套css样式,伪类选择器也是可以嵌套的
.box {
width: @width;
height: @height;
background-color: pink;
:hover {
background-color: deeppink;
}
}
编译结果是这样的
注意这里多了一个空格,这样是不生效的,那怎么样去掉这个空格呢,使用&
取消父子关系,让两个类挨在一起
.box {
width: @width;
height: @height;
background-color: pink;
&:hover {
background-color: deeppink;
}
}
再来看结果
空格没了
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会编译到最外层
2.4 混合
2.4.1 混合
混合就是将一系列属性从一个规则集引用到另一个规则集的方式,简单来说已定义的类可以在另一个类中进行引用
.border {
border-bottom: solid 2px #000;
}
.border-2 {
.border();
color: red;
}
结果
引用混合的时候,混合没有参数时,括号可以加也可以不加;混合需要使用默认参数时,括号必须加
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的时候将参数填入,然后进行编译
可以设置参数的默认值,可以传递命名参数
.bar(@w: 10px, @h:10px, @color:green) {
width: @w;
height: @h;
color: @color;
}
.nav-bar {
.bar(@color: #409eff);
}
结果
当引用混合的时候不加任何参数就会全部使用默认值
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);
}
匹配效果如图
注意代码开始的地方
.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();
}
结果如图
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会自动计算结果
使用转义来避免自动编译
.no {
height: ~"100 + 20px";
}
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类将会变成两个类公共部分,用逗号连接