相信前端开发人员对与CSS(Cascading Style Sheet-级联样式表)这种「面向命名语言」,一定非常熟悉。你可能在某个舍友熟睡的深夜,还在电脑面前被 css 繁重、冗杂的样式,折磨的死去活来。
我们曾经面对 css 很多令人发指的不友好特性,也因为 css 的低复用性而刀耕火种。
css 预处理器就是这样被创造出来,弥补了直接写 css 的一些缺憾:
CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-okzXIxnY-1669359456806)(.\img\02.png)]
直接引用(不推荐)
在引入之前,我们需要创建一个 Less 文件,Less 文件的后缀名为 .less
,所以我们可以将文件命名为 index.less
。
然后我们就可以通过 <link>
标签向 HTML 页面中引入 index.less
文件,和引入 CSS 文件类似,但是需要将 type
属性的值修改为 text/less
<link rel="stylesheet/less" type="text/less" href="./index.less" />
然后下载使用官方提供的 CDN 进行脚本引入
<script src="https://cdn.bootcdn.net/ajax/libs/less.js/3.13.0/less.js"></script>
通过NPM安装(不推荐)
vscode安装(推荐)
Easy LESS
插件引入js的方式
less
body {
background-color: red;
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.less" type="text/less">
<style type="text/less">
#box{
width: 100px;
height: 100px;
background-color: pink;
.con{
width: 50px;
height: 50px;
background-color: green;
}
}
</style>
</head>
<body>
<div id="box">
<div class="con"></div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/less.js/3.13.0/less.js"></script>
</body>
</html>
vsCode使用的方式
less
body{
background-color: aquamarine;
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="./Untitled-1.css">
</head>
<body>
</body>
</html>
注释的适当使用可以保证代码的可读性,Less 支持两种类型的注释:多行注释和单行注释
注释使代码清晰,并允许用户轻松地理解。 您可以在代码中使用块样式和行内注释,但是当编译LESS代码时,单行注释不会显示在CSS文件中
#box{
// 这是一个隐藏的注释
width: 200px;
height: 200px;
background-color: aquamarine;
/**
font-size: 100px;
我是一个可以显示的注释
**/
}
#box {
width: 200px;
height: 200px;
background-color: aquamarine;
/**
font-size: 100px;
我是一个可以显示的注释
**/
}
多次重复相同的值,通常在您的样式表中可看到。不用多次使用相同的值,可以使用变量。它使代码的维护更容易,并且可以从单个位置控制这些值。
观察代码有什么问题:
#outer {
width: 300px;
height: 300px;
background-color: aqua;
margin: auto;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
@v:0;
#outer {
width: 300px;
height: 300px;
background-color: aqua;
margin: auto;
position: absolute;
left: @v;
top: @v;
bottom: @v;
right: @v;
}
@bg : background;
#outer {
width: 300px;
height: 300px;
@{bg}: aqua;
margin: auto;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
@o:#outer;
@{o} {
width: 300px;
height: 300px;
background-color: aqua;
margin: auto;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
@img1:'https://img2.baidu.com/it/u=2238622225,3486857165&fm=11&fmt=auto&gp=0.jpg';
@img2:url('https://img2.baidu.com/it/u=2238622225,3486857165&fm=11&fmt=auto&gp=0.jpg');
@img3:@img2;
#outer {
width: 300px;
height: 300px;
background-color: aqua;
margin: auto;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
// background:url(@img1) 0 0 no-repeat;
// background: @img2 0 0 no-repeat;
background: @img3 0 0 no-repeat;
}
@v:0;
@z:@v + 2;
#outer {
width: 300px;
height: 300px;
background-color: aqua;
margin: auto;
position: absolute;
left: @v;
top: @v;
bottom: @v;
right: @z;
}
@var: 0;
.class {
@var: 1;
.brass {
@var: 2;
//less变量延迟加载,也就是等待当前样式所在区域的代码全部执行完毕,才进行加载变量
three: @var;
@var: 3;
}
one: @var;
}
在使用标准CSS时,要为多层嵌套的元素定义样式,要么使用后代选择器从外到内的嵌套定义,要么给这个元素加上类名或 id 来定义。这样的写法虽然很好理解,但维护起来很不方便,因为无法清晰了解到样式之间的关系。
在Less中,嵌套规则使这个问题迎刃而解。嵌套规则允许在一个选择器中嵌套另一个选择器,这更容易设计出精简的代码,并且样式之间的关系一目了然。
body{
background-color: red;
.outer{
width: 1200px;
border: 1px solid black;
.header{
height: 100px;
background-color: yellow;
}
.con{
margin: 0 auto;
border: 1px solid green;
}
.footer{
width: 1200px;
box-shadow: 0px 0px 0px 0px #ccc;
}
}
}
使用&:代表前边的所有父级元素,常用在伪元素 伪类 css结构类等需求上
内层选择器前面的 & 符号就表示对父选择器的引用。在一个内层选择器的前面,如果没有 & 符号,则它被解析为父选择器的后代;如果有 & 符号,它就被解析为父元素
ul{
li{
line-height: 40px;
&:nth-child(1){
line-height: 80px;
}
}
li:nth-child(1){
line-height: 80px;
}
}
div{
height: 100px;
&>span{
width: 100px;
&>nav{
background-color: red;
}
}
}
运算类型:任何数值,颜色,变量都可以运算
单位:less会给你自动推算单位,所以不需要每一个都加单位,但保证至少有一个加了单位
注意:运算符与数值之间要以空格分开,涉及优先级时以()进行优先级计算
header{
width: 100px + 10;
height: 20 + 10px;
// height: 20 - 10px;
// height: 20 * 10px;
// 注意除法必须加()
// less中做算术运算的时候一般加法+,减法-,乘法*
// 可以直接写基本不会出现什么问题但是除法/需要()括起来,
// 不然会认为你的是有两个值 值一 / 值二,不会进行计算返回计算结果
// height: (20 / 10px);
}
思考:如果两个数值都有单位,那么会返回什么单位
header{
width: 100px + 10;
height: 20rem + 10px;
}
注意:单位加在哪里都行,只要有一个地方有单位,less就能推断出计算后结果的单位。
规则: less在运算时,先将颜色值转化为rgba模式,然后再转换为16进制的颜色值并返回
注意1 : 在颜色运算时,能直接使用颜色的名称如green进行运算,比如 red - 55 = #c80000,但是在之前这个功能无效
注意2 : 实际上是拆分之后再转化成16进制的 #ffffff - 55 = c8c8c8 = rgb(200,200,200),拆成两个一个,分别代表r,g,b
注意3 : 加的值超过255,只会取到255 #111111 + 260 = #ffffff
注意4 : rgb模式的取值为 0~255
header {
color: #fff;
color: #f5f5f5;
background-color: #c80000;
background-color: #ffffff;
background-color: #373737;
}
@w:20px;
header{
width: @w + 2;
}
混合是一种将一组属性从一个规则集包含或混入到另一个规则集的方法。简单一点来说,其实混合就有点类似编程语言中的函数,通过这种方式,可以在代码中实现复用。
.s1{
font-size: 10px;
color: #ccc;
}
.s2{
font-size: 10px;
color: #ccc;
padding: 10px;
}
可以很明显的看到,.s1
样式类中的代码,.s2
样式类中也有,这里是只有两个样式类,如果有很多个选择器时,是不是就会造成很多重复的代码
混合 Mixin
就可以帮助我们来解决这个问题,实现代码的复用。使用起来也很简单,只需要在 .s2
中引用 .s1
即可
.s1 {
font-size: 14px;
color: #ccc;
}
.s2 {
.s1;//注意没有加();
padding: 10px;
}
思考:如果有很多的选择器都有类似样式,那么上面这种方式的缺点?
我们可以看到在编译时, .s1
和 .s2
两个样式类都被编译成了 CSS 代码,但是某些时候有可能这有可能造成重复,所以我们可能不希望 .s1
样式类本身被编译到 CSS 文件中
.s1(){
font-size: 14px;
color: #ccc;
}
.s2{
.s1();
padding: 10px;
}
在声明混合的时候,可以在小括号中声明形参。形参由@+变量名定义。调用的时候可以传入实参
如果很多的位置都需要使用某一个Mixins,而且参数还不一样的话,那么就可以使用参数的Mixins
.s1(@f,@c){
font-size: @f;
color: @c;
}
.s2{
.s1(14px,red);
padding: 10px;
}
思考:如果有屌丝不想按照顺序传递参数,咋办?
可以直接在混合中定义形参的时候,给形参设置默认值,比如(@color:red),当使用混合的时候,如果有实参传递,则使用实参的值,否则使用形参的默认值
.s1(@f:10px,@c:red){
font-size: @f;
color: @c;
}
.s2{
.s1();
padding: 10px;
}
Less 中也有命名空间的概念,命名空间用于在通用名称下对 Mixins 进行分组,使用命名空间可以避免名称冲突,并从外部封装 Mixins 组。例如可以将类选择器或者ID选择器作为一个命名空间,然后将 Mixins 放在命名空间中,这样可以避免与引入的其他文件造成冲突
.name_space{
.s1(){
font-size: 12px;
}
}
.s2{
// .name_space > .s1(); // 引用 以下哪种方式都可以
// .name_space.s1;
// .name_space.s1();
// .name_space .s1;
.name_space .s1();
}
!important
关键字用于覆盖特定属性。如果我们在 Mixins 引用后面加上 !important
关键字,则会将 Mixins 中的所有属性标记为 !important
。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>important关键字</title>
<link rel="styleSheet" type="text/css" href="./index.css">
</head>
<body>
<h1>welcome to red romance!</h1>
</body>
</html>
less
.mixin(){
color: red;
}
h1{
color: #ccc;
.mixin() !important;
}
在Less中尝试利用模式匹配替if/else,其执行原理类似switch/case。
因为一个混合可能有多种形式,所以Less提供了一种机制,允许根据参数的值来改变 mixin的行为。
其中当参数是@_开头的,是调用此混合必选的。
//模式匹配中,公有的样式混合 需要书写@_做为参数
.main(@_) {
width: 100px;
height: 100px;
}
.main(color1) {
background-color: pink;
}
.main(color2) {
background-color: yellow;
}
.outer {
.main(color1)
}
相同的混合,不同的行为,可以根据调用的时候传入的实参个数选择匹配的混合内容
.main(@w) {
width: @w;
}
.main(@w, @h) {
width: @w;
height: @h;
}
.outer {
//重载:根据参数个数不同,来匹配不同的混合
.main(100px, 100px)
}
根据判断条件选中Mixin的行为
类似于JavaScript的if/else,使用when语法
Guards 允许我们使用>,>=,<,<=,=,关键字true(只匹配关键字true,非true不会匹配),支持逻辑and ,not ()
同时我们可以使用“,”分割多个Guards,其表示只要其中任意一个满足就为true
案例1:
.main(@a) when(@a>30) {
width: 100px;
height: 100px;
}
.main(@a) when(@a<=30) {
width: 200px;
height: 200px;
}
.outer {
.main(30)
}
案例2:
.main(@w) when(@w>1000),(@w<200) {
width:~"@{w}px";
height: 100px;
}
.main(@w) when(@w<=1000) and (@w>=200) {
width:~"@{w}px";
height: 50px;
}
.outer {
.main(3000)
}
变量可以用类似ruby和php的方式嵌入到字符串中,通过**@{name}**这样的结构:
@h: 30;
@baseUrl: "http://redromance.vip:6666/";
.outer {
//变量加单位,字符串拼接 再转义
//@{h}在字符串中书写变量
//~转义 把字符串转成css可用代码
height:~"@{h}px";
//字符串插值
background: url("@{baseUrl}01.png")
}
.con {
background: url("@{baseUrl}02.png")
}
@import 'test1';
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <link rel="stylesheet" href="./01.css"> -->
<style>
@import "./01.css";
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>
css
div {
width: 200px;
height: 200px;
background-color: red;
}
参考文献:https://less.bootcss.com/functions/#less-%E5%87%BD%E6%95%B0
逻辑函数
if
@c: boo;
div {
margin: if((2 > 1), 1, 0);
color: if((iscolor(@c)), @c, black);
}
boolean
@c: boolean(2<1);
div {
margin: if(@c, 1, 0);
}
列表函数
length
p{
@list: "banana", "tomato", "potato", "peach";
n: length(@list);
}
extract
div{
@list: apple, pear, coconut, orange;
value: extract(@list, 3);
}
range
div{
value: range(4);
}
数学函数
ceil
ceil(2.4)
floor
floor(2.6)
percentage
percentage(0.5)
round
round(1.67, 1)
sqrt
sqrt(324)
abs
abs(-18)
pow
pow(5, 2);
mod
mod(10,6)
min
min(1,2,3,4,5)
max
max(1,2,3,4,5)
颜色调试
div{
v:hsl(90, 80%, 50%);
value: desaturate(hsl(90, 80%, 50%), 20%);
}