With all the hype surrounding the new APIs and the fancy parts of CSS, I had almost forgotten about the new reversed
attribute that allows you to write a descending list of numbered items, as opposed to the default ascending list of numbered items.
You can get full details in the specification, but here I’ll summarize what it does and I’ll offer a solution for the fact that there is (from what I can see) no browser support for this attribute.
Summary of the “reversed” Attribute
As mentioned, using the new reversed
attribute, you can tell the browser that the numbering for the list items should display in descending order, instead of the default ascending.
At first, this confused me. I was under impression that this attribute would actually physically reverse the contents of the list. But that’s not the case. The items will still appear in the same order as they appear in the markup, but the numbers will begin with the highest. So if you have 10 list items, then the first list item will display with a number 10, the second with a number 9, and so forth.
The syntax is simple, you just add the reversed
attribute to any <ol>
element. This attribute is a Boolean attribute, so it doesn’t take any value.
The code (as if you needed an example!) looks like this:
<ol reversed> <li>List item one</li> <li>List item two</li> <li>List item three</li> <li>List item four</li> <li>List item five</li> </ol>
The result in the browser would be:
The “start” Attribute
In addition to the reversed
attribute, HTML5 also reintroduces the start
attribute for ordered lists. I say reintroduces because this attribute was introduced in older versions of HTML but eventually was deprecated in HTML4.
Using this attribute, you can specify at what number you want the list to begin. The value must be an integer, otherwise it will just default to “1”. So, without reversed, if you specify a start of “100”, then each list item will be numbered starting with 100. The result would be as shown below:
If you reverse the list, and specify a start
value, then the list will begin with that specified value and will go backwards. Like this:
Because it’s an older attribute, the start
attribute has full support everywhere, so that’s good news.
Fixing Old Browsers With “value” Attributes
All modern browsers and in-use browsers now support this feature. But if you need older browser support, here’s the interesting thing: Every browser allows you to use the value
attribute to change the number of each list item directly. This attribute was deprecated in HTML4 but is valid in HTML5.
Using this attribute, we can do this:
<ol> <li value=5>List item one</li> <li value=4>List item two</li> <li value=3>List item three</li> <li value=2>List item four</li> <li value=1>List item five</li> </ol>
But we all know that’s pretty lame — unless you’re doing something funky where you’re adding numbers that have no order or whatever.
But this gave me an idea.
A Polyfill for “reversed” for Old IE
After starting to write this article, and then realizing there was no support, I decided to write a polyfill. It didn’t take too long, as it accomplishes a pretty simple task: It looks for the presence of the reversed
attribute on an ordered list; then it counts the number of list items in the list; then it adds the value
attribute to each list item, with the appropriate integer.
It also takes into consideration the start
attribute, so if that’s present, it will start the numbered list at that number and descend.
You can view or download the code on GitHub and I’ve put up a jsFiddle with some examples. The GitHub repo uses raw JS, while the jsFiddle uses jQuery.
Good stuff! I never figured out exactly why they deprecated the start attribute, since it’s really part of the content and not a style issue.
One tiny improvement could be made to the polyfill though. Where you have
$(myLists).each()
that should bemyLists.each()
since myLists is already a jQuery object. You end up doing$($('ol[reversed]'))
.Yep, you’re right. I think strangely the jQuery
$()
wrapper confuses me sometimes. I’ve corrected that in two places on the GitHub repo. Thanks.jQuery $() is a function so if you pass jQuery object as argument the function will return a clone of the object pointing to the same DOM.
You can see that in the spec:
Reference: jQuery()
Thanks, Pablo. Definitely the kind of thing I need to read up on more. :) It’s just so easy to take stuff like that for granted.
This one always catches me out too. :)
The weird thing is, you could do this:
And it would still work, albeit probably with performance drawbacks I assume.
The only problem with the reversed listing is that only the numbers are reversed. At a practicle level, one would want the accompanying text to also be reversed. For e.g. when listing out changes to a code and you want the list displayed chronologically with the latest change at the top. Hope I’m making sense.
Yeah, you’re sort of right. But it’s probably the same thing, all things considered. You can reverse the order of the list items manually, displaying them how you want, which is I think just as maintainable.
In fact, my first impression of reverse ordered lists was that the contents would be reversed, too, so I didn’t understand what the reversed attribute did at first.
I disagree that the text order should be reversed too. The text items should be in the order they are written, and only the numbering reversed, as it is. Consider a “Top 10 list, counting down to number 1”:
I can see how using pseudo elements such as :first-child could be problematic with reversing, but the idea is great nontheless. Thanks for finding this.
Using pseudo selectors such as :first-child should not cause any problems, as the chidren themselves do not change order.
You can do this, by the way, with CSS counters alone: http://jsfiddle.net/nYRTK/
No JavaScript needed.
Nice reminder. I wrote about counters here but didn’t think of it as a fallback for this.
Counters have a few major drawbacks though: No support in IE6/7, buggy support in IE8, and the syntax for counters is very complex.
But yes, thanks for the reminder, definitely a good footnote to this post. :)
The worst problem is, that they (CSS counters) are not reachable from within JS: http://stackoverflow.com/questions/2651739/how-to-access-css-generated-content-with-javascript
This bugs me most in the CSS-only solution, because it doesn’t allow for a simple fallback. (This is true for many other fancy new CSS3 things. The situation will get worse, even when CSSOM will land somewhen in the future.)
I might not entirely get this, so please feel free to correct me, but: Why not use PHP to accomplish exactly the same without writing a js code to get the HTML markup to work? Plus, by not using HTML5 you don’t have to bother writing hacks and fallbacks for all the clients out there who still don’t get the concept of using modern browsers.
Don’t get me wrong, personally I’m totally into using modern and responsive coding techniques and respect the effort you make to give us a overview. But it occurs to me that in the daily business with websites it (unfortunately) doesn’t make sense yet. Especially considering your own statement: “no support in any browser”.
Well, you don’t need PHP, even if you don’t to use JavaScript. As I explained under the heading “Fixing it…”, you can use the “value” attributes on the list items to change the numeric value of each item.
Yes, you could do that with PHP, and I suppose you could create a function that accepts an argument as the first value. So, that’s an option, no doubt. But many people don’t have a problem with relying on JS to enhance things, and most screen reader users have JS enabled, so it seems okay to me to do this using JS.
I’m not saying you’re wrong. If you’re concerned about using JS, then by all means, use PHP. I just think most people are pretty comfortable polyfilling this with JS instead so later it can be easily removed when browsers support it natively, and the markup stays the same.
Thanks for your reply, Louis. I’ll keep this in mind and just wait for an overall browser support. CSS3 and HTML5 better be web standards soon. (:
Very good option, some times i use reversed,thx
WOW, I had no idea about the “value” attribute!
Another feature that will probably never be used.
Just a heads-up: Gecko will support the reversed attribute from Gecko / Firefox 18 on which will go to beta next week.
Cool, good to know. Thanks.
Can you please update your post to reflect the support of Firefox for this feature?
Done. Thanks for the reminder!
Why is there a “start” attribute but no “end” attribute? Why do these obvious things never occur to the designers? If I want a reversed list that always ends at, say, 10 no matter how many elements it has, now I always have to calculate a value for the “start” attribute, and remember to fix it whenever I change the list. Are they deliberately trying to make the web as hard to use as possible? (rant over, I had to get this off my shoulder)
I don’t understand what you’re asking for…?
If you have a list of 15 elements, why would you number them from 10 to 1 but then not have numbers for the rest? If you want it like that, then just remove the last five items. I don’t think that’s a design flaw, I think you’re just approaching it the wrong way.
Unless I’m not understanding what you’re suggesting…?
Oh, I see now what you’re saying…. interesting. So if you want it to always end at “10”, then the “start” number would be dependent on the number of items, thus you’d have to have the list starting at a negative number if there were more than 10, and starting at a number higher than 1 if there were less than 10.
Well, I guess browsers usually only put in features that are actually practical, otherwise there would be too many features to support. To be honest, I can hardly think of a situation that would require a list to always end with 10. Can you provide a realistic example?
I was thinking of a reversed list that ends in 10, i.e. something like 15, 14, 13, 12, 11, 10.
You clearly think that “start” and “reversed” are useful, otherwise you wouldn’t have written this blog post. Therefore, just take any realistic case for those and combine them, and you have a realistic case for “end”. Anywhere you need a list to start at any specific number, if that list is reversed, you want it to end at a specific number.
This is further obviated by the fact that the *default* for a reversed list is to end at 1. You can’t even express the default semantics in attributes! That should have been an obvious alarm bell to the designers…
Actually, just because I wrote about it, doesn’t mean I think it’s practical. I found it was interesting, so I hacked around with it a little and wrote that polyfill.
But I don’t personally have many real-world ideas on how to use any of these. In 99% of cases, lists are just straight lists, with no reversed or start needed. That’s why when you throw “end” into the mix, the use cases decrease even more.
Not that you’re wrong, I just think it’s less important than something that’s already not very important.
I think you can do that with the help of CSS: counter(), content(), some clever selectors etc. Shouldn’t be too difficult.
Thank you very much for this workaround! My friend uses the text-based Web-browser Links, which both has an issue with ordered lists that start from zero and reversed ordered lists. I really needed a fix for this. Using the “value” attribute on the <li/> tags instead of the “start” attribute on the <ol/> tags causes Links to render the correct numbers.
“But we all know that’s pretty lame — unless you’re doing something funky where you’re adding numbers that have no order or whatever.”
You’re wrong about “numbers that have no order or whatever” being “funky”: Crosswords have such lists! I.e.:
ACROSS
1. American president.
3. Opposite of black.
DOWN
2. Dwarfs in fairy tales collect this metal.
3. Romantic flower.