一、变量详解
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元素添加两个类,然后重写对应的属性。
Bear.animal { background-color: black; color: white;}.bear { background-color: brown;}
第二种:简化html写法,只添加一个样式类,然后给它使用extend
Bear.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;}