less 文档整理
变量
控制单个位置的常用值。
概述
在您的样式表中看到相同的值重复数十次(*如果不是几百次)*并不罕见:
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
[email protected]{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");
}
import 语句
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;
[email protected]{property}: #999;
}
编译为:
.widget {
color: #0ee;
background-color: #999;
}
变量定义变量
在Less中,您可以使用其他变量定义变量的名称。
@primary: green;
@secondary: blue;
.section {
@color: primary;
.element {
color: @@color;
}
}
其编译为:
.section .element {
color: green;
}
作用域(Scope)
Less中的范围与编程语言非常相似。变量和mixin首先在本地查找,如果找不到,编译器将查找父范围,依此类推。
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}
Mixin和变量定义不必放在引用它们的行之前。所以下面的Less代码和前面的例子是一样的:
@var: red;
#page {
#header {
color: @var; // white
}
@var: white;
}
懒赋值
变量在使用之前不必声明。
有效更少的片段:
.lazy-eval {
width: @var;
}
@var: @a;
@a: 9%;
这是有效的less:
.lazy-eval {
width: @var;
@a: 9%;
}
@var: @a;
@a: 100%;
都编译成:
.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;
}
作为变量的属性**(新!)**
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
是深红色。
混合(Mixins)
混合是一种将一组属性从一个规则集合(另一个规则集合)(“混入”)的方式。所以说我们有以下class:
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
我们希望在其他规则集内使用这些属性。那么,我们只需要放下我们想要属性的类的名称,如下所示:
#menu a {
color: #111;
.bordered;
}
.post a {
color: red;
.bordered;
}
在的特性.bordered
类现在会出现在#menu a
和.post a
。(请注意,你也可以使用#ids
mixin。)
来自现有样式的“混合”属性
你可以混入类选择器和id选择器,例如
.a, #b {
color: red;
}
.mixin-class {
.a();
}
.mixin-id {
#b();
}
这导致:
.a, #b {
color: red;
}
.mixin-class {
color: red;
}
.mixin-id {
color: red;
}
注意当你调用混音时,括号是可选的。
// these two statements do the same thing:
.a();
.a;
不输出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;
}
并且两个>
和空白都是可选的
// all do the same thing
#outer > .inner;
#outer > .inner();
#outer .inner;
#outer .inner();
#outer.inner;
#outer.inner();
这种使用称为命名空间。你可以把你的mixin放在一个id选择器下,这样可以确保它不会与另一个库冲突。
例:
#my-library {
.my-mixin() {
color: black;
}
}
// which can be used like this
.class {
#my-library > .my-mixin();
}
保护命名空间
如果名称空间具有Guard警戒,则只有在警戒条件返回true时才使用由其定义的mixins。命名空间Guard的评估方式与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;
}
参数混合
如何将参数传递给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;
}
它将包括一个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;
}
混合使用多个参数
参数以分号或逗号分隔。建议使用分号。符号逗号具有双重含义:它可以解释为混合参数分隔符或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与一个参数一起使用,例如.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参考可以通过名称而不是位置来提供参数值。任何参数都可以通过其名称来引用,而且它们不必按照任何特殊顺序进行引用:
.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的定义相匹配,因为它预期有任何价值。
仅使用了匹配的mixin定义。变量匹配并绑定到任何值。除变量以外的任何内容仅与等于它自己的值相匹配。
我们也可以匹配arity,这里是一个例子:
.mixin(@a) {
color: @a;
}
.mixin(@a; @b) {
color: fade(@a; @b);
}
现在,如果我们.mixin
用单个参数调用,我们将获得第一个定义的输出,但如果我们用两个参数调用它,我们将得到第二个定义,即@a
淡入@b
。
返回来自mixin的值
从mixin返回变量或mixin
mixin中定义的变量和mixin是可见的,可用于调用者的范围。只有一个例外,如果调用方包含具有相同名称的变量(包含由另一个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; // 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;
}
递归混合
创建循环
少一个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;
}
使用递归循环生成CSS网格类的一个通用示例:
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
[email protected]{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%;
}
Mixin Guard
当你想匹配表达式时,卫兵是有用的,而不是简单的值或arity。如果您熟悉函数式编程,您可能已经遇到过它们。
为了尽量保持CSS的声明性质,Less选择通过保护的mixin而不是if
/ else
statement 来实现条件执行,这与@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
是唯一的truthy值,使这两个mixin等价:
.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 }
保护逻辑运算符
您可以使用逻辑运算符和Guard。该语法基于CSS媒体查询。
使用and
关键字组合警卫:
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
您可以通过用逗号分隔Guard来模拟或操作,`。如果任何Guard评估为真,则视为匹配:
.mixin (@a) when (@a > 10), (@a < -10) { ... }
使用not
关键字否定条件:
.mixin (@b) when not (@b > 0) { ... }
类型检查功能
最后,如果你想基于值类型匹配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
嵌套(Nesting)
Less使您能够使用嵌套代替或与级联结合使用。假设我们有以下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的结构。
您也可以使用此方法将伪选择器与您的mixin捆绑在一起。这里是经典的clearfix hack,重写为mixin(&
代表当前选择器父代):
.clearfix {
display: block;
zoom: 1;
&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
}
父选择器
引用父选择器
&
该&
运算符表示嵌套规则的父选择器,并且在将修改类或伪类应用于现有选择器时最常用:
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");
}
多次 &
&
可能会在选择器中出现多次。这使得重复引用父选择器而不重复其名称成为可能。
.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
输出:
.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;
}
嵌套的规则和冒泡
像规则一样,@media
或者@supports
可以像选择器一样嵌套。规则放在顶部,相对规则集中的其他元素的相对顺序保持不变。这叫做冒泡。
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
width: 800px;
}
}
编译为:
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}
Extend
Extend是一个较少的伪类,它将放置的选择器与它所引用的选择器进行合并。
发布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 an the below do the same thing
.e:extend(.f, .g) {}
扩展连接到选择器
将附加扩展选择器看起来像一个普通的伪类,其中选择器作为参数。选择器可以包含多个扩展子句,但是所有的扩展都必须位于选择器的末尾。
- 在选择器之后延伸:
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) {}
扩展嵌套选择器
Extend能够匹配嵌套选择器。less用:
例:
.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,而不是原来的less。
例:
.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
匹配相同的元素集,但扩展将它们视为不同的元素:
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
输出
link:hover:visited {
color: blue;
}
第n个表达式
第N个表达形式确实很重要。Nth表达式1n+3
和n+3
等价的,但扩展不符合它们:
: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”
当您在扩展参数中指定last关键字时,它会告诉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将忽略它。
但是,扩展可以附加到插值选择器。
变量选择器不匹配:
@variable: .bucket;
@{variable} { // interpolated selector
color: blue;
}
.some-class:extend(.bucket) {} // does nothing, no match is found
并在目标选择器中与变量一起扩展匹配nothing:
.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将所有属性复制到选择器中,这会导致不必要的重复。因此,您可以使用扩展而不是mixin将选择器移动到您希望使用的属性,这将导致生成的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的替代品 - 因为mixins只能与简单的选择器一起使用,如果您有两个不同的html块,但需要将相同的样式应用于两者,则可以使用extend来关联两个区域。
例:
li.list > a {
// list styles
}
button.list-style {
&:extend(li.list > a); // use the same list styles
}
merge
组合属性
该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
需要在每个连接挂起声明上显式+
或+_
标记。
CSS Guards
“如果”围绕着选择器
发布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;
}
}
分离规则集
将规则集分配给变量
已发布v1.7.0
分离的规则集是一组CSS属性,嵌套规则集,媒体声明或其他存储在变量中的其他内容。你可以将它包含到规则集或其他结构中,并且它的所有属性都将被复制到那里。您也可以将其用作mixin参数并将其作为任何其他变量传递。
简单的例子:
// declare detached ruleset
@detached-ruleset: { background: red; };
// 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,则声明范围值优先。
声明范围是分离的规则集体定义的范围。将分离的规则集从一个变量复制到另一个变量不能修改其范围。规则集仅通过在那里引用而无法访问新的范围。
最后,分离的规则集可以通过解锁(导入)到其中来访问范围。
定义和呼叫者范围可见性
分离的规则集可以看到调用者的变量和mixins:
@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;
}
变量和mixins可访问的表单定义胜过调用者可用的表单:
@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;
}
转义
转义允许您使用任何任意字符串作为属性或变量值。内部~"anything"
或内部的任何内容~'anything'
除插值外没有任何更改。
@min768: ~"(min-width: 768px)";
.element {
@media @min768 {
font-size: 1.2rem;
}
}
编译为:
@media (min-width: 768px) {
.element {
font-size: 1.2rem;
}
}
函数(Functions)
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。这些函数在函数手册中有详细介绍。
函数的用法非常简单。下面这个例子将介绍如何利用 percentage 函数将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度降低 25% 并且色相值增加 8 等用法:
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width); // returns `50%`
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}
参见:函数手册
命名空间和访问器
(不要与CSS@namespace
或命名空间选择器混淆)。
有时候,你可能想要将你的mixin分组,或为了组织目的,或者只是提供一些封装。您可以在Less中很直观地做到这一点。您想要将一些mixin和变量捆绑在一起#bundle
,以便以后重用或分发:
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white
}
}
.tab { ... }
.citation { ... }
}
现在,如果我们想.button
在我们的课堂中混合#header a
,我们可以这样做:
#header a {
color: orange;
#bundle > .button; // can also be written as #bundle.button
}
注意:追加()
到你的名字空间,如果你不希望它出现在你的CSS输出即#bundle .tab
。
还要注意,在命名空间中声明的变量将仅限于该命名空间,并且将不会在范围之外通过与用于引用mixin(#Namespace > .mixin-name
)的语法相同的语法提供。所以,例如,你不能做到以下几点:#Namespace > @this-will-not-work
。
注释(Comments)
块注释和行注释都可以使用:
/* 一个块注释
* style comment! */
@var: red;
// 这一行被注释掉了!
@var: white;
导入(Importing)
“导入”的工作方式和你预期的一样。你可以导入一个 .less
文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less
扩展名,则可以将扩展名省略掉:
@import "library"; // library.less
@import "typo.css";
转载于:https://my.oschina.net/reamd7/blog/1622343