[TOC]
## 开发环境与生产环境
LESS叫做预编译语言,写好的LESS代码,浏览器时不能直接渲染的,需要我们把它编译成为能渲染的CSS才可以
>开发环境
>在本地开发中,这是开发环境
>生产环境
>本地开发完成了,我们需要把代码上传到服务器上,服务器上的环境叫做生成环境
## 使用less的几种方式
### 法一:下载less.js
![](https://img.kancloud.cn/c0/ab/c0abc8f16f460b244fb95f51a5b1e2e1_257x241.png)
会自动将.less文件转译成css并插入到动态生成的style标签中
![](https://img.kancloud.cn/ee/e6/eee6bc09a8e621009ce069fe99e32f32_596x265.png)
![](https://img.kancloud.cn/d8/df/d8dfd0cffeaaae07c4188a5b41c8515e_630x140.png)
在开发环境下,我们一般都通过导入LESS插件(less-2.5.3.min.js)来随时编译LESS开发
```
<!--rel的值变为了stylesheet/less-->
<link rel='stylesheet/less' href='css/1.less'>
<script src="js/less=2.5.min.js"></script>
```
由于每一次加载页面,都需要导入less.js,并且把less文件重新编译为css(很消耗性能,页面打开速度肯定会变慢),所以真实项目中,只有开发环境下,我们使用这中模式,生产环境下,我们肯定需要首先把写好的LESS编译为正常的css后再上线,以后用户访问的都是编译好的css,而不是拿less先编译
### 法二:node中使用
#### 下载包
![](https://img.kancloud.cn/4d/2f/4d2f26a5a4126a01c011c17423f8ebdf_717x164.png)
#### 手动编译
![](https://img.kancloud.cn/fa/d8/fad8c507005290f6c75b1c186716e657_560x96.png)
![](https://img.kancloud.cn/47/75/477578d4bdfae0e82878ea765f8d8f80_296x194.png)
#### 集成webpack
略
#### webstorm配置编译
![](https://img.kancloud.cn/00/d0/00d0470e5f7e692797bbd124570347d1_326x136.png)
![](https://img.kancloud.cn/68/f7/68f7eae40650aed1d3a0bde1c081cca2_750x213.png)
![](https://img.kancloud.cn/03/4f/034fa6eb126bc27231873c30e4d78050_296x71.png)
![](https://img.kancloud.cn/e5/95/e595f5642cfe6ed61934e05924dc8584_461x266.png)
## LESS作用
CSS层叠样式表,它是标记语言,不是编程语言,所有预编译CSS语言(less/sass...)都是赋予了CSS面向对象思想
```
.outer{
margin:50px;
width:200px;
height:200px;
border:1px solid green;
}
.outer .inner{
margin:20px;
width:100px;
height:100px;
background:lightblue;
// 第三个擦书为模糊半径 第四个参为扩展半径
box-shadow: 0 0 5px 0 #000;
transition:.5s
}
.outer:hover .inner{
box-shadow: 0 0 10px 0 #999;
-webkit-transfor:rotate(360deg);
...
transform:rotate(360deg);
}
```
So传统的css 整个css的书写层级是从网下的 并且有些需要兼容的需要手动添加前缀
![](https://img.kancloud.cn/65/02/6502d3fd1c1c123b565bb39e0e09d388_330x136.png)
![](https://img.kancloud.cn/5d/2c/5d2ce996ddf7bf2b91c16c0d628aae90_526x360.png)
![](https://img.kancloud.cn/ca/cb/cacb96d050d1befe25a2895d1a62e060_436x94.png)
## 语法
### 嵌套
```
li{
a.link{
&:hover{}
}
}
```
### 变量
在浏览器总引入`less.js`的情况可以这样获取文档高度
```
@height:`document.documentElement.clientHeight`;
```
@可以支持传统css中支持能够支持的任何值
```
@a:1;
@b:30%;
@c:1000px;
@d:#000;
```
```
@width:2px;
@style:solid; //带引号的话会把引号也传入到border中
@color:red;
.box1{
width:300px;
height:100px;
border:@width @style @color;
}
```
变量名允许带`-`
```
@shadow-color:red;
```
@可以参与运算
```
@a:1;
.box{
opacity:@a;
filter:alpha(opacity=(@a*100));
}
```
变量名带`-`的变量参与运算时,需要使用括号括起来
```
@shadow-px:100;
@new:(@shadow-px)-20;
```
地址与变量
`@{}`插值表达式,可以将变量插入到要拼接的字符串中
```
.box{
background:url("../img/xxx.png");
}
@img-url:"../img/";
.box{
background:url("@{img-url}/xxx.png");
}
```
选择器与变量
```
@selector:box;
.@{selector}{
}
```
![](https://img.kancloud.cn/7f/b3/7fb330182602e77cdb0cee7457b804ea_755x502.png)
@@var
```
@var:"name"
@name:"ahhh"
@@var; //->@name
```
### 连字符
`&`代表当前作用域中的css选择器
```
&.pp{}
&>.mm{}
```
### 作用域
```
.box{
@a:10px; //这里的@a只在这大括号中起作用
}
```
### 混合(@Mixin)
#### 最简单的混合
```
@border:'border:1px solid #b7b7b7';
.box{
width:@border; //-->width:'border:1px solid #b7b7b7' //不符合要求
}
//--- --- ---
.classa{
border:1px solid #b7b7b7;
}
.classb{
.classa; //最最简单的混合方式
}
//--- --- ---
```
![](https://img.kancloud.cn/bb/ae/bbae61e574b800b0e63c580d634bae89_556x777.png)
#### 带参数混合
```
//带参数混合
.border{
border:1px solid #b7b7b7;
}
.borderRed{
border:1px solid #f00;
}
//---
.border(@width:1px,@color:#333){ //支持默认参数
border:@width solid @color;
}
.box1{
.border(2px,#b7b7b7);
}
```
#### arguments
#### 模式匹配
```
.border(top,@width){
border-top:@width solid #333
}
.border(right,@width){
border-right:@width solid #333
}
.border(@_){ //默认匹配 //全部都需要的写在这里
width:100px;
}
.box1{
.border(top);
}
.box2{
.border(right);
}
```
![](https://img.kancloud.cn/ad/b0/adb0cd1421154ec6c064f31cd931e9b6_678x427.png)
### 注释
```
//注释点什么1 // 此种注释不会被编译进css里 通常用于开发环境的注释
/* 注视点什么2 */
```
### 函数
#### 数学函数
round
```
width:round(5.5)*1px; //6px
```
ceil
floor
percentage
round
sqrt:计算数字的平方根
abs:计算数字的绝对值,原样保持单位
pow:计算一个数的乘方
#### isnumber
判断给定的值 是否 是一个数字。
```
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
```
#### iscolor
#### isur
#### 颜色操作
saturate:增加一定数值的颜色饱和度
lighten:增加一定数值的颜色亮度
darken:降低一定数值的颜色亮度
fade:给颜色设定一个数值的透明度
mix:根据比例混合两种颜色
#### 更多
[点击查看更多](http://lesscss.cn/functions/)
### 命名空间和作用域
less中的变量声明和提升都会执行
```
@a:10;
.box{
width:unit(@a,px);
@a:20;
.mark{
width:unit(@a,px);
}
}
```
```
.blue{
.button{
background:blue;
}
}
.red{
.button{
background:red;
}
}
.box{
.red > .button; //red里的button
}
```
### @import
```
>>> global.less
body{
margin:0;
}
a{
text-decoration:none;
color:inherit
}
//--- ---
>>> index
@import "global"
```
使用`@import`,那么编译以后的所有文件都会打包在一起(合并成一个css文件)
默认导入的就是.less,so不用添加后缀
![](https://img.kancloud.cn/ef/51/ef515764e085d415b2e98382da94714f_1249x144.png)
![](https://img.kancloud.cn/f7/65/f7653f6a11ef806ceb56588c5ac3ac25_611x274.png)
### ~避免编译
结构:` ~' 值 '`
![](https://img.kancloud.cn/8d/74/8d745ee3b03aaa73db7deaba788a586f_694x255.png)
```
/* Less */
#main{
width:~'calc(300px-30px)';
}
/* 生成后的 CSS */
#main{
width:calc(300px-30px);
}
```
## 属性变量 值变量 变量拼串 url变量 选择器变量 声明变量
https://juejin.im/post/5a2bc28f6fb9a044fe464b19#heading-6
### 值变量
```
/* Less */
@color: #999;
@bgColor: skyblue;//不要添加引号
@width: 50%;
#wrap {
color: @color;
background: @bgColor;
width: @width;
}
/* 生成后的 CSS */
#wrap {
color: #999;
background: skyblue;
width: 50%;
}
```
以 @ 开头 定义变量,并且使用时 直接 键入 @名称。
在平时工作中,我们就可以把 常用的变量 封装到一个文件中,这样利于代码组织维护。
```
@lightPrimaryColor: #c5cae9;
@textPrimaryColor: #fff;
@accentColor: rgb(99, 137, 185);
@primaryTextColor: #646464;
@secondaryTextColor: #000;
@dividerColor: #b6b6b6;
@borderColor: #dadada;
```
### 选择变量
让 选择器 变成 动态
```
/* 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;
}
```
### 属性变量
可减少代码书写量
```
/* Less */
@borderStyle: border-style;
@Soild:solid;
#wrap{
@{borderStyle}: @Soild;//变量名 必须使用大括号包裹
}
/* 生成的 CSS */
#wrap{
border-style:solid;
}
```
### url 变量
项目结构改变时,修改其变量即可。
```
/* Less */
@images: "../img";//需要加引号
body {
background: url("@{images}/dog.png");//变量名 必须使用大括号包裹
}
/* 生成的 CSS */
body {
background: url("../img/dog.png");
}
```
### 声明变量
有点类似于 下面的 混合方法
- 结构: @name: { 属性: 值 ;};
- 使用:@name();
等同于`.class1(){}`
```
/* 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;
}
```
### 变量运算
不得不提的是,Less 的变量运算完全超出我的期望,十分强大。
- 加减法时 以第一个数据的单位为基准
- 乘除法时 注意单位一定要统一
```
/* 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;
}
```
### 用变量去定义变量
```
/* Less */
@fnord: "I am fnord.";
@var: "fnord";
#wrap::after{
content: @@var; //将@var替换为其值 content:@fnord;
}
/* 生成的 CSS */
#wrap::after{
content: "I am fnord.";
}
```
## 继承与函数
### 继承
```
.pub{
width:100px;
height:100px;
background:green;
}
.box{
.pub;
background:red;
}
```
会发现在另外一个css类里调用一个css类的结果就是把原本的copy一份过来
![](https://img.kancloud.cn/68/e5/68e53291dcb2859f9008b3c1240f9087_195x176.png)
`extend`
less中的继承并不是copy代码,而是让当前的样式类和继承的样式类公用一套样式(编译为群组选择器的方式)
```
/* 第一种写法 */
.pub{
width:100px;
height:100px;
background:green;
}
.box:extend(.pub){
background:red;
}
/*****************/
/* 第二种写法 */
.box{
&:extend(.pub);
background:red;
}
```
![](https://img.kancloud.cn/e3/f6/e3f671369e2c204f4b78841db33874ce_259x162.png)
要继承多个的话可以用逗号分隔传参
```
.box:extend(.pub,.com){
}
```
![](https://img.kancloud.cn/11/f9/11f9262056b907020c67f07d6fa4eee6_277x198.png)
```
.box{
.mark{
width:100px;
height:100px;
}
.inner{
&:extend(.mark);
background:red;
}
}
```
![](https://img.kancloud.cn/4c/ab/4cab00ac907316f755ed789f5685c48b_226x140.png)
发现并没有其效果
原因是必须带上作用域
```
.box{
.mark{
width:100px;
height:100px;
}
.inner{
&:extend(.box .mark);
//.mark //或则直接copy过来
background:red;
}
}
```
真实项目中,如果想使用extend实现继承,我们一般都把需要继承的样式类写在最外层(而不是里层私有的作用域),如果想继承当前私有作用域中的某个样式,需要把前缀都准备好
### 函数
> 语法
> .xxx(@xxx:xxx,@yyy){
> @arguments
> }
再看这样一个栗子,给一个样式类加了`()`(那么这就是个函数)
```
.pub(){
width:100px;
height:100px;
background:green;
}
.box{
.pub();
background:red;
}
```
![](https://img.kancloud.cn/45/db/45dbc1dfeb19c068616315f79b2753ef_220x128.png)
可以发现函数本身是不会被编译的(So,它才叫函数嘛,执行才有效果)
`@argument`
```
.transition(property:all,@duration,@timing:linear,@delay:0s){
transition:@arguments;
//等同于
// transition:@property @duration @timing @delay;
}
```
`@result`
```
.sum(@n:0,@m:0){
@result:@n+@m;
}
.box{
.sum(10,20);
width:@result+'px';
}
```
![](https://img.kancloud.cn/b2/aa/b2aac045874abc81a6b68fd2a1b27941_201x67.png)
这个`@result`和常规return的区别在于,它其实是给result这个变量赋值,So这个函数并不需要一个变量来接收,它内部自己就创建了个,谁都可以用
上面的例子有个问题,最后输出的是`30 'px'`,我们希望是`30px`,可以用到`unit`方法
```
.box{
.sum(10,20);
width:unit(@result,px);
}
```
`unit`是less提供的方法
`unit([value],'px')`能给value值设置单位,如果之前已经有单位了,会把原先的单位去掉
## 流程控制(Mixin Guards)
`when`
```
.pub(@x) when(@x<=10){
width:100px;
height:100px;
}
.pub(@x) when(@x>10){
width:200px;
height:400px;
}
.box{
.pub(10);
}
```
- 满足多个条件那么都会执行(而不是只匹配一条)
`and/,`
```
.pub(@x) when(@x<=10) and (@a>0){
width:100px;
height:100px;
}
//and === ,
.pub(@x) when(@x<=10) , (@a>0){
width:100px;
height:100px;
}
```
![](https://img.kancloud.cn/7c/7a/7c7ac7f35ad059526d3cf7ee23e9b4db_459x273.png)
### 递归 实现 遍历
```
.columns(@i) when (@i<=4){
.box@{i}{
width:unit(@i*10,%);
}
.columns(@i+1);
}
.columns(1);
```
## 属性拼接:`+_`与`+`
+_ 代表的是 空格;+ 代表的是 逗号。
- 逗号
```
/* 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);
}
```
### 变量拼串
在平时工作中,这种需求 太常见了。 在下面例子中, 实现了不同的 transtion-delay、animation、@keyframes
结构: `~"字符@{变量}字符"`
```
.judge(@i) when(@i=1){
@size:15px;
}
.judge(@i) when(@i>1){
@size:16px;
}
.loopAnimation(@i) when (@i<16) {
.circle:nth-child(@{i}){
.judeg(@i);
border-radius:@size @size 0 0;
animation: ~"circle-@{i}" @duration infinite @ease;
transition-delay:~"@{i}ms";
}
@keyframes ~"circle-@{i}" {
// do something...
}
.loopAnimation(@i + 1);
}
```
## 附
![](https://img.kancloud.cn/e8/5c/e85c35c9905da7cbb5aa7e7a41dd7853_404x198.png)
![](https://img.kancloud.cn/5a/ed/5aeda9be67569ec352b16b92609abfad_962x78.png)
![](https://img.kancloud.cn/87/0c/870cc5b1aac0971df7d537816a9ecb7b_898x53.png)