Keywords: Sass | Parent Selector | Nested Selectors
Abstract: This article provides an in-depth analysis of the core role of the parent selector (&) in Sass nested selectors, demonstrating its applications in pseudo-class selectors, contextual selectors, and BEM naming conventions through concrete code examples. It explains why directly using :hover in nested structures causes selector failures and presents multiple practical scenarios for using the parent selector, including advanced nesting techniques and dynamic selector construction in SassScript.
Fundamentals of Sass Nesting Selectors and Common Issues
In the nesting functionality of the Sass preprocessor, developers often encounter issues where pseudo-class selectors fail to compile correctly. For example, in the following code:
.class {
margin:20px;
:hover {
color:yellow;
}
}This code intends to change the text color to yellow when hovering over the .class element, but the actual compiled CSS selector becomes .class :hover, which selects all :hover state elements inside the .class element, rather than the hover state of the .class element itself.
Core Role of the Parent Selector (&)
The parent selector & is a special identifier provided by Sass that represents the outer selector in nested structures. When & is used in an inner selector, Sass replaces it with the corresponding outer selector instead of applying the default nesting behavior.
The correct implementation should be:
.class {
margin:20px;
&:hover {
color:yellow;
}
}This compiles to .class:hover in CSS, precisely targeting the hover state of the .class element itself.
Multiple Application Scenarios for the Parent Selector
Combining with Pseudo-class Selectors
The most common use of the parent selector is combining with pseudo-class selectors. Beyond :hover, it can be used with :focus, :active, and all other pseudo-classes:
.button {
padding: 10px 20px;
&:hover {
background-color: #f0f0f0;
}
&:focus {
outline: 2px solid blue;
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
}Building Contextual Selectors
The parent selector can be used to redefine the styles of the outer selector in specific contexts:
.alert {
padding: 15px;
border: 1px solid #ccc;
[dir=rtl] & {
margin-left: 0;
margin-right: 10px;
}
.dark-theme & {
background-color: #333;
color: white;
}
}Support for BEM Naming Conventions
When adopting the BEM (Block Element Modifier) methodology, the parent selector conveniently adds suffixes:
.accordion {
max-width: 600px;
margin: 4rem auto;
&__copy {
display: none;
padding: 1rem 1.5rem;
&--open {
display: block;
}
}
&__header {
background-color: #f5f5f5;
padding: 10px;
cursor: pointer;
&--active {
background-color: #e0e0e0;
}
}
}Advanced Nesting Techniques and Selector Functions
Sass provides more advanced nesting capabilities. Combined with the @at-root rule and selector functions, complex selector combinations can be achieved:
@use "sass:selector";
@mixin unify-parent($child) {
@at-root #{selector.unify(&, $child)} {
@content;
}
}
.wrapper .field {
@include unify-parent("input") {
border: 1px solid #ccc;
padding: 5px;
}
@include unify-parent("select") {
background-color: #f9f9f9;
border-radius: 4px;
}
}This code compiles to .wrapper input.field and .wrapper select.field selectors, achieving precise element type matching.
Application of Parent Selector in SassScript
The parent selector can also be used as an expression in SassScript, returning a structured representation of the current parent selector:
.main aside:hover,
.sidebar p {
parent-selector: &;
// Returns: ((unquote(".main") unquote("aside:hover")), (unquote(".sidebar") unquote("p")))
}In mixins, the existence of & can be detected to dynamically generate selectors:
@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);
}Considerations and Best Practices
When using the parent selector, note its positional limitations: the parent selector can only appear at the beginning of compound selectors, similar to the restrictions on type selectors. For example, span& is not allowed.
In complex nested structures, pay special attention to the replacement logic of & to avoid unexpected selector combinations. It is recommended to regularly check the compiled CSS output during development to ensure selectors meet expectations.
By properly understanding and applying the parent selector, developers can fully leverage the advantages of Sass nesting functionality, writing more concise and maintainable style code while avoiding common selector errors.