user1131522
user1131522

Reputation: 157

How to wrap text correctly in nested list with counter-increment property?

I have ordered list with counter-increment property. How to make long text, if it breaks into multiple lines, to have same offset from left as first line? Now second line is shown under the numbers.

Here is the fiddle (look at 2.3 item): http://jsfiddle.net/1vh1tt81/1/

I was able to achieve desired result using "position: absolute" on "li:before" element, but that caused other problems specific to my project so this is not good solution for me.

There was a similar question, but in the markup there was additonal a tag while I can't have any additional tags: https://jsfiddle.net/rkmv3rn3/10/

Upvotes: 3

Views: 1475

Answers (3)

Nidhin Joseph
Nidhin Joseph

Reputation: 10227

If your project allows using flex, then you could go with something like this

ol {
  counter-reset: item;
  display: block;
  padding: 0;
  margin: 0;
  flex: 1;
}

body>ol:first-child::before {
  display: block;
}

ol::before {
  display: inline-flex;
  content: '';
}

li {
  display: flex;
}

li::before {
  content: counters(item, ".") ". ";
  counter-increment: item;
}
<ol>
  <li>one</li>
  <li>two
    <ol>
      <li>two.one</li>
      <li>two.two</li>
      <li>two.three long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text
        long tex long text long tex long text long tex </li>
      <li>
        hello hello hello hello hello
        <ol>
          <li>two.one</li>
          <li>two.two</li>
          <li>two.three long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long
            text long tex long text long tex long text long tex </li>
        </ol>
      </li>
    </ol>
  </li>
</ol>

<ol>
  <li>one</li>
  <li>two
    <ol>
      <li>two.one</li>
      <li>two.two</li>
      <li>two.three long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text
        long tex long text long tex long text long tex </li>
      <li>
        hello
        <ol>
          <li>two.one</li>
          <li>two.two</li>
          <li>two.three long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long
            text long tex long text long tex long text long tex </li>
        </ol>
      </li>
    </ol>
  </li>
</ol>

Upvotes: 0

kukkuz
kukkuz

Reputation: 42352

Used table layout for the inner ol and the cells line up nicely- guess this works for you:

li > ol > li{ 
  display: table;
}

li > ol > li:before { 
  content: counters(item, ".") ". "; 
  counter-increment: item ;
  display: table-cell;
}

snippet below:

ol {
  counter-reset: item;
  display: table;
}
li {
  display: block;
}
li:before {
  content: counters(item, ".")". ";
  counter-increment: item;
}
li > ol > li {
  display: table-row;
}
li > ol > li:before {
  content: counters(item, ".")". ";
  counter-increment: item;
  display: table-cell;
}
<ol>
  <li>one</li>
  <li>two
    <ol>
      <li>two.one</li>
      <li>two.two</li>
      <li>two.three long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text long tex long text
        long tex long text long tex long text long tex</li>
    </ol>
  </li>

</ol>

Upvotes: 3

C3roe
C3roe

Reputation: 96241

I usually solve this by giving the counter a fixed width and a negative margin-left of the same value, and then the same padding-left on the LI:

li { 
  display: block;
  padding-left: 1.75em;
}

li:before { 
  content: counters(item, ".") ". "; 
  counter-increment: item;
  display:inline-block;
  width: 1.75em;
  margin-left: -1.75em;
}

http://jsfiddle.net/1vh1tt81/2/

(If the indention of the items is too much for your taste in this fiddle now, then you might want to override the rest of default margins/padding of the OL and LI elements.)

Without a fixed width this would be harder to achieve, and probably require an additional container element for the LI content.
Taking the counter elements out of normal flow, by positioning them absolutely in regard to the LI, might be another option to achieve a similar effect.

Upvotes: 1

Related Questions