父选择器

父选择器 & 是 Sass 发明的一个特殊选择器,用于在嵌套选择器中引用外部选择器。它使得可以以更复杂的方式重用外部选择器,比如添加伪类或在父选择器之前添加选择器。

当在内部选择器中使用父选择器时,它会被替换为相应的外部选择器。这发生在正常嵌套行为之前。

Playground

SCSS Syntax

.alert {
  // 父选择器可用于为外部选择器添加伪类。
  &:hover {
    font-weight: bold;
  }

  // 它还可以用于在特定上下文中设置外部选择器的样式,例如设置为从右到左语言的正文。
  [dir=rtl] & {
    margin-left: 0;
    margin-right: 10px;
  }

  // 你甚至可以将其用作伪类选择器的参数。
  :not(&) {
    opacity: 0.8;
  }
}
Playground

Sass Syntax

.alert
  // 父选择器可用于为外部选择器添加伪类。
  &:hover
    font-weight: bold


  // 它还可以用于在特定上下文中设置外部选择器的样式,例如设置为从右到左语言的正文。
  [dir=rtl] &
    margin-left: 0
    margin-right: 10px


  // 你甚至可以将其用作伪类选择器的参数。
  :not(&)
    opacity: 0.8


CSS Output

.alert:hover {
  font-weight: bold;
}
[dir=rtl] .alert {
  margin-left: 0;
  margin-right: 10px;
}
:not(.alert) {
  opacity: 0.8;
}







⚠️ Heads up!

因为父选择器可能被替换为像 h1 这样的类型选择器,所以它只允许出现在复合选择器的开头,就像类型选择器允许的位置一样。例如,span& 是不允许的。

不过,我们正在研究放宽这一限制。如果你想帮助实现这一点,请查看这个 GitHub 问题

添加后缀添加后缀 permalink

你还可以使用父选择器为外部选择器添加额外的后缀。这在使用像 BEM 这样使用高度结构化类名的方法论时特别有用。只要外部选择器以字母数字名称(如类、ID 和元素选择器)结尾,你就可以使用父选择器附加额外的文本。

Playground

SCSS Syntax

.accordion {
  max-width: 600px;
  margin: 4rem auto;
  width: 90%;
  font-family: "Raleway", sans-serif;
  background: #f4f4f4;

  &__copy {
    display: none;
    padding: 1rem 1.5rem 2rem 1.5rem;
    color: gray;
    line-height: 1.6;
    font-size: 14px;
    font-weight: 500;

    &--open {
      display: block;
    }
  }
}
Playground

Sass Syntax

.accordion
  max-width: 600px
  margin: 4rem auto
  width: 90%
  font-family: "Raleway", sans-serif
  background: #f4f4f4

  &__copy
    display: none
    padding: 1rem 1.5rem 2rem 1.5rem
    color: gray
    line-height: 1.6
    font-size: 14px
    font-weight: 500

    &--open
      display: block



CSS Output

.accordion {
  max-width: 600px;
  margin: 4rem auto;
  width: 90%;
  font-family: "Raleway", sans-serif;
  background: #f4f4f4;
}
.accordion__copy {
  display: none;
  padding: 1rem 1.5rem 2rem 1.5rem;
  color: gray;
  line-height: 1.6;
  font-size: 14px;
  font-weight: 500;
}
.accordion__copy--open {
  display: block;
}


在 SassScript 中在 SassScript 中 permalink

父选择器还可以在 SassScript 中使用。它是一个特殊的表达式,返回当前父选择器,格式与选择器函数相同:一个逗号分隔的列表(选择器列表),其中包含空格分隔的列表(复杂选择器),这些列表又包含不带引号的字符串(复合选择器)。

Playground

SCSS Syntax

.main aside:hover,
.sidebar p {
  parent-selector: &;
  // => ((unquote(".main") unquote("aside:hover")),
  //     (unquote(".sidebar") unquote("p")))
}
Playground

Sass Syntax

.main aside:hover,
.sidebar p
  parent-selector: &
  // => ((unquote(".main") unquote("aside:hover")),
  //     (unquote(".sidebar") unquote("p")))

CSS Output

.main aside:hover,
.sidebar p {
  parent-selector: .main aside:hover, .sidebar p;
}


如果在任何样式规则之外使用 & 表达式,它将返回 null。由于 null假值,这意味着你可以轻松地用它来确定混入是否在样式规则中被调用。

Playground

SCSS Syntax

@mixin app-background($color) {
  #{if(&, '&.app-background', '.app-background')} {
    background-color: $color;
    color: rgba(#fff, 0.75);
  }
}

@include app-background(#036);

.sidebar {
  @include app-background(#c6538c);
}
Playground

Sass Syntax

@mixin app-background($color)
  #{if(&, '&.app-background', '.app-background')}
    background-color: $color
    color: rgba(#fff, 0.75)



@include app-background(#036)

.sidebar
  @include app-background(#c6538c)

CSS Output

.app-background {
  background-color: #036;
  color: rgba(255, 255, 255, 0.75);
}

.sidebar.app-background {
  background-color: #c6538c;
  color: rgba(255, 255, 255, 0.75);
}



高级嵌套高级嵌套 permalink

你可以将 & 用作普通的 SassScript 表达式,这意味着你可以将它传递给函数或在插值中包含它——甚至在其他选择器中!结合选择器函数@at-root 规则使用,可以以非常强大的方式嵌套选择器。

For example, suppose you want to write a selector that matches the outer selector and an element selector. You could write a mixin like this one that uses the selector.unify() function to combine & with a user’s selector.

Playground

SCSS Syntax

@use "sass:selector";

@mixin unify-parent($child) {
  @at-root #{selector.unify(&, $child)} {
    @content;
  }
}

.wrapper .field {
  @include unify-parent("input") {
    /* ... */
  }
  @include unify-parent("select") {
    /* ... */
  }
}
Playground

Sass Syntax

@use "sass:selector"

@mixin unify-parent($child)
  @at-root #{selector.unify(&, $child)}
    @content



.wrapper .field
  @include unify-parent("input")
    /* ... */

  @include unify-parent("select")
    /* ... */


CSS Output

.wrapper input.field {
  /* ... */
}

.wrapper select.field {
  /* ... */
}









⚠️ Heads up!

当 Sass 嵌套选择器时,它不知道用于生成它们的插值。这意味着即使你使用 & 作为 SassScript 表达式,它也会自动将外部选择器添加到内部选择器中。这就是为什么你需要显式地使用 @at-root 规则来告诉 Sass 不要包含外部选择器。