How to use CSS counters to beautify ordered lists of numbers

How to use CSS counters to beautify ordered lists of numbers

In web design, it is very important to use an organized method to display data so that users can clearly understand the data structure and content displayed on the website. Using an ordered list is a simple way to achieve an organized display of data.

If you need more in-depth control over the styling of the ordered list numbers, you might find that you have to add more html DOM structure or do it through JavaScript . Fortunately, this problem can be solved much more easily using CSS計數器.

In this tutorial, we will learn what CSS計數器are and some use cases.

The problem with ordered lists

When you write an ordered list like the following, the browser will automatically add numbers in front of the list items.

<ol>
  <li>My First Item</li>
  <li>My Second Item</li>
  <li>My Third Item</li>
</ol> 

This looks fine, but it doesn't allow you to style the numbers. Suppose, you need to modify the list by putting the numbers in front of it in a circle, what would you do?

One way is to remove the list entirely, and manually add the numbers yourself.

<div>
  <span>1</span> My First Item
</div>
<div>
  <span>2</span> My Second Item
</div>
<div>
  <span>3</span> My Third Item
</div>
div {
  margin-bottom:10px;
}
div span {
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:25px;
  height:25px;
  border-radius:50%;
  background-color:#000;
  color:#fff;
} 

This is exactly what we want to achieve, but it also has some drawbacks. First, adding numbers manually is cumbersome. If you need to change a number, you have to change them one by one. In this case, you can use JavaScript to dynamically add <span> tags to solve these problems, but this will add more nodes to DOM , resulting in a large amount of memory usage.

In most cases, it is better to use CSS counters. Let’s look at why.

Introduction to CSS Counters

CSS計數器are page-scope variables whose values ​​can be changed using CSS rules.

First, set the counter using the counter-reset property. list-number is the variable name used here.

div.list {
  counter-reset: list-number;
}

Next, use counter-increment property to increase the value of the counter.

div.list div {
  counter-increment: list-number;
}

Now, every time a div.listdiv element appears, list-number variable will increase by one.

Finally, we use the :before pseudo-element with a set content property and counter() function to display the number.

div.list div:before {
  content: counter(list-number);
}

Here is the full code:

<div class="list">
  <div>My first item</div>
  <div>My second item</div>
  <div>My third item</div>
</div>
div.list {
  counter-reset: list-number;
}
/** You can use counter-increment in :before elements **/
div.list div:before {
  counter-increment: list-number;
  content: counter(list-number);
}

Now we are not quite there yet. Let's style the :before pseudo-element to make it look better.

div.list div:before {
  counter-increment: list-number;
  content: counter(list-number);
  
  margin-right: 10px;
  margin-bottom:10px;
  width:35px;
  height:35px;
  display:inline-flex;
  align-items:center;
  justify-content: center;
  font-size:16px;
  background-color:#d7385e;
  border-radius:50%;
  color:#fff;
}

Modify the starting number

By default, counter-reset sets the counter to 0. When the first counter-increment is called it starts at 1. You can set the initial value by passing an integer as the second argument to counter-reset function.

div.list {
  counter-reset: list-number 1;
} 

If you want to start from 0 , you can set the initial value to -1 .

div.list {
  counter-reset: list-number -1;
} 

Change the increment value

By default, counter-increment increases the value of the counter by one. Just like counter-reset , you can define an offset value for counter-increment property.

In this example, counter-reset sets list-number to 0 . Each time counter-increment is called, list-number number increases by 2 , so you will see the list numbers 2 , 4 , and 6 .

div.list {
  counter-reset: list-number;
}
div.list div:before {
  counter-increment: list-number 2;
  // other styles
} 

Counter format

counter() function can take two parameters: counter-name and counter-format . For the second argument, you can use any valid list type value, including:

  • decimal (eg, 1, 2, 3…)
  • lower-latin (eg, a, b, c…)
  • lower-roman (eg, i, ii, iii…)

The default value is a number.

For example, if you're scientific like me, you could use lower-greek letters for the numbered values.

div.list div:before {
  counter-increment: list-number;
  content: counter(list-number, lower-greek);
  // ... other styles
} 

