Fork me on GitHub

关于 Less 的一些理解

最近项目用到 less 来做 css 预处理器,之前公司项目是用的 sass,所以抽空针对 less,重新了解了一番。

1. Less 的由来

[Less 中文官方网站]:http://lesscss.cn/

官网:http://lesscss.org/

在 Web 发展的这几年,有了 webpack 来做构建,所以为了让 CSS 富有逻辑性,短板(在语法更新时,每当新属性提出,浏览器的兼容又会马上变成绊脚石)不那么严重,涌现出了一些神奇的预处理语言。 它们让 CSS 彻底变成一门可以使用变量、循环、继承、自定义方法等多种特性的标记语言,逻辑性得以大大增强。

其中 常见的有三种:Sass、Less 、Stylus 。

  • Sass 诞生于 2007 年,Ruby 编写,其语法功能都十分全面,可以说 它完全把 CSS 变成了一门编程语言。另外 在国内外都很受欢迎,并-且它的项目团队很是强大 ,是一款十分优秀的预处理语言。
  • Stylus 诞生于 2010 年,来自 Node.js 社区,语法功能也和 Sass 不相伯仲,是一门十分独特的创新型语言。
  • Less 诞生于 2009 年,受 Sass 的影响创建的一个开源项目。 它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护、方便制作主题、扩充(引用于官网)。

如何选择?

这个问题其实不重要,主要看你们项目和团队的情况,如果你们团队成员都喜欢用 less, 那便选择它就行啦。

2. 如何使用

常见的有两种方式:

  • 在页面中 引入 Less.js,可在官网下载,或使用 CDN
1
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js"></script>
  • 在命令行 使用 npm 安装
1
# npm install -g less

使用命令

1
# lessc styles.less > styles.css

如果你使用了 webpack,那么你需要配合 less-loader 进行处理(这个网上很多文章有介绍)

3. Less 常用功能特性

3.1 变量

我们常常在 CSS 中 看到同一个值重复多次,这样难易于代码维护。

  • 值变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 以 @ 开头 定义变量
@color: #999;
@bgColor: red;
@width: 50%;
#wrap {
color: @color;
width: @width;
}

/* 生成后的 CSS */
#wrap {
color: #999;
width: 50%;
}

通常我们在实际项目中会把变量定义存到到一个文件,方便维护。

  • 选择器变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* Less */
@mySelector: #wrap;
@Wrap: wrap;
@{mySelector} { // 变量名 必须使用大括号包裹
color: #999;
width: 50%;
}
.@{Wrap} {
color:#ccc;
}
#@{Wrap} {
color:#666;
}

/* 生成的 CSS */
#wrap{
color: #999;
width: 50%;
}
.wrap{
color:#ccc;
}
#wrap{
color:#666;
}
  • 属性变量
1
2
3
4
5
6
7
8
9
10
11
/* Less */
@borderStyle: border-style;
@Soild: solid;
#wrap{
@{borderStyle}: @Soild; // 变量名 必须使用大括号包裹
}

/* 生成的 CSS */
#wrap{
border-style: solid;
}
  • url 变量
1
2
3
4
5
6
7
8
9
10
/* Less */
@images: "../img"; // 需要加引号
body {
background: url("@{images}/dog.png");//变量名 必须使用大括号包裹
}

/* 生成的 CSS */
body {
background: url("../img/dog.png");
}
  • 声明变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Less */
@background: {background:red;};
#main{
@background();
}
@Rules:{
width: 200px;
height: 200px;
border: solid 1px red;
};
#con{
@Rules();
}

/* 生成的 CSS */
#main{
background:red;
}
#con{
width: 200px;
height: 200px;
border: solid 1px red;
}
  • 变量运算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* Less */
@width: 300px;
@color: #222;
#wrap{
width: @width-20;
height: @width- 20 * 5;
margin:(@width - 20) * 5;
color: @color * 2;
background-color: @color + #111;
}

/* 生成的 CSS */
#wrap{
width: 280px;
height: 200px;
margin: 1400px;
color: #444;
background-color: #333;
}
  • 变量作用域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* Less */
@var: @a;
@a: 100%;
#wrap {
width: @var;
@a: 9%;
}

/* 生成的 CSS */
#wrap {
width: 9%;
}

// ================================

/* Less */
@fnord: "I am fnord.";
@var: "fnord";
#wrap::after{
content: @@var; //将@var替换为其值 content:@fnord;
}

/* 生成的 CSS */
#wrap::after{
content: "I am fnord.";
}

3.2 嵌套

  • & 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Less */
