Reputation: 5503
I want to simply add a border-bottom
to the last .slab
I tried a few things and I am unable to understand what is going on.
Case 1 - use .wrapper:last-child
If I try this on codepen.io or on Stackoverflow snippets, I don't get a border-bottom
on last .slab
If I try this on JSFiddle or run the code separately in Chrome, I get a border-bottom
on last .slab
. However, if I uncomment <div class="something">New</div>
, then the border-bottom
on last .slab
vanishes in both JSFiddle and on Chrome.
.wrapper {
width: 10em;
margin: 1em;
}
.wrapper:last-child {
border-bottom: 1px solid #999;
}
.slab {
background-color: #eee;
border-top: 1px solid #999;
padding: 1em;
}
<div class="wrapper">
<div class="slab">Hello</div>
<div class="slab">Hello</div>
<div class="slab">Hello</div>
</div>
<!--<div class="something">New</div>-->
Case 2 - use .slab:last-child
Turns out this works everywhere - JSFiddle, Chrome, codepen.io and on Stackoverflow. But I thought the selection was really for the last-child of .slab
and not the last .slab
.wrapper {
width: 10em;
margin: 1em;
}
.slab {
background-color: #eee;
border-top: 1px solid #999;
padding: 1em;
}
.slab:last-child {
border-bottom: 1px solid #999;
}
<div class="wrapper">
<div class="slab">Hello</div>
<div class="slab">Hello</div>
<div class="slab">Hello</div>
</div>
Questions:
.slab:last-child
mean the last child of .slab
or the last occurrence of .slab
?border-bottom
vanishing after the introduction of an unrelated element .something
?border-bottom
to the last .slab
?Upvotes: 1
Views: 314
Reputation: 371231
The :last-child
structural pseudo-class selector applies to siblings of a parent. It is equivalent to :nth-last-child(1)
,
In terms of your code, you would apply :last-child
to .slab
to select the last sibling of parent div.wrapper
.
If the last child of div.wrapper
did not have a slab
class, then the selector wouldn't match. It would do nothing.
If the :last-child
were applied to the div
children of div.wrapper
, like this:
.wrapper > div:last-child { ... }
... then the selector would match the last child regardless of the class
, id
or other attributes. It would match any div
. If the last child was not a div
, the selector would do nothing.
If you wanted to match the last child of div.wrapper
, regardless of anything – meaning it just needs to be the last child – then you could do something like this:
.wrapper > *:last-child { ... }
Without the >
child combinator, let's say .wrapper *:last-child { ... }
, the last child of all descendant parent elements would be matched.
When you select .wrapper:last-child
, you're targeting the element with class wrapper
that is the last child of its parent (presumably body
, in this case).
If div.wrapper
is the only child of its parent, then :last-child
, :first-child
, :only-child
and most other structural pseudo-class keyword selectors would match.
For a better understanding of these selectors (and all others), refer to this section of the CSS spec: http://www.w3.org/TR/css3-selectors/#selectors
Upvotes: 2
Reputation: 723638
Does
.slab:last-child
mean the last child of.slab
or the last occurrence of.slab
?
Neither. It matches an element that
The last .slab
within its parent may not necessarily be its last child. .slab:last-child
will match if and only if both conditions are true for the given element.
In case 1, why is the
border-bottom
vanishing after the introduction of an unrelated element.something
?
Because then the last child of the parent of .wrapper
becomes that other element. This element isn't unrelated to .wrapper
— it's related to it by way of being its next sibling.
The .slab
elements within that wrapper never receive a border; the border is being applied to the .wrapper
for as long as it is the last child of its parent. (Incidentally, the parent of .wrapper
in your examples is implied to be body
.)
What is the best way to apply
border-bottom
to the last.slab
?
You won't be able to do this reliably unless you can guarantee that the only possible children of .wrapper
are .slab
elements, in which case the class name then becomes quite irrelevant (but you can still include it in your selector so you avoid matching the last child of .wrapper
when it's not a .slab
).
Upvotes: 7
Reputation: 115046
last-child
means exactly what is says...the very last element that is a child of a parent.
Not the last of class...the last element.
There is no last-of-class
selector.
This: .slab:last-child
means the last child that also has a class of .slab
.
If it's not the last-child it won't apply and, equally, if it doesn't have a class of .slab
it won't be selected.
Upvotes: 2