Less 学习。

313 阅读18分钟

开发工具

WebStorm

因为他支持创建 less文件,而且编辑好less文件后,自己生成css代码。

image.png

image.png

image.png

概览

Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。这里呈现的是 Less 的官方文档(中文版),包含了 Less 语言以及利用 JavaScript 开发的用于将 Less 样式转换成 CSS 样式的 Less.js 工具。

因为 Less 和 CSS 非常像,因此很容易学习。而且 Less 仅对 CSS 语言增加了少许方便的扩展,这就是 Less 如此易学的原因之一。

Less 语言特性

变量 Variables

变量不仅可以作用于值, 还可以作用于,选择器名称、属性名称、URL和@import语句。

变量选择器

// 变量
@my-selector: banner;

// 使用
.@{my-selector} {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
}

汇编成CSS代码:

.banner {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
}

变量URL

// 变量
@images: "/Less";
// 使用
body {
  color: #444;
  background: url("@{images}/white-sand.png");
}

汇编成CSS代码:

body {
  color: #444;
  background: url("/Less/white-sand.png");
}

变量导入语句

导入功能后续会用到。

// Variables
@themes: "../../src/themes";
@import "@{themes}/tidal-wave.less";

变量属性

@property: color;
.widget {
    @{property}: #0ee;
    background-@{property}: #999;
}

汇编成CSS代码:

.widget {
  color: #0ee;
  background-color: #999;
}

属性懒加载 Lazy Evaluation

变量在使用前不必声明。我暂且将他理解为JS中的“属性提升”功能。

.lazy-eval {
  width: @var;
}

@var: @a;
@a: 9%;

这样也可以

.lazy-eval {
  width: @var;
  @a: 9%;
}

@var: @a;
@a: 100%;

编译出来的CSS代码都是:

.lazy-eval {
  width: 9%;
}

当定义一个变量两次时,将使用该变量的最后一个定义,从当前范围向上搜索。这类似于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);  // 值为 black
  --color: black;
}

属性同时可以作为变量使用。

.widget {
  color: #efefef;
  background-color: $color;
}

编译成CSS代码:

.widget {
  color: #efefef;
  background-color: #efefef;
}

请注意,与变量一样,Less将选择当前/父范围内的最后一个属性作为“最终”值。

.block {
  color: red;
  .inner {
    background-color: $color;
  }
  color: blue;
} 

会变成CSS代码

.block {
  color: red;
  color: blue;
}
.block .inner {
  background-color: blue;
}

&父选择器

引用父选择器&

&运算符表示 嵌套规则的父选择器,最常用于将修改类或伪类应用于现有选择器:

a {
  color: blue;
  &:hover {
    color: green;
  }
}

汇编结果:

a {
  color: blue;
}
a:hover {
  color: green;
}

请注意,如果没有&,上面的示例将导致a :hover规则(匹配<a>标签内悬停元素的后代选择器),这不是我们通常想要的嵌套:hover

“父选择器”运算符有多种用途。基本上,任何时候,您需要以默认规则以外的其他方式组合嵌套规则的选择器。例如,&的另一个典型用途是生成重复的类名:

.button {
  &-ok {
    background-image: url("/123.png");
  }
  &-cancel {
    background-image: url("/234.png");
  }
}

汇编结果:

.button-ok {
  background-image: url("/123.png");
}
.button-cancel {
  background-image: url("/234.png");
}

请注意,&代表所有父选择器(而不仅仅是最近的祖先),因此示例如下:

.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('/123.png');
    }
  }
}

汇编结果:

.header .menu {
  border-radius: 5px;
}
.no-borderradius .header .menu {
  background-image: url('/123.png');
}

Combinatorial Explosion(组合爆炸)

&还可用于在逗号分隔列表中生成选择器的所有可能排列:

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;
}

Extend扩展

Extend是一个更少的伪类,它将它所安装的选择器与它引用的选择器合并。

nav ul {
  &:extend(.inline);
  background: blue;
}
.inline {
  color: red;
}

