To give my question some context, I have 12 sibling divs that each represent a month of the year. Either 0, 1, or 2 of these divs can be selected at a given time. When selected, a class of "active" is applied to that div. When two divs are selected I would like to apply a style to all divs between the two selected.
eg.
<div class="month">Jan</div>
<div class="month active">Feb</div>
<div class="month">Mar</div>
<div class="month">Apr</div>
<div class="month">May</div>
<div class="month">Jun</div>
<div class="month active">Jul</div>
<div class="month">Aug</div>
<div class="month">Sep</div>
<div class="month">Oct</div>
<div class="month">Nov</div>
<div class="month">Dec</div>
So in the above snippet, I would like to apply a CSS style to the active months, as well as all months in-between. Is this possible in CSS, or am I better off with JS?
EDIT:
This doesn't work, but I think it might be on the right track.
.month.active ~ .month {
background-color: $color-lighter-text;
color: #fff;
}
.month.active:nth-child(2) ~ .month {
background-color: #fff !important;
color: $color-muted-text !important;
}
General Sibling Selector (~) The general sibling selector selects all elements that are next siblings of a specified element.
No, there is no "previous sibling" selector. On a related note, ~ is for general successor sibling (meaning the element comes after this one, but not necessarily immediately after) and is a CSS3 selector. + is for next sibling and is CSS2.
The general sibling selector (~) selects all elements that are next siblings of a specified element.
Definition and UsageThe :nth-child(n) selector matches every element that is the nth child of its parent. n can be a number, a keyword (odd or even), or a formula (like an + b). Tip: Look at the :nth-of-type() selector to select the element that is the nth child, of the same type (tag name), of its parent.
You could select all the .month
elements following the first .active
element, and then override that styling by selecting all the .month
elements that follow the second .active
element:
.month.active ~ .month,
.active {
color: #f00;
}
.month.active ~ .month.active ~ .month {
color: initial;
}
<div class="month">Jan</div>
<div class="month active">Feb</div>
<div class="month">Mar</div>
<div class="month">Apr</div>
<div class="month">May</div>
<div class="month">Jun</div>
<div class="month active">Jul</div>
<div class="month">Aug</div>
<div class="month">Sep</div>
<div class="month">Oct</div>
<div class="month">Nov</div>
<div class="month">Dec</div>
However, if you want a cleaner solution, I'd suggest using JS and adding an .active
class to all the elements that you want to target.
If you're using jQuery, you can simply use the .nextUntil()
method:
$('.month.active:first').nextUntil('.active').addClass('active');
$('.month.active:first').nextUntil('.active').addClass('active');
.month.active {
color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="month">Jan</div>
<div class="month active">Feb</div>
<div class="month">Mar</div>
<div class="month">Apr</div>
<div class="month">May</div>
<div class="month">Jun</div>
<div class="month active">Jul</div>
<div class="month">Aug</div>
<div class="month">Sep</div>
<div class="month">Oct</div>
<div class="month">Nov</div>
<div class="month">Dec</div>
You need to use general sibling selectors: ~
<div class="month">Jan</div>
<div class="month active">Feb</div>
<div class="month">Mar</div>
<div class="month">Apr</div>
<div class="month">May</div>
<div class="month">Jun</div>
<div class="month active">Jul</div>
<div class="month">Aug</div>
<div class="month">Sep</div>
<div class="month">Oct</div>
<div class="month">Nov</div>
<div class="month">Dec</div>
.month {background: red;}
.month.active {background: blue;}
.month.active ~ .month {background: blue;}
.month.active ~ .month.active ~ .month {background: red;}
Because of the cascading nature of CSS, the element before the .active
cannot be effectively targeted from .active's
reference. I added a .prev
class to the element before an .active
, then used the adjacent sibling selector +
when referencing .active
to the element after it.
My bad, you wanted the months in between so that can be done with the more indiscriminate ~
. Updated to reflect OP's request but probably the same solution as some before me, sorry :-\
.month.active {
background-color: orange;
}
.month.active ~ .month {
background-color: orange;
}
.month.active ~ .month.active ~ .month {
background-color: white;
}
<div class="month">Jan</div>
<div class="month active">Feb</div>
<div class="month">Mar</div>
<div class="month">Apr</div>
<div class="month">May</div>
<div class="month">Jun</div>
<div class="month active">Jul</div>
<div class="month">Aug</div>
<div class="month">Sep</div>
<div class="month">Oct</div>
<div class="month">Nov</div>
<div class="month">Dec</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With