Less的嵌套规则
在使用标准CSS时,要为多层嵌套的元素定义样式,要么使用后代选择器从外到内的嵌套定义,要么给这个元素加上类名或 id 来定义。这样的写法虽然很好理解,但维护起来很不方便,因为无法清晰了解到样式之间的关系。
在Less中,嵌套规则使这个问题迎刃而解。嵌套规则允许在一个选择器中嵌套另一个选择器,这更容易设计出精简的代码,并且样式之间的关系一目了然。假设以下HTML 代码片段:
<header><h1><a href="http://www.waibo.wang/">歪脖网</a></h1><p>学Web开发,就到歪脖网!</p></header>
Less代码可以这样写:
header {h1 {font-size: 26px;font-weight: bold;a {color: #f36;text-decoration: none;&:hover {color: #63f;text-decoration: underline;}}}p {font-size: 12px;&.slogan {color: #f00;}}}
这难道不就是DOM的写法吗?说实话,当你第一眼看到这种写法,你就会情不自禁地爱上Less。这种写法减了选择器的层级关系,使代码的结构非常清晰,无论是阅读、还是后期维护都是那么自然,是不是有一种本来就该如此的感觉?
在使用嵌套规则时,需要特别注意 & 符号。内层选择器前面的 & 符号就表示对父选择器的引用。在一个内层选择器的前面,如果没有 & 符号,则它被解析为父选择器的后代;如果有 & 符号,它就被解析为父元素自身或父元素的伪类。
比如,上述代码中,由于选择器 h1 前面没有 & 符号,则 h1 被解析为 header 选择器的后代,即 header h1;而 :hover 和 .slogan 前面有 & 符号,& 符号表示对父选择器的引用,则 &.slogan 表示父元素自身,&:hover 表示父元素的伪类,解析结果为 a:hover 和 p.slogan。编译后的CSS代码为:
header h1 {font-size: 26px;font-weight: bold;}header h1 a {color: #f36;text-decoration: none;}header h1 a:hover {color: #63f;text-decoration: underline;}header p {font-size: 12px;}header p.slogan {color: #f00;}
事实上,父选择器运算符 & 的作用,就是让当前的选择器和父级选择器,按照特定的规则进行连接。它有多种用途,比如创建重复的类名:
.button {&-ok {background-image: url("ok.png");}&-cancel {background-image: url("cancel.png");}&-custom {background-image: url("custom.png");}}
编译后的CSS代码为:
.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;}}
编译后的CSS代码为:
.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;}}}
编译后的CSS代码为:
.grand .parent > .grand .parent {color: red;}.grand .parent .grand .parent {color: green;}.grand .parent.grand .parent {color: blue;}.grand .parent,.grand .parentish {color: cyan;}
还可以将 & 放在一个选择器的后面,来改变选择器的顺序,将当前选择器排列到最前面。如:
.header {.menu {border-radius: 5px;.no-borderradius & {background-image: url('images/button-background.png');}}}
选择器 .no-borderradius & 会使 .no-borderradius 置于他的父选择器 .header .menu 的前面,形成 .no-borderradius .header .menu的结构。编译后的CSS代码为:
.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;}}
上述列表中有 4 个选择器,列表中所有选择器的所有可能的排列,将有 16 种可能。编译后的CSS代码为:
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;}