Sass 嵌套规则 下载APP
Sass 嵌套规则

嵌套CSS规则

CSS中要写一大串指向页面中同一块的样式时,需要多次写同一个ID:

#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }

这种情况下,sass可以只写一遍,并且使样式可读性更高。Sass中,可以在规则块中嵌套规则块。Sass在输出css时会把嵌套规则处理好,避免重复书写。

#content {
  article {
    h1 { color: #333 }    p { margin-bottom: 1.4em }
  }  aside { background-color: #EEE }
}
 /* 编译后 */
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }

上边的例子,会在输出css时把它转换成跟你之前看到的一样的效果。这个过程中,sass用了两步,每一步都是像打开俄罗斯套娃那样把里边的嵌套规则块一个个打开。首先,把#content(父级)这个id放到article选择器(子级)和aside选择器(子级)的前边:

#content {
  article {
    h1 { color: #333 }    p { margin-bottom: 1.4em }
  }  #content aside { background-color: #EEE }
}
 /* 编译后 */
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }

然后,#content article里边还有嵌套的规则,sass重复一遍上边的步骤,把新的选择器添加到内嵌的选择器前边。

一个给定的规则块,既可以像普通的CSS那样包含属性,又可以嵌套其他规则块。

当要为一个容器元素及其他子元素编写特定样式时,这种功能非常有用。

#content {
  background-color: #f5f5f5;
  aside { background-color: #eee }
}

容器元素的样式规则会被单独抽离出来,而嵌套元素的样式规则会像容器元素没有包含任何属性时那样被抽离出来。

#content { background-color: #f5f5f5 }
#content aside { background-color: #eee }

大多数情况下这种简单的嵌套都没问题,但是有些场景下不行,比如要在嵌套的选择器里边立刻应用一个类似于:hover的伪类。为了解决这种以及其他情况,sass提供了一个特殊结构&。

父选择器标识符&

 一般情况下,sass在解开一个嵌套规则时就会把父选择器(#content)通过一个空格连接到子选择器的前边(article和aside)形成(#content article和#content aside)。这种在CSS里边被称为后代选择器,因为它选择ID为content的元素内所有命中选择器article和aside的元素。但在有些情况下却不会希望sass使用这种后代选择器的方式生成这种连接。

最常见的一种情况是为链接之类的元素写:hover这种伪类时,并不希望以后代选择器的方式连接。比如说,下面这种情况sass就无法正常工作:

article a {
  color: blue;
  :hover { color: red }
}

这意味着color: red这条规则将会被应用到选择器article a :hover,article元素内链接的所有子元素在被hover时都会变成红色。这是不正确的。想把这条规则应用到超链接自身,而后代选择器的方式无法实现。

解决之道为使用一个特殊的sass选择器,即父选择器。在使用嵌套规则时,父选择器能对于嵌套规则如何解开提供更好的控制。它就是一个简单的&符号,且可以放在任何一个选择器可出现的地方,比如h1放在哪,它就可以放在哪。

article a {
  color: blue;
  &:hover { color: red }
}

当包含父选择器标识符的嵌套规则被打开时,它不会像后代选择器那样进行拼接,而是&被父选择器直接替换:

article a { color: blue }
article a:hover { color: red }

在为父级选择器添加:hover等伪类时,这种方式非常有用。同时父选择器标识符还有另外一种用法,可以在父选择器之前添加选择器。举例来说,当用户在使用IE浏览器时,会通过JavaScript在<body>标签上添加一个ie的类名,为这种情况编写特殊的样式如下:

#content aside {
  color: red;
  body.ie & { color: green }
}

/*编译后*/
#content aside {color: red};
body.ie #content aside { color: green }

sass在选择器嵌套上是非常智能的,即使是带有父选择器的情况。当sass遇到群组选择器(由多个逗号分隔开的选择器形成)也能完美地处理这种嵌套。

群组选择器的嵌套

在CSS里边,选择器h1h2和h3会同时命中h1元素、h2元素和h3元素。与此类似,.buttonbutton会命中button元素和类名为.button的元素。这种选择器称为群组选择器。群组选择器的规则会对命中群组中任何一个选择器的元素生效。

.button, button {
  margin: 0;
}

css的写法会在群组选择器中的每一个选择器前都重复一遍容器元素的选择器。

.container h1, .container h2, .container h3 { margin-bottom: .8em }

sass的嵌套特性在这种场景下也非常有用。当sass解开一个群组选择器规则内嵌的规则时,它会把每一个内嵌选择器的规则都正确地解出来:

.container {
  h1, h2, h3 {margin-bottom: .8em}
}

首先sass将.container和h1.container和h2.container和h3分别组合,然后将三者重新组合成一个群组选择器,生成前边看到的普通css样式。对于内嵌在群组选择器内的嵌 套规则,处理方式也一样:

nav, aside {
  a {color: blue}
}

首先sass将nav和aaside和a分别组合,然后将二者重新组合成一个群组选择器:

nav a, aside a {color: blue}

子组合选择器和同层组合选择器

子组合选择器和同层组合选择器有如下三个>、+和~。这三个组合选择器必须配合其他选择器使用,用来指定浏览器仅选择某种特定上下文中的元素。

article section { margin: 5px }
article > section { border: 1px solid #ccc }

可以用子组合选择器>选择一个元素的直接子元素。上例中,第一个选择器会选择article下的所有命中section选择器的元素。第二个选择器只会选择article下紧跟着的子元素中命中section选择器的元素。

可以用同层相邻组合选择器+选择header元素后紧跟的p元素:

header + p { font-size: 1.1em }

可以用同层全体组合选择器~,选择所有跟在article后的同层article元素,不管它们之间隔了多少其他元素:

article ~ article { border-top: 1px dashed #ccc }

这些组合选择器可以应用到sass的规则嵌套中。可以把它们放在外层选择器后边,或里层选择器前边:

article {
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
    dl > {
        dt { color: #333 }
        dd { color: #555 }
  }
    nav + & { margin-top: 0 }
}

sass会将这些嵌套规则一一解开组合在一起:

article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }

嵌套属性

在sass中,你需敲写一遍border:

nav {
  border: {
  style: solid;
  width: 1px;
  color: #ccc;
  }
}

嵌套属性的规则:把属性名从中划线-的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }块,把子属性部分写在这个{ }块中。就像css选择器嵌套一样,sass会把子属性一一解开,把根属性和子属性部分通过中划线-连接起来。

nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

对于属性的缩写形式,还可以像下边这样来嵌套,指明例外规则:

nav {
  border: 1px solid #ccc {
  left: 0px;
  right: 0px;
  }
}