汇编结果:

nav ul {
  background: blue;
}
.inline,
nav ul {
  color: red;
}

这个过程可以理解为,在一个选择器里面引入(扩展)了另外一个选择器。

Extend语法

扩展要么附加到选择器上,要么放在规则集中。它看起来像一个伪类,选择器参数可选后跟关键字all

示例:

//放在选择器上
.a:extend(.b) {}
//放在规则集中
.a {
  &:extend(.b);
}

带有all

//放在选择器上
.a:extend(.b all) {}
//放在规则集中
.a {
  &:extend(.b all);
}

它可以包含一个或多个要扩展的类,用逗号分隔。

.a:extend(.b, .c) {}

Extend Attached to Selector(扩展附加到选择器)

附加到选择器的扩展看起来像一个以选择器为参数的普通伪类。选择器可以包含多个扩展子句,但所有扩展必须位于选择器的末尾。

  • 在选择器之后扩展:pre:hover:extend(div pre)
  • 选择器和扩展之间的空间是允许的:pre:hover :extend(div pre)
  • Multiple extends are allowed: pre:hover:extend(div pre):extend(.bucket tr) - Note this is the same as pre:hover:extend(div pre, .bucket tr)
  • 这是不允许的:pre:hover:extend(div pre).nth-child(odd)延期必须是最后期限。

如果规则集包含多个选择器,其中任何一个都可以具有扩展关键字。在一个规则集中扩展的多个选择器:

.big-division,
.big-bag:extend(.bag),
.big-bucket:extend(.bucket) {
  // body
}

扩展内部规则集

说明

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) {} // n

汇编成CSS:

.bucket tr,
.some-class {
  color: blue;
}

第n个表达式

//这个的意思是 使偶数标签 改变颜色以及字体
:nth-child(n+2) {
  color: #BF70A5;
  font-style: italic;
}

extend all (扩展"所有")

当您在扩展参数中指定最后一个关键字时,它会告诉Less将该选择器匹配为另一个选择器的一部分。选择器将被复制,然后仅选择器的匹配部分将被扩展替换,从而形成一个新的选择器。

.test.c {
  color: orange;
}
.test {
  &:hover {
    color: green;
  }
}
.replacement:extend(.test all) {}

汇编成CSS代码:

.test.c,
.replacement.c {
  color: orange;
}
.test:hover,
.replacement:hover {
  color: green;
}

可以将这种操作模式视为 本质上进行无损搜索和替换。

Scoping / Extend Inside @media

目前,@media声明中的:extend将仅匹配同一媒体声明中的选择器:

@media screen {
  .selector1 {  /* ruleset inside nested media - top level extend works */
    color: blue;
  }
  @media (min-width: 1023px) {
    .selector1 {  /* ruleset inside nested media - top level extend works */
      color: blue;
    }
  }
}
.topLevel:extend(.selector1) {} /* top level extend matches everything */

会变成CSS代码:

@media screen {
  .selector1,
  .topLevel {
    /* ruleset inside nested media - top level extend works */
    color: blue;
  }
}
@media screen and (min-width: 1023px) {
  .selector1,
  .topLevel {
    /* ruleset inside nested media - top level extend works */
    color: blue;
  }
}

重复检测

Less目前没有重复检测。

.alert-info,
.widget {
  /* declarations */
}
.alert:extend(.alert-info, .widget) {}

汇编成CSS:

.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;
}

汇编成CSS:

.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);
}

汇编成CSS:

.thing1 {
  display: inline-block;
  font-size: 0;
}
.thing2 {
  display: inline-block;
  font-size: 0;
}

merge 合并

merge功能允许将多个属性的值聚合到单个属性下的逗号或空格分隔列表中。merge对背景和转换等属性非常有用。

逗号

用逗号(,)附加属性值

实例:

.mixin() {
  box-shadow+: inset 0 0 10px #555;
}
.myclass {
  .mixin();
  box-shadow+: 0 0 20px black;
}

