Right-align legal-styled numbers and left-align text in ordered lists using CSS
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.htmlOL { 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:
ol {
width: 10em;
counter-reset: item;
list-style-position: outside;
}
li {
position: relative;
left: 2em;
display: block;
list-style-position: outside;
}
li:before {
content: "("counters(item, ".") ") ";
counter-increment: item;
position: absolute;
left: -2.5em;
}
li li:before {
left: -2.5em;
}
li li li:before {
left: -3em;
}
This just uses position: relative;
to allow the li
text to be moved to the right (left: 2em;
) while positioning the li:before
text absolutely and moving it to the left.
The awkward part comes from having to specify different left:
values for the li:before
, li li:beforeand
li 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:
Thanks, I believe I understand how that works. To continue the pattern, I'd have to create "li li li li" for a list that was 4 levels deep, right? Also, I don't see that the numbers are left-aligned. Is there a way to get at those value and apply similar repositioning or alignment to just them?
I mean the numbers are NOT right-aligned.
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
:
li:before {
content: "("counters(item, ".") ") ";
counter-increment: item;
position: absolute;
left: -2.5em;
display: block;
width: 2em; /* to give the same dimensions to all counter 'blocks' */
text-align: right; /* does exactly what you'd think =) */
}
With this approach bear in mind that the size of the contents of li:before
must be less than the left:
positioning of the li
, 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:before
as before.
Demo at: http://jsbin.com/ovuru3
精彩评论