skip to Main Content

I need to add styling between all the components that are between two selectors.

The first selector has an activity class, and the second hover has a state.

When you hover over the sixth element, all elements between the first and sixth should turn gray, as in the screenshot

enter image description here

.day {
  border: 1px solid;
}

.day:hover {
  background: #CCC;
}

.active {
 background: blue;
}
<div class="day">-1</div>
<div class="day">0</div>
<div class='day active'>1</div>
<div class="day">2</div> 
<div class="day">3</div>
<div class="day">4</div>
<div class="day">5</div>
<div class="day">6</div>
<div class="day">7</div>

2

Answers


  1. An easy way is to catch hover on the parent, give the background to all chidren, then exclude every one behind the one hovered.

    selectors that you can use for this is : ~ and not()

    the idea is to style anything in between .active and the one hovered.

    here is an example:

    .day {
      border: 1px solid;
    }
    
    .parent:hover .day.active~.day:not(:hover~.day) {
      background: #CCC;
    }
    
    .active {
      background: blue;
    }
    
    /* ones before active */
    /* 
    start from hovered but exclude .active and any behind it*/
    .day:hover:not(.active,.active~.day),
    .day:hover~.day:not(.active,.active~.day) {background:red;}
    <div class="parent"><!-- parent where to catch hover at first can be any tag, even body or html-->
      <div class="day">-1</div>
      <div class="day">0</div>
      <div class='day active'>1</div>
      <div class="day">2</div>
      <div class="day">3</div>
      <div class="day">4</div>
      <div class="day">5</div>
      <div class="day">6</div>
      <div class="day">7</div>
    </div>

    selector explanation :

    .parent:hover /* the parent*/
    .day.active /* select the active one to start from */
    ~ .day /* select any element behind that has the class .day */
    :not(:hover ~.day)/* exclude any one with class .day after the one hovered */
    {/*style*/}
    

    ressources :

    Login or Signup to reply.
  2. You can use Javascript for this purpose. You can get the days elements and add mouseenter and mouseleave events for them to set all lines after the active one until the current one, including the current one to gray.

    let days = [...document.querySelectorAll(".day")];
    for (let index = 0; index < days.length; index++) {
        days[index].addEventListener("mouseenter", function() {
            for (let innerIndex = days.indexOf(days.filter(item => item.classList.contains("active"))[0]) + 1; innerIndex <= days.indexOf(this); innerIndex++) {
                days[innerIndex].style.backgroundColor = "gray";
            }
        });
        days[index].addEventListener("mouseleave", function() {
            for (let innerIndex = days.indexOf(days.filter(item => item.classList.contains("active"))[0]) + 1; innerIndex <= days.indexOf(this); innerIndex++) {
                days[innerIndex].style.backgroundColor = "white";
            }
        });
    }
    .day {
      border: 1px solid;
    }
    
    /*.day:hover {
      background: #CCC;
    }*/
    
    .active {
     background: blue;
    }
    <div class="day">-1</div>
    <div class="day">0</div>
    <div class='day active'>1</div>
    <div class="day">2</div> 
    <div class="day">3</div>
    <div class="day">4</div>
    <div class="day">5</div>
    <div class="day">6</div>
    <div class="day">7</div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search