3

I have a grid of elements that I want to appear in their unfiltered form when the page loads. When a user mouses over one of them, it should stay highlighted while the other elements fade to grey. I was able to get this working fine for subsequent elements but not the previous. I then came up with the following solution:

.child:hover {
  filter: grayscale(0);
  /*forces the 'active' element to stay unfiltered. */
}

.parent:hover>div {
  filter: grayscale(1);
  transition: filter 0.5s;
}

.parent>div {
  filter: grayscale(0);
  transition: filter 0.5s;
  /* so the transition back out is smooth */
}
<div class="parent">
  <div class="child">One</div>
  <div class="child">of</div>
  <div class="child">any</div>
  <div class="child">number</div>
  <div class="child">of</div>
  <div class="child">children</div>
</div>

The problem is that the fadeout occurs when a user places the cursors in the gaps between the elements as well - so if their placement is unlucky it will show everything in grayscale and look off.

I'd like to achieve this without using JavaScript if possible. I know that CSS doesn't have a built-in "previous siblings" selector, and I've tried various combinations of "has" and not gotten anywhere. Is this possible?

1 Answer 1

6

You don't need to do anything with the cell that is to be not-filtered, just select those cells which are not hovered on but when the parent has a cell that is hovered on.

Note: you don't need to set the transition conditions twice.

<style>
  .parent {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    width: 300px;
    gap: 20px;
  }

  .parent>div {
    filter: grayscale(0);
    transition: filter 0.5s;
    /* so the transition back out is smooth */
    background: cyan;
    /* just for demo so we can see the effect of filter */
  }

  .parent:has(>div:hover)>div:not(:hover) {
    filter: grayscale(1);
  }
</style>
<div class="parent">
  <div class="child">One</div>
  <div class="child">of</div>
  <div class="child">any</div>
  <div class="child">number</div>
  <div class="child">of</div>
  <div class="child">children</div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! There's always something I miss with CSS...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.