Edit the markdown source for "features-overview"

Less作为CSS的扩展,不仅向下兼容CSS,而且Less是在现有CSS语法基础上增添的额外特性,这使Less更容易上手,如果有疑问,可以回退的普通的CSS。

1.变量

变量看上去就一目了然:

@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header {
  color: @light-blue;
}

输出为:

#header {
  color: #6c94be;
}

请注意,变量实际上是“常量”,因为它们只能被定义一次。

2.混合

混合是一种将一个规则集中包含(“混入”)一组属性插入到另一个规则集的方法。 比如说有以下class:

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

我们希望在其他规则集中使用这些属性。 那么,我们只需要将我们想要放入其中的规则集的class名称放入,就像这样:

#menu a {
  color: #111;
  .bordered;
}

.post a {
  color: red;
  .bordered;
}

“.bordered” 这个class的属性现在将出现在“#menu a”和“.post a”中。 (请注意,您也可以使用#ids作为混合。)

了解更多

3.嵌套规则

Less使您能够使用嵌套代替CSS中逐级书写。 假设我们有以下CSS:

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

我们可以使用Less这样书写:

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

模仿HTML的结构,使代码更加简洁。

你也可以使用这种方法将伪选择器与混合捆绑在一起。这是经典的clearfix hack,用混合重写(代表当前的父选择器):

.clearfix {
  display: block;
  zoom: 1;

  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

参见

4.嵌套指令和冒泡

像“media”或“keyframe”这样的指令可以像选择器一样嵌套。 指令放置在顶部,相对于同一规则集内其他元素的相对顺序保持不变。 这叫做冒泡。

条件指令,例如 @ Media@ supports@ document选择器会被复制到它们的主体中:

.screen-color {
  @media screen {
    color: green;
    @media (min-width: 768px) {
      color: red;
    }
  }
  @media tv {
    color: black;
  }
}

编译为

@media screen {
  .screen-color {
    color: green;
  }
}
@media screen and (min-width: 768px) {
  .screen-color {
    color: red;
  }
}
@media tv {
  .screen-color {
    color: black;
  }
}

其他的非条件指令,例如font-facekeyframes,也会冒泡。 它们的主体不会改变:

#a {
  color: blue;
  @font-face {
    src: made-up-url;
  }
  padding: 2 2 2 2;
}

编译为

#a {
  color: blue;
}
@font-face {
  src: made-up-url;
}
#a {
  padding: 2 2 2 2;
}

5.运算

算术运算+``,*/可以在任何数字,颜色或变量上运行。 数学运算会尽可能将单位考虑在内并在加,减或比较之前转换为数字。 结果最左边明确指出的单位类型。 如果是无意义或无效的转换,则单位被忽略。 无法转换的示例:px到cm或rad到%。

// 数字运算被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果为 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果为 -1.5cm

// 无效的转换
@incompatible-units: 2 + 5px - 3cm; // 结果为 4px

// 带变量的例子
@base: 5%;
@filler: @base * 2; // 结果为 10%
@other: @base + @filler; // 结果为 15%

乘法和除法不转换数字。 在大多数情况下,这是没有意义的 - 长度乘以长度会给出一个区域,而css不支持指定区域。 Less将按原样操作数字,并将明确指定的单位类型分配给结果。

@base: 2cm * 3mm; // 结果是 6cm

颜色分为红色,绿色,蓝色和alpha值。 该操作分别应用于每个颜色维度。 例如,如果用户添加了两种颜色,则结果的绿色维度等于输入颜色的绿色维度的总和。 如果用户乘以一个数字的颜色,则每个颜色尺寸将相乘。

注意:没有定义对alpha的算术运算,因为对颜色的数学运算没有标准的约定意义。 不要依赖当前的实现,因为它可能会在更高版本中更改

对颜色的操作总是产生有效的颜色。 如果结果的某个颜色尺寸大于ff或小于00,那么这个尺寸被舍入为ff00。 如果alpha结果大于1.0或小于0.0,则alpha被舍入为1.00.0

@color: #224488 / 2; //结果为 #112244
background-color: #112244 + #111; // 结果为 #223355

6.转义

转义允许您使用任何任意字符串作为属性或变量值。 任何~~任何内容都可以按照原样使用,除了插值之外没有任何变化。

.weird-element {
  content: ~"^//* some horrible but needed css hack";
}

results in:

.weird-element {
  content: ^//* some horrible but needed css hack;
}

7.函数

Less提供变换颜色,操作字符串和数学运算的各种函数。 具体在函数参考表中有完整记录。

