Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CSS "content" to style hierarchical nested list

I'm running into a bit of a problem using the css "content" property to create an ordered list that has been styled to display using decimals for more deeply nested items. What I'm trying to do seems like an obvious task, but I haven't succeeded yet, and I'm running into some cross browser issues, but I can't seem to find much poking around the internets... What I'm trying to do is spelled out pretty clearly in the image I've attached at the bottom of this question.

My CSS:

ol {list-style:none; font:11px arial; margin:0px 0px 0px 10px; padding:0;}

ol li:before {
        content: counter(num) ". ";
        counter-increment: num;
        counter-reset: sub_num;
}

ol ol li:before {
        content: counter(num) "." counter(sub_num)  " ";
        counter-increment: sub_num; 
        counter-reset: sub_sub_num;
}
ol ol ol li:before {
        content: counter(num) "." counter(sub_num)  "." counter(sub_sub_num) " ";
        counter-increment: sub_sub_num; 
        counter-reset:none;
}

My HTML:

<ol>
    <li>Level 1 - should be '1.'</li>
    <li>Level 1 - should be '2.'
      <ol>
        <li>Level 2 - Should be '2.1'</li>
        <li>Level 2 - Should be '2.2'
          <ol>
            <li>Level 3 - Should be '2.2.1'</li>

            <li>Level 3 - Should be '2.2.2'</li>
          </ol>
        </li>
      </ol>
    </li>
    <li>Level 1 - should be '3.'
      <ol>
        <li>Level 2 - Should be '3.1'</li>
      </ol>
    </li>
</ol>

My Outcomes

Unfortunately, the css isn't incrementing the 'num' variable

counter-increment: num;

in any browser, and Chrome isn't incrementing 'sub_sub_num'

counter-increment: sub_sub_num; 

I'm a little baffled, as it seems that all the browsers are being internally inconsistent with how they're handling the styles (why would all browsers ignore the num increment, but accept the sub_num increment?) and it's a little surprising the firefox and ie have the same behavior, whereas chrome seems to be handling it particularly badly (i'm used to ie being the odd man out).

Here's an image with the outputs of my sample for ff8, chrome16, and ie8 which shows the outputs I'm seeing, along with a user agent string:

Issues with the css content property

Am I just missing something, or is this an understood issue? Are there any good implementations out there?

like image 910
Ben D Avatar asked Jan 02 '12 19:01

Ben D


1 Answers

There is a convenient function called counters() that handles all this automatically for you — simply pass in the num variable and the period symbol as the separator. You don't have to create or increment any other variables.

You also forgot to reset num in your top-level ol element.

Here's the CSS that you need:

ol {
    list-style: none; 
    font: 11px arial; 
    margin: 0px 0px 0px 10px; 
    padding: 0;
    counter-reset: num;
}

ol li:before {
    content: counter(num) '. ';
    counter-increment: num;
}

ol ol li:before {
    content: counters(num, '.') ' ';
}

jsFiddle demo

If you'd like to understand how to use multiple counters with nested lists, this answer demonstrates something a little more complex. The idea is to reset your counters in the parent ol elements and increment them in their respective child li:before pseudo-elements; in your case, you're doing both in the li:before pseudo-elements, which isn't quite correct.

Useful reading: W3C CSS2.1 generated content spec, §12.4.1 Nested counters and scope

like image 197
BoltClock Avatar answered Nov 03 '22 00:11

BoltClock