汇编成CSS:

.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);
}

为了避免任何无意的连接,merge需要在每个挂起声明的连接上有一个显式++_标志。

Mixins

从现有样式的“mix-in”属性, 您可以混合类选择器和ID选择器,例如

.a, #b {
  color: red;
}
.mixin-class {
  .a();
}
.mixin-id {
  #b();
}

汇编结果是:

.a,#b {
  color: red;
}
.mixin-class {
  color: red;
}
.mixin-id {
  color: red;
}

带括号的mix-in

如果您想创建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;
}

Namespaces 命名空间

如果您想在更复杂的选择器中混合属性,您可以堆叠多个ID或类。

#outer() {
  .inner {
    color: red;
  }
}
.c {
  #outer.inner();
}

汇编结果:

.c {
  color: red;
}

或者可以这样

#outer {
  .inner() {
    color: red;
  }
}

.c {
  #outer.inner();
}

汇编结果:

.c {
  color: red;
}

Guarded Namespaces(守护命名空间)

也就是带有条件的命名空间。

如果命名空间有守卫,则仅当守卫条件返回true时,才会使用由其定义的混合。命名空间守卫的计算与混合器上的守卫完全相同,因此以下两个混合器的工作方式相同:

#namespace when (@mode = huge) {
  .mixin() { /* */ }
}

#namespace {
  .mixin() when (@mode = huge) { /* */ }
}

!important关键词

在mixin调用后使用!important关键字将它继承的所有属性标记为!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;
}

mixin 参数

Mixins也可以接受参数,这些参数是混合时传递给选择器块的变量。

.border-radius(@radius) {
  border-radius: @radius;
}
#header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

Overloading mixins

定义多个具有相同名称和参数数量的mixins是合法的。” “Less”将使用所有适用的属性。

.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引用可以通过它们的名称而不是位置来提供参数值。任何参数都可以通过其名称引用,它们不必处于任何特殊顺序:

.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变量

@argumentsmixin内部有一个特殊的含义,它包含调用mixin时传递的所有参数。如果您不想处理单个参数,这非常有用:

.box-shadow(@x: 0, @y: 0, @blur: 1px, @color: #000) {
  box-shadow: @arguments;
}
.big-block {
  .box-shadow(2px, 5px);
}

汇编结果:

.big-block {
  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

@rest(没看懂)

.mixin(@a, @rest...) {
  // @rest is bound to arguments after @a
  // @arguments is bound to all arguments
}

模式匹配

里如果我们想要根据@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);
}

汇编结果:

.class {
  color: #a2a2a2;
  display: block;
}

解释:

  • 第一个混合定义不匹配,因为它预计第一个参数是dark
  • 第二个混合定义是匹配的,因为它预期light
  • 第三个mixin定义是匹配的,因为它期望任何值。

Using Mixins as Functions(使用Mixins函数)

从减去3.5开始,您可以使用属性/变量访问器从评估的混合规则中选择一个值。这可以让您使用类似于函数的mixins。

下面的例子,可以像Map一样访问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;
}

未命名的查找

如果您没有在[@lookup]中指定查找值,而是写入[]在mixin或规则集调用后,所有值都将级联,并将选择最后一个声明的值。

意思是:上述示例中的平均混合可以写为:

.average(@x, @y) {
  @result: ((@x + @y) / 2);
}
div {
  // call a mixin and look up its "@result" value
  padding: .average(16px, 50px)[];
}

汇编结果

div {
  padding: 33px;
}

递归Mixin

在Less的mixin中,mixin 可以调用自身。当这种递归混合与Guard表达式和模式匹配相结合时,可用于创建各种迭代/循环结构。

示例:

.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;
}

Mixin Guards (Mixin 守卫)

当您想要匹配表达式时,而不是简单的值或属性时,Guards非常有用。 

为了尽可能接近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;
}

.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }

汇编结果:

