Inner elements not targeted by SCSS with :hover selector:

Viewed 59

I'm trying to target an inner element with Sass using the :hover selector, but for some reason when using the partial selector with the underscore, the property gets ignored. The only workaround is to type the entire class name:

HTML:

    <div class="cds__grid">
        <div class="cds__card">
          <img src="images/content/image.svg">
          <div class="cds__card-overlay"> 
            <h4>A Title</h4>
            <p>Some Text</p>
          </div>
        </div>
    </div>

SCSS:

.cds{
    &__grid{
        //Some Properties
    }

    &__card{
        &-overlay{
            background-color: grey;
        }

        &:hover{
            //Ignored
            &-overlay{
                background-color: blue; 
            }

            //Applied on Hover
            .cds__card-overlay{
                background-color: blue; 
            }
        }
    } 
}
3 Answers

Here is the solution, you need to add & after hover to keep reference of the parent class

CodePen Link

.cds{
    &__grid{
        //Some Properties
    }

    &__card{          
        &-overlay{
            background-color: grey;
        }
        
        &:hover &{
            // Ignored
            &-overlay{
                background-color: blue; 
            }
        }
    }
}
<div class="cds__grid">
    <div class="cds__card">
      <img src="images/content/image.svg">
      <div class="cds__card-overlay"> 
        <h4>A Title</h4>
        <p>Some Text</p>
      </div>
    </div>
</div>

To understand why this is ignored it helps to learn more about the ampersand in SCSS.

This is not some magic tool that sorts selectors, it just inserts the parent at the point where you write the &.

So if you write something like this:

.class {
  &:hover {
    &-detail {
   }
  }
}

This will be compiled into this:

.class {}
.class:hover {}
.class:hover-detail {}

Note the last selector, this is not a valid CSS selector, so this is why it get's ignored.

To achieve something like .class-detail:hover you would have to do something like this:

.class {
  &:hover {
  }
  &-detail {
    &:hover {
    }
  }
}

You simply missed a } at the end of your code, and also an & sign to refer to your original element. See in codepen.io: https://codepen.io/basescriptnet/pen/KKqWweo

.cds{
    &__grid {
        //Some Properties
    }

    &__card{
        &-overlay {
            background-color: grey;
        }

        &:hover &{
            //Ignored
            &-overlay {
                background-color: blue; 
            }

            //Applied on Hover
            .cds__card-overlay {
                background-color: blue; 
            }
        }
    }
}
 <div class="cds__grid">
    <div class="cds__card">
      <img src="images/content/image.svg">
      <div class="cds__card-overlay"> 
        <h4>A Title</h4>
        <p>Some Text</p>
      </div>
    </div>
</div>

Update. I missed & sign after :hover, which led to wrong execution of the code. Instead of referring to parent, it was referring to .cds__card:hover-overlay.

Related