使用函数非常简单。 以下示例使用百分比来转换0.5到50%,将基本颜色的饱和度增加5%,然后将背景颜色设置为减少25%并旋转8度的颜色:

@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // 返回 `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}

8.命名空间和访问器

(不要混淆 CSS @namespace命名空间选择器).

有时,为了组织结构,你可能想要分组你的mixins,或者只是提供一些封装。 你可以在Less中很直观地做到这一点,比如你想在#bundle下捆绑一些mixin和变量,以便以后重用或分发:

#bundle {
  .button {
    display: block;
    border: 1px solid black;
    background-color: grey;
    &:hover {
      background-color: white
    }
  }
  .tab { ... }
  .citation { ... }
}

现在,如果我们要在#header a中混入.button类,我们可以这样做:

#header a {
  color: orange;
  #bundle > .button;
}

Note that variables declared within a namespace will be scoped to that namespace only and will not be available outside of the scope via the same syntax that you would use to reference a mixin (#Namespace > .mixin-name). So, for example, you can't do the following: (#Namespace > @this-will-not-work).

请注意,在名称空间中声明的变量将仅限于该名称空间,当你想引用一个mixin (#Namespace> .mixin-name),相同的语法在作用域之外将会失效。例如,你不能这样使用:(#Namespace > @this-will-not-work)。

9.作用域

Less中的作用域与编程语言非常相似。 首先在本地查找变量和mixin,如果找不到,编译器将查找父范围,依此类推。

@var: red;

#page {
  @var: white;
  #header {
    color: @var; // 白色
  }
}

变量和mixin在使用之前不必声明,所以下面的Less代码和前面的例子是一样的:

@var: red;

#page {
  #header {
    color: @var; // 白色
  }
  @var: white;
}

参见

10.注释

可以使用块式和行内式注释:

/* 块式风格
  注释 */
@var: red;

// 行内式注释!
@var: white;

11.导入

导入非常便捷。 你可以导入一个.less文件,可以使用其中的所有变量。 默认扩展名为.less文件。

@import "library"; // library.less
@import "typo.css";

Edit the markdown source for "variables"

将常用的属性值提取出来。

1.概述

在样式表中看到相同的属性值重复许多次甚至上百次,这并不是罕见的情况:

a,
.link {
  color: #428bca;
}
.widget {
  color: #fff;
  background: #428bca;
}

使用变量将这些属性值提取到一个地方会使代码变得更易于维护:

// 定义变量
@link-color:        #428bca; // 海蓝色
@link-color-hover:  darken(@link-color, 10%);

// 使用方法
a,
.link {
  color: @link-color;
}
a:hover {
  color: @link-color-hover;
}
.widget {
  color: #fff;
  background: @link-color;
}

2.变量插补

上面例子中,着重于使用变量提取CSS规则中的属性值,其实变量也可以在其他地方使用,例如选择器名称,URL,以及“@ import”语句。

2-1.选择器

Version: 1.4.0

// 定义变量
@my-selector: banner;

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

编译为:

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

3.URLs

// 定义变量
@images: "../img";

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

3-1.声明import

Version: 1.4.0

语法: @import "@{themes}/tidal-wave.less";

请注意,在v2.0.0之前,只允许在根目录或当前作用域内声明的变量,并且只能在当前文件和调用文件中查找变量。

例如:

// 定义变量
@themes: "../../src/themes";

// 使用方法
@import "@{themes}/tidal-wave.less";

3-2.属性

Version: 1.6.0

@property: color;

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

编译为:

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

4.变量名定义

也可以使用一个变量来定义变量名称:

@fnord:  "I am fnord.";
@var:    "fnord";
content: @@var;

编译为:

content: "I am fnord.";

5.惰性加载

变量可以惰性加载,不必在使用之前进行声明。

合法的Less语法:

.lazy-eval {
  width: @var;
}

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

同样合法:

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

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

都会被编译为:

.lazy-eval-scope {
  width: 9%;
}

当同一个变量被定义两次,第二次定义的变量将会生效,并从当前作用域开始向上查找,这与CSS中定义的最后一个属性值会被使用的规则类似。 例如:

@var: 0;
.class {
  @var: 1;
  .brass {
    @var: 2;
    three: @var;
    @var: 3;
  }
  one: @var;
}

编译为:

.class {
  one: 1;
}
.class .brass {
  three: 3;
}

6.变量默认值

我们有时候会需要设置变量默认值 - 只有变量在尚未使用的情况下才能设置。 此功能不是必需的,因为你可以地通过之后的定义来覆盖默认变量。