.class1 {
  background-color: black;
  color: #ddd;
}
.class2 {
  background-color: white;
  color: #555;
}

Guards 比较符号

守卫中可用的比较运算符的完整列表是:>,>=,=,=<,<。

必须要使条件成立。

使用and关键字组合条件:

.mixin(@a) when (isnumber(@a)) and (@a > 0) { ... }

使用逗号组合条件

.mixin(@a) when (@a > 10), (@a < -10) { ... }

使用not关键字否定条件:

.mixin(@b) when not (@b > 0) { ... }

类型检查功能

以下是基本的类型检查功能:

  • iscolor
  • isnumber
  • isstring
  • iskeyword
  • isurl

如果您想检查一个值是否在特定单位中,除了是一个数字外,您还可以使用以下之一:

  • ispixel
  • ispercentage
  • isem
  • isunit

将mixin调用分配给变量

#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赋值给一个变量,通过变量调用这个 mixin

#library() {
  .colors() {
    background: green;
  }
}
.box {
  @alias: #library.colors();
  @alias();
}

汇编结果:

.box {
  background: green;
}

但是如果把 mixin 作为选择器来使用。

.box {
  @alias: #library.colors;
  @{alias} {
    a: b;
  }
}
.box #library.colors {
  a: b;
}

区别在于:尾部是否带有 ()

image.png

独立规则集(闭包?)

一个分离的规则集是一组css属性、嵌套规则集、媒体声明或存储在变量中的任何东西。 您可以将它包含到一个规则集或另一个结构中,它的所有属性都将被复制到那里。 你也可以将它用作mixin参数,并将它作为任何其他变量传递。

当您想要定义一个mixin抽象出包装媒体查询中的一段代码或不支持的浏览器类名时,它非常有用。 规则集可以传递给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;
  });
}

汇编结果:

header {
  background-color: blue;
}
@media screen and (min-width: 1200px) {
  header {
    background-color: red;
  }
}
html.lt-ie9 header {
  background-color: red;
}

与mixin调用相同,分离的规则集调用将其所有mixin解锁(导入)到调用方。 但是,它不返回变量。

@detached-ruleset: {
  .mixin() {
    color: blue;
  }
};
// call detached ruleset
.caller {
  @detached-ruleset();
  .mixin();
}

汇编结果:

.caller {
  color: blue;
}

范围界定(Scoping)

一个分离的规则集可以在定义它的地方和调用它的地方使用所有可访问的变量和mixin。 也就是说,定义和调用者作用域都可用。 如果两个作用域包含相同的变量或mixin,则声明作用域值优先。  

声明作用域是定义分离规则集主体的作用域。 将分离的规则集从一个变量复制到另一个变量不能修改其作用域。 规则集不会通过被引用而获得对新作用域的访问权。  

最后,分离的规则集可以通过解锁(导入)到其中来获得对作用域的访问。  

注意:不推荐使用mixin将变量解锁到作用域中。 推荐使用属性/变量访问器。

从定义中可访问的变量和mixin胜过调用者中可用的变量和mixin:

@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: value;
}

引用不会修改已分离的规则集作用域 关键词:scope-detached

@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();
}

报错

variable @one is undefined

解锁将会修改已分离的规则集作用域 分离的规则集通过在范围内解锁(导入)来获得访问权限:

#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;
}

属性/变量访问器(我把他理解为一个map通过key查找value)

从Less 3.5开始,您可以使用属性/变量访问器(也称为“查找”)从变量(分离的)规则集中选择值。

@config: {
  option1: true;
  option2: false;
}

.mixin() when (@config[option1] = true) {
  selected: value;
}

.box {
  .mixin();
}

汇编结果:

.box {
  selected: value;
}

他也可以这样:

@config: {
  @dark: {
    primary: darkblue;
  }
  @light: {
    primary: lightblue;
  }
}

.box {
  @lookup: dark;
  color: @config[@@lookup][primary];
}

汇编结果:

.box {
  color: darkblue;
}

@import 规则

