对于一个深入的指南,安装和设置一个都不能少环境,以及对欠发达文档,请参阅:使用Less.js。
变数
在一个位置控制常用值。
总览
在样式表中看到相同的值重复数十次甚至数百次的情况并不少见:
a,
.link {
color: #428bca;
}
.widget {
color: #fff;
background: #428bca;
}
变量使您可以从一个位置控制这些值,从而使代码易于维护:
// Variables
@link-color: #428bca; // sea blue
@link-color-hover: darken(@link-color, 10%);
// Usage
a,
.link {
color: @link-color;
}
a:hover {
color: @link-color-hover;
}
.widget {
color: #fff;
background: @link-color;
}
可变插值
上面的示例着重于使用变量来控制CSS规则中的值,但它们也可以在其他地方使用,例如选择器名称,属性名称,URL和@import
语句。
选择器
v1.4.0
// Variables
@my-selector: banner;
// Usage
.@{my-selector} {
font-weight: bold;
line-height: 40px;
margin: 0 auto;
}
编译为:
.banner {
font-weight: bold;
line-height: 40px;
margin: 0 auto;
}
网址
// Variables
@images: "../img";
// Usage
body {
color: #444;
background: url("@{images}/white-sand.png");
}
进口声明
v1.4.0
句法: @import "@{themes}/tidal-wave.less";
请注意,在v2.0.0之前,仅考虑在根范围或当前范围中声明的变量,并且在查找变量时仅考虑当前文件和调用文件。
例:
// Variables
@themes: "../../src/themes";
// Usage
@import "@{themes}/tidal-wave.less";
物产
v1.6.0
@property: color;
.widget {
@{property}: #0ee;
background-@{property}: #999;
}
编译为:
.widget {
color: #0ee;
background-color: #999;
}
可变变量
在Less中,可以使用另一个变量定义变量的名称。
@primary: green;
@secondary: blue;
.section {
@color: primary;
.element {
color: @@color;
}
}
编译为:
.section .element {
color: green;
}
懒惰评估
变量在使用之前不必声明。
有效的更少代码段:
.lazy-eval {
width: @var;
}
@var: @a;
@a: 9%;
这也是有效的Less:
.lazy-eval {
width: @var;
@a: 9%;
}
@var: @a;
@a: 100%;
两者都编译成:
.lazy-eval {
width: 9%;
}
两次定义变量时,使用变量的最后定义,从当前作用域向上搜索。这类似于css本身,其中css定义中的最后一个属性用于确定值。
例如:
@var: 0;
.class {
@var: 1;
.brass {
@var: 2;
three: @var;
@var: 3;
}
one: @var;
}
编译为:
.class {
one: 1;
}
.class .brass {
three: 3;
}
本质上,每个作用域都有一个“最终”值,类似于浏览器中的属性,例如使用自定义属性的以下示例:
.header {
--color: white;
color: var(--color); // the color is black
--color: black;
}
这意味着,与其他CSS预处理语言不同,Less变量的行为与CSS的行为非常相似。
属性作为变量(新!)
v3.0.0
您可以使用$prop
语法轻松地将属性像变量一样对待。有时,这会使您的代码更轻一些。
.widget {
color: #efefef;
background-color: $color;
}
编译为:
.widget {
color: #efefef;
background-color: #efefef;
}
请注意,像变量一样,Less将选择当前/父范围内的最后一个属性作为“最终”值。
.block {
color: red;
.inner {
background-color: $color;
}
color: blue;
}
编译为:
.block {
color: red;
color: blue;
}
.block .inner {
background-color: blue;
}
默认变量
有时我们会请求默认变量-一种仅在尚未设置变量的情况下才可以设置的功能。不需要此功能是因为您可以通过在后面放置定义来轻松覆盖变量。
例如:
// library
@base-color: green;
@dark-color: darken(@base-color, 10%);
// use of library
@import "library.less";
@base-color: red;
由于延迟加载,此方法效果很好- @base-color
已被覆盖并且@dark-color
为深红色。
父母选择者
引用父选择器
&
的&
操作者表示的父选择嵌套规则并且最常用的施加改性类或伪类到现有的选择器时:
a {
color: blue;
&:hover {
color: green;
}
}
结果是:
a {
color: blue;
}
a:hover {
color: green;
}
请注意,如果没有使用&
,则上面的示例将产生a :hover
rule(与<a>
标记内的悬停元素匹配的后代选择器),而这并不是我们通常希望使用nested的结果:hover
。
“父选择器”运算符有多种用途。基本上,任何时候您都需要使用默认规则以外的其他方式组合嵌套规则的选择器。例如,的另一种典型用法&
是产生重复的类名:
.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;
}
更改选择器顺序
将选择器放在继承的(父)选择器之前可能很有用。这可以通过&
在当前选择器之后放置来完成。例如,在使用Modernizr时,您可能要根据支持的功能指定不同的规则:
.header {
.menu {
border-radius: 5px;
.no-borderradius & {
background-image: url('images/button-background.png');
}
}
}
选择器.no-borderradius &
将.no-borderradius
在其父项之前.header .menu
形成.no-borderradius .header .menu
on输出:
.header .menu {
border-radius: 5px;
}
.no-borderradius .header .menu {
background-image: url('images/button-background.png');
}
组合爆炸
&
也可以用于生成逗号分隔列表中选择器的所有可能排列:
p, a, ul, li {
border-top: 2px dotted #366;
& + & {
border-top: 0;
}
}
这将扩展为指定元素的所有可能(16)组合:
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;
}
延伸
Extend是一个Less伪类,它将合并的选择器与匹配其引用的选择器合并。
发布了v1.4.0
nav ul {
&:extend(.inline);
background: blue;
}
另外,在上述设定的规则,则:extend
选择器将所述“延伸选择器”(申请nav ul
)到.inline
类的任何地方.inline
类出现。声明块将保持原样,但不对扩展进行任何引用(因为扩展不是CSS)。
因此,以下内容:
nav ul {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
产出
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
注意nav ul:extend(.inline)
选择器是如何输出的nav ul
-扩展在输出之前被删除,选择器块保持原样。如果该块中未放置任何属性,则该块将从输出中删除(但扩展仍然可能影响其他选择器)。
扩展语法
扩展要么附加到选择器,要么放置在规则集中。看起来像是带有选择器参数的伪类(可选),其后跟关键字all
:
例:
.a:extend(.b) {}
// the above block does the same thing as the below block
.a {
&:extend(.b);
}
.c:extend(.d all) {
// extends all instances of ".d" e.g. ".x.d" or ".d.x"
}
.c:extend(.d) {
// extends only instances where the selector will be output as just ".d"
}
它可以包含一个或多个要扩展的类,以逗号分隔。
例:
.e:extend(.f) {}
.e:extend(.g) {}
// the above and the below do the same thing
.e:extend(.f, .g) {}
扩展附加到选择器
附加到选择器的扩展看起来像一个普通的伪类,带有选择器作为参数。一个选择器可以包含多个extend子句,但是所有扩展都必须在选择器的末尾。
- 在选择器之后扩展:
pre:hover:extend(div pre)
。 - 选择器和扩展之间允许有空格:
pre:hover :extend(div pre)
。 - 允许多个扩展:
pre:hover:extend(div pre):extend(.bucket tr)
-注意,这与pre:hover:extend(div pre, .bucket tr)
- 这是不允许的:
pre:hover:extend(div pre).nth-child(odd)
。扩展必须是最后一个。
如果规则集包含多个选择器,则它们中的任何一个都可以具有extend关键字。在一个规则集中扩展的多个选择器:
.big-division,
.big-bag:extend(.bag),
.big-bucket:extend(.bucket) {
// body
}
扩展内部规则集
可以使用&:extend(selector)
语法将扩展放置在规则集的主体中。将扩展放置到主体中是将其放入该规则集的每个选择器的快捷方式。
在体内延伸:
pre:hover,
.some-class {
&:extend(div pre);
}
与在每个选择器之后添加扩展名完全相同:
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
扩展嵌套选择器
扩展能够匹配嵌套的选择器。以下少:
例:
.bucket {
tr { // nested ruleset with target selector
color: blue;
}
}
.some-class:extend(.bucket tr) {} // nested ruleset is recognized
产出
.bucket tr,
.some-class {
color: blue;
}
从本质上讲,扩展将查看已编译的CSS,而不是原始的CSS。
例:
.bucket {
tr & { // nested ruleset with target selector
color: blue;
}
}
.some-class:extend(tr .bucket) {} // nested ruleset is recognized
产出
tr .bucket,
.some-class {
color: blue;
}
精确匹配与扩展
默认情况下扩展查找选择器之间的完全匹配。选择器是否使用前导星并不重要。两个nth表达式具有相同的含义并不重要,它们必须具有相同的形式才能匹配。唯一的例外是属性选择器中的引号,很少知道它们的含义相同并匹配它们。
例:
.a.class,
.class.a,
.class > .a {
color: blue;
}
.test:extend(.class) {} // this will NOT match the any selectors above
领军人物确实很重要。选择器*.class
和.class
是等效的,但扩展名将与它们不匹配:
*.class {
color: blue;
}
.noStar:extend(.class) {} // this will NOT match the *.class selector
产出
*.class {
color: blue;
}
伪类的顺序很重要。选择器link:hover:visited
和link:visited:hover
匹配相同的元素集,但extend将它们视为不同的元素:
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
产出
link:hover:visited {
color: blue;
}
第n个表达式
第N个表达形式很重要。Nth个表达式1n+3
和n+3
是等效的,但extend与它们不匹配:
:nth-child(1n+3) {
color: blue;
}
.child:extend(:nth-child(n+3)) {}
产出
:nth-child(1n+3) {
color: blue;
}
属性选择器中的引用类型无关紧要。以下所有都是等效的。
[title=identifier] {
color: blue;
}
[title='identifier'] {
color: blue;
}
[title="identifier"] {
color: blue;
}
.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}
产出
[title=identifier],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title="identifier"],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
扩展“全部”
当在扩展参数中最后指定all关键字时,它告诉Less将该选择器作为另一个选择器的一部分进行匹配。选择器将被复制,然后仅将选择器的匹配部分替换为扩展名,从而创建一个新的选择器。
例:
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
产出
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
您可以认为这种操作模式实质上是在进行无损搜索和替换。
带扩展的选择器插值
扩展是不能够与变量匹配选择。如果选择器包含变量,则extend将忽略它。
但是,extend可以附加到插值选择器。
具有变量的选择器将不匹配:
@variable: .bucket;
@{variable} { // interpolated selector
color: blue;
}
.some-class:extend(.bucket) {} // does nothing, no match is found
并在目标选择器中使用变量扩展不匹配:
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {} // interpolated selector matches nothing
@variable: .bucket;
以上两个示例均编译为:
.bucket {
color: blue;
}
但是,将其:extend
附加到插值选择器即可:
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
编译为:
.bucket, .selector {
color: blue;
}
在@media范围内/扩展
当前,声明:extend
内的@media
内容仅与同一媒体声明内的选择器匹配:
@media print {
.screenClass:extend(.selector) {} // extend inside media
.selector { // this will be matched - it is in the same media
color: black;
}
}
.selector { // ruleset on top of style sheet - extend ignores it
color: red;
}
@media screen {
.selector { // ruleset inside another media - extend ignores it
color: blue;
}
}
编译成:
@media print {
.selector,
.screenClass { /* ruleset inside the same media was extended */
color: black;
}
}
.selector { /* ruleset on top of style sheet was ignored */
color: red;
}
@media screen {
.selector { /* ruleset inside another media was ignored */
color: blue;
}
}
注意:扩展与嵌套@media
声明中的选择器不匹配:
@media screen {
.screenClass:extend(.selector) {} // extend inside media
@media (min-width: 1023px) {
.selector { // ruleset inside nested media - extend ignores it
color: blue;
}
}
}
编译成:
@media screen and (min-width: 1023px) {
.selector { /* ruleset inside another nested media was ignored */
color: blue;
}
}
顶级扩展匹配所有内容,包括嵌套媒体中的选择器:
@media screen {
.selector { /* ruleset inside nested media - top level extend works */
color: blue;
}
@media (min-width: 1023px) {
.selector { /* ruleset inside nested media - top level extend works */
color: blue;
}
}
}
.topLevel:extend(.selector) {} /* top level extend matches everything */
编译成:
@media screen {
.selector,
.topLevel { /* ruleset inside media was extended */
color: blue;
}
}
@media screen and (min-width: 1023px) {
.selector,
.topLevel { /* ruleset inside nested media was extended */
color: blue;
}
}
复制检测
当前没有重复检测。
例:
.alert-info,
.widget {
/* declarations */
}
.alert:extend(.alert-info, .widget) {}
产出
.alert-info,
.widget,
.alert,
.alert {
/* declarations */
}
扩展用例
经典用例
经典的用例是避免添加基类。例如,如果您有
.animal {
background-color: black;
color: white;
}
并且您想要一个动物的子类型来替代背景色,那么您有两个选择,首先是更改HTML
<a class="animal bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
background-color: brown;
}
或简化了html并在您更少的范围内使用扩展。例如
<a class="bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
&:extend(.animal);
background-color: brown;
}
减少CSS大小
Mixins将所有属性复制到选择器中,这可能导致不必要的重复。因此,您可以使用扩展而不是混合来将选择器上移到要使用的属性,这将减少生成CSS的次数。
示例-使用mixin:
.my-inline-block() {
display: inline-block;
font-size: 0;
}
.thing1 {
.my-inline-block;
}
.thing2 {
.my-inline-block;
}
产出
.thing1 {
display: inline-block;
font-size: 0;
}
.thing2 {
display: inline-block;
font-size: 0;
}
示例(带有扩展):
.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;
}
组合样式/更高级的混音
另一个用例是mixin的替代方案-因为mixin仅可与简单的选择器一起使用,如果您有两个不同的html块,但需要对两者应用相同的样式,则可以使用扩展来关联两个区域。
例:
li.list > a {
// list styles
}
button.list-style {
&:extend(li.list > a); // use the same list styles
}
合并
合并属性
该merge
功能允许将多个属性中的值聚合到单个属性下的逗号或空格分隔的列表中。merge
对于背景和变换等属性很有用。
逗号
用逗号附加属性值
发布了v1.5.0
例:
.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;
}
空间
用空格附加属性值
发布了v1.7.0
例:
.mixin() {
transform+_: scale(2);
}
.myclass {
.mixin();
transform+_: rotate(15deg);
}
产出
.myclass {
transform: scale(2) rotate(15deg);
}
为了避免任何无意的联接,在每个联接未决声明上都merge
需要显式+
或+_
标记。
混合蛋白
现有样式的“混合”属性
您可以混合使用类选择器和ID选择器,例如
.a, #b {
color: red;
}
.mixin-class {
.a();
}
.mixin-id {
#b();
}
结果是:
.a, #b {
color: red;
}
.mixin-class {
color: red;
}
.mixin-id {
color: red;
}
从历史上看,mixin调用中的括号是可选的,但是不建议使用可选的括号,并且在将来的发行版中将需要使用括号。
.a();
.a; // currently works, but deprecated; don't use
.a (); // white-space before parentheses is also deprecated
带括号的Mixins
如果要创建一个mixin,但又不希望该mixin出现在CSS输出中,请在mixin定义后加上括号。
.my-mixin {
color: black;
}
.my-other-mixin() {
background: white;
}
.class {
.my-mixin();
.my-other-mixin();
}
输出
.my-mixin {
color: black;
}
.class {
color: black;
background: white;
}
Mixins中的选择器
Mixins不仅可以包含属性,还可以包含选择器。
例如:
.my-hover-mixin() {
&:hover {
border: 1px solid red;
}
}
button {
.my-hover-mixin();
}
产出
button:hover {
border: 1px solid red;
}
命名空间
如果要在更复杂的选择器中混合属性,则可以堆叠多个ID或类。
#outer() {
.inner {
color: red;
}
}
.c {
#outer.inner();
}
注意:遗留的less语法允许>
在名称空间和mixin之间使用空格。不推荐使用此语法,可以将其删除。目前,这些功能是相同的。
#outer > .inner(); // deprecated
#outer .inner(); // deprecated
#outer.inner(); // preferred
为混合文件命名空间可以减少与其他库混合文件或用户混合文件的冲突,但是这也可以是“组织”混合文件组的一种方式。
例:
#my-library {
.my-mixin() {
color: black;
}
}
// which can be used like this
.class {
#my-library.my-mixin();
}
受保护的命名空间
如果名称空间具有保护,则仅当保护条件返回true时,才使用由其定义的混合。命名空间防护的评估方式与Mixin的防护方式完全相同,因此以下两个Mixin的工作方式相同:
#namespace when (@mode = huge) {
.mixin() { /* */ }
}
#namespace {
.mixin() when (@mode = huge) { /* */ }
}
default
假定该函数对于所有嵌套的名称空间和mixin具有相同的值。永远不会评估以下mixin,因此保证其警惕之一是错误的:
#sp_1 when (default()) {
#sp_2 when (default()) {
.mixin() when not(default()) { /* */ }
}
}
该!important
关键字
!important
在mixin调用之后使用关键字将其继承的所有属性标记为!important
:
例:
.foo (@bg: #f5f5f5; @color: #900) {
background: @bg;
color: @color;
}
.unimportant {
.foo();
}
.important {
.foo() !important;
}
结果是:
.unimportant {
background: #f5f5f5;
color: #900;
}
.important {
background: #f5f5f5 !important;
color: #900 !important;
}
参数混合
如何将参数传递给Mixins
Mixins还可以接受参数,这些参数是在混合时传递到选择器块的变量。
例如:
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
这是我们如何将其混合到各种规则集中:
#header {
.border-radius(4px);
}
.button {
.border-radius(6px);
}
参数mixin也可以具有其参数的默认值:
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
我们现在可以像这样调用它:
#header {
.border-radius();
}
并且它将包括5px的边框半径。
您也可以使用不带参数的参数混合。如果您想从CSS输出中隐藏规则集,但想将其属性包含在其他规则集中,则这很有用:
.wrap() {
text-wrap: wrap;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
word-wrap: break-word;
}
pre { .wrap() }
哪个会输出:
pre {
text-wrap: wrap;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
word-wrap: break-word;
}
具有多个参数的Mixins
参数以分号或逗号分隔。建议使用分号。符号逗号具有双重含义:可以将其解释为mixin参数分隔符或css列表分隔符。
使用逗号作为mixin分隔符使不可能创建逗号分隔的列表作为参数。另一方面,如果编译器在mixin调用或声明中看到至少一个分号,则假定参数用分号分隔,并且所有逗号都属于css列表:
- 两个参数,每一个包含逗号分隔的列表:
.name(1, 2, 3; something, else)
, - 三个参数,并且每个包含一个数字:
.name(1, 2, 3)
, - 使用虚拟分号创建混入调用一个包含参数逗号分隔的CSS列表:
.name(1, 2, 3;)
, - 逗号分隔的默认值:
.name(@param1: red, blue;)
。
定义具有相同名称和数量的参数的多个混合是合法的。更少会使用所有可能适用的属性。如果您将mixin与一个参数一起使用,例如.mixin(green);
,那么将使用具有一个强制参数的所有mixin的属性:
.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 div {
.mixin(#008000);
}
编译成:
.some .selector div {
color-1: #008000;
color-2: #008000;
padding-2: 2;
}
命名参数
混合引用可以通过名称而不是位置来提供参数值。可以通过名称来引用任何参数,并且它们不必采用任何特殊顺序:
.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;
}
高级参数和@rest
变量
...
如果您希望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(@a; @rest...) {
// @rest is bound to arguments after @a
// @arguments is bound to all arguments
}
模式匹配
有时,您可能想根据传递给它的参数来更改混合的行为。让我们从一些基本的东西开始:
.mixin(@s; @color) { ... }
.class {
.mixin(@switch; #888);
}
现在,我们要.mixin
基于的值来表现不同@switch
,我们可以这样定义.mixin
:
.mixin(dark; @color) {
color: darken(@color, 10%);
}
.mixin(light; @color) {
color: lighten(@color, 10%);
}
.mixin(@_; @color) {
display: block;
}
现在,如果我们运行:
@switch: light;
.class {
.mixin(@switch; #888);
}
我们将获得以下CSS:
.class {
color: #a2a2a2;
display: block;
}
颜色传递到的地方变.mixin
亮了。如果值@switch
是dark
,其结果将是一个较深的颜色。
这是发生了什么:
- 第一个mixin定义不匹配,因为它应
dark
作为第一个参数。 - 第二个mixin定义匹配,因为它符合预期
light
。 - 第三个mixin定义匹配,因为它期望任何值。
仅使用匹配的混合定义。变量匹配并绑定到任何值。除变量外,其他任何事物都仅与等于其自身的值匹配。
我们还可以匹配使用arity,这是一个示例:
.mixin(@a) {
color: @a;
}
.mixin(@a; @b) {
color: fade(@a; @b);
}
现在,如果.mixin
使用单个参数调用,则将获取第一个定义的输出,但是如果使用两个参数调用,则将获取第二个定义,即@a
淡出为@b
。
使用Mixins作为函数
从混合调用中选择属性和变量
财产/价值访问者
发布了v3.5.0
从Less 3.5开始,您可以使用属性/变量访问器从评估的混合规则中选择一个值。这可以允许您使用与功能相似的mixin。
例:
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
// call a mixin and look up its "@result" value
padding: .average(16px, 50px)[@result];
}
结果是:
div {
padding: 33px;
}
覆盖混合值
如果您有多个匹配的mixin,则将评估并合并所有规则,并返回带有该标识符的最后一个匹配值。这类似于CSS中的层叠,它允许您“覆盖” mixin值。
// library.less
#library() {
.mixin() {
prop: foo;
}
}
// customize.less
@import "library";
#library() {
.mixin() {
prop: bar;
}
}
.box {
my-value: #library.mixin[prop];
}
输出:
.box {
my-value: bar;
}
未命名的查询
如果您未在其中指定查找值[@lookup]
,而是[]
在mixin或规则集调用之后写入,则所有值将级联,最后一个声明的值将被选择。
含义:上面示例中的平均mixin可以写成:
.average(@x, @y) {
@result: ((@x + @y) / 2);
}
div {
// call a mixin and look up its final value
padding: .average(16px, 50px)[];
}
输出是相同的:
div {
padding: 33px;
}
对于混入调用的规则集或变量,同样的级联行为也适用。
@dr: {
value: foo;
}
.box {
my-value: @dr[];
}
输出:
.box {
my-value: foo;
}
将mixins和变量解锁到调用者作用域中
弃用-使用属性/值访问器
混合中定义的变量和混合是可见的,可以在调用者的作用域中使用。只有一个例外:如果调用者包含具有相同名称的变量(其中包括由另一个mixin调用定义的变量),则不会复制变量。仅存在于调用者本地范围内的变量受到保护。从父范围继承的变量将被覆盖。
注意:不建议使用此行为,将来,变量和混合将不会以这种方式合并到调用方作用域中。
例:
.mixin() {
@width: 100%;
@height: 200px;
}
.caller {
.mixin();
width: @width;
height: @height;
}
结果是:
.caller {
width: 100%;
height: 200px;
}
在调用者作用域中直接定义的变量不能被覆盖。但是,在调用者父作用域中定义的变量不受保护,将被覆盖:
.mixin() {
@size: in-mixin;
@definedOnlyInMixin: in-mixin;
}
.class {
margin: @size @definedOnlyInMixin;
.mixin();
}
@size: globaly-defined-value; // callers parent scope - no protection
结果是:
.class {
margin: in-mixin in-mixin;
}
最后,在mixin中定义的mixin也充当返回值:
.unlock(@value) { // outer mixin
.doSomething() { // nested mixin
declaration: @value;
}
}
#namespace {
.unlock(5); // unlock doSomething mixin
.doSomething(); //nested mixin was copied here and is usable
}
结果是:
#namespace {
declaration: 5;
}
递归混合
创建循环
在Less中,mixin可以自称。与Guard表达式和模式匹配结合使用时,此类递归mixin 可用于创建各种迭代/循环结构。
例:
.loop(@counter) when (@counter > 0) {
.loop((@counter - 1)); // next iteration
width: (10px * @counter); // code for each iteration
}
div {
.loop(5); // launch the loop
}
输出:
div {
width: 10px;
width: 20px;
width: 30px;
width: 40px;
width: 50px;
}
使用递归循环生成CSS网格类的一般示例:
.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%;
}
混合守卫
当您想在表达式上进行匹配时,与简单值或Arity相反,保护很有用。如果您熟悉函数式编程,则可能已经遇到过。
为了尽量接近CSS的声明性,Less选择了通过受保护的mixins而不是if
/ else
语句来实现条件执行,这与@media
查询功能规范类似。
让我们从一个例子开始:
.mixin(@a) when (lightness(@a) >= 50%) {
background-color: black;
}
.mixin(@a) when (lightness(@a) < 50%) {
background-color: white;
}
.mixin(@a) {
color: @a;
}
关键是when
关键字,它引入了一个保护序列(这里只有一个保护)。现在,如果我们运行以下代码:
.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }
这是我们将得到的:
.class1 {
background-color: black;
color: #ddd;
}
.class2 {
background-color: white;
color: #555;
}
后卫比较运算符
比较运营商在后卫可用的完整列表是:>
,>=
,=
,=<
,<
。此外,关键字true
是唯一的真实值,使这两个mixins等效:
.truth(@a) when (@a) { ... }
.truth(@a) when (@a = true) { ... }
除关键字以外的任何值true
都是伪造的:
.class {
.truth(40); // Will not match any of the above definitions.
}
请注意,您还可以将参数彼此或与非参数进行比较:
@media: mobile;
.mixin(@a) when (@media = mobile) { ... }
.mixin(@a) when (@media = desktop) { ... }
.max(@a; @b) when (@a > @b) { width: @a }
.max(@a; @b) when (@a < @b) { width: @b }
警卫逻辑运算符
您可以将逻辑运算符与防护一起使用。语法基于CSS媒体查询。
使用and
关键字来组合警卫:
.mixin(@a) when (isnumber(@a)) and (@a > 0) { ... }
您可以通过用逗号分隔警卫队来模仿or运算符,
。如果任何一个守卫评估为true,则认为是匹配:
.mixin(@a) when (@a > 10), (@a < -10) { ... }
使用not
关键字来否定条件:
.mixin(@b) when not (@b > 0) { ... }
类型检查功能
最后,如果要基于值类型匹配混合,则可以使用以下is
功能:
.mixin(@a; @b: 0) when (isnumber(@b)) { ... }
.mixin(@a; @b: black) when (iscolor(@b)) { ... }
以下是基本的类型检查功能:
iscolor
isnumber
isstring
iskeyword
isurl
如果要检查值是否是数字,是否还使用特定单位,则可以使用以下方法之一:
ispixel
ispercentage
isem
isunit
混叠别名
发布了v3.5.0
将mixin调用分配给变量
可以将Mixins分配给变量以称为变量调用,也可以将其用于映射查找。
#theme.dark.navbar {
.colors(light) {
primary: purple;
}
.colors(dark) {
primary: black;
secondary: grey;
}
}
.navbar {
@colors: #theme.dark.navbar.colors(dark);
background: @colors[primary];
border: 1px solid @colors[secondary];
}
这将输出:
.navbar {
background: black;
border: 1px solid grey;
}
变量调用
整个mixin调用可以被别名并称为变量调用。如:
#library() {
.rules() {
background: green;
}
}
.box {
@alias: #library.rules();
@alias();
}
输出:
.box {
background: green;
}
请注意,与root中使用的mixin不同,分配给变量且不带参数的 mixin调用始终需要括号。以下无效。
#library() {
.rules() {
background: green;
}
}
.box {
@alias: #library.colors;
@alias(); // ERROR: Could not evaluate variable call @alias
}
这是因为如果为变量分配选择器列表或mixin调用是不明确的。例如,在Less 3.5+中,可以用这种方式使用此变量。
.box {
@alias: #library.colors;
@{alias} {
a: b;
}
}
以上将输出:
.box #library.colors {
a: b;
}
CSS卫队
“如果”在选择器周围
发布了v1.5.0
与Mixin Guards一样,guards也可以应用于css选择器,它是用于声明mixin然后立即调用它的语法糖。
例如,在1.5.0之前,您必须执行以下操作:
.my-optional-style() when (@my-option = true) {
button {
color: white;
}
}
.my-optional-style();
现在,您可以将后卫直接应用于样式。
button when (@my-option = true) {
color: white;
}
您还可以if
通过将其与&
功能结合使用来实现类型声明,从而可以对多个防护进行分组。
& when (@my-option = true) {
button {
color: white;
}
a {
color: blue;
}
}
请注意,您还可以通过使用实际if()
函数和变量调用来实现类似的模式。如:
@dr: if(@my-option = true, {
button {
color: white;
}
a {
color: blue;
}
});
@dr();
独立规则集
将规则集分配给变量
发布了v1.7.0
分离的规则集是一组CSS属性,嵌套规则集,媒体声明或存储在变量中的任何其他内容。您可以将其包括在规则集中或其他结构中,并且所有属性都将复制到那里。您还可以将其用作mixin参数,并将其作为其他任何变量传递。
简单的例子:
// declare detached ruleset
@detached-ruleset: { background: red; }; // semi-colon is optional in 3.5.0+
// use detached ruleset
.top {
@detached-ruleset();
}
编译成:
.top {
background: red;
}
分离的规则集调用后的括号是强制性的(除非后面带有查找值)。通话@detached-ruleset;
将无法进行。
当您想要定义一个混合(摘要)以在媒体查询中包装一段代码或不支持的浏览器类名称时,此方法很有用。可以将规则集传递给mixin,以便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;
});
}
在这里,desktop-and-old-ie
mixin定义了媒体查询和根类,以便您可以使用mixin来包装一段代码。这将输出
header {
background-color: blue;
}
@media screen and (min-width: 1200px) {
header {
background-color: red;
}
}
html.lt-ie9 header {
background-color: red;
}
现在可以将规则集分配给变量或传递给mixin,并且可以包含完整的Less功能集,例如
@my-ruleset: {
.my-selector {
background-color: black;
}
};
你甚至可以利用媒体查询起泡,例如
@my-ruleset: {
.my-selector {
@media tv {
background-color: black;
}
}
};
@media (orientation:portrait) {
@my-ruleset();
}
将输出
@media (orientation: portrait) and tv {
.my-selector {
background-color: black;
}
}
分离的规则集调用以与mixin调用相同的方式将其所有mixin解锁(返回)到调用者中。但是,它并没有返回变量。
返回的mixin:
// detached ruleset with a mixin
@detached-ruleset: {
.mixin() {
color: blue;
}
};
// call detached ruleset
.caller {
@detached-ruleset();
.mixin();
}
结果是:
.caller {
color: blue;
}
私有变量:
@detached-ruleset: {
@color:blue; // this variable is private
};
.caller {
color: @color; // syntax error
}
范围界定
分离的规则集可以使用在定义和调用位置都可访问的所有变量和混合。否则,定义和调用方作用域都可用。如果两个作用域包含相同的变量或混合,则声明作用域值优先。
声明范围是定义独立规则集主体的范围。将分离的规则集从一个变量复制到另一个变量无法修改其范围。仅在其中引用该规则集就无法访问新范围。
最后,分离的规则集可以通过被解锁(导入)到作用域中来访问。
注意:不赞成通过调用mixin将变量解锁到作用域中。使用属性/变量访问器。
定义和呼叫者范围可见性
分离的规则集可以看到调用方的变量和混合宏:
@detached-ruleset: {
caller-variable: @caller-variable; // variable is undefined here
.caller-mixin(); // mixin is undefined here
};
selector {
// use detached ruleset
@detached-ruleset();
// define variable and mixin needed inside the detached ruleset
@caller-variable: value;
.caller-mixin() {
variable: declaration;
}
}
编译成:
selector {
caller-variable: value;
variable: declaration;
}
从定义中可访问的变量和混入将胜过调用方中可用的那些:
@variable: global;
@detached-ruleset: {
// will use global variable, because it is accessible
// from detached-ruleset definition
variable: @variable;
};
selector {
@detached-ruleset();
@variable: value; // variable defined in caller - will be ignored
}
编译成:
selector {
variable: global;
}
引用不会修改分离的规则集范围
规则集不能仅在其中引用而获得对新作用域的访问:
@detached-1: { scope-detached: @one @two; };
.one {
@one: visible;
.two {
@detached-2: @detached-1; // copying/renaming ruleset
@two: visible; // ruleset can not see this variable
}
}
.use-place {
.one > .two();
@detached-2();
}
引发错误:
ERROR 1:32 The variable "@one" was not declared.
解锁将修改分离的规则集范围
分离的规则集通过在范围内解锁(导入)来获得访问权限:
#space {
.importer-1() {
@detached: { scope-detached: @variable; }; // define detached ruleset
}
}
.importer-2() {
@variable: value; // unlocked detached ruleset CAN see this variable
#space > .importer-1(); // unlock/import detached ruleset
}
.use-place {
.importer-2(); // unlock/import detached ruleset second time
@detached();
}
编译成:
.use-place {
scope-detached: value;
}
属性/变量访问器
(查询值)
发布了v3.5.0
从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];
}
查找中的变量变量
返回的查找值本身可以是可变的。如上所示,您可以编写:
@config: {
@dark: {
primary: darkblue;
}
@light: {
primary: lightblue;
}
}
.box {
@lookup: dark;
color: @config[@@lookup][primary];
}
这将输出:
.box {
color: darkblue;
}
@import规则
从其他样式表导入样式
在标准CSS中,@import
规则必须位于所有其他类型的规则之前。但是Less不在乎您将@import
语句放在何处。
例:
.foo {
background: #900;
}
@import "this-is-valid.less";
文件扩展名
@import
取决于文件扩展名,Less可以对语句进行不同的处理:
- 如果文件具有
.css
扩展名,它将被视为CSS,并且该@import
语句保持原样(请参见下面的内联选项)。 - 如果有其他扩展名,则将其视为Less并导入。
- 如果没有扩展名,
.less
将被附加,并将其作为导入的Less文件包含在内。
例子:
@import "foo"; // foo.less is imported
@import "foo.less"; // foo.less is imported
@import "foo.php"; // foo.php imported as a Less file
@import "foo.css"; // statement left in place, as-is
以下选项可用于替代此行为。
导入选项
Lessless提供了CSS
@import
CSS规则的几个扩展,以提供更多的灵活性来处理外部文件。
句法: @import (keyword) "filename";
已实现以下导入选项:
reference
:使用较少的文件,但不输出inline
:在输出中包含源文件,但不对其进行处理less
:无论文件扩展名是什么,都将其视为少文件css
:无论文件扩展名为什么,都将其视为CSS文件once
:仅包含一次文件(这是默认行为)multiple
:多次包含文件optional
:找不到文件时继续编译
每个关键字
@import
允许使用多个关键字,您必须使用逗号分隔关键字:
例: @import (optional, reference) "foo.less";
参考
使用@import (reference)
导入外部文件,只是不添加导入样式编译后的输出,除非引用。
发布了v1.5.0
例: @import (reference) "foo.less";
想象一下,在导入的文件reference
中用引用标记标记每个规则和选择器,并按常规进行导入,但是在生成CSS时,不会输出“引用”选择器(以及仅包含引用选择器的所有媒体查询)。reference
除非将参考样式用作mixins或extended,否则样式不会在生成的CSS中显示。
此外,reference
根据所使用的方法(混合或扩展),还会产生不同的结果:
- extend:扩展选择器时,仅将新选择器标记为未引用,并将其拉入引用
@import
语句的位置。 - mixins:当
reference
样式用作隐式mixin时,其规则将被混合,标记为“ not reference”,并照常显示在被引用的位置。
参考例子
这样,您可以通过执行以下操作从诸如Bootstrap之类的库中仅提取特定的,有针对性的样式:
.navbar:extend(.navbar all) {}
而且您将.navbar
仅从Bootstrap中提取相关样式。
排队
使用@import (inline)
包括外部文件,但不能对其进行处理。
发布了v1.5.0
例: @import (inline) "not-less-compatible.css";
当CSS文件可能不兼容时,您将使用此选项。这是因为尽管Less支持大多数已知的标准CSS,但在某些地方它不支持注释,并且不修改CSS就不支持所有已知的CSS hack。
因此,您可以使用它在输出中包含文件,以便所有CSS都在一个文件中。
减
使用@import (less)
治疗导入的文件一样都不能少,无论文件扩展名。
发布了v1.4.0
例:
@import (less) "foo.css";
的CSS
使用@import (css)
治疗导入的文件作为常规CSS,无论文件扩展名。这意味着import语句将保持原样。
发布了v1.4.0
例:
@import (css) "foo.less";
输出
@import "foo.less";
一旦
@import
语句的默认行为。这意味着该文件仅导入一次,该文件的后续导入语句将被忽略。
发布了v1.4.0
这是@import
语句的默认行为。
例:
@import (once) "foo.less";
@import (once) "foo.less"; // this statement will be ignored
多
使用@import (multiple)
允许使用相同的名称导入的多个文件。这是一次相反的行为。
发布了v1.4.0
例:
// file: foo.less
.a {
color: green;
}
// file: main.less
@import (multiple) "foo.less";
@import (multiple) "foo.less";
产出
.a {
color: green;
}
.a {
color: green;
}
可选的
用于@import (optional)
仅在文件存在时才允许导入。如果没有optional
关键字Less,则在导入找不到的文件时会引发FileError并停止编译。
发布了v2.3.0
@plugin规则
发布了v2.5.0
导入JavaScript插件以添加Less.js函数和功能
编写您的第一个插件
使用@plugin
的规则类似于使用@import
您的.less
文件。
@plugin "my-plugin"; // automatically appends .js if no extension
由于Less插件是在Less范围内求值的,因此插件定义可能非常简单。
registerPlugin({
install: function(less, pluginManager, functions) {
functions.add('pi', function() {
return Math.PI;
});
}
})
或者,您可以使用module.exports
(在浏览器以及Node.js中均可以使用(调整后))。
module.exports = {
install: function(less, pluginManager, functions) {
functions.add('pi', function() {
return Math.PI;
});
}
};
请注意,其他Node.js CommonJS约定require()
在浏览器中不可用。编写跨平台插件时请记住这一点。
您可以使用插件做什么?很多,但让我们从基础开始。我们将首先关注您可能在install
函数中放置的内容。假设您是这样写的:
// my-plugin.js
install: function(less, pluginManager, functions) {
functions.add('pi', function() {
return Math.PI;
});
}
// etc
恭喜你!您已经编写了一个Less插件!
如果要在样式表中使用此功能:
@plugin "my-plugin";
.show-me-pi {
value: pi();
}
您将获得:
.show-me-pi {
value: 3.141592653589793;
}
但是,如果您想将其与其他值相乘或执行其他Less操作,则需要返回一个适当的Less节点。否则,样式表中的输出为纯文本(可能对您有用)。
意思是,这更正确:
functions.add('pi', function() {
return new tree.Dimension(Math.PI);
});
注意:尺寸是有或没有单位的数字,例如“ 10px” less.Dimension(10, "px")
。有关单位列表,请参见Less API。
现在,您可以在操作中使用函数了。
@plugin "my-plugin";
.show-me-pi {
value: pi() * 2;
}
您可能已经注意到,插件文件有可用的全局变量,即函数注册表(functions
对象)和less
对象。这些是为了方便。
插件范围
@plugin
规则添加的功能遵循“少定义范围”规则。对于希望在不引入命名冲突的情况下添加功能的少图书馆作者来说,这非常有用。
例如,假设您有两个来自两个第三方库的插件,它们两个都有一个名为“ foo”的函数。
// lib1.js
// ...
functions.add('foo', function() {
return "foo";
});
// ...
// lib2.js
// ...
functions.add('foo', function() {
return "bar";
});
// ...
没关系!您可以选择哪个库的函数创建哪个输出。
.el-1 {
@plugin "lib1";
value: foo();
}
.el-2 {
@plugin "lib2";
value: foo();
}
这将产生:
.el-1 {
value: foo;
}
.el-2 {
value: bar;
}
对于共享插件的插件作者来说,这意味着您还可以通过将其置于特定范围内来有效地实现私有功能。就像这样,将导致错误:
.el {
@plugin "lib1";
}
@value: foo();
从Less 3.0开始,函数可以返回任何类型的Node类型,并且可以在任何级别调用。
这意味着,这将在2.x中引发错误,因为函数必须是属性或变量赋值的一部分:
.block {
color: blue;
my-function-rules();
}
在3.x中,情况不再如此,函数可以返回At-Rules,Rulesset,任何其他Less节点,字符串和数字(后两个将转换为Anonymous节点)。
空函数
有时您可能想调用一个函数,但是却不希望输出任何东西(例如存储一个值供以后使用)。在这种情况下,您只需false
要从函数中返回即可。
var collection = [];
functions.add('store', function(val) {
collection.push(val); // imma store this for later
return false;
});
@plugin "collections";
@var: 32;
store(@var);
稍后,您可以执行以下操作:
functions.add('retrieve', function(val) {
return new tree.Value(collection);
});
.get-my-values {
@plugin "collections";
values: retrieve();
}
Less.js插件对象
Less.js插件应导出具有一个或多个这些属性的对象。
{
/* Called immediately after the plugin is
* first imported, only once. */
install: function(less, pluginManager, functions) { },
/* Called for each instance of your @plugin. */
use: function(context) { },
/* Called for each instance of your @plugin,
* when rules are being evaluated.
* It's just later in the evaluation lifecycle */
eval: function(context) { },
/* Passes an arbitrary string to your plugin
* e.g. @plugin (args) "file";
* This string is not parsed for you,
* so it can contain (almost) anything */
setOptions: function(argumentString) { },
/* Set a minimum Less compatibility string
* You can also use an array, as in [3, 0] */
minVersion: ['3.0'],
/* Used for lessc only, to explain
* options in a Terminal */
printUsage: function() { },
}
该install()
函数的PluginManager实例提供添加访问者,文件管理器和后处理器的方法。
这是一些示例存储库,显示了不同的插件类型。
- 后处理器:https : //github.com/less/less-plugin-clean-css
- 访客:https://github.com/less/less-plugin-inline-urls
- 文件管理器:https : //github.com/less/less-plugin-npm-import
预装插件
虽然@plugin
呼叫在大多数情况下都能正常运行,但有时您可能想在解析开始之前加载插件。
请参阅:“使用Less.js”部分中的“ 预加载的插件 ”,以了解有关操作。
地图(新!)
发布了v3.5.0
使用规则集和混合作为值的映射
通过将命名空间与查找[]
语法结合使用,您可以将规则集/混合生成地图。
@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的功能,mixin作为地图的用途更为广泛。
#library() {
.colors() {
primary: green;
secondary: blue;
}
}
#library() {
.colors() { primary: grey; }
}
.button {
color: #library.colors[primary];
border-color: #library.colors[secondary];
}
输出:
.button {
color: grey;
border-color: blue;
}
您也可以通过别名mixins来简化此操作。那是:
.button {
@colors: #library.colors();
color: @colors[primary];
border-color: @colors[secondary];
}
注意,如果查找值产生另一个规则集,则可以追加第二个[]
查找,如下所示:
@config: {
@options: {
library-on: true
}
}
& when (@config[@options][library-on] = true) {
.produce-ruleset {
prop: val;
}
}
通过这种方式,规则集和变量调用可以模拟“名称间隔”类型,类似于混合。
至于是否使用分配给变量的mixin或规则集作为映射,则取决于您。您可能需要通过重新声明分配给rulset的变量来替换整个地图。或者您可能想“合并”单个键/值对,在这种情况下,将混合作为映射可能更合适。
在查询中使用变量变量
需要注意的重要一件事是,其中的值[@lookup]
是键(变量)名称@lookup
,而不是被评估为变量。如果您希望键名本身是可变的,则可以使用@@variable
语法。
例如
.foods() {
@dessert: ice cream;
}
@key-to-lookup: dessert;
.lunch {
treat: .foods[@@key-to-lookup];
}
这将输出:
.lunch {
treat: ice cream;
}