Nesting in SCSS
What is Nesting?
Nesting is one of the most powerful features of SCSS. It allows you to nest your CSS selectors in a way that follows the same visual hierarchy of your HTML, making your stylesheets more readable and maintainable.
Basic Nesting
SCSS
.card {
background: white;
border-radius: 4px;
.card-header {
padding: 15px;
border-bottom: 1px solid #eee;
h2 {
margin: 0;
font-size: 18px;
}
}
.card-body {
padding: 15px;
p {
margin-bottom: 10px;
}
}
}
Compiled CSS
.card {
background: white;
border-radius: 4px;
}
.card .card-header {
padding: 15px;
border-bottom: 1px solid #eee;
}
.card .card-header h2 {
margin: 0;
font-size: 18px;
}
.card .card-body {
padding: 15px;
}
.card .card-body p {
margin-bottom: 10px;
}
Parent Selector (&)
The ampersand (&) is used to reference the parent selector. It's particularly useful for pseudo-classes, pseudo-elements, and modifier classes:
SCSS
.button {
background: blue;
color: white;
// Pseudo-classes
&:hover {
background: darkblue;
}
&:active {
transform: translateY(1px);
}
// Pseudo-elements
&::before {
content: "";
display: inline-block;
width: 10px;
height: 10px;
margin-right: 5px;
}
// Modifier classes
&.button--large {
padding: 15px 30px;
font-size: 18px;
}
&.button--small {
padding: 5px 10px;
font-size: 12px;
}
// Parent selector in compound selectors
.dark-theme & {
background: black;
color: white;
}
}
Compiled CSS
.button {
background: blue;
color: white;
}
.button:hover {
background: darkblue;
}
.button:active {
transform: translateY(1px);
}
.button::before {
content: "";
display: inline-block;
width: 10px;
height: 10px;
margin-right: 5px;
}
.button.button--large {
padding: 15px 30px;
font-size: 18px;
}
.button.button--small {
padding: 5px 10px;
font-size: 12px;
}
.dark-theme .button {
background: black;
color: white;
}
Advanced Parent Selector Usage
The parent selector can be used in more complex ways:
// Using & to create BEM-style class names
.block {
// Element
&__element {
// Styles for .block__element
// Modifier
&--modifier {
// Styles for .block__element--modifier
}
}
// Block modifier
&--modifier {
// Styles for .block--modifier
}
}
// Using & with suffixes
.icon {
&-home {
background-image: url('home.png');
}
&-profile {
background-image: url('profile.png');
}
&-settings {
background-image: url('settings.png');
}
}
// Compiled CSS will be:
// .icon-home { ... }
// .icon-profile { ... }
// .icon-settings { ... }
Nesting Properties
SCSS also allows you to nest properties that share a namespace:
SCSS
.element {
font: {
family: 'Roboto', sans-serif;
size: 16px;
weight: 400;
style: normal;
}
margin: {
top: 10px;
right: 15px;
bottom: 10px;
left: 15px;
}
border: 1px solid black {
radius: 4px;
left: {
width: 2px;
color: red;
}
}
}
Compiled CSS
.element {
font-family: 'Roboto', sans-serif;
font-size: 16px;
font-weight: 400;
font-style: normal;
margin-top: 10px;
margin-right: 15px;
margin-bottom: 10px;
margin-left: 15px;
border: 1px solid black;
border-radius: 4px;
border-left-width: 2px;
border-left-color: red;
}
Nesting Media Queries
SCSS allows you to nest media queries within selectors, keeping related styles together:
.sidebar {
width: 30%;
float: left;
@media (max-width: 768px) {
width: 100%;
float: none;
}
.widget {
padding: 15px;
@media (max-width: 768px) {
padding: 10px;
}
h3 {
font-size: 18px;
@media (max-width: 768px) {
font-size: 16px;
}
}
}
}
Compiles to:
.sidebar {
width: 30%;
float: left;
}
@media (max-width: 768px) {
.sidebar {
width: 100%;
float: none;
}
}
.sidebar .widget {
padding: 15px;
}
@media (max-width: 768px) {
.sidebar .widget {
padding: 10px;
}
}
.sidebar .widget h3 {
font-size: 18px;
}
@media (max-width: 768px) {
.sidebar .widget h3 {
font-size: 16px;
}
}
Best Practices and Pitfalls
Best Practices
- Limit nesting depth: Try to keep nesting to 3-4 levels deep to avoid overly specific selectors.
- Use BEM with nesting: BEM methodology works well with SCSS nesting to create maintainable code.
- Group related styles: Use nesting to group related styles together, improving readability.
- Use parent selector wisely: The & selector is powerful but can lead to confusing code if overused.
Common Pitfalls
The Nesting Trap
Excessive nesting can lead to:
- Overly specific selectors that are hard to override
- Bloated CSS output
- Styles that are too tightly coupled to HTML structure
// Avoid this level of nesting
.header {
.navigation {
.list {
.item {
a {
&:hover {
// This will compile to .header .navigation .list .item a:hover
// which is very specific and hard to override
}
}
}
}
}
}
// Better approach
.nav-item {
// Styles for nav items
&:hover {
// Hover styles
}
}