Nested counters

When using nested order lists, numbers are always displayed in this format:

If you need numeric numbers for sublist items (for example, 1.1), you can use CSS計數器with counters() function.

<ol>
  <li>
     My First Item
    <ol>
      <li>My Nested First Item</li>
      <li>My Nested Second Item</li>
    </ol>
  </li>
  <li>My Second Item</li>
</ol>
ol {
  list-style-type:none;
  counter-reset:list;
}
ol li:before {
    counter-increment:list;
    content: counters(list, ".") ". ";
}

Note that we are using the counters() function instead of counter() function.

The second parameter of counters() function is the connection string. It can also have a third argument to set the format (for example, Greek or Roman numerals).

Nested counter with title

Elements like <h1> , <h2> are not nested in the document. They appear as different elements but still represent a hierarchy. Here's how to set nested numbers into your title:

body {
  counter-reset:h1;
}
h1 {
  counter-reset:h2;
}
h1:before {
  counter-increment: h1;
  content: counter(h1) ". ";
}
h2:before {
  counter-increment:h2;
  content: counter(h1) "." counter(h2) ". ";
}

Each time <h1> is found, the <h2> counter is reset. <h2> is given a number in the document relative to <h1> .

Browser support

Thankfully, CSS counters have gained widespread browser support since their introduction with CSS2 . Although using the counter() function with properties other than content is still experimental, you can execute all the examples covered in this tutorial without hesitation.

A simple challenge

Are you ready for a simple challenge involving CSS counters?

Use CSS計數器to display 1 to 1000 with their Roman characters in just 10 lines of code.

If you’re stumped, here’s how you can do it:

To create 1000 div elements you could use the following.

for (var i = 0; i < 1000; i++) {
  document.body.appendChild( document.createElement("div") );  
}

CSS Counters:

body {
  counter-reset:number;
}
div:before {
  counter-increment:number;
  content: counter(number) " => " counter(number, lower-roman);
}

in conclusion

CSS counters are a little-known feature in CSS, but you'd be surprised how often they come in handy. In this tutorial, we discussed how and when to use CSS counters and showed some examples.

Following is the list of properties we use.

property usage
counter-reset Reset (or create) a given value counter (default 0)
counter-increment Increment the given counter by the given offset (default 1)
counter(counter-name, counter-format) Get the value of the counter in the given format
counters(counter-name, counter-string, counter-format) Get the value of a nested counter in a given format

CSS counters are cool though. But one thing to understand is that all counters are global. If you are working in a large project with many CSS files, you may not be able to find where they are created, reset and incremented. Don't overuse them, and be sure to use descriptive names for counters to avoid conflicts.

Some practical examples

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Counter</title>
  <style>
    html {
      box-sizing: border-box;
      font-size: 62.5%;
    }

    *,
    *::before,
    *:after {
      box-sizing: inherit;
    }

    body {
      font-family: Rambla, sans-serif;
      font-size: 2rem;
      line-height: 1.5;
      color: #03c03c;
    }

    h1 {
      text-align: center;
    }

    .wrapper {
      margin: 0 auto;
      width: 85%;
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-justify-content: space-around;
      -ms-flex-pack: distribute;
      justify-content: space-around;
    }

    @media (max-width: 1100px) {
      .wrapper {
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
        -webkit-flex-direction: column;
        -ms-flex-direction: column;
        flex-direction: column;
        -webkit-box-align: center;
        -webkit-align-items: center;
        -ms-flex-align: center;
        align-items: center;
      }
    }

    ol {
      counter-reset: li;
      margin: 20px 0;
      padding-left: 0;
    }

    ol>li {
      position: relative;
      margin: 0 0 25px 2em;
      padding: 4px 8px 4px 20px;
      list-style: none;
    }

    ol>li::before {
      content: counter(li);
      counter-increment: li;
      position: absolute;
      top: -2px;
      left: -2em;
      width: 2em;
      margin-right: 8px;
      padding: 4px;
      font-weight: bold;
      text-align: center;
    }

    li ol,
    li ul {
      margin-top: 6px;
    }

    ol ol li:last-child {
      margin-bottom: 0;
    }

    .disc>li::before {
      color: white;
      background-color: #03c03c;
      border-radius: 50%;
    }

    .circle>li::before {
      color: #03c03c;
      border: solid 2px #03c03c;
      border-radius: 50%;
    }

    .angle>li::before {
      color: #03c03c;
      border-right: solid 3px #03c03c;
      border-bottom: solid 3px #03c03c;
    }

    .shadow>li::before {
      color: white;
      background: #03c03c;
      box-shadow: 5px 5px 0 0 greenyellow;
    }

    .rombo>li {
      margin-bottom: 25px;
    }

    .rombo>li::before {
      color: white;
      z-index: 2;
    }

    .rombo>li::after {
      position: absolute;
      top: -2px;
      left: -2em;
      width: 2em;
      margin-right: 8px;
      padding: 4px;
      background-color: #03c03c;
      height: 2em;
      -webkit-transform: rotate(45deg);
      -ms-transform:rotate(45deg);
      transform: rotate(45deg);
      content: '';
      z-index: 1;
    }

    .underline>li::before {
      border-bottom: solid 3px #03c03c;
    }
  </style>
