SCSS extends CSS with features like nesting and parent selector referencing to reduce repetition and improve maintainability.
1. CSS selector recap
Standard CSS selectors include:
- Universal:
* - Type:
div,p, etc. - Class:
.classname - ID:
#id - Attribute selectors:
[attr],[attr=val],[attr~=val],[attr|=val],[attr^=val],[attr$=val],[attr*=val] - Selector list (comma-separated)
- Descendant: space (e.g.,
div p) - Child:
>(e.g.,ul > li) - General sibling:
~(e.g.,p ~ span) - Adjacent sibling:
+(e.g.,h2 + p) - Column combinator:
||(e.g.,col || td) - Pseudo-classes and pseudo-elements
Reference: MDN CSS selectors
2. Nesting in SCSS
SCSS allows seletcors to be nested, mirroring the HTML structure. This eliminates repetition of parent selectors.
// Child selector
ul > {
li {
list-style: none;
}
}
// Adjacent sibling
h2 {
+ p {
border-top: 1px solid gray;
}
}
// General sibling
p {
~ {
span { opacity: 0.8; }
h1 { color: red; }
}
}
3. Parent selector &
The & character refers to the parent selector. It is replaced by the parent rule's selector when compiled.
Adding pseudo-classes or pseudo-elemants
.alert {
max-width: 600px;
margin: 4rem auto;
width: 90%;
font-family: "Raleway", sans-serif;
background: #f4f4f4;
&:hover {
font-weight: bold;
}
}
Appending suffixes (BEM-like naming)
.alert {
&__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;
}
}
}
Distinguishing descendant from naming reuse
// SCSS
.btn {
color: red;
// descendant
a {
color: white;
}
// descendant with parent class
& &-item {
color: purple;
}
// new class based on parent name (not descendant)
&-item {
color: black;
&-green {
color: green;
}
}
}
// Compiled CSS
.btn { color: red; }
.btn a { color: white; }
.btn .btn-item { color: purple; }
.btn-item { color: black; }
.btn-item-green { color: green; }
Parent selector with multiple selectors
When the parent is a selector list, & refers to the whole list.
// SCSS
.main aside:hover,
.sidebar p {
parent-selector: &;
}
// Compiled CSS
.main aside:hover, .sidebar p {
parent-selector: .main aside:hover, .sidebar p;
}
Nested parent references
// SCSS
ul, ol {
text-align: left;
& & {
padding-bottom: 0;
padding-left: 0;
}
}
// Compiled CSS
ul, ol { text-align: left; }
ul ul, ol ol { padding-bottom: 0; padding-left: 0; }
Note: Shorthand nested properties like padding can be split in to sub-properties (e.g., padding-bottom, padding-left).
Extracting nested selector to root with @at-root
// SCSS
.selector {
color: blue;
@at-root #{a + &} {
color: red;
}
}
// Compiled CSS
.selector { color: blue; }
a.selector { color: red; }