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
  }
}