安装 编译

koala是现在市面上,最好用的 CSS预处理语言 图形编译工具,可以编译多种 CSS预处理语言,例如: less、sass、compass

  • 支持中文
  • 有图形界面
  • 可以很方便地修改输出路径
  • 修改压缩方式方便
  • 可以设置编译选项
    • sourcemap 生成源文件映射
    • line Comments 行注释
    • debug Info 调试信息
    • strict Math 严格运算模式,数学运算必须加上()
    • strict Units 严格单位模式
    • autoprefix 自动添加前缀
  • 其他使用方法,参见官网

基本语法

变量

@变量名: 变量值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@w: 100px; /* 属性值 */
@imgurl: "../images"; /* 插值: 属性值中的某一部分 */
@box: box_one; /* 插值: 选择器中的某一部分 */
@background: background; /* 插值: 属性名中的某一部分 */

.@{box} {
width: @w;
@{background}-image: url('@{imgurl}/bg.jpg');
}

/* 用变量定义变量 */
@name: "I am Bobo";
@content: "name";

div::before {
content: @@content;
}

/* 作用域 */
.box {
@w: 200px;
width: @w;
}

混合

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
/* 无参混合 */
.box {
height: 200px;
background: red;
.nav {
color: #ccc;
}
}
.content {
.box; /* 也可以是 .box() */
}
.container {
/* 嵌套的命名空间,混合某个子级样式 */
.box .nav;
/* color: #ccc; */
}

/* 传参混合 */
.box(@height: 100px, @background: transparent) {
height: @height;
background: @background;
}
.content {
.box (200px, red);
}

