共计 6062 个字符,预计需要花费 16 分钟才能阅读完成。
第二节(Less)github
Variables(变量)
在你的样式表中相同的值重复几十次 甚至上百次 并不少见,变量通过为你提供一种在一个地方管理这些值的方法让你的代码变得更容易维护。
@nice-blue: #5B83AD; | |
@light-blue: @nice-blue + #111; | |
#header {color: @light-blue;} | |
// 作为属性名 | |
@mySelector: banner; | |
.@{mySelector} { | |
font-weight: bold; | |
line-height: 40px; | |
margin: 0 auto; | |
} | |
// 作为 URL | |
@images: "../img"; | |
body { | |
color: #444; | |
background: url("@{images}/white-sand.png"); | |
} | |
// 作为 import 引入 | |
@themes: "../../src/themes"; | |
@import "@{themes}/tidal-wave.less"; | |
// 作为属性 | |
@property: color; | |
.widget {@{property}: #0ee; | |
background-@{property}: #999; | |
} | |
// 作为变量 | |
@fnord: "I am fnord."; | |
@var: "fnord"; | |
content: @@var; |
由于变量只能定义一次,实际上也相当于常量。
变量是延迟加载的,在使用前不一定要预先声明。
同名变量后面的会覆盖前面的。
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); | |
} | |
.c:extend(.d all) {// 扩展 ".d" 的所有实例,比如 ".x.d" 或者 ".d.x"} | |
.c:extend(.d) {// 扩展选择器编译为 ".d" 的唯一实例} | |
.e:extend(.f) {} | |
.e:extend(.g) {} | |
// 上面的代码与下面的做一样的事情 | |
.e:extend(.f, .g) {} |
如果你想有一个 animal 子类型,并且要重写背景颜色。那么你有两个选择:
1. 首先改变你的 HTML | |
<a class="animal bear">Bear</a> | |
.animal { | |
background-color: black; | |
color: white; | |
} | |
.bear {background-color: brown;} | |
2. 简化你的 HTML | |
<a class="bear">Bear</a> | |
.animal { | |
background-color: black; | |
color: white; | |
} | |
.bear {&:extend(.animal); | |
background-color: brown; | |
} |
Mixins 会复制所有的属性到选择器中,这可能导致不必要的重复。因此你可以使用 extend 来代替 mixin 将你要用的属性移过去,这样就会生成更少的 CSS。
.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; | |
} |
Mixins(混入)
从现有的样式混合(mixin)属性。
.a, #b {color: red;} | |
.mixin-class {.a(); | |
} | |
.mixin-id {#b(); | |
} | |
// 编译为:.a, #b {color: red;} | |
.mixin-class {color: red;} | |
.mixin-id {color: red;} |
如果你想要创建一个混合集,但是却不想让它输出到你的样式中,你可以在混合集的名字后面加上一个括号。
.my-mixin {color: black;} | |
.my-other-mixin() {background: white;} | |
.class { | |
.my-mixin; | |
.my-other-mixin; | |
} | |
// 编译为:.my-mixin {color: black;} | |
.class { | |
color: black; | |
background: white; | |
} |
混合集不仅可以包含各种属性,而且可以包括各种选择器。
.my-hover-mixin() { | |
&:hover {border: 1px solid red;} | |
} | |
button {.my-hover-mixin(); | |
} | |
// 编译为:button:hover {border: 1px solid red;} |
如果你想要将属性混合到比较复杂的选择器中,你可以通过嵌套多层 id 或者 class。
#outer { | |
.inner {color: red;} | |
} | |
.c {#outer > .inner;} | |
// 下面四种写法效果是一样的 | |
#outer > .inner; | |
#outer > .inner(); | |
#outer.inner; | |
#outer.inner(); |
在调用的混合集后面追加 !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; | |
} |
mixinx 参数
mixins 也可以接受参数,在它进行 mix in 操作时会将变量传递给选择器代码块。
// 比如:.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; | |
} |
多个参数的 mixins
参数可以用 分号 或者 逗号 分割。但是推荐使用 分号 分割。因为逗号符号有两个意思:它可以解释为 mixins 参数分隔符或者 css 列表分隔符。
定义多个具有相同名称和参数数量的 mixins 是合法的
.mixin(@color) {color-1: @color;} | |
.mixin(@color; @padding: 2) { | |
color-2: @color; | |
padding-2: @padding; | |
} | |
.mixin(@color; @padding; @margin: 2) { | |
color-3: @color; | |
padding-3: @padding; | |
margin: @margin @margin @margin @margin; | |
} | |
.some .selector div {.mixin(#008000); | |
} | |
// 编译为:.some .selector div { | |
color-1: #008000; | |
color-2: #008000; | |
padding-2: 2; | |
} |
引用 mixin 时可以通过参数名称而不是参数的位置来为 mixin 提供参数值。任何参数都已通过它的名称来引用,这样就不必按照任意特定的顺序来使用参数:
.mixin(@color: black; @margin: 10px; @padding: 20px) { | |
color: @color; | |
margin: @margin; | |
padding: @padding; | |
} | |
.class1 {.mixin(@margin: 20px; @color: #33acfe); | |
} | |
.class2 {.mixin(#efca44; @padding: 40px); | |
} | |
// 编译为:.class1 { | |
color: #33acfe; | |
margin: 20px; | |
padding: 20px; | |
} | |
.class2 { | |
color: #efca44; | |
margin: 10px; | |
padding: 40px; | |
} |
arguments 变量
@arguments
在 mixins 内部有特殊意义,调用 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 的行为。先来看一些基础的示例:
.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(@a) {color: @a;} | |
.mixin(@a; @b) {color: fade(@a; @b); | |
} |
Mixins as Functions(作为函数使用的混合)
所有定义在一个 mixin 中的变量都是可见的,还可以用于调用它的作用域中(除非调用它的作用域定义了同名变量)。
.mixin() { | |
@width: 100%; | |
@height: 200px; | |
} | |
.caller {.mixin(); | |
width: @width; | |
height: @height; | |
} | |
// 编译为:.caller { | |
width: 100%; | |
height: 200px; | |
} |
因此定义在 mixin 中的变量还可以充当它的返回值。这样就允许我们创建一个用起来类似函数的 mixin。
.average(@x, @y) {@average: ((@x + @y) / 2); | |
} | |
div {.average(16px, 50px); // "call" the mixin | |
padding: @average; // use its "return" value | |
} | |
// 编译为: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(); // 嵌套混入被复制到这里,并可用} | |
// 编译为:#namespace {declaration: 5;} |
Import Directives(导入准则)
从其他样式表中导入样式。
在标准的 CSS 中,@import
必须在所有其他类型的规则之前。但是 Less.js 不在乎你把 @import
语句放在什么位置。
.foo {background: #900;} | |
@import "this-is-valid.less"; |
Import Options(导入选项)
Less 提供了一系列的 CSS 扩展来让你使用 @import
更灵活的导入第三方 CSS 文件。
语法:@import (keyword) "filename";
-
reference
:使用 Less 文件但不输出 -
inline
:在输出中包含源文件但不加工它 -
less
:将文件作为 Less 文件对象,无论是什么文件扩展名 -
css
:将文件作为 CSS 文件对象,无论是什么文件扩展名 -
once
:只包含文件一次(默认行为) -
multiple
:包含文件多次