</head>

<body>
  <h1>Styling Ordered List Numbers</h1>
  <div class="wrapper">
    <ol class="disc">
      <li>Tomato</li>
      Cucumber
      <li>Onion</li>
      <li>Pepper</li>
    </ol>
    <ol class="circle">
      <li>Tomato</li>
      Cucumber
      <li>Onion</li>
      <li>Pepper</li>
    </ol>
    <ol class="angle">
      <li>Tomato</li>
      Cucumber
      <li>Onion</li>
      <li>Pepper</li>
    </ol>
    <ol class="shadow">
      <li>Tomato</li>
      Cucumber
      <li>Onion</li>
      <li>Pepper</li>
    </ol>
    <ol class="rombo">
      <li>Tomato</li>
      Cucumber
      <li>Onion</li>
      <li>Pepper</li>
    </ol>
    <ol class="underline">
      <li>Tomato</li>
      Cucumber
      <li>Onion</li>
      <li>Pepper</li>
    </ol>
  </div>
  More examples
</body>
</html>

More excellent cases

https://css-tricks.com/custom-list-number-styling/

This concludes this article on how to use CSS counters to beautify ordered lists of numbers. For more information about CSS counters of ordered lists of numbers, please search previous articles on 123WORDPRESS.COM or continue browsing the related articles below. I hope you will support 123WORDPRESS.COM in the future!

This concludes this article on how to use CSS counters to beautify ordered lists of numbers. For more information about CSS counters of ordered lists of numbers, please search previous articles on 123WORDPRESS.COM or continue browsing the related articles below. I hope you will support 123WORDPRESS.COM in the future!

<<:  SQL optimization often makes mistakes, that's because you don't understand the usage of MySQL explain plan

>>:  Introduction to common commands and shortcut keys in Linux

Recommend

How to stop CSS animation midway and maintain the posture

Preface I once encountered a difficult problem. I...

JavaScript implements changing the color of a web page through a slider

Hello everyone, today when I was looking at the H...

How to install vncserver in Ubuntu 20.04

Ubuntu 20.04 has been officially released in Apri...

Graphic tutorial on configuring log server in Linux

Preface This article mainly introduces the releva...

Native JS implementation of loading progress bar

This article shares a dynamic loading progress ba...

Ubuntu20.04 VNC installation and configuration implementation

VNC is a remote desktop protocol. Follow the inst...

Vue achieves seamless carousel effect

This article shares the specific code of Vue to a...

...

How to deploy MySQL and Redis services using Docker

Table of contents How to deploy MySQL service usi...

In-depth understanding of the matching logic of Server and Location in Nginx

Server matching logic When Nginx decides which se...

Summary of the characteristics of SQL mode in MySQL

Preface The SQL mode affects the SQL syntax that ...

Detailed explanation of mysql trigger example

Table of contents What is a trigger Create a trig...