For instance:

// library
@base-color: green;
@dark-color: darken(@base-color, 10%);

// 使用library
@import "library.less";
@base-color: red;

其原作机制是因为 惰性加载 - base-color 会被覆盖 and dark-color 将会是深红色。


Edit the markdown source for "extend"

Extend是Less的一个伪类,它会把所选择的选择器与它所引用的选择器进行合并。

发布v1.4.0

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

在上面的规则集中,:extend选择器会将“扩展选择器”(nav ul)应用到 .inline class 出现的 .inline class中 。 声明块将保持原样,并不会直接添加extend中的属性(因为extend不是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时输出结果 - 在输出之前将extend移除,而选择器块保持原样。 如果没有任何属性放在该块中,则会从输出中移除(但extend仍然可能会影响其他选择器)。

1.Extend 语法

extend要么附加到选择器,要么放在规则集中。 它看起来像一个带有选择器参数的伪类,可搭配关键字all

例子:

.a:extend(.b) {}

// 上面和下面的会得到同样的结果。
.a {
  &:extend(.b);
}
.c:extend(.d all) {
  // extend “.d”的所有实例,例如 “.x.d”或“.d.x”。
}
.c:extend(.d) {
  // ".d"仅继承实例将被输出为“.d”的选择器。
}

可以继承包含一个或多个类,以逗号分隔。

例如:

.e:extend(.f) {}
.e:extend(.g) {}

// 上面和下面的将会得到同样的结果。
.e:extend(.f, .g) {}

2.Extend 附加到选择器

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

  • 在选择器之后Extend: pre:hover:extend(div pre).
  • 选择器和Extend之间允许有空格: pre:hover :extend(div pre).
  • 运行多个Extend: pre:hover:extend(div pre):extend(.bucket tr) - 请注意,这是相同的 pre:hover:extend(div pre, .bucket tr)
  • 这是不允许的: pre:hover:extend(div pre).nth-child(odd). Extend必须在末尾。

如果一个规则集包含多个Extend,它们中的任何一个都可以有个Extend关键字。 多个带有Extend的选择器在一个规则集中:

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

3.Extend 在规则集中

Extend 可以被放在一个规则集的主体中通过使用 &:extend(selector) 语法。将Extend放到主体中就是将其放到该规则集的每个选择器中的快捷方式。

Extend 在一个主体中:

pre:hover,
.some-class {
  &:extend(div pre);
}

与每个选择器之后添加Extend完全相同:

pre:hover:extend(div pre),
.some-class:extend(div pre) {}

4.Extend 嵌套选择器

Extend能够匹配嵌套的选择器。 如下:

例子:

.bucket {
  tr { // 与目标选择器嵌套的规则集
    color: blue;
  }
}
.some-class:extend(.bucket tr) {} // 嵌套的规则集被识别

编译为

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

Extend本质上接受的是编译后的CSS,而不是原始的Less。

例如:

.bucket {
  tr & { // 与目标选择器嵌套的规则集
    color: blue;
  }
}
.some-class:extend(tr .bucket) {} // 嵌套的规则集被识别

编译为

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

5.Extend 精确匹配

在默认情况下Extend会查找精确匹配到的选择器。 无论选择者器是否使用通配符*,或者两个nth表达式是否具有相同的含义,它们都需要具有相同的形式才能被匹配。 唯一的例外是属性选择器中的单引号和双引号,less知道它们具有相同的含义并会匹配它们。

例如:

.a.class,
.class.a,
.class > .a {
  color: blue;
}
.test:extend(.class) {} // 以上选择器都不会被匹配

带通配符不会被匹配。 虽然 *.class.class 是一样的效果, 但是 extend 不会匹配它们:

*.class {
  color: blue;
}
.noStar:extend(.class) {} //  *.class 将不会被匹配

编译为

*.class {
  color: blue;
}

伪类的顺序很重要。选择器 link:hover:visitedlink:visited:hover 会匹配相同的一组元素,但是对于extend,它们是不同的:

link:hover:visited {
  color: blue;
}
.selector:extend(link:visited:hover) {}

编译为

link:hover:visited {
  color: blue;
}

6.nth 表达式

Nth 表达形式很重要。 Nth表达式 1n+3n+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;
}

7.Extend "all"

当使用关键字all在extend参数的最后时,Less会将其作为另一个选择器的一部分匹配该选择器。选择器将被复制,只有选择器匹配部分将被替换为extend,同时创建一个新的选择器。

例如:

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

