CSS中的嵌套是特别繁琐的,即便用比较强大的编辑器比如Webstorm来编辑代码,可是在维护的时候还是不能一目了然的去找到对应的代码,我们经常看到类似这样的代码段:
#content article h1 { color: #333 }#content article p { margin-bottom: 1.4em }#content aside { background-color: #eee }
如果用sass来编写的话,这些重复的选择器就只用写一次了,而且可读性也更高了
#content { article { h1 { color: #333 } p { margin-bottom: 1.4em } } aside { background-color: #eee }}
sass的嵌套包括两种:一种是选择器的嵌套,另一种是属性的嵌套
选择器嵌套
所谓选择器嵌套指的是在一个选择器中嵌套另一个选择器来实现继承,从而增强了sass文件的结构性和可读性
//scss#top_nav{ line-height: 40px; text-transform: capitalize; background-color:#333; li{ float:left; } a{ display: block; padding: 0 10px; color: #fff; &:hover{ color:#ddd; } }}//css#top_nav { line-height: 40px; text-transform: capitalize; background-color: #333; } #top_nav li { float: left; } #top_nav a { display: block; padding: 0 10px; color: #fff; } #top_nav a:hover { color: #ddd; }
在选择器嵌套中,可以使用&表示父元素选择器,最常见的就是:hover这种伪类,否则,就会被误编译成后代选择器
//scssa { font-weight: bold; text-decoration: none; &:hover { text-decoration: underline; } body.firefox & { font-weight: normal; }}//cssa { font-weight: bold; text-decoration: none; } a:hover { text-decoration: underline; } body.firefox a { font-weight: normal; }
//scss#main { color: black; a { font-weight: bold; &:hover { color: red; } }}//css#main { color: black; } #main a { font-weight: bold; } #main a:hover { color: red; }
//scss#main { color: black; &-sidebar { border: 1px solid; }}//css#main { color: black; } #main-sidebar { border: 1px solid; }
群组选择器的嵌套
//scss.container {h1, h2, h3 {margin-bottom: .8em}}//css.container h1, .container h2, .container h3 { margin-bottom: .8em;}
子组合选择器和同层组合选择器:>、+和~
先来回忆下这三种选择器
后代选择器: article section { margin: 5px }
子代选择器: article>section { margin: 5px }
相邻兄弟选择器:article+section { margin: 5px }
通用兄弟选择器:article~section { margin: 5px }
//scssarticle { ~ article { border-top: 1px dashed #ccc } > section { background: #eee } dl > { dt { color: #333 } dd { color: #555 } } nav + & { margin-top: 0 }}//cssarticle ~ article { border-top: 1px dashed #ccc; }article > section { background: #eee; }article dl > dt { color: #333; }article dl > dd { color: #555; }nav + article { margin-top: 0; }
属性嵌套
所谓属性嵌套指的是有些属性拥有同一个开始单词,如border-width,border-color都是以border开头
嵌套属性的规则是这样的:把属性名从中划线-的地方断开,在根属性后边添加一个冒号:, 紧跟一个{ }块,把子属性部分写在这个{ }块中。就像CSS选择器嵌套一样,Sass会把你的子属 性一一解开,把根属性和子属性部分通过中划线-连接起来,最后生成的效果与你手动一遍遍写 的CSS样式一样:
//scssnav {border: {style: solid;width: 1px;color: #ccc;}}//cssnav { border-style: solid; border-width: 1px; border-color: #ccc;}
对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则
//scssnav {border: 1px solid #ccc {left: 0px;right: 0px;}}//cssnav { border: 1px solid #ccc; border-left: 0px; border-right: 0px;}
@at-root
sass3.3.0中新增的功能,用来跳出选择器嵌套的。默认所有的嵌套,继承所有上级选择器,但有了这个就可以跳出所有上级选择器。
//scss 没有跳出.parent-1 { color:#f00; .child { width:100px; }}//css.parent-1 { color: #f00;}.parent-1 .child { width: 100px;}
//scss 单个选择器跳出.parent-2 { color:#f00; @at-root .child { width:200px; }}//css.parent-2 { color: #f00;}.child { width: 200px;}
//scss 多个选择器跳出.parent-3 { background:#f00; @at-root { .child1 { width:300px;} .child2 { width:400px;} }}//css.parent-3 { background: #f00;}.child1 { width: 300px;}.child2 { width: 400px;}
@at-root (without: ...)
默认@at-root只会跳出选择器嵌套,而不能跳出@media或@support,如果要跳出这两种,则需使用@at-root (without: media),@at-root (without: support)。
这个语法的关键词有四个:all(表示所有),rule(表示常规css),media(表示media),support(表示support,因为@support目前还无法广泛使用,所以在此不表)。
我们默认的@at-root其实就是@at-root (without:rule)。
//scss 跳出父级元素嵌套@media print { .parent1{ color:#f00; @at-root .child1 { width:200px; } }}//css@media print { .parent1 { color: #f00; } .child1 { width: 200px; }}
//scss 跳出media嵌套,父级有效@media print { .parent2{ color:#f00; @at-root (without: media) { .child2 { width:200px; } } }}//css@media print { .parent2 { color: #f00; }}.parent2 .child2 { width: 200px;}
//scss 跳出media和父级@media print { .parent3{ color:#f00; @at-root (without: all) { .child3 { width:200px; } } }}//css@media print { .parent3 { color: #f00; }}.child3 { width: 200px;}
@at-root和&的结合
//scss.foo { @at-root .bar & { color:gray; }}//css.bar .foo { color: gray;}
在Sass中同时使用@at-root和&起到的作用是一样的,换句话说,这样并没有带来新的特性,而且在整个开发中还带来了额外的工作量
//scss.foo { @at-root & .bar { color:gray; }}.foo { & .bar { color:gray; }}//css.foo .bar { color: gray;}.foo .bar { color: gray;}
应用于@keyframe
//scss.demo { ... animation: motion 3s infinite; @at-root { @keyframes motion { ... } }}//css.demo { ... animation: motion 3s infinite;}@keyframes motion { ...}
@at-root和#{&}结合
Sass有脚本模式#{},他和&不同之处是,&只用作选择器,它只能出现在一个复合的开始选择器,类似于一个类型选择器,如a或者h1。但#{}他表示的是一个插值,它可以用在任何地方。同样的,当@at-root和#{&}一起使用时,可以给我们的开发带来极大的方便与优势。例如:
//scss.foo { @at-root .bar #{&} { color: gray; }}.foo { @at-root #{&} .bar { color:gray; }}.foo { @at-root #{&}.bar { color:gray; }}//css.bar .foo { color: gray;}.foo .bar { color: gray;}.foo.bar { color: gray;}