:last-of-type doesn't always work




CSS Parsing and Computation
5 years ago
5 years ago


(Reporter: move5mexico, Unassigned)


Windows 7

Firefox Tracking Flags

(Not tracked)



(1 attachment)



5 years ago
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 SeaMonkey/2.15.1
Build ID: 20130118191213

Steps to reproduce:

I used the example at https://developer.mozilla.org/en-US/docs/CSS/:last-of-type and changed it to use a class. It works, but another similar example does not.

Actual results:

My test page is
.demo:last-of-type {color: lime;}
.sidebar_top {background-color:white}
.sidebar_top:last-of-type {border: 5px solid red;}
 <span class="demo">I'm not lime :(</span>
 <strong>I'm not lime :(</strong>
 <span class="demo">I'm lime :D</span>
 <strong>I'm also not lime :(</strong>

<div id="container">
 <div id="sitewide-top-widget-area" class="sidebar_top widget-area">first widget</div>
 <div id="top-widget-area" class="sidebar_top widget-area">second widget- should have a red border</div>
 <div id="content"> content </div>

The paragraph is from the example and it works. The div is similar and it does not work.

Expected results:

The 2nd widget area should have a red border.
Created attachment 724502 [details]
Reporters testcase
Safari renders the testcase in the same way
Component: General → Style System (CSS)
Product: SeaMonkey → Core
Version: SeaMonkey 2.15 Branch → Trunk
The rendering is correct.  :last-of-type matches the last element with the same localName+namespace that has the same parent.  So in the example above, the <span class="demo"> would match that selector, as would the second <strong> inside the <p> and as would the <div id="content">.

But there are no elements in the testcase that would match the selector "sidebar_top:last-of-type", because the only element with that class is in fact not last-of-type.

The point being that "type" for purposes of :last-of-type only includes the namespace and localName.
Last Resolved: 5 years ago
Resolution: --- → INVALID

Comment 4

5 years ago
(In reply to Boris Zbarsky (:bz) from comment #3)
Do you have a reference for that?
Looking at http://www.w3.org/TR/css3-selectors/#last-of-type-pseudo, it says
"Same as :nth-last-of-type(1). The :last-of-type pseudo-class represents an element that is the last sibling of its type in the list of children of its parent element."

Can you tell me how the class "sidebar_top" is different from "demo" in this example? There are two of each and they are siblings of each other. The tags with class demo are both <span> and the tags with class demo are both <div>.

I guess I just don't understand what you are calling localName that the spec doesn't mention.
> Do you have a reference for that?

Absolutely.  It's the bit you quoted, plus http://www.w3.org/TR/css3-selectors/#type-selectors which talks about what "type" means plus the :nth-last-of-type specification.  In the case of CSS applied to a DOM, "type" is the element name.

> Can you tell me how the class "sidebar_top" is different from "demo" in this example? 

There is a <div> after the last <div class="sidebar_top">.  There is no <span> after the last <span class="demo">.

> I guess I just don't understand what you are calling localName that the spec doesn't
> mention.

http://dom.spec.whatwg.org/#dom-element-localname (basically the tag name; in this case the relevant one is "div").

Comment 6

5 years ago
(In reply to Boris Zbarsky (:bz) from comment #5)
Wow, I see it now that I found the definition of "expanded element name".
I was hoping it was a matter of the words "type" and "element" being used both generically and specifically.

This means that the pseudo-classes are not nearly as useful as I thought. I was reading it as a modifier for the selector that precedes the colon, but it's not.
All the examples I've read on the web need updating to explain this correctly. I think it is a common mistake to read ".demo:last-of-type" as the last thing with class demo instead of all elements that are the last sibling of their type that also have the class demo.

It also means that there is not a way to select the last one of something in a document with a mixture of elements, as in my small example trying to select the last thing with class sidebar_top. In my actual use case, the document is generated by a CMS so I have no control over the nesting or which tags are used, and the user supplies the content so I don't know how many of anything there will be. Trying to apply a rule to the last widget so that it lines up with the content block is not that uncommon, but apparently very difficult. Since CSS can't address any elements previous, I don't know how to do it. 

Thanks for your time. Shall I open documentation bugs for all the pseudo-classes described on developer.mozilla.org?
Yeah, I think what you were looking for is more like the proposal at http://dev.w3.org/csswg/selectors4/#the-nth-last-match-pseudo

Opening documentation bugs would be great.  Even better would be just editing the wiki, of course.  ;)
You need to log in before you can comment on or make changes to this bug.