你可以把这种操作模式看作是一个非破坏性的搜索和替换。

8.选择器中插入Extend

Extend 不能匹配带变量的选择器. 如果选择器中带有变量, 将会被extend忽略。

有一个悬而未决的提案,同时也不会轻易改变。 但是,extend可以附加到被插值的选择器。

带变量的选择器将不会被匹配:

@variable: .bucket;
@{variable} { // 被插值的选择器
  color: blue;
}
.some-class:extend(.bucket) {} // 不会被匹配

同时在目标选择器中使用变量也不会被extend匹配到:

.bucket {
  color: blue;
}
.some-class:extend(@{variable}) {} // 被插值的选择器不会被匹配
@variable: .bucket;

上述两个例子都编译成:

.bucket {
  color: blue;
}

然而, :extend 附加到一个被插值得选择器上是可以有效的:

.bucket {
  color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;

编译为

.bucket, .selector {
  color: blue;
}

9.作用于 / 在@media中使用Extend

在媒体查询中声明Extend只匹配同一媒体查询中的选择器:

@media print {
  .screenClass:extend(.selector) {} // 在@media中使用Extend
  .selector { // 会被匹配 - 在同一个媒体查询中
    color: black;
  }
}
.selector { // 规则集在样式表的顶部 - extend会忽略它
  color: red;
}
@media screen {
  .selector {  // 规则集在另一个媒体查询中 - extend会忽略它
    color: blue;
  }
}

编译为

@media print {
  .selector,
  .screenClass { /*  在同一个媒体查询中的规则集将会被集成 */
    color: black;
  }
}
.selector { /* 规则集在样式表的顶部被忽略 */
  color: red;
}
@media screen {
  .selector { /* 规则集在另一个媒体查询中被忽略 */
    color: blue;
  }
}

Extend在媒体查询中不会匹配媒体查询中嵌套的选择器:

@media screen {
  .screenClass:extend(.selector) {} // extend在媒体查询中
    .selector {  //规则集在媒体查询的嵌套中- extend会忽略它
      color: blue;
    }
  }
}

编译为

@media screen and (min-width: 1023px) {
  .selector { /* 规则集在另一个媒体查询的嵌套中,会被忽略 */
    color: blue;
  }
}

顶级的extend会匹配包括嵌套在媒体查询内的所有选择器:

@media screen {
  .selector {  /* 规则集嵌套在媒体查询中 - 顶级 extend 有效 */
    color: blue;
  }
  @media (min-width: 1023px) {
    .selector {  /* 规则集嵌套在媒体查询中 - 顶级 extend 有效 */
      color: blue;
    }
  }
}

.topLevel:extend(.selector) {} /* 顶级 extend都会匹配 */

编译为

@media screen {
  .selector,
  .topLevel { /* 在媒体查询中的规则集会被继承 */
    color: blue;
  }
}
@media screen and (min-width: 1023px) {
  .selector,
  .topLevel { /* 在媒体查询中的规则集会被继承 */
    color: blue;
  }
}

10.重复检测

目前没有重复检测。

例如:

.alert-info,
.widget {
  /* 声明 */
}

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

编译为

.alert-info,
.widget,
.alert,
.alert {
  /* 声明 */
}

11.Extend用例

11.1经典用例

其中一个经典用例是避免添加一个基本class。 例如:

.animal {
  background-color: black;
  color: white;
}

你希望有一个animal子类型并覆盖其背景颜色,那么你有两个选择,首先,一种是改变你的HTML

<a class="animal bear">Bear</a>
.animal {
  background-color: black;
  color: white;
}
.bear {
  background-color: brown;
}

或着简化HTML和在Less中使用Extend。 例如:

<a class="bear">Bear</a>
.animal {
  background-color: black;
  color: white;
}
.bear {
  &:extend(.animal);
  background-color: brown;
}

11.2减少CSS大小

Mixins会将所有的属性复制到一个选择器,这可能会导致不必要的重复。 因此,可以使用Extend替代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;
}

例子 - 使用 Extend:

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

11.3样式组合 / 更先进的 Mixin

还有一个用例是替代mixin - 因为mixins只能与简单的选择器一起使用,如果你有两个不同的html块,但是需要使用相同的样式,你可以使用extends来关联两个区域。

例如:

li.list > a {
  // list 样式
}
button.list-style {
  &:extend(li.list > a); // 使用同样的 list 样式
}

Edit the markdown source for "mixins"

从现有样式的“混入”属性

您可以混入类选择器和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;

1.不输出Mixin

如果你想创建一个mixin,但你不想要输出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;
}

2.Mixins中的选择器

Mixins不仅可以包含属性,还可以包含选择器。

例子:

.my-hover-mixin() {
  &:hover {
    border: 1px solid red;
  }
}
button {
  .my-hover-mixin();
}

编译为

button:hover {
  border: 1px solid red;
}

3.命名空间

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

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

.c {
  #outer > .inner;
}

> 和空格是可选的

// 全部都是同样的效果
#outer > .inner;
#outer > .inner();
#outer .inner;
#outer .inner();
#outer.inner;
#outer.inner();

这种使用称为命名空间。 你可以把你的mixin放在一个id选择器下,这样可以确保它不会和另一个库冲突。

例子:

#my-library {
  .my-mixin() {
    color: black;
  }
}
// 可以这样使用
.class {
  #my-library > .my-mixin();
}

4.命名空间警戒

如果名称空间有一个警戒,那么只有在警戒条件返回true的情况下才能使用定义的mixins。 命名空间警戒的评估方式与mixin上的警戒完全相同,所以接下来的两个mixin的工作方式相同:

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

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

对于所有嵌套的命名空间和mixin,default函数被假定为相同的值。 mixin从来没有被评估过,其中一个警戒保证是假的:

#sp_1 when (default()) {
  #sp_2 when (default()) {
    .mixin() when not(default()) { /* */ }
  }
}

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

Edit the markdown source for "mixins-parametric"

如何将参数传递给mixin

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

border-radius将会为5px。

你也可以使用不带参数的参数mixins。 如果您希望从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;
}

1.多参数Mixins

参数是分号逗号分隔。 建议使用分号。 逗号有双重含义:它可以被解释为混合参数分隔符或CSS列表分隔符。

使用逗号作为mixin分隔符使得不能再用逗号作为参数创建分隔列表。 另一方面,如果编译器在mixin调用或声明中看到至少一个分号,则假定参数以分号分隔,并且所有逗号都属于css列表:

  • 两个参数,每个都包含逗号分隔列表: .name(1, 2, 3; something, else),
  • 三个参数,每个包含一个数字: .name(1, 2, 3),
  • 使用分号模拟创建一个包含逗号分隔的CSS列表参数的mixin调用: .name(1, 2, 3;),
  • 逗号分隔默认值: .name(@param1: red, blue;).

定义多个具有相同名称和参数的mixin是合法的。 Less将使用所有可以用属性。 如果你用了一个参数的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;
}

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

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

4.高级参数和@rest变量

如果你想让你的mixin获取可变数量的参数,你可以使用...。 在变量名后使用这个参数将把这些参数赋值给变量。

.mixin(...) {        // 匹配0-N个参数
.mixin() {           // 精确匹配0个参数
.mixin(@a: 1) {      // 匹配0-1个参数
.mixin(@a: 1; ...) { // 匹配0-N个参数
.mixin(@a; ...) {    // 匹配1-N个参数

此外:

.mixin(@a; @rest...) {
   // @在@a之后,@rest被绑定到参数上
   // @arguments 会接受所有参数
}

5.模式匹配

有时,可能想要根据传递给它的参数来改变mixin的行为。 让我们从基本的东西开始:

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

编译为:

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

传到.mixin的颜色变浅了。 如果@ switch的值是dark,结果将是一个更深的颜色。

以下是发生的事情:

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

只有mixin匹配的结果被使用。 变量会匹配并绑定到任意值。 除变量以外的任何内容只与等于它自己的值相匹配。

同样可以根据参数数量匹配,例如:

.mixin(@a) {
  color: @a;
}
.mixin(@a; @b) {
  color: fade(@a; @b);
}

现在,如果我们用一个参数调用.mixin,我们将得到第一个定义的输出, 但是如果我们用2个参数来调用它,我们会得到第二个定义,即@ a渐变为@ b


Edit the markdown source for "mixins-as-functions"

从mixin返回变量或mixin

在mixin中定义的变量和mixin是可见的,可用于调用者的作用域。 只有一个例外,如果调用者包含相同名称的变量(包括在另一个mixin调用中定义的变量)时,变量不会被复制。 只有调用者本地作用域中的变量才受保护。 从父范围继承的变量会被覆盖。

例子:

.mixin() {
  @width:  100%;
  @height: 200px;
}

.caller {
  .mixin();
  width:  @width;
  height: @height;
}

编译为

.caller {
  width:  100%;
  height: 200px;
}

Thus variables defined in a mixin can act as its return values. This allows us to create a mixin that can be used almost like a function.

因此,在mixin中定义的变量可以作为其返回值。 这使我们可以像创建函数一样创建一个mixin。

例子:

.average(@x, @y) {
  @average: ((@x + @y) / 2);
}

div {
  .average(16px, 50px); // "调用" mixin
  padding: @average;    // 使用其"返回"值
}

编译为

div {
  padding: 33px;
}

在当前作用域中定义的变量不能被覆盖。 但是,在其父作用域中定义的变量不受保护并会被覆盖:

.mixin() {
  @size: in-mixin;
  @definedOnlyInMixin: in-mixin;
}

.class {
  margin: @size @definedOnlyInMixin;
  .mixin();
}

@size: globaly-defined-value; // 调用者父作用域 - 不受保护

编译为

.class {
  margin: in-mixin in-mixin;
}

最后,mixin中定义的mixin也作为返回值:

.unlock(@value) { // 外层 mixin
  .doSomething() { // 嵌套 mixin
    declaration: @value;
  }
}

#namespace {
  .unlock(5); // unlock doSomething mixin
  .doSomething(); //嵌套的mixin被复制到这里,可用
}

编译为:

#namespace {
  declaration: 5;
}

Edit the markdown source for "detached-rulesets"

允许在mixin中定义一个包裹的css块

发布 v1.7.0

分离的规则集是一组css属性,嵌套的规则集,媒体查询或存储在变量中的其他内容。 你可以将它包含到一个规则集或其他结构中,它所有的属性都将被复制到过去。 你也可以用它作为一个mixin参数,并把它作为任何其他变量传递。

例子:

// 声明分离的规则集
@detached-ruleset: { background: red; };

// 使用分离的规则集
.top {
    @detached-ruleset(); 
}

编译为:

.top {
  background: red;
}

调用分离的规则集必需使用括号。 不能用@ detached-ruleset;调用。

当你想要定义一个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;
  });
}

这里desktop-and-old-ie mixin定义了媒体查询和根class,这样你就可以使用一个mixin来包裹一段代码。编译为

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

一个规则集可以立刻分配给一个变量,或者被传递给一个混合,并且可以包含一整套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:

// 带mixin的分离规则集
@detached-ruleset: { 
    .mixin() {
        color:blue;
    }
};
// 调用分离的规则集
.caller {
    @detached-ruleset(); 
    .mixin();
}

编译为:

.caller {
  color: blue;
}

私有变量:

@detached-ruleset: { 
    @color:blue; //这是个私有变量
};
.caller {
    color: @color; // 语法报错
}

1.作用域

一个分离的规则集可以使用所有的变量和mixin,它们在被定义被调用处被访问。即定义和调用者作用域都可用。 如果两个作用域都包含相同的变量或mixin,则当前声明的作用域中的值优先。

声明作用域被定义为分离规则主题。将分离规则集从一个变量复制到另一个变量时,不能修改其范围。 规则集不能仅通过在那里引用就可访问新的作用域。

最后,分离的规则集可以通过解锁(导入)的方式来访问作用域。

1-1.定义和调用作用域可见性

分离的规则集可以看到调用者的变量和mixin:

@detached-ruleset: {
  caller-variable: @caller-variable; // 变量在这里未定义
  .caller-mixin(); // mixin在这里未定义
};

selector {
  // 使用分离规则集
  @detached-ruleset(); 

  // 在分离的规则集内定义需要的变量和mixin
  @caller-variable: value;
  .caller-mixin() {
    variable: declaration;
  }
}

编译为

selector {
  caller-variable: value;
  variable: declaration;
}

变量和mixins可访问到的外部定义优先于调用者中可用的定义:

@variable: global;
@detached-ruleset: {
  // 使用全局变量,因为其可以访问
  // 从分离规则集定义
  variable: @variable; 
};

selector {
  @detached-ruleset();
  @variable: value; // 在调用者中定义的变量将被忽略
}

编译为:

selector {
  variable: global;
}

1-2.引用不会修改分离规则集的作用域

规则集不能仅仅通过引用而访问新的作用域:

@detached-1: { scope-detached: @one @two; };
.one {
  @one: visible;
  .two {
    @detached-2: @detached-1; // 复制/重命名规则集
    @two: visible; // 规则集不能访问这个变量
  }
}

.use-place {
  .one > .two(); 
  @detached-2();
}

报错:

ERROR 1:32 The variable "@one" was not declared.

1-3.解锁修改分离规则集的作用域

分离的规则集通过在范围内解锁(导入)来获得访问权限:

