less学习笔记四
一、变量详解
Variables,在一个地方用来控制常用的值。
css样式表中经常看到在一个值被重复使用了许多次,变量就是在一个地方控制元素的值,以便代码更简单地进行维护。
// Variables
@link-color: #428bca; // sea blue
@link-color-hover: darken(@link-color, 10%);
.header{
.menu{
a{color:@link-color;}
a:hover{color:@link-color-hover;}
}
h1{color:@link-color;}
}
/**outputs**/
.header .menu a {
color: #428bca;
}
.header .menu a:hover {
color: #3071a9;
}
.header h1 {
color: #428bca;
}
变量不止可以像上面一样用来控制css规则中的值,也可以在别的地方使用,例如选择器名、属性名、URLs和@import声明。
@my-selector:menu;
.@{my-selector}{
font-weight:bold;
font-size:16px;
}
/**outputs**/
.menu {
font-weight: bold;
font-size: 16px;
}
/**url**/
@images:"img";
body{background:url("@{images}/desk_01.jpg");}
/**outputs**/
body {
background: url("file:///E:/BaiduYunDownload/Less/doc/img/desk_01.jpg");
}
/**import**/
@themes:"common";
@import "@{themes}/styles.less";
/**输出的样式表中包含原有样式和styles中的样式**
/**Properties**/
@property:color;
.header {@{property}:#0ee;background-@{property}:#ffa;}
/**outputs**/
.header {
color: #0ee;
background-color: #ffa;
}
/**Variable Names**/
@fnord: "I am fnord.";
@var: "fnord";
.header{
h2{content: @@var;}
}
/**outputs**/
.header h2 {
content: "I am fnord.";
}
二、Extend扩展
扩展是less的一个伪类,它将自身所有的选择器与它引用的选择器进行融合。
.inline{display:inline;}
.nav ul li{
&:extend(.inline);
color:red;
}
/**outputs**/
.inline,
.nav ul li {
display: inline;
}
.nav ul li {
color: red;
}
上面的输出结果中,:extend选择器它的将扩展选择器(.nav ul li)放置在.inline选择器出现的地方。声明块保持原样,并且对extend没有任何引用。
如果extend块中没有别的样式属性,它将不会出现在输出结果中。
.inline{display:inline;}
.nav ul li{
&:extend(.inline);
}
/**outputs**/
.inline,
.nav ul li {
display: inline;
}
Extend语法
extend既可以使用在选择器上,也可以放置在一个样式属性规则中。它看似一个拥有选择器参数和可选关键字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" }
参数中使用all关键字的时候,会把所有选择器中含有对应参数的样式扩展进来。
.inline{display:inline;}
.para.inline{background:blue;}
.section:extend(.inline all){}
/**outputs**/
.inline,
.section {
display: inline;
}
.para.inline,
.para.section {
background: blue;
}
Extend Attached to Selector,附加到选择器上的扩展
看起来类似一个有选择器参数的普通伪类,一个选择器可以包含多个伪类语句,但所有的伪类语句必须放在选择器的最后。
- 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) - extend必须放在最后,右侧例子是不允许的:pre:hover:extend(div pre).nth-child(odd)
.inline{display:inline;}
.hover{color:green;}
.bgred{background:red;}
.section:extend(.inline):extend(.bgred){}
.section:hover:extend(.hover){}
/**outputs**/
.inline,
.section {
display: inline;
}
.hover,
.section:hover {
color: green;
}
.bgred,
.section {
background: red;
}
Extend Inside Ruleset,规则集中扩展
使用&:extend(selector)
语法,将extend放在一个规则集的正文中。采用简写&的方式,将extend放在规则集的每个选择器中。
pre:hover,
.some-class {
&:extend(div pre);
}
/**等价于**/
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
Extending Nested Selectors,嵌套选择器扩展
.nav{
.para{font-size:20px;}
}
.section:extend(.nav .para){}//空格不能少
/**outputs**/
.nav .para,
.section {
font-size: 20px;
}
Exact Matching with Extend,与扩展完全匹配
less默认查找选择器间的完全匹配,无论选择器是否使用了*,或者具有相同含义nth-表达式,less只关心选择器是否有相同的形态以用来匹配。
唯一例外的是属性选择器中的引用,less知道它们拥有相同的意义,然后用做匹配。
.a.class,
.class.a,
.class > .a {
color: blue;
}
.test:extend(.class) {} // this will NOT match the any selectors above
//*.class
和.class匹配相同的规则集,但extend认为不匹配
*.class {
color: blue;
}
.noStar:extend(.class) {} // this will NOT match the *.class selector
//伪类中的排序也有影响,尽管link:hover:visited
和link:visited:hover
匹配相同的规则集,但extend认为不匹配
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
//Nth-expressions 1n+3
and n+3
are equivalent, but extend will not match them
:nth-child(1n+3) { color: blue; }
.child:extend(:nth-child(n+3)) {}
//属性引用选择器的几种写法是等价的,extend都可以匹配,下面的例子中[title="identifier"]定义的样式覆盖了上面两种样式
[title=identifier] {
color: blue;
}
[title='identifier'] {
color: red;
}
[title="identifier"] {
color: green;
}
.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}
/**outputs**/
[title=identifier],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
color: red;
}
[title="identifier"],
.noQuote,
.singleQuote,
.doubleQuote {
color: green;
}
Extend "all",扩展关键字all
当你在less的参数中指定在最后的all关键字时,这将使less匹配作为别的选择器中一部分的元素。
输出结果中,原来的选择器会复制过来,匹配的那部分选择器会被less扩展作为一个新的选择器替换掉。
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
/**outputs**/
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
Selector Interpolation with Extend,选择器差值扩展
extend无法匹配变量选择器,但它可以附加在变量定义的选择器上。
@variable: .bucket;
@{variable} { // interpolated selector
color: blue;
}
.some-class:extend(.bucket) {} // does nothing, no match is found
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {} // interpolated selector matches nothing
@variable: .bucket;
//匹配变量选择器
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
/**outputs**/
.bucket, .selector { color: blue; }
Scoping / Extend Inside @media,@media中的范围和扩展
写在media声明中的extend只能匹配media声明范围内的选择器。
//在同一个media声明中,extend将与之匹配
@media screen{
.media{color:red;}
.replacement:extend(.media){}
}
/**outputs**/
@media screen {
.media,
.replacement {
color: red;
}
}
//写在外面的,无法匹配
@media screen{
.replacement:extend(.media){}
}
.media{color:red;}
//不会匹配写在嵌套的media中的选择器
@media screen{
@media(min-width:768px){.media{color:red;}}
.replacement:extend(.media){}
}
//写在media外面的扩展将匹配嵌套media中的所有可匹配选择器。
@media screen{
@media(min-width:768px){.media{color:red;}}
.media{background:#ffa;}
}
.replacement:extend(.media){}
/**outputs**/
@media screen {
.media,
.replacement {
background: #ffa;
}
}
@media screen and (min-width: 768px) {
.media,
.replacement {
color: red;
}
}
Duplication Detection,重复检测
extend扩展的选择器没有重复检测。当它的参数选择器在同一个规则集中时,会匹配多次。
.border,.media{background:#ffa;}
.replacement:extend(.media,.border){}
/**outputs**/
.border,
.media,
.replacement,
.replacement {
background: #ffa;
}
Classic Use Case,经典用例
经典用例用来避免添加基类。例如现有样式
.animal {
background-color: black;
color: white;
}
这时,一个子类型的animal需要重写background-color属性,有两种方法可以实现,第一种:给html元素添加两个类,然后重写对应的属性。
<a class="animal bear">Bear</a> .animal { background-color: black; color: white; } .bear { background-color: brown; }
第二种:简化html写法,只添加一个样式类,然后给它使用extend
<a class="bear">Bear</a> .animal { background-color: black; color: white; } .bear { &:extend(.animal); background-color: brown; }
Reducing CSS Size,减少css大小
混合类会将所有属性复制到对应的选择器中,造成不必要的重复。因此你可以使用extend来代替混合类,将选择器放置到需要的样式属性集中。
.my-inline-block() {
display: inline-block;
font-size: 0;
}
.thing1 {
.my-inline-block;
}
.thing2 {
.my-inline-block;
}
/**outputs**/
.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);
}
/**outputs**/
.my-inline-block,
.thing1,
.thing2 {
display: inline-block;
font-size: 0;
}
Combining Styles / A More Advanced Mixin,组合样式,更高级的混合类
extend的另一个用例是作为混合类的替代
.nav ul>li{
color:red;
}
.replacement{
&:extend(.nav ul>li);
}
/**outputs**/
.nav ul > li,
.replacement {
color: red;
}