mattstuehler
mattstuehler

Reputation: 9282

CSS ordered list - style the number, when li contains multiple lines, maintaining indentation

Variants of this question have been asked and answered, but I can't find an answer to this specific question...

I would like to style the number in each li item in my ol, given that each li may span multiple lines, in a way that maintains the indentation.

For example - here is a simple, un-styled example:

<div style="width: 200px;">
  <ol>
    <li>blah blah blah blah blah blah blah blah blah blah</li>
    <li>blah</li>
    <li>blah blah blah blah blah blah blah blah blah blah</li>
    <li>blah</li>
  </ol>
</div>

This produces the following result - note the proper indentation of multiple lines:

enter image description here

I've tried styling the numbers using li:before:

ol {
  counter-reset: li;
  list-style: none;
}
li {
  counter-increment: li;
}
li:before {
  margin-right: 10px;
  content: counter(li) '.';
  width: 1.2em;
  display: inline-block;
}
<div style="width: 200px;">
  <ol>
    <li>blah blah blah blah blah blah blah blah blah blah</li>
    <li>blah</li>
    <li>blah blah blah blah blah blah blah blah blah blah</li>
    <li>blah</li>
  </ol>
</div>

Now, I can easily style the numbers, but the indentation on multiple lines is lost:

enter image description here

So, how can I style the numbers, and maintain proper indentation?

Upvotes: 1

Views: 1202

Answers (4)

Jake
Jake

Reputation: 1217

You can also update the display: to use the table values.

The table-row value makes the element act like a <tr> and the table-cell makes the element act like a <td> ensuring that the different parts of the list stay aligned.

ol {
  counter-reset: li;
  list-style: none;
}
li {
  counter-increment: li;
  display:table-row;
  
}
li:before {
  margin-right: 10px;
  content: counter(li) '.';
  width: 1.2em;
  display: table-cell;
}
<div style="width: 200px;">
  <ol>
    <li>blah blah blah blah blah blah blah blah blah blah</li>
    <li>blah</li>
    <li>blah blah blah blah blah blah blah blah blah blah</li>
    <li>blah</li>
  </ol>
</div>

Upvotes: 2

Michael Coker
Michael Coker

Reputation: 53674

If you don't mind introducing another element, you can just wrap the text in a span.

li {
  color: red;
}
li span {
  color: black;
}
<div style="width: 200px;">
  <ol>
    <li><span>blah blah blah blah blah blah blah blah blah blah</span></li>
    <li><span>blah</span></li>
  </ol>
</div>

Upvotes: 1

ppajer
ppajer

Reputation: 3145

You could just make some space on the left side of the element by padding it, remove the :before element from the content flow with position: absolute, and position it in the space created by the padding.

ol {
  counter-reset: li;
  list-style: none;
}
li {
  counter-increment: li;
  /* Anchor all :before elements to their respective li */
  position: relative;
  padding-left: 1em;
}
li:before {
  content: counter(li) '.';
  width: 1.2em;
  display: inline-block;
  position:absolute;
  left: 0;
}

Upvotes: 1

Web Dev Guy
Web Dev Guy

Reputation: 1789

Use this css.

li {
  counter-increment: li;
  padding-left: 30px;
}
li:before {
  margin-right: 10px;
  content: counter(li) '.';
  width: 1.2em;
  display: inline-block;
  margin-left: -30px;
}

Upvotes: 1

Related Questions