CSS counter property

Recently I built on an online manual. It's a really long HTML document with lots of chapters and sub-chapters in a navigation. The brief was to number each item in the navigation, including nested items with automatically generated numbers. This is how I discovered the counter, counter-reset and counter-increment CSS properties.

This is how an ordered looks without any custom CSS styles:

  1. Item 1
  2. Item 2
    1. Item
    2. Item
    3. Item
  3. Item 3
    1. Item
    2. Item
    3. Item

As you can see, nested lists are labelled, but they don't inherit their parent's list value to explicitly show which sub-chapter it is in. What I want to create is this:

1. Item 1
2. Item 2
2.1 Item
2.2 Item
2.3 Item
3. Item 3
3.1 Item
3.2 Item
4. Item

CSS counters

CSS counters are variables whose values may be reset and incremented in CSS. It allows us to adjust an element's appearance based on it's placement in a page. Using CSS counters I have created an automatic custom numbering system on an ordered list. Note: it's not just <ol> and <ul>s that can be automatically numbered—it works with any element.

As this is a list, I'm going to hide the list numbers because they aren't giving me what I want.

ol, li {	
	list-style: none; 
}

Add a counter reset to the containing element, which will automatically increment by each number value by 1. The variable name can be anything at all.

ol {
    counter-reset: nav-counter;
}

If you want the counter to increment by a different value, you can add this by stating the value after the variable name like this:

ol {
    counter-reset: nav-counter, 3;
}

Next, set the counter-increment value. As mentioned, this defaults to 1 unless changed like above.

li {
    counter-increment: nav-counter;
}

Now generate the content to display the counter and include the counter variable name.

li::before {
    content: counter(nav-counter);
}

Now generate the counter content for the nested items. Notice counters this time. This will find each nested list and add counters to them—pretty clever!

li li::before {
	content: counters(nav-counter, ".") "";
}

Here's a working example on codepen:

See the Pen CSS counter property by Lottejackson (@lottejackson) on CodePen.

Tags: