快速入门
概览
变量(Variables)
混入(Mixins)
嵌套(Nesting)
运算(Operations)
转义(Escaping)
函数(Functions)
命名空间和访问符
映射(Maps)
作用域(Scope)
注释(Comments)
导入(Importing)
使用 Less.js
命令行用法
浏览器使用
Less.js选项
预加载插件
程序化使用
API
为 Less.js 做贡献
Less 函数手册
逻辑函数
字符串函数
列表函数
数学函数
类型函数
杂项函数
颜色定义函数
颜色通道函数
颜色操作函数
颜色混合函数
进阶指南
变量
父选择器
继承
合并
Mixins
CSS Guards
分离规则集
@import At-Rules
@plugin At-Rules
Maps (NEW!)
作用域
Mixins - Less入门文档 - 笔下光年
网站首页
Mixins
从现有样式中 "mix-in"属性 您可以混合使用类选择器和 ID 选择器,例如 ```less .a, #b { color: red; } .mixin-class { .a(); } .mixin-id { #b(); } ``` 结果是: ```less .a, #b { color: red; } .mixin-class { color: red; } .mixin-id { color: red; } ``` 从历史上看,mixin 调用中的括号都是可选的,但可选的括号已被弃用,在未来的版本中将被要求使用。 ```less .a(); .a; // currently works, but deprecated; don't use .a (); // white-space before parentheses is also deprecated ``` ### 不输出 Mixin 如果您想创建一个 mixin,但又不想在 CSS 输出中出现该 mixin,请在 mixin 定义后加上括号。 ```less .my-mixin { color: black; } .my-other-mixin() { background: white; } .class { .my-mixin(); .my-other-mixin(); } ``` 输出 ```less .my-mixin { color: black; } .class { color: black; background: white; } ``` ### Mixins 中的选择器 Mixins 不仅可以包含属性,还可以包含选择器。 例如: ```less .my-hover-mixin() { &:hover { border: 1px solid red; } } button { .my-hover-mixin(); } ``` 输出 ```less button:hover { border: 1px solid red; } ``` ### 命名空间 如果要在更复杂的选择器中混合属性,可以堆叠多个 id 或类。 ```less #outer() { .inner { color: red; } } .c { #outer.inner(); } ``` 注意:旧版的 Less 语法允许 `>` 和名称空间与 mixins 之间的空格。该语法已被弃用,可能会被移除。目前,这些语法的作用相同。 ```less #outer > .inner(); // deprecated #outer .inner(); // deprecated #outer.inner(); // preferred ``` 像这样命名你的 mixins 可以减少与其他库 mixins 或用户 mixins 的冲突,但也可以成为 "organize" 组 mixins 的一种方式。 示例: ```less #my-library { .my-mixin() { color: black; } } // which can be used like this .class { #my-library.my-mixin(); } ``` ### 受保护的命名空间 如果命名空间有 guard,则只有在 guard 条件返回 true 时,才会使用该命名空间定义的 mixin。命名空间防护的评估方式与 mixin 上的防护完全相同,因此以下两个 mixins 的工作方式也相同: ```less #namespace when (@mode = huge) { .mixin() { /* */ } } #namespace { .mixin() when (@mode = huge) { /* */ } } ``` 对于所有嵌套命名空间和 mixin,默认函数被假定为具有相同的值。如果 mixin 从未被求值,则保证其中一个 guards 为 `false`: ```less #sp_1 when (default()) { #sp_2 when (default()) { .mixin() when not(default()) { /* */ } } } ``` ### !important 关键字 在调用 mixin 后使用 !important 关键字,将其继承的所有属性标记为 !important 属性: 示例: ```less .foo (@bg: #f5f5f5, @color: #900) { background: @bg; color: @color; } .unimportant { .foo(); } .important { .foo() !important; } ``` Results in: ```less .unimportant { background: #f5f5f5; color: #900; } .important { background: #f5f5f5 !important; color: #900 !important; } ``` ### 参数 Mixins #### 如何向 mixins 传递参数 Mixins 还可以接受参数,即在混合时传递给选择器块的变量。 示例: ```less .border-radius(@radius) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } ``` 下面是我们如何将其混入各种规则集的方法: ```less #header { .border-radius(4px); } .button { .border-radius(6px); } ``` 参数 mixins 也可以为其参数设置默认值: ```less .border-radius(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } ``` 我们现在可以这样调用它: ```less #header { .border-radius(); } ``` 它将包含一个 5px 的边框半径。 您还可以使用不带参数的参数 mixins。如果你想在 CSS 输出中隐藏规则集,但又想在其他规则集中包含其属性,这就很有用了: ```less .wrap() { text-wrap: wrap; white-space: -moz-pre-wrap; white-space: pre-wrap; word-wrap: break-word; } pre { .wrap() } ``` 这将输出: ```css pre { text-wrap: wrap; white-space: -moz-pre-wrap; white-space: pre-wrap; word-wrap: break-word; } ``` #### 具有多个参数的 Mixins 参数可以用分号或逗号分隔。建议使用分号。逗号符号有双重含义:既可以解释为混合参数分隔符,也可以解释为 css 列表分隔符。 使用逗号作为 mixin 分隔符,就无法创建逗号分隔的列表作为参数。另一方面,如果编译器在 mixin 调用或声明中看到至少一个分号,它就会认为参数是用分号分隔的,而所有逗号都属于 css 列表: - 两个参数,每个参数都包含以逗号分隔的列表: `.name(1,2,3;something,else)`。 - 三个参数,每个参数包含一个数字:`.name(1, 2, 3)`。 - 使用假分号创建 mixin 调用,其中一个参数包含逗号分隔的 css 列表: `.name(1,2,3;)`。 - 逗号分隔的默认值: - `.name(@param1: red, blue;)` - `.name(@param1: ~(red, blue))` 使用相同的名称和参数数定义多个 mixins 是合法的。Less 将使用所有可应用的属性。如果您使用的 mixin 只有一个参数,例如 `.mixin(green);`,那么将使用所有带有一个必选参数的 mixin 的属性: ```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); } ``` 编译成: ```css .some .selector div { color-1: #008000; color-2: #008000; padding-2: 2; } ``` #### 命名参数 mixin 引用可以通过名称而不仅仅是位置来提供参数值。任何参数都可以用其名称来引用,而且不必按照任何特殊顺序排列: ```less .mixin(@color: black; @margin: 10px; @padding: 20px) { color: @color; margin: @margin; padding: @padding; } .class1 { .mixin(@margin: 20px; @color: #33acfe); } .class2 { .mixin(#efca44; @padding: 40px); } ``` 编译成: ```less .class1 { color: #33acfe; margin: 20px; padding: 20px; } .class2 { color: #efca44; margin: 10px; padding: 40px; } ``` #### @arguments 变量 `@arguments` 在 mixin 中有特殊含义,它包含调用 mixin 时传递的所有参数。如果不想处理单个参数,这一点非常有用: ```less .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); } ``` 结果是: ```less .big-block { -webkit-box-shadow: 2px 5px 1px #000; -moz-box-shadow: 2px 5px 1px #000; box-shadow: 2px 5px 1px #000; } ``` #### 高级参数和 @rest 变量 如果你想让你的 mixin 接受数量可变的参数,你可以使用 ... 。在变量名后使用此选项将把这些参数赋值给变量。 ```less .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 ``` 此外: ```less .mixin(@a; @rest...) { // @rest is bound to arguments after @a // @arguments is bound to all arguments } ``` ### 模式匹配 有时,您可能想根据传递给 mixin 的参数来改变它的行为。让我们从最基本的开始: ```less .mixin(@s; @color) { ... } .class { .mixin(@switch; #888); } ``` 现在,假设我们希望 .mixin 根据 `@switch` 的值有不同的行为,我们可以这样定义 `.mixin`: ```less .mixin(dark; @color) { color: darken(@color, 10%); } .mixin(light; @color) { color: lighten(@color, 10%); } .mixin(@_; @color) { display: block; } ``` 现在,如果我们运行: ```less @switch: light; .class { .mixin(@switch; #888); } ``` 我们将得到以下 CSS: ```less .class { color: #a2a2a2; display: block; } ``` 传递给 `.mixin` 的颜色会变浅。如果 `@switch` 的值是 `dark`,结果将是更深的颜色。 事情是这样的: - 第一个 mixin 定义不匹配,因为它预期 `dark` 为第一个参数。 - 第二个 mixin 定义是匹配的,因为它预期是 `light`。 - 第三个 mixin 定义是匹配的,因为它期待任何值。 只有匹配的 mixin 定义才会被使用。变量可与任何值匹配和绑定。变量以外的任何其他值都只能与等于自身的值匹配。 我们还可以根据 arity 进行匹配,下面就是一个例子: ```less .mixin(@a) { color: @a; } .mixin(@a; @b) { color: fade(@a; @b); } ``` 现在,如果我们使用一个参数调用 `.mixin`,我们将得到第一个定义的输出,但如果我们使用两个参数调用它,我们将得到第二个定义,即 `@a` 淡化为 `@b`。 ### 使用 Mixins 作为函数 从 mixin 调用中选择属性和变量 #### 属性/值访问器 发布于 v3.5.0 从 Less 3.5 开始,你可以使用属性/变量访问器从已评估的 mixin 规则中选择一个值。这样,你就可以像使用函数一样使用 mixin。 示例: ```less .average(@x, @y) { @result: ((@x + @y) / 2); } div { // call a mixin and look up its "@result" value padding: .average(16px, 50px)[@result]; } ``` 结果是: ```less div { padding: 33px; } ``` #### 重写 mixin 值 如果有多个匹配的 mixins,则会对所有规则进行评估和合并,并返回最后一个与该标识符匹配的值。这类似于 CSS 中的级联,可以 "override" 混合元素值。 ```less // library.less #library() { .mixin() { prop: foo; } } // customize.less @import "library"; #library() { .mixin() { prop: bar; } } .box { my-value: #library.mixin[prop]; } ``` 输出: ```less .box { my-value: bar; } ``` #### 未命名的查找 如果不在 [`@lookup`]中指定查找值,而是在调用 mixin 或 ruleset 后写入 `[]`,所有值都将级联,并选择最后声明的值。 意思是:上面例子中的平均 mixin 可以写成: ```less .average(@x, @y) { @result: ((@x + @y) / 2); } div { // call a mixin and look up its final value padding: .average(16px, 50px)[]; } ``` 输出结果是一样的: ```less div { padding: 33px; } ``` 同样的级联行为也适用于 mixin 调用的规则集或变量别名。 ```less @dr: { value: foo; } .box { my-value: @dr[]; } ``` 这输出: ```css .box { my-value: foo; } ``` #### 在调用者作用域中解锁 mixins 和变量 已删除 - 使用属性/值访问器 在 mixin 中定义的变量和 mixins 是可见的,可以在调用者的作用域中使用。只有一个例外:如果调用者包含一个同名变量(包括由另一个 mixin 调用定义的变量),则该变量不会被复制。只有调用者本地作用域中的变量才受保护。从父作用域继承的变量会被覆盖。 **注意:**这种行为已被弃用,今后变量和 mixins 将不会以这种方式合并到调用者作用域中。 例如: ```less .mixin() { @width: 100%; @height: 200px; } .caller { .mixin(); width: @width; height: @height; } ``` 结果是: ```less .caller { width: 100%; height: 200px; } ``` 在调用者作用域中直接定义的变量不能被覆盖。但是,在调用者父作用域中定义的变量不受保护,可以被重载: ```less .mixin() { @size: in-mixin; @definedOnlyInMixin: in-mixin; } .class { margin: @size @definedOnlyInMixin; .mixin(); } @size: globaly-defined-value; // callers parent scope - no protection ``` 结果是: ```less .class { margin: in-mixin in-mixin; } ``` Finally, mixin defined in mixin acts as return value too: ```less .unlock(@value) { // outer mixin .doSomething() { // nested mixin declaration: @value; } } #namespace { .unlock(5); // unlock doSomething mixin .doSomething(); //nested mixin was copied here and is usable } ``` 结果是: ```less #namespace { declaration: 5; } ``` ### 递归 Mixins #### 创建循环 在 Less 中,mixin 可以调用自身。这种递归 mixins 与 Guard 表达式和模式匹配相结合,可用于创建各种迭代/循环结构。 例如: ```less .loop(@counter) when (@counter > 0) { .loop((@counter - 1)); // next iteration width: (10px * @counter); // code for each iteration } div { .loop(5); // launch the loop } ``` 输出: ```less div { width: 10px; width: 20px; width: 30px; width: 40px; width: 50px; } ``` 使用递归循环生成 CSS 网格类的通用示例: ```less .generate-columns(4); .generate-columns(@n, @i: 1) when (@i =< @n) { .column-@{i} { width: (@i * 100% / @n); } .generate-columns(@n, (@i + 1)); } ``` 输出: ```less .column-1 { width: 25%; } .column-2 { width: 50%; } .column-3 { width: 75%; } .column-4 { width: 100%; } ``` ### Mixin Guards 与简单的值或迭代相比,当您想根据表达式进行匹配时,Guards 非常有用。如果你熟悉函数式编程,你可能已经遇到过它们。 为了尽可能贴近 CSS 的声明性质,Less 选择通过有保护的混合体(而非 `if/else` 语句)来实现条件执行,这与 `@media` 查询功能规范一脉相承。 让我们从一个例子开始: ```less .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)。现在我们运行以下代码 ```less .class1 { .mixin(#ddd) } .class2 { .mixin(#555) } ``` 这就是我们将得到的: ```less .class1 { background-color: black; color: #ddd; } .class2 { background-color: white; color: #555; } ``` #### Guard 比较运算符 在保护中可用的比较运算符的完整列表是 `>`, `>=`, `=`, `=<`, `<`. 此外,关键字 `true` 是唯一的真值,因此这两个 mixins 等价: ```less .truth(@a) when (@a) { ... } .truth(@a) when (@a = true) { ... } ``` 除关键字 `true` 之外的任何值都是假的: ```less .class { .truth(40); // Will not match any of the above definitions. } ``` 请注意,您也可以将参数相互比较,或与非参数比较: ```less @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 } ``` #### Guard 逻辑运算符 您可以使用带保护的逻辑运算符。该语法基于 CSS 媒体查询。 使用 `and` 关键字来组合 guards: ```less .mixin(@a) when (isnumber(@a)) and (@a > 0) { ... } ``` 您可以用逗号 `,` 来分隔守护符,从而模仿 `or` 运算符。如果其中任何一个保护符的值为 `true`,则视为匹配: ```less .mixin(@a) when (@a > 10), (@a < -10) { ... } ``` 使用 `not` 关键字否定条件: ```less .mixin(@b) when not (@b > 0) { ... } ``` #### 类型检查函数 最后,如果您想根据值类型匹配 mixins,可以使用 `is` 函数: ```less .mixin(@a; @b: 0) when (isnumber(@b)) { ... } .mixin(@a; @b: black) when (iscolor(@b)) { ... } ``` 下面是基本的类型检查功能: - `iscolor` - `isnumber` - `isstring` - `iskeyword` - `isurl` 如果要检查数值除了是数字外是否还有特定的单位,可以使用以下方法之一: - `ispixel` - `ispercentage` - `isem` - `isunit` ### 别名 Mixins 发布于 v3.5.0 #### 将 mixin 调用赋值给变量 Mixins 可以分配给变量,作为变量调用,也可以用于地图查找。 ```less #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]; } ``` 这将输出: ```less .navbar { background: black; border: 1px solid grey; } ``` #### 变量调用 整个 mixin 调用都可以别名,并作为变量调用。例如: ```less #library() { .rules() { background: green; } } .box { @alias: #library.rules(); @alias(); } ``` 输出: ```less .box { background: green; } ``` 请注意,与 `root` 中使用的 mixin 不同,分配给变量的 mixin 调用和不带参数的 mixin 调用总是需要括号。下面的内容无效。 ```less #library() { .rules() { background: green; } } .box { @alias: #library.colors; @alias(); // ERROR: Could not evaluate variable call @alias } ``` 这是因为如果变量被分配给一个选择器列表或一个 mixin 调用,就会产生歧义。例如,在 Less 3.5+ 中,这个变量可以这样使用。 ```less .box { @alias: #library.colors; @{alias} { a: b; } } ``` 以上将输出: ```less .box #library.colors { a: b; } ```
上一篇:
合并
下一篇:
CSS Guards