I want to highlight ranges of dates in a calendar (monthly view). The ranges of dates should be rounded of at both sides. I can round of the left side, but I cannot get the right side to work. What’s the problem here?
/* For the first highlighted li element in any range (this works well) */
.days li:not(.highlighted) + li.highlighted {
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
/* For the last highlighted li element in any range (this doesn't work) */
.days li.highlighted + li:not(.highlighted) {
border-top-right-radius: 10px !important;
border-bottom-right-radius: 10px !important;
}
<div class="calendar">
<ul class="weeks">
<li>Sun</li>
<li>Mon</li>
<li>Tue</li>
<li>Wed</li>
<li>Thu</li>
<li>Fri</li>
<li>Sat</li>
</ul>
<ul class="days">
<li class="inactive">26</li>
<li class="inactive">27</li>
<li class="inactive">28</li>
<li class="inactive">29</li>
<li class="inactive">30</li>
<li class="inactive">31</li>
<li>1</li>
<li class="highlighted">2</li>
<li class="highlighted">3</li>
<li>4</li>
</ul>
</div>
I’ve provided the full HTML code and an example in a JSFiddle as well.
And here is the full code :
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
padding: 0 10px;
justify-content: center;
min-height: 100vh;
background: #9B59B6;
}
.wrapper {
width: 95%;
margin: auto;
margin-top: 10px;
background: #fff;
border-radius: 10px;
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.12);
}
.calendar {
padding: 20px;
}
.calendar ul {
display: flex;
flex-wrap: wrap;
list-style: none;
text-align: center;
}
.calendar .days {
margin-bottom: 20px;
}
.calendar li {
color: #333;
width: calc(100% / 7);
font-size: 1.07rem;
}
.calendar .weeks li {
font-weight: 500;
cursor: default;
}
.calendar .days li {
z-index: 1;
cursor: pointer;
position: relative;
margin-top: 30px;
}
.days li.highlighted {
background-color: lightblue;
}
/* For the first highlighted li element in any range */
.days li:not(.highlighted)+li.highlighted {
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
/* For the last highlighted li element in any range */
.days li.highlighted+li:not(.highlighted) {
border-top-right-radius: 10px !important;
border-bottom-right-radius: 10px !important;
}
<div class="wrapper">
<div class="calendar">
<ul class="weeks">
<li>Sun</li>
<li>Mon</li>
<li>Tue</li>
<li>Wed</li>
<li>Thu</li>
<li>Fri</li>
<li>Sat</li>
</ul>
<ul class="days">
<li class="inactive">26</li>
<li class="inactive">27</li>
<li class="inactive">28</li>
<li class="inactive">29</li>
<li class="inactive">30</li>
<li class="inactive">31</li>
<li>1</li>
<li>2</li>
<li class="highlighted">3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
<li class="highlighted">19</li>
<li class="highlighted">20</li>
<li class="active highlighted">21</li>
<li class="highlighted">22</li>
<li class="highlighted">23</li>
<li class="highlighted">24</li>
<li class="highlighted">25</li>
<li class="highlighted">26</li>
<li class="highlighted">27</li>
<li class="highlighted">28</li>
<li class="highlighted">29</li>
<li class="highlighted">30</li>
<li class="inactive highlighted">1</li>
<li class="inactive highlighted">2</li>
<li class="inactive highlighted">3</li>
<li class="inactive">4</li>
<li class="inactive">5</li>
<li class="inactive">6</li>
</ul>
</div>
</div>
3
Answers
This is a live demo of your code:
You’re targetting
li:not(.highlighted)
but since it has no visible border or background colour you can’t see any difference.When I set a background on the other li elements you can see the radius on 4:
You want to target
li.highlighted
, but that isn’t the subject of the selector.The
:has()
psuedo-class will let you make the highlighted li element the subject but browser support is still lacking (most major browsers support it now, but Firefox’s implementation is still buggy and locked behind a feature flag).You’re be safest adding an extra class:
The issue it that with
.days li.highlighted + li:not(.highlighted)
you are selecting the element after the last.highlighted
and that one doesn’t have the lightblue background so no round border can be displayed.As shown by Quentin, there is no reliable CSS selector to target the last element with a specific class. And the safest would be to add a class to the last elements with the
.highlighted
class.If you cannot do that, you could use a workaround with a pseudo element to make the last round border :
Note that :
.highlighted
class. but it can only be seen over the first elements after the.highlighted
onesoverflow: hidden;
on the.days
element to hide the pseudo elements that shouldn’t be seen (at the end of each line)Another option (in addition to the already proposed solutions) is to use
:before
and:after
in.days li.highlighted + li:not(.highlighted)
with the colors used:In this case, the selection will not go beyond the cell, as in @web-tiki solution.