#header {
&:after {
content:"Less is more!";
}
.title {
font-weight: bold;
}
&_content {
margin:20px;
}
}

/* 生成的 CSS */
#header::after {
content:"Less is more!";
}
#header .title {
font-weight:bold;
}
#header_content {
margin:20px;
}
  • 媒体查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Less */
#main{
@media screen{
@media (max-width: 768px){
width:100px;
}
}
@media tv {
width:2000px;
}
}

/* 生成的 CSS */
@media screen and (max-width:768px){
#main{
width:100px;
}
}
@media tv{
#main{
width:2000px;
}
}

3.3 混合方法

  • 无参数方法
1
2
3
4
5
6
7
8
9
10
11
12
/* Less */
.card { // 等价于 .card()
background: #fff;
}
#wrap {
.card; // 等价于 .card();
}

/* 生成的 CSS */
#wrap {
background: #fff;
}
  • 默认参数方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* Less */
.border(@a:10px,@b:50px,@c:30px,@color:#000){
border:solid 1px @color;
box-shadow: @arguments; // 指代的是 全部参数
}
#main{
.border(0px,5px,30px,red);
}
#wrap{
.border(0px);
}
#content{
.border;//等价于 .border()
}

/* 生成的 CSS */
#main{
border:solid 1px red;
box-shadow:0px,5px,30px,red;
}
#wrap{
border:solid 1px #000;
box-shadow: 0px 50px 30px #000;
}
#content{
border:solid 1px #000;
box-shadow: 10px 50px 30px #000;
}
  • 条件筛选 when
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* Less */
#card{
// and 运算符 ,相当于 与运算 &&,必须条件全部符合才会执行
.border(@width,@color,@style) when (@width>100px) and(@color=#999){
border:@style @color @width;
}

// not 运算符,相当于 非运算 !,条件为 不符合才会执行
.background(@color) when not (@color>=#222){
background:@color;
}

// , 逗号分隔符:相当于 或运算 ||,只要有一个符合条件就会执行
.font(@size:20px) when (@size>50px) , (@size<100px){
font-size: @size;
}
}
#main{
#card>.border(200px,#999,solid);
#card .background(#111);
#card > .font(40px);
}

/* 生成后的 CSS */
#main{
border:solid #999 200px;
background:#111;
font-size:40px;
}
  • 数量不定的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Less */
.boxShadow(...){
box-shadow: @arguments;
}
.textShadow(@a,...){
text-shadow: @arguments;
}
#main{
.boxShadow(1px,4px,30px,red);
.textShadow(1px,4px,30px,red);
}

/* 生成后的 CSS */
#main{
box-shadow: 1px 4px 30px red;
text-shadow: 1px 4px 30px red;
}
  • !important 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* Less */
.border{
border: solid 1px red;
margin: 50px;
}
#main{
.border() !important;
}

/* 生成后的 CSS */
#main {
border: solid 1px red !important;
margin: 50px !important;
}
  • 属性拼接方法

+_ 代表的是 空格;+ 代表的是 逗号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/* Less */
.boxShadow() {
box-shadow+: inset 0 0 10px #555;
}
.main {
.boxShadow();
box-shadow+: 0 0 20px black;
}

/* 生成后的 CSS */
.main {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}

// ===================================

/* Less */
.Animation() {
transform+_: scale(2);
}
.main {
.Animation();
transform+_: rotate(15deg);
}

/* 生成的 CSS */
.main {
transform: scale(2) rotate(15deg);
}

// =====================================

/* Less */
.average(@x, @y) {
@average: ((@x + @y) / 2);
}

div {
.average(16px, 50px); // 调用 方法
padding: @average; // 使用返回值
}

/* 生成的 CSS */
div {
padding: 33px;
}

3.4 继承

  • extend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Less */
.animation{
transition: all .3s ease-out;
.hide{
transform:scale(0);
}
}
#main{
&:extend(.animation);
}
#con{
&:extend(.animation .hide);
}

/* 生成后的 CSS */
.animation, #main{
transition: all .3s ease-out;
}
.animation .hide , #con{
transform:scale(0);
}
  • all 全局继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* Less */
#main {
width: 200px;
}
#main {
&:after {
content:"Less is good!";
}
}
#wrap:extend(#main all) {}

/* 生成的 CSS */
#main,#wrap {
width: 200px;
}
#main:after, #wrap:after {
content: "Less is good!";
}

3.5 导入

  • @import

3.6 函数

1
2
3
isnumber(#ff0);     // false

saturate(hsl(90, 80%, 50%), 20%) // #80ff00 // hsl(90, 100%, 50%)

查看更多函数链接

-------------本文结束感谢您的阅读-------------