#space {
  .importer-1() {
    @detached: { scope-detached: @variable; }; // 定义分离规则集
  }
}

.importer-2() {
  @variable: value; // 解锁分离的规则集CAN可以看到这个变量
  #space > .importer-1(); // 解锁/导入分离的规则集
}

.use-place {
  .importer-2(); // 再次解锁/导入分离的规则集
   @detached();
}

编译为:

.use-place {
  scope-detached: value;
}

Edit the markdown source for "import-directives"

从其他样式表导入样式

在标准CSS中,@import 规则必须在所有其他类型规则之前。 但 不关心你把@ import语句放在哪里。

例如:

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

1.文件扩展名

@import statements may be treated differently by Less depending on the file extension:

根据Less文件扩展名的不同,会用不同方式处理@import语句:

  • 如果文件具有.css扩展名,那么它将被视为CSS并且@ import语句保持原样 (参见 内联选项 below).
  • 如果为其他扩展名它将被视为Less文件并被导入。
  • 如果没有扩展名,则会追加“.less”,并将其作为Less文件导入。

例如:

@import "foo";      // foo.less 被导入
@import "foo.less"; // foo.less 被导入
@import "foo.php";  // foo.php 作为Less文件被导入
@import "foo.css";  // 保留原本的导入声明

以下配置项可用于覆盖此行为。

import配置项

Less offers several extensions to the CSS @import CSS at-rule to provide more flexibility over what you can do with external files.

Less提供了几个CSS@import规则扩展项,在使用外部文件时提供更多的灵活性。

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

以下导入指令已经被实现:

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

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

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

1.reference

使用@import (reference))导入外部文件,但不会将导入的样式添加到编译后的输出中,除非被引用。

发布 v1.5.0

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

想象一下,reference在导入的文件中用reference flag标记每个指令和选择器,正常导入,但是当生成CSS时,不会输出“引用”选择器(以及任何只包含引用选择器的媒体查询)。 除非使用引用样式,reference样式不会显示在生成的CSS中作为 mixins继承.

此外,reference根据不同使用方法(mixin或extend)产生不同的结果:

  • 继承: 当一个选择器继承时,只有新的选择器被标记为not referenced,并且出现在引入@ import语句的位置。
  • mixins: 当reference样式被用作隐式mixin时,它的规则被混入,标记为“not reference”,并以正常的方式出现在引用的位置。

1-1.reference 示例

这样就可以通过执行如下操作从库[Bootstrap] Bootstrap中只引用特定的目标样式:

.navbar:extend(.navbar all) {}

你将只从Bootstrap中提取.navbar相关的样式。

2.inline

使用 @import (inline)输出中包含外部文件,但不处理它们。

发布 v1.5.0

示例: @import (inline) "not-less-compatible.css";

当CSS文件可能不兼容Less时,你会使用这个; 虽然Less支持大多数已知的标准CSS,但它不支持某些地方的注释,并且不支持所有已知的CSS hacks。

所以你可以使用这个在输出中包含这个文件,这样所有的CSS都会在一个文件中。

3.less

忽略文件扩展名,使用@import (less)将导入的文件视为Less。

发布 v1.4.0

示例:

@import (less) "foo.css";

4.css

使用@import(css)将输入的文件视为普通的CSS,而忽略文件的扩展名。 这意味着导入声明将保持原样。

发布 v1.4.0

示例:

@import (css) "foo.less";

编译为

@import "foo.less";

5.once

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

发布 v1.4.0

这是@import语句的默认行为。

示例:

@import (once) "foo.less";
@import (once) "foo.less"; // 此声明将会被忽略

6.multiple

使用@import (multiple) 来导入多个具有相同名称的文件。 与once的行为相反。

发布 v1.4.0

示例:

// 文件: foo.less
.a {
  color: green;
}
// 文件: main.less
@import (multiple) "foo.less";
@import (multiple) "foo.less";

编译为

.a {
  color: green;
}
.a {
  color: green;
}

7.optional

使用@import (optional)只允许在文件存在的情况下导入文件。 如果没有optional关键字Less引发FileError并在导入无法找到的文件时停止编译。

发布 v2.3.0


Edit the markdown source for "mixin-guards"

附带条件的 mixins

Guards are useful when you want to match on expressions, as opposed to simple values or arity. If you are familiar with functional programming, you have probably encountered them already.

当你想在匹配表达式,而不是简单的值或数量时,Guard很有。 如果你熟悉函数式编程,你可能已经遇到过它们了。

