LESS 基本用法大全
注释
Less 同时支持行注释 // 和块注释 /**/,区别是行注释不会生成到编译结果中,而块注释则会生成到编译结果中。
变量
基本用法
@width: 10px;
@height: @width + 10px;
#header {
width: @width;
height: @height;
}
编译为:
#header {
width: 10px;
height: 20px;
}
在上面的例子中,我们主要关注使用变量来控制 CSS 规则中的值。但变量也可以在其他地方使用,例如选择器名称、属性名称、URL 和导入语句。
选择器名称
@my-selector: banner;
.@{my-selector} {
font-weight: bold;
}
编译为:
.banner {
font-weight: bold;
}
属性名称
@property: color;
.widget {
@{property}: #0ee;
background-@{property}: #999;
}
编译为:
.widget {
color: #0ee;
background-color: #999;
}
URL
@images: "../img";
body {
background: url("@{images}/white-sand.png");
}
编译为:
body {
background: url("../img/white-sand.png");
}
导入语句
@themes: "./src/themes";
@import "@{themes}/tidal-wave.less";
使用变量定义变量
@primary: green;
.section {
@color: primary;
.element {
color: @@color;
}
}
编译为:
.section .element {
color: green;
}
惰性求值
变量在使用前不必声明。
.lazy-eval {
width: @var;
}
@var: @a;
@a: 9%;
编译为:
.lazy-eval {
width: 9%;
}
当重复定义变量时,将使用该变量的最后一个定义,并从当前作用域向上搜索。这类似于 CSS 本身,使用定义中的最后一个属性来确定其值。
@var: 10px;
.class {
@var: 20px;
.brass {
@var: 30px;
width: @var;
@var: 40px;
}
height: @var;
}
编译为:
.class {
height: 20px;
}
.class .brass {
width: 40px;
}
属性作为变量
使用 $prop 语法可以轻松地将属性视为变量。
.widget {
color: #efefef;
background-color: $color;
}
编译为:
.widget {
color: #efefef;
background-color: #efefef;
}
注意:与变量一样,Less 将选择当前/父范围内的最后一个属性作为“最终”值。
.block {
color: red;
.inner {
border: 1px solid $color;
}
color: blue;
}
编译为:
.block {
color: red;
color: blue;
}
.block .inner {
border: 1px solid blue;
}
运算
从 less 4.0 版本开始,除法运算需要用小括号包裹起来。
两个操作数都没有单位
.demo {
line-height: 1 + 0.5; // 1.5
line-height: 2 - 0.3; // 1.7
line-height: 0.4 * 4; // 1.6
line-height: (4 / 3); // 1.33333333
}
一个操作数有单位,一个操作数没有单位
.demo {
// px
width: 10px + 20; // 30px
width: 10 + 25px; // 35px
width: 50px - 5; // 45px
width: 60 - 5px; // 55px
width: 10px * 4; // 40px
width: 10 * 5px; // 50px
width: (100px / 5); // 20px
width: (100 / 4px); // 25px
// ms
transition-duration: 100ms + 200; // 300ms
transition-duration: 100 + 250ms; // 350ms
transition-duration: 500ms - 50; // 450ms
transition-duration: 600 - 50ms; // 550ms
transition-duration: 100ms * 4; // 400ms
transition-duration: 100 * 5ms; // 500ms
transition-duration: (1000ms / 5); // 200ms
transition-duration: (1000 / 4ms); // 250ms
// deg
transform: rotate(10deg + 20); // 30deg
transform: rotate(10 + 25deg); // 35deg
transform: rotate(50deg - 5); // 45deg
transform: rotate(60 - 5deg); // 55deg
transform: rotate(10deg * 4); // 40deg
transform: rotate(10 * 5deg); // 50deg
transform: rotate((100deg / 5)); // 20deg
transform: rotate((100 / 4deg)); // 25deg
}
两个操作数都有单位
这里仅讨论两个操作数的单位不一致的情况。
进行加法和减法运算时,若单位属于同一类别(如长度、时间、角度等),则会在运算前进行单位换算;若单位不属于同一类别,则无法进行单位换算。无论两个操作数的单位是否属于同一类别,运算结果的单位都以左侧操作数的单位类型为准。
.demo {
// 单位属于同一类别
width: 20mm + 10cm; // 120mm
width: 10cm + 20mm; // 12cm
width: 10cm - 20mm; // 8cm
width: 100mm - 3cm; // 70mm
transition-duration: 500ms + 1s; // 1500ms
transition-duration: 1s + 500ms; // 1.5s
transition-duration: 1s - 500ms; // 0.5s
transition-duration: 1000ms - 0.5s; // 500ms
transform: rotate(90deg + 1turn); // 450deg
transform: rotate(1turn + 90deg); // 1.25turn
transform: rotate(1turn - 90deg); // 0.75turn
transform: rotate(180deg - 0.25turn); // 90deg
// 单位属于不同类别
width: 10px + 90deg; // 100px
width: 10px + 100ms; // 110px
width: 300px - 90deg; // 210px
width: 300px - 100ms; // 200px
transition-duration: 100ms + 10px; // 110ms
transition-duration: 100ms + 90deg; // 190ms
transition-duration: 100ms - 50px; // 50ms
transition-duration: 100ms - 90deg; // 10ms
transform: rotate(90deg + 10px); // 100deg
transform: rotate(90deg + 100ms); // 190deg
transform: rotate(90deg - 10px); // 80deg
transform: rotate(90deg - 50ms); // 40deg
}
进行乘法和除法运算时,不进行单位换算,直接忽略右侧操作数的单位,运算结果以左侧操作数的单位类型为准。
.demo {
width: 20mm * 10cm; // 200mm
width: 10px * 90deg; // 900px
transition-duration: 500ms * 1s; // 500ms
transition-duration: 1s * 90deg; // 90s
transform: rotate(90deg * 1turn); // 90deg
transform: rotate(0.5turn * 10px); // 5turn
width: (20mm / 10cm); // 2mm
width: (100px / 2turn); // 50px
transition-duration: (1000ms / 5s); // 200ms
transition-duration: (10s / 0.5turn); // 20s
transform: rotate((180deg / 2turn)); // 90deg
transform: rotate((1turn / 0.5s)); // 2turn
}
颜色运算
Less 支持直接对颜色进行算术运算,本质上是分别计算颜色的 rgb 通道值。但并不建议这么做,建议使用专门的色彩函数(如
light()、darken()等)对颜色进行处理。
.demo {
color: #0a1937 + #8c4d4d; // #966684
color: #a25c6b - #230307; // #7f5964
color: #1e1c51 * 3; // #5a54f3
color: (#9a38e2 / 2); // #4d1c71
}
calc() 特例
为了与 CSS 保持兼容,less中的 calc() 并不会对数学表达式进行计算。
@var: 50vh / 2;
.demo {
width: calc(50% + (@var - 20px));
}
编译为:
.demo {
width: calc(50% + (25vh - 20px));
}
函数
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。下面是一个简单的函数使用例子:
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width);
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}
编译为:
.class {
width: 50%;
color: #f6430f;
background-color: #f8b38d;
}
更多 Less 内置函数见 LESS 函数手册。
嵌套
基本用法
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
编译为:
#header {
color: black;
}
#header .navigation {
font-size: 12px;
}
#header .logo {
width: 300px;
}
引用父选择器 &
& 运算符代表嵌套规则的父选择器。下面是一个经典的清除浮动的代码:
.clearfix {
display: block;
*zoom: 1;
&:after {
content: "";
display: block;
clear: both;
font-size: 0;
height: 0;
visibility: hidden;
}
}
编译为:
.clearfix {
display: block;
*zoom: 1;
}
.clearfix:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
& 运算符的另一个典型用途是生成重复的类名:
.button {
&-ok {
background-image: url("ok.png");
}
&-cancel {
background-image: url("cancel.png");
}
&-custom {
background-image: url("custom.png");
}
}
编译为:
.button-ok {
background-image: url("ok.png");
}
.button-cancel {
background-image: url("cancel.png");
}
.button-custom {
background-image: url("custom.png");
}
多种的 &
& 可以在一个选择器中出现多次,这样就可以重复引用父选择器,而无需重复定义其名称。
.link {
& + & {
color: red;
}
& & {
color: green;
}
&& {
color: blue;
}
&, &ish {
color: cyan;
}
}
编译为:
.link + .link {
color: red;
}
.link .link {
color: green;
}
.link.link {
color: blue;
}
.link,
.linkish {
color: cyan;
}
请注意,& 代表所有父选择器,而不仅仅是最近的祖先。因此以下示例:
.grand {
.parent {
& > & {
color: red;
}
& & {
color: green;
}
&& {
color: blue;
}
&, &ish {
color: cyan;
}
}
}
编译结果为:
.grand .parent > .grand .parent {
color: red;
}
.grand .parent .grand .parent {
color: green;
}
.grand .parent.grand .parent {
color: blue;
}
.grand .parent,
.grand .parentish {
color: cyan;
}
改变选择器顺序
将选择器添加到继承的(父)选择器之前有时会很有用。
.menu {
border-radius: 5px;
.no-borderradius & {
border-radius: 0px;
}
}
编译为:
.menu {
border-radius: 5px;
}
.no-borderradius .menu {
border-radius: 0px;
}
& 组合
& 还可以用于生成以逗号分隔的列表中选择器的所有可能排列。
p, a, ul, li {
border-top: 2px dotted #366;
& + & {
border-top: 0;
}
}
编译为:
p,
a,
ul,
li {
border-top: 2px dotted #366;
}
p + p,
p + a,
p + ul,
p + li,
a + p,
a + a,
a + ul,
a + li,
ul + p,
ul + a,
ul + ul,
ul + li,
li + p,
li + a,
li + ul,
li + li {
border-top: 0;
}
@ 规则嵌套和冒泡
@ 规则(例如 @media 或 @supports)可以与选择器以相同的方式进行嵌套。@ 规则会被放在前面,同一规则集中其它 CSS 规则的相对顺序保持不变(冒泡)。
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
width: 800px;
}
}
编译为:
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}
转义
转义允许你使用任意字符串作为属性或变量值。任何 ~"anything" 或 ~'anything' 形式的内容都将按原样输出,不被 Less 编译。
@min768: ~"(min-width: 768px)";
.element {
@media @min768 {
font-size: 1.2rem;
}
}
编译为:
@media (min-width: 768px) {
.element {
font-size: 1.2rem;
}
}
tip:从 Less 3.5+ 版本开始,许多以前需要转义的情况都不再需要了,因此上述 Less 代码也可以简写为:
@min768: (min-width: 768px);
.element {
@media @min768 {
font-size: 1.2rem;
}
}
tip:Less 内置函数
e()专门用于字符串转义,该函数接受一个要转义的字符串,返回转义之后的结果(原样返回,但不带引号)。
合并
用逗号附加属性值
.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;
}
用空格附加属性值
.mixin() {
transform+_: scale(2);
}
.myclass {
.mixin();
transform+_: rotate(15deg);
}
编译为:
.myclass {
transform: scale(2) rotate(15deg);
}
Mixins
基本用法
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#flex-center {
display: flex;
align-items: center;
justify-content: center;
}
#menu {
color: #ccc;
.bordered();
}
.flex {
width: 100%;
#flex-center();
}
编译为:
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#flex-center {
display: flex;
align-items: center;
justify-content: center;
}
#menu {
color: #ccc;
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
.flex {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
带括号的 Mixins
如果想创建一个 mixin,但又不希望该 mixin 出现在编译结果中,可以在定义 mixin 时加上括号。
.my-mixin {
color: black;
}
.my-other-mixin() {
background-color: white;
}
.class {
.my-mixin();
.my-other-mixin();
}
编译为:
.my-mixin {
color: black;
}
.class {
color: black;
background-color: white;
}
Mixins 中的选择器
Mixins 不仅可以包含属性,还可以包含选择器。
.hover-mixin() {
&:hover {
border: 1px solid red;
}
}
button {
.hover-mixin();
}
编译为:
button:hover {
border: 1px solid red;
}
命名空间
#my-library1 {
.custom-color() {
color: #f40;
}
.hover() {
&:hover {
border-bottom: 1px solid red;
}
}
}
#my-library2 {
.custom-color() {
color: #008c8c;
}
}
.class1 {
#my-library1.custom-color();
#my-library1.hover();
}
.class2 {
#my-library2.custom-color();
}
编译为:
.class1 {
color: #f40;
}
.class1:hover {
border-bottom: 1px solid red;
}
.class2 {
color: #008c8c;
}
Mixins 守卫
示例 1
.mixin(@a) when (lightness(@a) > 50%) {
background-color: black;
}
.mixin(@a) when (lightness(@a) =< 50%) {
background-color: white;
}
.mixin(@a) {
color: @a;
}
.class1 {
// lightness(#ddd) 为 86.67%
.mixin(#ddd);
}
.class2 {
// lightness(#555) 为 33.33%
.mixin(#555);
}
编译为:
.class1 {
background-color: black;
color: #ddd;
}
.class2 {
background-color: white;
color: #555;
}
tip:less 中的比较运算符有:
>、>=、=、=<、<。
示例 2
.mixin(@a) when (isnumber(@a)) and (@a > 0) {
width: @a;
}
.class {
.mixin(100px);
}
编译为:
.class {
width: 100px;
}
tip:
- less 中的逻辑运算符有:
and、or、not。- 可以用逗号分隔多个守卫来模拟
or运算符,只要任何一个守卫的计算结果为 true,就认为匹配成功。
示例 3
.mixin(@a) when (iscolor(@a)) {
background-color: @a;
}
.mixin(@a) when (isnumber(@a)) {
width: @a;
}
.class {
.mixin(wheat);
.mixin(80%);
}
编译为:
.class {
background-color: wheat;
width: 80%;
}
tip:
- 基本类型检查函数:
iscolor、isnumber、isstring、iskeyword、isurl。- 如果要检查某个值除了是数字之外是否还具有特定的单位,可以使用这些函数:
ispixel、ispercentage、isem、isunit。
CSS 守卫
与 Mixin 守卫类似,守卫也可以应用于 css 选择器,它是声明 mixin 然后立即调用它的语法糖。
例如,在 Less 1.5.0 之前你必须这样做:
.my-optional-style() when (@my-option = true) {
button {
color: white;
}
}
.my-optional-style();
现在,可以将守卫直接应用于样式。
button when (@my-option = true) {
color: white;
}
关键词 !important
在 mixin 调用后可以使用 !important 关键字将其继承的所有属性标记为 !important。
.foo (@bg: #f5f5f5; @color: #900) {
background-color: @bg;
color: @color;
}
.unimportant {
.foo();
}
.important {
.foo() !important;
}
编译为:
.unimportant {
background-color: #f5f5f5;
color: #900;
}
.important {
background-color: #f5f5f5 !important;
color: #900 !important;
}
向 Mixins 传递参数
基本示例
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius(4px);
}
.button {
.border-radius(6px);
}
编译为:
#header {
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.button {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
参数默认值
可以为 mixins 的参数设置默认值。
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius();
}
编译为:
#header {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
参数分隔符
最初,参数仅用逗号分隔,但后来添加了分号以支持将逗号分隔的列表值传递给单个参数。
// 形参列表可以使用逗号分割
.mixin1 (@color, @bg) {
color: @color;
background-color: @bg;
}
// 形参列表也可以使用分号分隔
.mixin2 (@font-family; @pos: center) {
font-family: @font-family;
text-align: @pos;
}
.mixin3(@tp) {
transition-property: @tp;
}
.test1 {
// #008c8c传递给@color;skyblue传递给@bg
.mixin1(#008c8c, skyblue);
// "Helvetica Neue", Arial, sans-serif传递给@font-family;right传递给@pos
.mixin2("Helvetica Neue", Arial, sans-serif; right);
// margin-right, color传递给@tp
.mixin3(margin-right, color;);
}
.test2 {
// "Helvetica Neue", Arial, sans-serif传递给@font-family;@pos使用默认值center
.mixin2(@font-family: "Helvetica Neue", Arial, sans-serif;);
// margin-right, color传递给@tp
.mixin3(~(margin-right, color));
}
编译为:
.test1 {
color: #008c8c;
background-color: skyblue;
font-family: "Helvetica Neue", Arial, sans-serif;
text-align: right;
transition-property: margin-right, color;
}
.test2 {
font-family: "Helvetica Neue", Arial, sans-serif;
text-align: center;
transition-property: margin-right, color;
}
重载 mixins
.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;
}
.class {
.mixin(#008000);
}
编译为:
.class {
color-1: #008000;
color-2: #008000;
padding-2: 2;
}
命名参数
mixin 引用可以通过参数名称而非位置来提供参数值。任何参数都可以通过其名称引用,并且无需遵循任何特殊顺序。
.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;
}
@arguments 变量
@arguments 在 mixin 中具有特殊含义,它包含了调用 mixin 时传递的所有参数。如果你不想处理单个参数,这很有用。
.box-shadow(@x: 0, @y: 0, @blur: 1px, @color: #000) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}
.big-block {
.box-shadow(2px, 5px);
}
编译为:
.big-block {
-webkit-box-shadow: 2px 5px 1px #000;
-moz-box-shadow: 2px 5px 1px #000;
box-shadow: 2px 5px 1px #000;
}
剩余参数
如果希望 mixin 接受可变数量的参数,可以使用 ...。在变量名后使用 ... 会将剩余的所有参数都赋值给该变量。
.mixin(...) { // matches 0-N arguments
.mixin() { // matches exactly 0 arguments
.mixin(@a: 1) { // matches 0-1 arguments
.mixin(@a: 1, ...) { // matches 0-N arguments
.mixin(@a, ...) { // matches 1-N arguments
.mixin(@font-size, @color, @border...) {
// @border is bound to arguments after @font-size and @color
// @arguments is bound to all arguments
font-size: @font-size;
color: @color;
border: @border;
}
.test {
.mixin(1.5rem, #f40, 1px, solid, #008c8c);
}
编译为:
.test {
font-size: 1.5rem;
color: #f40;
border: 1px solid #008c8c;
}
模式匹配
可以根据传递给 mixin 的参数改变 mixin 的行为。
.mixin(dark, @color) {
color: darken(@color, 10%);
background-color: #fff;
}
.mixin(light, @color) {
color: lighten(@color, 10%);
background-color: black;
}
@switch: light;
.class {
// 第一个mixin期望的第一个参数是dark,第二个mixin期望的第一个参数是light
// 因此这里只会匹配第二个mixin
.mixin(@switch, #888);
}
编译为:
.class {
color: #a2a2a2;
background-color: black;
}
也可以根据传递的参数个数进行匹配(和上文提到的重载 mixins 类似),比如对于以下 mixin:
.mixin(@a) {
color: @a;
}
.mixin(@a, @b) {
color: fade(@a, @b);
}
若用一个参数调用它,将得到第一个 mixin 的输出;若用两个参数调用它,则会得到第二个 mixin 的输出。
属性 / 变量访问器
从 Less 3.5 开始,我们可以像使用函数一样使用 mixin —— 通过属性 / 变量访问器从 mixin 规则中选择一个值。
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
.mixin() {
color: #008c8c;
}
div {
padding: .average(16px, 50px)[@result];
color: .mixin()[color];
// 也可以写成:color: .mixin[color];
}
.no-lookup {
// 没有指定查找值,则使用最后一个声明的值
padding: .average(16px, 50px)[];
}
编译为:
div {
padding: 33px;
color: #008c8c;
}
.no-lookup {
padding: 33px;
}
Mixins 递归
在 Less 中,mixin 可以调用自身。这种特性与 mixin 守卫结合使用,可以用来创建各种迭代 / 循环结构。
示例 1
.loop(@counter) when (@counter > 0) {
width: (10px * @counter);
.loop((@counter - 1))
}
div {
.loop(5);
}
编译为:
div {
width: 50px;
width: 40px;
width: 30px;
width: 20px;
width: 10px;
}
示例 2
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (100% * @i / @n);
}
.generate-columns(@n, (@i + 1))
}
.generate-columns(4);
编译为:
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}
Mixins 别名
将 mixin 调用赋值给变量,可以用于后续的映射查找,也可以进行变量调用。
映射查找
#theme.dark.navbar {
.colors(light) {
primary: purple;
}
.colors(dark) {
primary: black;
secondary: grey;
}
}
.navbar {
// 将 mixin 调用赋值给变量
@colors: #theme.dark.navbar.colors(dark);
// 映射查找
background: @colors[primary];
border: 1px solid @colors[secondary];
}
编译为:
.navbar {
background: black;
border: 1px solid grey;
}
变量调用
#library() {
.colors() {
background: green;
}
}
.box {
// 将 mixin 调用赋值给变量
@alias: #library.colors();
// 变量调用
@alias();
}
编译为:
.box {
background: green;
}
分离规则集
基本用法
// 声明分离规则集
@detached-ruleset: {
background: red;
}; // 这里的分号在 less 3.5.0+ 中是可选的
.top {
// 调用分离规则集
@detached-ruleset();
}
编译为:
.top {
background: red;
}
备注:调用分离规则集的括号是必需的,除非后面跟着查找值(见下文的「属性 / 变量访问器」和「将规则集作为映射关系」)。
分离规则集的一个常见应用场景是将其作为 mixin 参数传递:
.desktop-and-old-ie(@rules) {
@media screen and (min-width: 1200px) {
@rules();
}
html.lt-ie9 & {
@rules();
}
}
header {
background-color: blue;
.desktop-and-old-ie({
background-color: red;
});
}
编译为:
header {
background-color: blue;
}
@media screen and (min-width: 1200px) {
header {
background-color: red;
}
}
html.lt-ie9 header {
background-color: red;
}
作用域
分离规则集和 mixin 一个重要的区别是:mixin 中变量的作用域取决于调用 mixin 处的作用域,而分离规则集中的变量有自己的独立作用域。
.mixin() {
@color: blue;
}
.mixin-caller {
.mixin();
color: @color; // color: blue;
}
@ruleset: {
@color: blue;
};
.ruleset-caller {
@ruleset();
color: @color; // 语法错误
}
分离规则集可以使用其声明和调用处所有可访问的变量和混合。如果两个作用域包含相同的变量或混合,则声明作用域的值优先。
@detached-ruleset: {
caller-variable: @caller-variable;
.caller-mixin();
};
selector {
@detached-ruleset();
@caller-variable: value;
.caller-mixin() {
variable: declaration;
}
}
编译为:
selector {
caller-variable: value;
variable: declaration;
}
@caller-variable: global-value;
.caller-mixin() {
variable: global-declaration;
}
@detached-ruleset: {
caller-variable: @caller-variable;
.caller-mixin();
};
selector {
@detached-ruleset();
@caller-variable: value;
.caller-mixin() {
variable: declaration;
}
}
编译为:
selector {
caller-variable: global-value;
variable: global-declaration;
}
属性 / 变量访问器
从 Less 3.5 开始,可以使用属性 / 变量访问器(也称为“查找”)从分离规则集中选择一个值。
@config: {
option1: true;
option2: false;
}
.mixin() when (@config[option1] = true) {
selected: value;
}
.box {
.mixin();
}
编译为:
.box {
selected: value;
}
如果查找返回的是另一个分离规则集,则可以使用第二次查找来获取该值。
@config: {
@colors: {
primary: blue;
}
}
.box {
color: @config[@colors][primary];
}
编译为:
.box {
color: blue;
}
映射
将规则集作为映射关系
@sizes: {
mobile: 320px;
tablet: 768px;
desktop: 1024px;
}
.navbar {
display: block;
@media (min-width: @sizes[tablet]) {
display: inline-block;
}
}
编译为:
.navbar {
display: block;
}
@media (min-width: 768px) {
.navbar {
display: inline-block;
}
}
将 Mixin 调用作为映射关系
#library() {
.colors() {
primary: green;
secondary: blue;
}
}
.button {
background-color: #library.colors()[primary];
border-color: #library.colors()[secondary];
// 也可以写成:
// background-color: #library.colors[primary];
// border-color: #library.colors[secondary];
}
编译为:
.button {
background-color: green;
border-color: blue;
}
当然也可以使用 mixin 别名简化操作:
.button {
@color: #library.colors();
background-color: @color[primary];
border-color: @color[secondary];
}
在查找中使用变量
需要注意的是,[@lookup] 查找语法中的 @lookup 会被视为映射关系中的键名,而非变量。如果希望键名被当作变量处理,可以使用 @@variable 语法。
.foods() {
@dessert: ice cream;
}
@key-to-lookup: dessert;
.lunch {
treat: .foods[@@key-to-lookup];
}
编译为:
.lunch {
treat: ice cream;
}