Can ordered list produce result that looks like 1.1, 1.2, 1.3 (instead of just 1, 2, 3, ...) with css?

Can an ordered list produce results that looks like 1.1, 1.2, 1.3 (instead of just 1, 2, 3, ...) with CSS? So far, using list-style-type:decimal has produced only 1, 2, 3, not 1.1, 1.2., 1.3.


Solution 1:

You can use counters to do so:

The following style sheet numbers nested list items as "1", "1.1", "1.1.1", etc.

OL { counter-reset: item }
LI { display: block }
LI:before { content: counters(item, ".") " "; counter-increment: item }

Example

ol { counter-reset: item }
li{ display: block }
li:before { content: counters(item, ".") " "; counter-increment: item }
<ol>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
  <li>li element</li>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
</ol>

See Nested counters and scope for more information.

Solution 2:

None of solutions on this page works correctly and universally for all levels and long (wrapped) paragraphs. It’s really tricky to achieve a consistent indentation due to variable size of marker (1., 1.2, 1.10, 1.10.5, …); it can’t be just “faked,” not even with a precomputed margin/padding for each possible indentation level.

I finally figured out a solution that actually works and doesn’t need any JavaScript.

It’s tested on Firefox 32, Chromium 37, IE 9 and Android Browser. Doesn't work on IE 7 and previous.

CSS:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
}

ol > li {
  display: table;
  counter-increment: item;
  margin-bottom: 0.6em;
}

ol > li:before {
  content: counters(item, ".") ". ";
  display: table-cell;
  padding-right: 0.6em;    
}

li ol > li {
  margin: 0;
}

li ol > li:before {
  content: counters(item, ".") " ";
}

Example: Example

Try it on JSFiddle, fork it on Gist.

Solution 3:

The chosen answer is a great start, but it essentially forces list-style-position: inside; styling on the list items, making wrapped text hard to read. Here's a simple workaround that also gives control over the margin between the number and text, and right-aligns the number as per the default behaviour.

ol {
    counter-reset: item;
}
ol li {
    display: block;
    position: relative;
}
ol li:before {
    content: counters(item, ".")".";
    counter-increment: item;
    position: absolute;
    margin-right: 100%;
    right: 10px; /* space between number and text */
}

JSFiddle: http://jsfiddle.net/3J4Bu/