In trying to stay as close as possible to the declarative nature of CSS, Less has opted to implement conditional execution via guarded mixins instead of if/else statements, in the vein of @media query feature specifications.

为了尽量保持CSS的声明性,Less选择通过guarded mixins而不是if /else语句来实现条件执行的格式。

从一个例子开始:

.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}

关键是when关键字,它引入了一个guard序列(这里只有一个guard)。 如果我们运行下面的代码:

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

得到的结果为:

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

1.Guard 比较运算符

在guard中可用的所有比较运算符:>> === <<。 此外,关键字 true是唯一的真值,以下两个mixin等价:

.truth (@a) when (@a) { ... }
.truth (@a) when (@a = true) { ... }

除关键字“true”以外的任何值都是假的:

.class {
  .truth(40); // 不符合上述任何一个定义。
}

请注意,也可以参数相互比较或者与非参数比较:

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

2.Guard 逻辑运算符

您可以使用guard逻辑运算符。 该语法基于CSS媒体查询。

使用and和关键字组合guard:

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

可以通过用逗号,分隔guard来模拟or操作符。 如果任何一名guards为真,则认为是匹配:

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

使用not关键字否定条件:

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

3.类型检查功能

最后,如果你想基于值类型来匹配mixins,你可以使用is函数:

.mixin (@a; @b: 0) when (isnumber(@b)) { ... }
.mixin (@a; @b: black) when (iscolor(@b)) { ... }

这里是基本的类型检查功能:

  • iscolor
  • isnumber
  • isstring
  • iskeyword
  • isurl

如果你想检查一个值是否在一个特定的单位,除了是一个数字,你可以使用以下:

  • ispixel
  • ispercentage
  • isem
  • isunit

4.附带条件的 Mixins

(FIXME)此外,可以使用default函数使一个mixin匹配依赖于另一个mixin匹配,可以使用它来创建类似于elsedefault的“条件mixins” 语句(分别是 ifcase结构):

.mixin (@a) when (@a > 0) { ...  }
.mixin (@a) when (default()) { ... } // 只有当第一个mixin不匹配,即@a <= 0时才匹配

Edit the markdown source for "css-guards"

"if"在选择器周围

发布 v1.5.0

Guard 也可以应用于CSS选择器, 这是用于声明mixin的语法糖,然后立即调用它。

例如,在1.5.0之前,你将不得不这样做:

.my-optional-style() when (@my-option = true) {
  button {
    color: white;
  }
}
.my-optional-style();

现在,可以直接将guard应用于某种样式。

button when (@my-option = true) {
  color: white;
}

也可以通过与&功能结合起来来实现一个if类型的语句,允许您将多个guard分组。

& when (@my-option = true) {
  button {
    color: white;
  }
  a {
    color: blue;
  }
}

Edit the markdown source for "loops"

创建循环

在Less中一个mixin可以调用自己。 这种递归mixins结合Guard ExpressionsPattern Matching,可以用来创建各种迭代/循环结构。

示例:

.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // 下一次迭代
  width: (10px * @counter); // 每次迭代的code
}

div {
  .loop(5); // 启动循环
}

编译为

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

Edit the markdown source for "merge"

组合属性

merge功能允许将多个属性的值汇总到单个属性下的逗号或空格分隔列表中。 merge对于诸如背景和变换之类的属性非常有用的。

1.逗号

用逗号追加属性值

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

2.空格

用空格追加属性值

发布 v1.7.0

示例:

.mixin() {
  transform+_: scale(2);
}
.myclass {
  .mixin();
  transform+_: rotate(15deg);
}

编译为

.myclass {
  transform: scale(2) rotate(15deg);
}

为了避免任何不必要的连接,merge需要在每个连接等待声明中都显式地使用 +'或+_标志。


Edit the markdown source for "parent-selectors"

&引用父选择器

&运算符表示嵌套规则中的父选择器,常用于在已存在选择器上修改类或伪类。

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

编译为:

a {
  color: blue;
}

a:hover {
  color: green;
}

注意,如果没有 &,上面的例子会导致a:hover规则(匹配<a>标签内的悬停元素的后代选择器),嵌套: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");
}

1.复合 &

&可能在选择器中多次出现。 可以实现多次引用父选择器名称而不用重复书写其名称

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

2.改变选择器顺序

将选择器预先添加到继承的(父)选择器可能很有用。 可以通过在当前选择器之后放置 & 来完成。 例如,使用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形式输出:

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

3.超级组合

& 也可以用来在逗号分隔列表中生成每个选择器可能的排列组合:

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