# less回顾记录
项目中一直使用scss,现在新框架出来,推荐使用less了,所以再过一遍已经忘掉的less语法
# 0.less与scss比较
- less比scss的编辑环境简单
scss需要ruby环境,是在服务器端处理; less基于js,需要引入less.js来编译;
scss设置了四种输出设置——(less没有)
- nested:嵌套缩进的css代码;
- expanded:展开的多行css代码;
- compact:简洁格式的css代码;
- compressed:压缩后的css代码
scss中有if/else,for这些语法,less中是when
scss的工具库是compass,less网上查是bootstrap(还未用)
引入文件不同
其他语法上的不同
tlm总结基本就是:要使用这两个的话,scss比less对环境要求高,所以单纯开发一上来,如果之前用户没有装ruby,还得装ruby费点时间;less比较简单;scss比less功能更强大些。实际上在平时开发中,对css预编译器没有很高的要求,大部分人只是简单使用变量,多使用嵌套,少使用mixins等功能,二者均可以达成,所以目前看来less可以达到更快的进入项目的目的——所以,公司新框架也就切换了吧。
# 1.变量使用的是@
@link-color:#428bca;
less使用变量不在乎顺序,即声明的变量在使用之前不是必须的
# 2.不想用转义
~后面的内容不会被转,原封不动的处理成css:
.weird-element {
content: ~"^ some horrible but needed css hack";
}
//输出
.weird-element {
content: ^ some horrible but needed css hack;
}
2
3
4
5
6
7
# 3.命名空间
封装一个"对象",直接取其中的一个样式使用:
#bundle {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white
}
}
.tab { ... }
.citation { ... }
}
2
3
4
5
6
7
8
9
10
11
12
#header a {
color: orange;
#bundle > .button; /*只使用其中的button样式*/
}
2
3
4
# 4.作用域
@var: red;
#page {
#header {
color: @var; // white
}
@var: white;
}
2
3
4
5
6
7
8
# 5.引入less文件
可不加后缀
@import "library"; // library.less
@import "typo.css";
2
# 6.变量插值
// class名
@my-selector: banner;
// Usage
.@{my-selector} {
margin: 0 auto;
}
// 输出:
.banner {
margin: 0 auto;
}
2
3
4
5
6
7
8
9
10
11
12
// 值-图片路径
@images: "../img";
// Usage
body {
color: #444;
background: url("@{images}/white-sand.png");
}
2
3
4
5
6
7
8
// 引用路径
@themes: "../../src/themes";
// Usage
@import "@{themes}/tidal-wave.less";
2
3
4
5
// 属性名
@property: color;
.widget {
@{property}: #0ee;
background-@{property}: #999;
}
2
3
4
5
6
7
// 变量用变量
@fnord: "I am fnord.";
@var: "fnord";
content: @@var;
// 输出
content: "I am fnord.";
2
3
4
5
6
// 如果你希望在 media query 中使用 Less 变量,你可以直接使用普通的变量方式。 因为“~”后面的值是不被编译的,所以可以用作 media query 的参数
@singleQuery: ~"(max-width: 480px)";
@media screen, @singleQuery {
div {
width:2000px;
}
}
2
3
4
5
6
7
// 属性值拼接
.mixin (@b: 0) when (isnumber(@b)) {
width:e('@{b}px');
}
.class {
.mixin(40);
}
// 输出
.class {
width: 40px;
}
2
3
4
5
6
7
8
9
10
11
12
# 7.Extend(复制)
extend必须在最后面
非常准确复制(extend里面的类名必须和已有的一模一样):
nav ul {
&:extend(.inline); // 只扩展.inline的
background: blue;
}
.inline {
color: red;
}
//输出
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
所有带有这个样式的都复制:
nav ul {
&:extend(.inline all); // extends all instances of ".d" e.g. ".x.d" or ".d.x"
background: blue;
}
.inline {
color: red;
a{
color:blue;
}
}
.box{
.inline{
color:yellow;
}
}
// 输出
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
.inline a,
nav ul a {
color: blue;
}
.box .inline,
.box nav ul {
color: yellow;
}
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
一次复制多个:
// 可扩展多个
.e:extend(.f, .g) {}
2
# extend的用处:
1.样式意义上的继承:
<a class="animal bear">Bear</a> <a class="bear">Bear</a>
1
2.animal { background-color: black; color: white; } .bear { &:extend(.animal); background-color: brown; }
1
2
3
4
5
6
7
82.缩小css大小
.my-inline-block() { display: inline-block; font-size: 0; } .thing1 { .my-inline-block; // mixin写法 } .thing2 { .my-inline-block; // mixin写法 } // 输出 .thing1 { display: inline-block; font-size: 0; } .thing2 { display: inline-block; font-size: 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.my-inline-block { display: inline-block; font-size: 0; } .thing1 { &:extend(.my-inline-block); } .thing2 { &:extend(.my-inline-block); } // 输出 .my-inline-block, .thing1, .thing2 { display: inline-block; font-size: 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 8.能反向嵌套
.bucket {
tr & { // nested ruleset with target selector
color: blue;
}
}
// 输出
tr .bucket {
color: blue;
}
2
3
4
5
6
7
8
9
# 9.mixins
# 1.基础的Mixins(单纯的复制)
直接继承,不需要特殊字段引入
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu a {
color: #111;
.bordered;
}
.post a {
color: red;
.bordered();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
后面带不带圆括号都可以,等价;
如果不想让此样式输出,其后增加圆括号,相当于scss中的%名定义的:
.my-mixin {
color: black;
}
.my-other-mixin() {
background: white;
}
.class {
.my-mixin;
.my-other-mixin;
}
// 输出
.my-mixin {
color: black;
}
.class {
color: black;
background: white;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
命名空间:
在使用上,以下的是同一个意思:
// all do the same thing
#outer > .inner;
#outer > .inner();
#outer .inner;
#outer .inner();
#outer.inner;
#outer.inner();
2
3
4
5
6
7
**受保护的命名空间 **:
#namespace when (@mode=huge) {
.mixin() { /* */ }
}
#namespace {
.mixin() when (@mode=huge) { /* */ }
}
2
3
4
5
6
7
上面的两个虽然是相同的意思,但是在使用上还是存在区别:
// 这个变量必须在#namespace的同层空间定义,否则报错
@bg:red;
#namespace when (@bg=red) {
.mixin() {
color:red;
}
}
.box{
@bg:red; // 此处定义的不起作用
#namespace .mixin()
}
.box1{
@bg:yellow;
#namespace .mixin()
}
// 输出:
.box {
color: red;
}
.box1 {
color: red;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 这个@bg在#namespace下的空间定义,即.mixin曾可用
#namespace {
.mixin() when (@bg=red) {
font-size:14px;
}
}
.box{
@bg:red;
#namespace .mixin()
}
.box1{
@bg:yellow;
#namespace .mixin()
}
// 输出:
.box {
font-size:14px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 一次定义两个,匹配到哪个变量拿那个
#namespace {
.mixin() when (@bg=red) {
font-size:14px;
}
.mixin() when (@bg=yellow){
font-size:20px;
}
}
.box{
@bg:red;
#namespace .mixin();
}
.box1{
@bg:yellow;
#namespace .mixin();
}
// 输出:
.box {
font-size: 14px;
}
.box1 {
font-size: 20px;
}
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
给复制的样式后面直接添加!important
:
.foo (@bg: #f5f5f5, @color: #900) {
background: @bg;
color: @color;
}
.important {
.foo() !important;
}
2
3
4
5
6
7
8
# 2. 传递参数的Mixins:
此用法和scss一致,可用默认值,也可以传递:
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius;
}
.button {
.border-radius(6px);
}
2
3
4
5
6
7
8
9
10
11
12
多个参数的时候:
一旦分隔符中出现封号,就使用封号作为整体的分隔符,就不看逗号了;
如果就是单个的,使用逗号分隔也没有问题;
.mixin(@color) {
color-1: @color;
}
.mixin(@color; @padding: 2) {
color-2: @color;
padding-2: @padding;
}
.mixin(@color; @padding; @margin: 2) {
color-3: @color;
padding-3: @padding;
margin: @margin @margin @margin @margin;
}
.some .selector div1 {
.mixin(#008000); // 只传一个就会匹配上两个,第二个有默认值
}
.some .selector div2 {
.mixin(#008000,5px); // 只传两个就会匹配上三个,第三个有默认值
}
.some .selector div3 {
.mixin(#008000,5px,4px);
}
.some .selector div4 {
.mixin(#008000;5px;4px);
}
.some .selector div5 {
.mixin(#008000;5px 4px);
}
.some .selector div6 {
.mixin(#008000,5px 4px;2px);
}
// 输出:
.some .selector div1 {
color-1: #008000;
color-2: #008000;
padding-2: 2;
}
.some .selector div2 {
color-2: #008000;
padding-2: 5px;
color-3: #008000;
padding-3: 5px;
margin: 2 2 2 2;
}
.some .selector div3 {
color-3: #008000;
padding-3: 5px;
margin: 4px 4px 4px 4px;
}
.some .selector div4 {
color-3: #008000;
padding-3: 5px;
margin: 4px 4px 4px 4px;
}
.some .selector div5 {
color-2: #008000;
padding-2: 5px 4px;
color-3: #008000;
padding-3: 5px 4px;
margin: 2 2 2 2;
}
.some .selector div6 {
color-2: #008000, 5px 4px;
padding-2: 2px;
color-3: #008000, 5px 4px;
padding-3: 2px;
margin: 2 2 2 2;
}
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
既可以按顺序依次传递参数,也可以使用属性值的方式传递:
.mixin(@color: black; @margin: 10px; @padding: 20px) {
color: @color;
margin: @margin;
padding: @padding;
}
.class1 {
.mixin(@margin: 20px; @color: #33acfe);
}
.class2 {
.mixin(#efca44; @padding: 40px);
}
// 输出
.class1 {
color: #33acfe;
margin: 20px;
padding: 20px;
}
.class2 {
color: #efca44;
margin: 10px;
padding: 40px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
还可以使用@arguments
:
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
box-shadow: @arguments;
}
.big-block {
.box-shadow(2px,5px);
//.box-shadow(2px;5px); 同上
}
.block{
.box-shadow(2px 5px);
//.box-shadow(2px 5px;);同上
}
// 输出
.big-block {
box-shadow: 2px 5px 1px #000;
}
.block {
box-shadow: 2px 5px 0 1px #000;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
rest参数(...):
.mixin(@a; @rest...) {
color:@a;
padding:@rest...;
}
.box{
.mixin(@a:red;2px;3px;4px;);
}
// 输出
.box {
color: red;
padding: 2px 3px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
模式匹配:
.mixin(dark; @color) { // 需要第一个参数是dark
color: darken(@color, 10%);
}
.mixin(light; @color) { // 需要第一个参数是light
color: lighten(@color, 10%);
}
.mixin(@_; @color) { // 需要第一个参数是任意的
display: block;
}
@switch: light;
.class {
.mixin(@switch; #888); // 匹配了第二个和第三个
}
// 输出
.class {
color: #a2a2a2;
display: block;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.mixin(@a) {
color: @a;
}
.mixin(@a; @b) {
color: lighten(@a, @b);;
}
.box{
.mixin(red);
}
.box1{
.mixin(red,10%);
}
// 输出:
.box {
color: red;
}
.box1 {
color: #ff3333;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3.mixins用作函数
可以在mixins里面定义变量直接引用使用:
常用适配时的媒体查询可以这么分别写:
.mixinsless1440(){
@width:400px;
@fontSize:12px;
}
.mixinsbig1440(){
@width:300px;
@fontSize:20px;
}
@media screen and (max-width:1400px){
.mixinsless1440();
width:@width;
font-size: @fontSize;
}
@media screen and (min-width:1401px){
.mixinsbig1440();
width:@width;
font-size: @fontSize;
}
// 输出
@media screen and (max-width: 1400px) {
width: 400px;
font-size: 12px;
}
@media screen and (min-width: 1401px) {
width: 300px;
font-size: 20px;
}
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
根据某个宽度及其他计算其中的margin值时,可以在代码中直接体现:
.average(@x, @y) {
@average: ((@x + @y) / 2);
}
div {
.average(16px, 50px); // "call" the mixin
margin: @average; // use its "return" value
}
// 输出
div {
margin: 33px;
}
2
3
4
5
6
7
8
9
10
11
12
13
# 4.可以一次一个集合(属性,mixins)
.desktop-and-old-ie(@rules) {
@media screen and (min-width: 1200) { @rules(); }
html.lt-ie9 & { @rules(); }
}
header {
background-color: blue;
// 一次传递n个不确定的属性和值
.desktop-and-old-ie({
background-color: red;
font-size:14px;
});
}
// 输出
header {
background-color: blue;
}
@media screen and (min-width: 1200) {
header {
background-color: red;
font-size: 14px;
}
}
html.lt-ie9 header {
background-color: red;
font-size: 14px;
}
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
思考:此写法和mixin定义实现。。。:
@my-ruleset: {
.my-selector {
background-color: black;
}
};
@media (orientation:portrait) {
@my-ruleset();
}
// 输出
@media (orientation: portrait) {
.my-selector {
background-color: black;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mixin在媒体查询下不能直接写,否则报错:
.my-mixin(){
.my-bg{
background:red;
}
}
@media (max-width:1440px){
.my-mixin() // 报错
}
// 修正
@media (max-width:1440px){
.ddd{
.my-mixin() // 可行
}
}
// 输出
@media (max-width: 1440px) {
.ddd .my-bg {
background: red;
}
}
一般mixin定义一个类样式不会多个嵌套?
.my-mixin(){
background:red;
}
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
Passing Rulesets to Mixins (opens new window)的使用作用就像是定义了一个公用的对象那样吗?
其中不止可以是属性和选择器还可以是mixin:
// detached ruleset with a mixin
@detached-ruleset: {
.mixin() {
color:blue;
}
};
// call detached ruleset
.caller {
@detached-ruleset();
.mixin();
}
// 输出
.caller {
color: blue;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 10.import
less中可以随意在任何地方引入文件
less中引入文件,如果有.css后缀就认为是css文件;如果有.less或者无后缀或其他后缀都认为是less文件
【@import (keyword) "filename"】keyword可以配置选项:
reference
: use a Less file but do not output itinline
: include the source file in the output but do not process itless
: treat the file as a Less file, no matter what the file extensioncss
: treat the file as a CSS file, no matter what the file extensiononce
: only include the file once (this is default behavior)multiple
: include the file multiple timesoptional
: continue compiling when file is not found
- reference:引入一个文件但是不会输出这个文件,只在其中的样式被extend或者混合复杂的mixins中使用的时候才会输出;通常我们在引入某个插件库时,只使用其中之一的样式就可以使用这个配置项;例如对bootstrap样式的引用,此时navbar的样式只被输出:
@import (reference) "bootstrap.less" .navbar:extend(.navbar all) {}
1
2
3inline:引入的文件的css不做处理
less:文件后缀为less,作为less处理
css:文件后缀为css,作为css处理
once: 只引入一次(平常的就是这样)
multiple:可以在一个文件中多次引入(也不知道多次引用能有什么用?)
optional:平时不加此参数,引入的文件不存在的话会报错,但添加此参数后,存在时引入,不存在时不引入
# 11.when(if/else的效果)
连续写几个可以形成if/else的效果;
when后面的值为真才能匹配上
.mixin (@a) when (lightness(@a) >= 50%) {
background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
background-color: white;
}
.mixin (@a) {
color: @a;
}
2
3
4
5
6
7
8
9
比较的操作符包括: >
, >=
, =
, =<
, <
除了true以后其他的值都是假值(这个和js不同):
.truth (@a) when (@a) {
color:blue;
}
.truth (@a) when (@a = true) {
color:red;
}
.class {
.truth(40); // 匹配不上,40为假值
}
.class1{
.truth(true);
}
// 输出
.class1 {
color: blue;
color: red;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
逻辑操作符: and
,,
,not
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
.mixin (@a) when (@a > 10), (@a < -10) { ... }
.mixin (@b) when not (@b > 0) { ... }
2
3
类型检查:
iscolor
isnumber
isstring
iskeyword
isurl
ispixel
ispercentage
isem
isunit
If/else中有一个可用的default():
.mixin (@a: 0) when not (ispixel(@a)) {
width:e('@{a}px');
}
.mixin (@a) when (default()) {
width:@a;
}
.class {
.mixin(40);
}
.class1{
.mixin(30px)
}
// 输出
.class {
width: 40px;
}
.class1 {
width: 30px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
css中也可以直接用:
.class1{
@myoption:true;
& when (@myoption = true) {
button {
color: white;
}
}
}
// 输出
.class1 button {
color: white;
}
2
3
4
5
6
7
8
9
10
11
12
@my-option:true;
button when (@my-option = true) {
color: white;
}
// 输出
button {
color: white;
}
2
3
4
5
6
7
8
9
# 12.循环
@i:8;
.loop(@i)when(@i>0){
.loop((@i - 1));
.cell-bg@{i} {background: url('../images/cell-bg@{i}.png') no-repeat;}
}
.loop(@i);
// 输出
.cell-bg1 {
background: url('../images/cell-bg1.png') no-repeat;
}
.cell-bg2 {
background: url('../images/cell-bg2.png') no-repeat;
}
.cell-bg3 {
background: url('../images/cell-bg3.png') no-repeat;
}
.cell-bg4 {
background: url('../images/cell-bg4.png') no-repeat;
}
.cell-bg5 {
background: url('../images/cell-bg5.png') no-repeat;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
// 输出
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 13 合并
这个感觉一般很少用
// +号是逗号连接
.mixin() {
box-shadow+: inset 0 0 10px #555;
}
.myclass {
.mixin();
box-shadow+: 0 0 20px black;
}
// 输出
.myclass {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}
2
3
4
5
6
7
8
9
10
11
12
// +_号是空格连接
.mixin() {
transform+_: scale(2);
}
.myclass {
.mixin();
transform+_: rotate(15deg);
}
// 输出
.myclass {
transform: scale(2) rotate(15deg);
}
2
3
4
5
6
7
8
9
10
11
12