.border (@w: 1px, @s: solid, @c: #000) {
/* 当你发现,所有的传入参数都是加给一个样式的时候,就可以使用 arguments 啦~ */
border: @arguments;
}
.box {
/* 在有默认值的情况下,如果只想修改其中一个值,一定要指定修改的变量名 */
.border(@c: #fff);
}

深入混合

  • 相同的自定义函数不会被替换

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .box {
    width: 100px;
    }
    .box {
    height: 200px;
    }

    .content {
    .box();
    }
    1
    2
    3
    4
    .content {
    width: 100px;
    height: 200px;
    }
  • 混合匹配

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .border(l) {
    border-left: 10px solid red;
    }
    .border(r) {
    border-right: 10px solid red;
    }
    .border(@_) {
    /* @_ 表示允许匹配任意值 */
    }

    .box {
    .border(r);
    }

    需要匹配的内容放在所有参数最前面
    不一样的参数会匹配出不一样的结果,上述案例,匹配的为参数 r

    1
    2
    3
    .box {
    border-right: 10px solid red;
    }
  • 利用混合特性,达到返回值效果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    .box {
    @w: 100px;
    @h: 200px;
    }
    .content {
    .box();
    width: @w;
    height: @h;
    }

    .average(@w, @h) {
    @average: (@w + @h) / 2;
    }
    .container {
    .average(10px, 20px);
    padding: @average;
    }
  • 条件混合

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .average(@w, @h) when not (@w = 100) {
    width: @w;
    height: @h;
    }
    /* 当条件不满足时,执行 default 情况 */
    .average(@w, @h) when (default()) {
    width: 0;
    height: 0;
    }

嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.box {
.nav {
border: 1px solid #000;
}
}

.clearfix {
/* & 表示父级 */
&::after {
content: '';
display: block;
clear: both;
}
}

嵌套冒泡

在页面的任何位置,都可以放心的写一些指令,例如@font-face

1
2
3
4
5
6
7
div {
font: 50px / 100px "fonts";
@font-face {
font-family: 'fonts';
src: url('../font/font.ttf');
}
}

这里的@font-face最终解析的时候,不会被设置到div内,而是会分离出来。对于样式多的时候,很棒~ 我们不用特意去找最外层写

1
2
3
4
5
6
7
div {
font: 50px / 100px "fonts";
}
@font-face {
font-family: 'fonts';
src: url('../font/font.ttf');
}

运算

1
2
3
4
5
6
7
8
9
10
11
12
@color: #006622;

.box {
width: 800px - 50 * 2;
height: 800px - 50 * 2;
padding: 50px;

color: @color / 2;

/* ~ 忽略运算 */
font: (100px - 20px) ~'/' (200px - 20px) "微软雅黑";
}
  • 运算符的左右,都保留空格
  • 运算的时候,最好包裹在()
  • 当运算数值具有单位时,需要注意
    • 一个单位最终结果根据唯一的这个单位
    • 两个单位看运算符,* 为最后一个单位,+ - / 为第一个单位

转义

1
2
3
4
.box {
/* ~ 忽略运算 */
font: (100px - 20px) ~'/' (200px - 20px) "微软雅黑";
}

继承

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
.box {
height: 200px;
background: red;
.nav {
color: #ccc;
}
}
.wrap {
line-height: 2;
}

.content:extend(.box) {
/* 相比 混合,群组选择器 节省代码体积,但是不能传参 */
}
.content {
/* 等效于👆的写法 */
&:extend(.box);
}

.container:extend(.box all) {
/* 子级也继承过来了 */
}

.container:extend(.box all, .wrap) {
/* 多继承 */
}

.content {
/* 扩展必须是在最后的 */
&:hover:extend(.wrap);
/* &:extend:hover(.wrap); ❌ */
};

1
2
3
4
5
6
7
8
9
10
.box,
.content,
.container {
height: 200px;
background: red;
}
.box .nav,
.container .nav {
color: #ccc;
}

判断

我可不是你想调用就能调用的混合,有些时候,我也是有条件的,通过when关键词,可以为设定条件调用

1
2
3
.box(@w) when (@w > 0) {
width: @w;
}

当 when 后面 () 的结果为真,则添加后续样式,否则不执行

比较运算符

>、<、>=、<=、=

逻辑运算符

  • and可以连接两个条件,并且两个条件都需要满足,才可以添加后续样式

    1
    2
    3
    4
    .box(@w, @h) when (@w > 0) and ((@h > 0)) {
    width: @w;
    height: @h;
    }
  • ,任何一个结果符合条件,就执行后面的代码(或)

    1
    2
    3
    4
    .box(@w, @h) when (@w > 0) , ((@h > 0)) {
    width: @w;
    height: @h;
    }
  • not判断条件不成立,就可以

    1
    2
    3
    .box(@h) when not (@h = 100) {
    height: @h;
    }

类型检查功能

  • iscolor

  • isnumber

  • isstring

  • ispixel

  • ispercentage

  • isem

循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.width(@num) when (@num > 0) {
.width(@num - 1);
width: 100 * @num;
}

div {
.width(3px);
}

.bg(@num) when (@num > 0) {
.bg(@num - 1);
&:nth-of-type(@{ num }) {
.img {
background-position: 0px (@num - 1) * (-100px);
}
&:hover {
.img {
background-position: -100px (@num - 1) * (-100px);
}
}
}
}
1
2
3
4
5
div {
width: 100px;
width: 200px;
width: 300px;
}

属性合并

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
.box() {
box-shadow: 10px 10px 5px #000;
}
.content {
.box();
/* 利用 , 分隔的,使用 + */
box-shadow+: inset 5px 5px 5px red;
}

.box() {
transform+_: translate(100px);
}
.content {
.box();
/* 利用 空格 分隔的,使用 +_ */
transform+_: rotate(180deg);
}

.box {
width: 200px;
height: 300px;
}
.content {
.box() !important;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
.content {
box-shadow+: 10px 10px 5px #000,
inset 5px 5px 5px red;
}

.content {
transform: translate(100px) rotate(180deg);
}

.content {
width: 200px !important;
height: 300px !important;
}

注释

1
2
3
4
// 行注释

/* 一个块注释
* style comment! */

导入

1
@import 'less/variable.less';

编码

1
@charset "utf-8";

函数

  • lighten() 增加颜色亮度
  • darken() 减少颜色亮度
  • fade() 给颜色设定透明度
  • mix() 根据比例混合两种颜色
  • saturate() 饱和度
  • 更多