在标准的CSS中,@import at-rules必须先于所有其他类型的规则。 但是Less并不关心你把@import语句放在哪里。

.foo { background: #900; } 
@import "this-is-valid.less";

文件扩展名

  • 如果文件具有.css扩展名,它将被视为CSS,并将@import语句视为原样。
  • 如果它有任何其他扩展,它将被视为less并导入。
  • 如果它没有扩展名,.less将被附加,并将它作为导入的更少文件包含在内。

导入选项(Import Options)

Less为CSS @import CSS at-rule提供了几个扩展,为您处理外部文件提供了更多的灵活性。

语法:@import (keyword) "filename";

已实施以下导入选项:

  • reference:使用Less的文件,但不要输出它
  • inline:在输出中包含源文件,但不要处理它
  • less:将文件视为less的文件,无论文件扩展名是什么
  • css:将文件视为CSS文件,无论文件扩展名是什么
  • once:只包含一次文件(这是默认行为)
  • multiple:多次包含文件
  • optional:当找不到文件时,继续编译

每个@import允许多个关键字,您必须使用逗号来分隔关键字:

示例:@import (optional, reference) "foo.less";

Less

无论文件扩展名如何,使用@import (less)将导入的文件视为更少。

CSS

使用@import (css)将导入的文件视为常规CSS,无论文件扩展名如何。这意味着导入语句将保持原样。

once

@import语句的默认行为。这意味着该文件仅导入一次,该文件的后续导入语句将被忽略。

multiple

使用@import (multiple)允许导入多个同名文件。这与一次相反。

optional

使用@import (optional)仅在文件存在时才允许导入文件。如果没有optional关键字,Lesss会抛出FileError,并在导入找不到的文件时停止编译。

@plugin 规则

导入JavaScript插件以添加Less.js功能和功能

使用@plugin at-rule类似于为.less文件使用@import。

编写第一个插件。

my-plugin.js 文件

functions.add('pi', function() {
    return new tree.Dimension(Math.PI);
});

my-plugin.less 文件

@plugin "my-plugin";
.show-me-pi {
  value: pi();
}

编译后CSS文件

.show-me-pi {
  value: 3.14159265;
}

就是这么简单。

插件范围(Plugin Scope)

@plugin at-rule添加的函数遵循Less作用域规则。 这对于想要添加功能而不引入命名冲突的Less库作者来说非常好。

例如,假设您有两个来自两个第三方库的插件,这两个插件都有一个名为“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();
}

编译后CSS代码:

.el-1 {
    value: foo;
}
.el-2 {
    value: bar;
}

空函数

有时,您可能想调用函数,但不想要任何输出(例如存储值以供以后使用)。在这种情况下,您只需要从函数返回false

var collection = [];

functions.add('store', function(val) {
    collection.push(val);  // imma store this for later
    return false;
});
@plugin "collection";
@var: 32;
store(@var);

Map (新!)

发布v3.5.0

使用规则集和mixins作为值的映射  

通过将名称空间与lookup[]语法结合起来,您可以将规则集/ mixins转换为映射。

@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;
  }
}

由于名称空间和重载Mixins的能力,Mixins作为映射更通用一些。

#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;
}

也可以使用 aliasing mixins 来简化此操作

.button {
  @colors:#library.colors[primary];
  color: @colors[primary];
  border-color: @colors[secondary];
}

如果查找值产生另一个规则集,您可以附加第二个[]查找,如:

@config: {
  @options: {
    library-on: true
  }
}

& when (@config[@options][library-on] = true) {
  .produce-ruleset {
    prop: val;
  }
}

在查找中使用变量

需要注意的一件重要的事情是,[@lookup]中的值是键(变量)名称@lookup,而不是作为变量计算。如果您希望密钥名称本身是可变的,您可以使用@@variable语法。

.foods() {
  @dessert: ice cream;
}

@key-to-lookup: dessert;

.lunch {
  treat: .foods[@@key-to-lookup];
}