While composing documentation, I created an outline using ordered lists within ordered lists and applied a pseudo-legal-style row numbering using CSS. The default behavior of lists is to right-align numbers and left align text; however, the CSS2 snippet I’m using is changing that behavior so that numbers are left-aligned and text, though left-aligned flows incorrectly. See the following examples:
Default behavior (Number 10 highlights the desired alignments):
1. Item
2. Item
1. Item
2. Item
1. Item
2. Item
3. Item
...
10. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nunc et diam sem. Pellentesque vitae dolor id eros commodo
dapibus tristique sit amet eros. Pellentesque turpis turpis.
Styled behavior (Number 10 highlights the undesirable alignments):
Using a derived CSS2 snippet from http://www.w3.org/TR/CSS2/generate.html
OL { counter-reset: item }
LI { display: block }
LI:before { content: "("counters(item, ".") ") "; counter-increment: item }
Results:
(1) Item
(2) Item
(2.1) Item
(2.2) Item
(2.2.1) Item
(2.2.2) Item
(3) Item
...
(10) Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nunc et diam sem. Pellentesque vitae dolor id eros commodo
dapibus tristique sit amet eros. Pellentesque turpis turpis.
I see that the LI { display: block } is suppressing the default numbering and LI:before is prefixing “normal” text with counter values. How can I have both legal-style numbering and desired alignment of numbers and text?
Here’s a full document showing the issue:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Outline</title>
<style type="text/css">
ol {
counter-reset: item;
list-style-position: outside
}
li {
display: block;
padding-left: 10px;
}
li:before {
content: "("counters(item, ".") ") ";
counter-increment: item
}
</style>
</head>
<body>
<h1>Outline</h1>
<ol>
<li>Item</li>
<li>Item
<ol>
<li>Item</li>
<li>Item
<ol>
<li>Item</li>
<li>Item</li>
</ol>
</li>
</ol>
</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nunc et diam sem. Pellentesque vitae dolor id eros commodo
dapibus tristique sit amet eros. Pellentesque turpis turpis.</li>
</ol>
</body>
</html>
A slightly awkward solution might be:
This just uses
position: relative;to allow thelitext to be moved to the right (left: 2em;) while positioning theli:beforetext absolutely and moving it to the left.The awkward part comes from having to specify different
left:values for theli:before, li li:beforeandli li li:before` so it’s not quite as simple as it might be.There’s a demo of what I came up with over at: http://jsbin.com/asaru3
Edited in response to comments from OP:
To the first question ‘to continue the pattern, I’d have to create “li li li [li:before]” for a list…4 levels deep?” Yeah, which is one of the reasons I think it’s an awkward solution. Albeit it does work.
To address the latter question, I believe that you want the numbers to align along their right edge?
If you revise the css for
li:before:With this approach bear in mind that the size of the contents of
li:beforemust be less than theleft:positioning of theli, otherwise there’ll be overlap of the counter and the content.Be aware that as the counter grows in size its width should also be amended for
li li:before,li li li:beforeas before.Demo at: http://jsbin.com/ovuru3