As I had explained in my answer here, :last-child
selector does not work that way. This selector points to only one element and it is always the element which is the last child of its parent. The child that is selected doesn't change based on the other conditions that are attached to the selector. Only thing that is affected by the additional conditions is whether the last child element itself is selected or not.
The below selector simply means select the last child li element only if it does not have class x and not select the last child li element which does not have class x.
li li:not(.x):last-child {
color: red;
}
There are no plans to introduce previous sibling selector even in Selectors Level 4 and I don't think they would ever be introduced because that goes against the meaning of Cascading Style Sheets.
There is however a selector that is specced in Level 4 which could solve cases like this and it is the :nth-last-match
pseudo-selector. For your case, it could end up being something like the below:
li li:nth-last-match(1 of :not(.x))
I am assuming the nth-last-match
will allow a negation selector because there is no mention about it being invalid even though :matches(:not(...))
is said to be invalid. There is a chance that it may be marked as invalid in which case we would still find it tough to select such elements.
As per the latest Editor's Draft of the spec, it seems like the :nth-last-match
selector is no longer in scope (and has been subsumed into :nth-last-child
selector). So, the selector would instead be:
li li:nth-last-child(1 of :not(.x))
It also talks about another one which could be useful for this case. It is the :has
pseudo selector.
li li {
color: red; /* apply the styling which needs to be set to the last child without class x */
}
li li:has( ~ li:not(.x)) { /* this selects all li which have a sibling whose class is not x */
color: black; /* override the style for these alone and set them to the default */
}
Note: This again is only a draft and can change.
One possible solution would be to use jQuery (or JavaScript) to find out the last element that satisfies the conditions and then set the required styles or classes to it.
$(document).ready(function() {
$('li ol').map(function() {
return $(this).children().not('.x').get(-1);
}).css('color', 'red');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol>
<li>
<ol>
<li>A</li>
<li>B</li>
<li class="x">X</li>
</ol>
</li>
<li>
<ol>
<li>A</li>
<li>C</li>
<li class="x">X</li>
</ol>
</li>
<li>
<ol>
<li>A</li>
<li>D</li>
<li class="x">X</li>
</ol>
</li>
<li>
<ol>
<li>A</li>
<li>D</li>
<li class="ex">X</li>
</ol>
</li>
</ol>