Solving SCSS Parent Selector Scope Issue

Solving SCSS Parent Selector Scope Issue

Β·

2 min read

Have you ever encountered issues with SCSS where the scope of the parent element gets lost within multiple nested selectors? This is a common problem, especially when you're dealing with complex stylesheets. However, fear not! There's a simple and elegant solution to this issue using SCSS variables.

Let's first examine this problem on an example code using BEM methodology.

<section class="hero-section">
  <div class="container">
    <div class="hero-section__left">
      <p>Content 1</p>
    </div>
    <div class="hero-section__left">
      <p>Content 2</p>
    </div>
  </div>
</section>

We created a selector named .hero-section and this selector has two child elements named .hero-section__left and .hero-section__left.

.hero-section {
  background: blue;
  padding: 20px;

  .container {
    display: flex;
    justify-content: space-evenly;

    &__left {
      background: yellow;
    }

    &__right {
      background: pink;
    }
  }
}

It doesn't seem like there's a problem but when we compile the code, it becomes clear what the error is:

.hero-section {
  background: blue;
  padding: 20px;
}
.hero-section .container {
  display: flex;
  justify-content: space-evenly;
}
.hero-section .container__left {
  background: yellow;
}
.hero-section .container__right {
  background: pink;
}

Our main goal was to style the .hero-section .hero-section__left and .hero-section .hero-section__right selectors. As you see, since the & selector has block scope, the nested selectors &left and &right may lose their parent scope, leading to unexpected styling behavior. In other words, the value of the & parent selection changes in each new block.

To solve this problem, let's review our code again by assigning our .hero-section scope to a variable called $self.

.hero-section {
  $self: &;
  background: blue;
  padding: 20px;

  .container {
    display: flex;
    justify-content: space-evenly;

    #{ $self }__left {
      background: yellow;
    }

    #{ $self }__right {
      background: pink;
    }
  }
}

Now let's look at the current compiled version of our code.

.hero-section {
  background: blue;
  padding: 20px;
}
.hero-section .container {
  display: flex;
  justify-content: space-evenly;
}
.hero-section .container .hero-section__left {
  background: yellow;
}
.hero-section .container .hero-section__right {
  background: pink;
}

Finally, we achieved the effect we wanted. By assigning the parent scope to a variable (let's call it $self), we can keep everything in check. So when you're styling those nested elements, just use #{$self} to refer back to the parent selector. It's like telling SCSS, "Hey, remember where we came from!".

Thank you for reading. If you find the article useful, please do not forget to like and comment so that others can access it. If you're on a generous day, you can even buy me a coffee. πŸ™ƒ

Β