Why does this not work? http://jsfiddle.net/84C5W/1/
p{ display: none; } p.visible:last-of-type { display: block; }
<div> <p class="visible">This should be hidden</p> <p class="visible">This should be displayed</p> <p class="">This should be hidden</p> </div>
In fact, none of my <p>
elements are visible. If I remove the reference to .visible
in my selector, this does show the last <p>
in the div, but this is not what I want.
Of course I could only keep one .visible
at all times, but this is for a reveal.js presentation and I do not have control over the JavaScript.
How can I select the last element inside the div WITH the class .visible
? I do NOT want to use JavaScript for this.
Yes, using :last-of-type with a class selector alone is very unintuitive; it is best used with a type selector unless you really want the last of any type to have that class.
The :last-of-type selector allows you to target the last occurence of an element within its container. It is defined in the CSS Selectors Level 3 spec as a “structural pseudo-class”, meaning it is used to style content based on its relationship with parent and sibling content.
To select the last element of a specific class, you can use the CSS :last-of-type pseudo-class.
The :not() selector excludes the element passed to it from selection. The :last-child selector selects the last child.
Your issue is that you're reading :last-of-type
and thinking it works as a :last-of-class
selector, when instead it specifically means elements only. There is no selector for the last instance of a class, unfortunately.
From the W3C:
The
:last-of-type
pseudo-class represents an element that is the last sibling of its type.
You have p.visible:last-of-type
as your selector, which does the following:
:last-of-type
applied to it) within each containing element in your HTML<p>
element.visible
on it.In short, your selector will only apply its styles to a <p>
that also has the class .visible
on it. In your markup, only the first two <p>
elements have that class; the third does not.
Here's a demo of different styles to illustrate:
p:last-of-type { /* this will be applied in the third paragraph because the pseudo-selector checks for nodes only */ color: green; } p.visible:last-of-type { /* this does not get applied, because you are using the pseudo-selector with a specific class in addition to the node type. */ color: red; }
<p class="visible">First paragraph.</p> <p class="visible">Second paragraph.</p> <p>Third paragraph.</p>
Per your ultimate goal,
How can I select the last element inside the div WITH the class .visible? I do NOT want to use JavaScript for this.
The simplest and most performant way is to invert the way you're trying to apply the styles; instead of trying to hide two out of three divs, where one of the divs to hide has a class and the other div to hide has no class, and the div you want to show shares the same class as the one div you want to hide which also has a class (see? that's pretty confusing), do the following:
p { display: none; } .visible { display: block; }
<div> <p>This should be hidden</p> <p class="visible">This should be displayed</p> <p>This should be hidden</p> </div>
As you can see from this demo, not only are your HTML and CSS simpler, but this also has the benefit of using only a class selector rather than a *-of-type
pseudo-selector, which will make the page load faster (see more on that below).
Why is there no followed by or parent selector? This could potentially bog down the speed of a lot of webpages by changing just one class name dynamically on the page.
Dave Hyatt, while working on the WebKit implementation in 2008, mentioned some reasons why these implementations are avoided:
With parent selectors it becomes extremely easy to accidentally cause a document-wide grovel. People can and will misuse this selector. Supporting it is giving people a whole lot of rope to hang themselves with.
The sad truth about CSS3 selectors is that they really shouldn’t be used at all if you care about page performance. Decorating your markup with classes and ids and matching purely on those while avoiding all uses of sibling, descendant and child selectors will actually make a page perform significantly better in all browsers.
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