131

How can I left-align the numbers in an ordered list?

1.  an item
// skip some items for brevity 
9.  another item
10. notice the 1 is under the 9, and the item contents also line up

Change the character after the number in an ordered list?

1) an item

Also is there a CSS solution to change from numbers to alphabetic/roman lists instead of using the type attribute on the ol element.

I am mostly interested in answers that work on Firefox 3.

kapa
  • 77,694
  • 21
  • 158
  • 175
grom
  • 15,842
  • 19
  • 64
  • 67
  • 1
    a very elegant example with nesting! --> https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Counter_Styles/Using_CSS_counters#example_of_a_nested_counter – Kay V Jan 16 '22 at 03:20

17 Answers17

117

This is the solution I have working in Firefox 3, Opera and Google Chrome. The list still displays in IE7 (but without the close bracket and left align numbers):

ol {
  counter-reset: item;
  margin-left: 0;
  padding-left: 0;
}
li {
  display: block;
  margin-bottom: .5em;
  margin-left: 2em;
}
li::before {
  display: inline-block;
  content: counter(item) ") ";
  counter-increment: item;
  width: 2em;
  margin-left: -2em;
}
<ol>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
  <li>Five</li>
  <li>Six</li>
  <li>Seven</li>
  <li>Eight</li>
  <li>Nine<br>Items</li>
  <li>Ten<br>Items</li>
</ol>

EDIT: Included multiple line fix by strager

Also is there a CSS solution to change from numbers to alphabetic/roman lists instead of using the type attribute on the ol element.

Refer to list-style-type CSS property. Or when using counters the second argument accepts a list-style-type value. For example the following will use upper roman:

li::before {
  content: counter(item, upper-roman) ") ";
  counter-increment: item;
/* ... */
Nhan
  • 3,595
  • 6
  • 30
  • 38
grom
  • 15,842
  • 19
  • 64
  • 67
  • Needed to add the numbers back in, a global style was removing them (who knows why you would use a ol and remove the numbers rather than a ul??). Very clear answer +1 for full explanation and code, can easily be modified to do anything. – Morvael Feb 13 '14 at 11:35
  • I suggest a cleaner CSS *margin/padding* solution, that works better with lists having wide numbering: `ol {counter-reset: item; padding-left: 0;} li {display: block; margin-bottom: .5em;} li:before {display: inline-block; content: counter(item) ") "; counter-increment: item; padding-right: 0.8em;}`. – mmj Jul 26 '16 at 14:55
36

HTML5: Use the value attribute (no CSS needed)

Modern browsers will interpret the value attribute and will display it as you expect. See MDN documentation.

<ol>
  <li value="3">This is item three.</li>
  <li value="50">This is item fifty.</li>
  <li value="100">This is item one hundred.</li>
</ol>

Also have a look at the <ol> article on MDN, especially the documentation for the start and attribute.

Flimm
  • 136,138
  • 45
  • 251
  • 267
31

The CSS for styling lists is here, but is basically:

li {
    list-style-type: decimal;
    list-style-position: inside;
}

However, the specific layout you're after can probably only be achieved by delving into the innards of the layout with something like this (note that I haven't actually tried it):

ol { counter-reset: item }
li { display: block }
li:before { content: counter(item) ") "; counter-increment: item }
thanksd
  • 54,176
  • 22
  • 157
  • 150
Marcus Downing
  • 10,054
  • 10
  • 63
  • 85
14

You can also specify your own numbers in the HTML - e.g. if the numbers are being provided by a database:

ol {
  list-style: none;
}

ol>li:before {
  content: attr(seq) ". ";
}
<ol>
  <li seq="1">Item one</li>
  <li seq="20">Item twenty</li>
  <li seq="300">Item three hundred</li>
</ol>

The seq attribute is made visible using a method similar to that given in other answers. But instead of using content: counter(foo), we use content: attr(seq).

Demo in CodePen with more styling

Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
z0r
  • 8,185
  • 4
  • 64
  • 83
  • 8
    You can simplify this if you just use the `value` attribute on `
  • `. e.g. `
  • `. Then you don't need any pseudo elements. [Demo](http://codepen.io/anon/pen/EPbZJM)
  • – GWB Jan 18 '16 at 21:38
  • 4
    @GWB While that is valid (and a good solution), it's limited to numerical values as the list is ordinal. As such, you can't do something like `value="4A"`, as it won't work. Additionally, the value attribute can work with the `type` attribute, but value still must be a number (as it works within an ordered set). –  Nov 07 '16 at 15:34
  • Thanks - this worked for me when I needed [Flying Saucer](https://github.com/flyingsaucerproject/flyingsaucer) to show a list in reverse order (`reversed` attribute is html5 only, as is using the `value` of the `li`). Instead of using your `seq` I set a `value` and used `attr(value)` instead of `attr(seq)` – jaygooby Feb 14 '18 at 16:29
  • 3
    Is `seq` a standard attribute defined anywhere? If not, wouldn't it be better to use data-seq? – nHaskins Oct 01 '21 at 20:24