Styling list numerations with CSS
I suppose it's possible to argue that list numerations are purely presentational. I don't think it's an argument you can win, but I'll grant that you can make it.
Up front, I'll concede that for some documents, the numeration style of some lists may be purely presentational. But I don't think that's universally the case. It's certainly not as simple as just changing the list numeration style.
Consider any document that cross-references a list item. If the prose says “see item 5 in such-and-such a list” the reader is going to be confused, at least, if the fifth item of the list in question is labeled “V”. This is true even if “item 5” is a link to the item in question.
But fine, let's set all that aside and turn our attention to
list numbering. Once upon a time, there was a start
attribute on ol
elements to set the starting number. But
that's
been deprecated. As far as I can tell, that moves the problem out of the markup
and into CSS. That's just broken.
The fact that the list numeration continues is absolutely part of the nature of the document itself. It should be part of the markup. That said, I agree that setting a starting item number was a poor design choice. At the very least, it's too fragile in the face of edits to the preceding list.
I think the right semantic here (yes, semantic, not presentation or style) is for the list to specify that its numeration continues the numeration of the preceding list. If you really, really wanted to be explicit, you could add a link back to the list that it continues, but that introduces the possibility of out-of-order continued lists and so is probably best avoided.
The markup I want is something like <ol continues>
.
(What about the case where the list continues a list from a preceding page, not part
of this HTML document? Yeah, that's a problem. Maybe you do need start
as well for that case.)
Anyway. I can't have that, and I can't have the start
attribute either (the practical
application I'm working on is in the context of EPUB 2 where the
start
attribute is non-conformant), so I guess I have to
resort to CSS. (And I can assume EPUB readers will support this
complex CSS, because why? [One thing at a time. —ed]).
The relevant CSS appears to be something like this:
ol {
counter-reset: item
}
li {
display: block;
list-style: none;
}
li:before {
content: counter(item) ". ";
counter-increment: item;
}
And when I want to continue a list, I specify one minus the starting number [WTF!? —ed] in a CSS property:
ol.startsat5 {
counter-reset: item 4;
}
But wait, I hear you cry, you mean I have to keep track of the class or ID values of all the lists that continue and correctly manufacture style rules that are based not on the actual starting list number, but one less than that number?
Yeah. Well. No. That's just absurd. What you end up doing is putting that in an inline style because frankly, for a document of any size, anything else is as close to utterly unmaintainable as I can possibly imagine:
<ol style="counter-reset: item 4;">
But at least we can all see how that's a vast improvement over
<ol start="5">
[Are you on crack? —ed]
But wait, it keeps getting better. Consider this list:
<ol>
<li>Item 1.</li>
<li><pre>Item 2
is a pre.
It is, ok? That's not negotiable.</pre></li>
<li><p>Item 3 is a p.</p>
</li>
</ol>
If you let the browser enumerate that, you get what you expect. But try it with the CSS numeration. Go ahead, I'll wait. Put this in your browser:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Using CSS</title>
<style type="text/css">
ol {
counter-reset: item
}
li {
display: block;
list-style: none;
}
li:before {
content: counter(item) ". ";
counter-increment: item;
}
</style>
</head>
<body>
<h1>Using CSS</h1>
<ol>
<li>Item 1.</li>
<li><pre>Item 2
is a pre.
It is, ok? That's not negotiable.</pre></li>
<li><p>Item 3 is a p.</p>
</li>
</ol>
<h2>New section</h2>
<ol style="counter-reset: item 3;">
<li>Is it a good idea to continue numerations across section
headings? I don't know and I don't care. That's not negotiable either.</li>
<li><p>Another paragraph just for good measure.</p>
</li>
</ol>
</body>
</html>
Lovely, isn't it? Those extra line breaks between the number and the list item when the list item begins with a block element add a real touch of professionalism and class to your document, don't they?
With luck, someone will comment on this post with a pointer to the solution that actually, you know, works. In the meantime, I can't decide which is less awful: borked numeration or borked presentation. Neither seems…acceptable, really.
Comments
HTML5 has restored the
start
attribute to its proper status.I think what you're looking for is
::marker
. Unfortunately, no browsers currently implement this. The:before
selector is definitely not your friend here. If you’re reasonably sure about the contents of theli
items you may be able to do something withli>*:first-child
.Just to close the loop on an exchange that Karl and I had on twitter about his proposed solution: apparently it does the right thing in Opera but not in Firefox or Chrome.
Or, rather, it does something different in Firefox and Chrome, I'll leave it to someone else to determine which thing is right.
For their documents the US House of Representatives (and probably the Senate) actually hard code their numbering into their XML content (mostly gov't bills and other similar legal documents).
This is something most people should not try at home (hopefully for obvious reasons). I just thought it might be interesting to add to the discussion.
There are at least three reasons they do this that I am aware of:
1) The 'numbers' (they use digits, roman, alpha, upper and lower case, parens, periods and other stuff) are tied directly to the legal content so the numbers are effectively permanent. Anything else might reference them (at any point in the future) and they don't trust any rendering engine (or transform) to do the right thing, only hard coding is considered safe. This lets you reference things like this for all time: "under subsection (c)(9)(A)(ii)" (which, by the way, is a real life example).
2) Items can, seemingly, appear out of order (at least what any normal person would consider the right order). Items can be removed or moved around while the numbers remain the same (I think, and perhaps not always).
3) They didn't want to re-code their old publishing system (which supposedly works "just fine thank you very much") so the content was actually coded to squeeze into that system with minimal (if any) changes required.
[I know this because I helped them with some of the technical aspects of this years ago. They have various scripts that help their authors insert numbers for different portions of each document when they are authoring their files in XMetaL. These scripts are run with a lot of human supervision and generally only on small portions of documents.]
At the end of the day, I'm transforming DocBook into HTML, so the HTML is "RTF for the web" as much as anything else. I'd be willing to hard code the numbers, if it would help, but I don't think it does. And of course it reduces accessibility by removing useful semantic markup from the document.
I suppose the new CSS3 Lists spec could solve your problem - when implemented of course.
I haven't had the pleasure of having to deal with continuations in anything except the simplest cases, but I did run into the para inside of a list item problem when converting to html for epub/mobi. In that case, I found that the rendering is inconsistent across browsers/ereaders (in fact, if I remember correctly, it was even different between the kindle emulator and a kindle device). That was without trying Karl's fix. I ended up doing a post-conversion clean-up on the epub xhtml to remove the <p> on the first paragraph of a list item (if one exists). Not pretty:-), but it did the job.
Trust me when I tell you, I'm not having fun with this. I am converting to ePub/mobi my Flash tutorials, originally written in MS Word. I have a plethora of headings and images per section. I'm now currently hard-coding my numbers, 56 on the first tutorial btw. I may try some suggestions above, the hard-coding just looks so boot-leg.