counters() CSS function

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

The counters() CSS function enables combining markers when nesting counters. The function returns a string that concatenates the current values of the named and nested counters, if any are present, with the string provided. The third, optional parameter enables defining the list style.

The counters() function is generally used within pseudo-element through the content property, but theoretically, it can be used wherever a <string> value is supported.

The counters() function has two forms: counters(<name>, <string>) and counters(<name>, <string>, <style>). The generated text is the value of all counters with the given <name>, arranged from the outermost to the innermost, and separated by the specified <string>. The counters are rendered in the <style> indicated, defaulting to decimal if no <style> is specified.

Try it

ol {
  counter-reset: index;
  list-style-type: none;
}

li::before {
  counter-increment: index;
  content: counters(index, ".", decimal) " ";
}
<ol>
  <li>Mars</li>
  <li>
    Saturn
    <ol>
      <li>Mimas</li>
      <li>Enceladus</li>
      <li>
        <ol>
          <li>Voyager</li>
          <li>Cassini</li>
        </ol>
      </li>
      <li>Tethys</li>
    </ol>
  </li>
  <li>
    Uranus
    <ol>
      <li>Titania</li>
    </ol>
  </li>
</ol>

Syntax

css
/* Basic usage  - style defaults to decimal */
counters(counter-name, '.');

/* changing the counter display */
counters(counter-name, '-', upper-roman)

A counter has no visible effect by itself. The counters() function (and counter() function) is what makes it useful by returning developer-defined content.

Values

The counters() function accepts two or three parameters. The first parameter is the <counter-name>. The second parameter is the concatenator <string>. The optional third parameter is the <counter-style>.

<counter-name>

A <custom-ident> identifying the counters, which is the same case-sensitive name used for the counter-reset and counter-increment properties. The name cannot start with two dashes and can't be none, unset, initial, or inherit. Alternatively, for inline, single-use counters, the symbols() function can be used instead of a named counter in browsers that support symbols().

<string>

Any number of text characters. Non-Latin characters must be encoded using their Unicode escape sequences: for example, \000A9 represents the copyright symbol.

<counter-style>

A counter style name or a symbols() function. The counter style name can be a predefined style such as numeric, alphabetic, or symbolic, a complex longhand predefined style such as East Asian or Ethiopic, or another predefined counter style. If omitted, the counter-style defaults to decimal.

The return value is a string containing all the values of all the counters in the element's CSS counters set named <counter-name> in the counter style defined by <counter-style> (or decimal, if omitted). The return string is sorted in outermost-first to innermost-last order, joined by the <string> specified.

Note: For information about non-concatenated counters, see the counter() function, which omits the <string> as a parameter.

Formal syntax

<counters()> = 
counters( <counter-name> , <string> , <counter-style>? )

<counter-name> =
<custom-ident>

<counter-style> =
<counter-style-name> |
<symbols()>

<counter-style-name> =
<custom-ident>

<symbols()> =
symbols( <symbols-type>? [ <string> | <image> ]+ )

<symbols-type> =
cyclic |
numeric |
alphabetic |
symbolic |
fixed

<image> =
<url> |
<image()> |
<image-set()> |
<cross-fade()> |
<element()> |
<gradient>

<image()> =
image( <image-tags>? [ <image-src>? , <color>? ]! )

<image-set()> =
image-set( <image-set-option># )

<cross-fade()> =
cross-fade( <cf-image># )

<element()> =
element( <id-selector> )

<image-tags> =
ltr |
rtl

<image-src> =
<url> |
<string>

<image-set-option> =
[ <image> | <string> ] [ <resolution> || type( <string> ) ]?

<cf-image> =
[ <image> | <color> ] &&
<percentage [0,100]>?

<id-selector> =
<hash-token>

Examples

Comparing default counter value to uppercase roman numerals

This example includes two counters() functions: one with <counter-style> set and the other defaulting to decimal.

HTML

html
<ol>
  <li>
    <ol>
      <li></li>
      <li></li>
      <li></li>
    </ol>
  </li>
  <li></li>
  <li></li>
  <li>
    <ol>
      <li></li>
      <li>
        <ol>
          <li></li>
          <li></li>
          <li></li>
        </ol>
      </li>
    </ol>
  </li>
</ol>

CSS

css
ol {
  counter-reset: listCounter;
}
li {
  counter-increment: listCounter;
}
li::marker {
  content:
    counters(listCounter, ".", upper-roman) ") ";
}
li::before {
  content:
    counters(listCounter, ".") " == "
    counters(listCounter, ".", lower-roman);
}

Result

Comparing decimal-leading-zero counter value to lowercase letters

This example includes three counters() functions, each with different <string> and <counter-style> values.

HTML

html
<ol>
  <li>
    <ol>
      <li></li>
      <li></li>
      <li></li>
    </ol>
  </li>
  <li></li>
  <li></li>
  <li>
    <ol>
      <li></li>
      <li>
        <ol>
          <li></li>
          <li></li>
          <li></li>
        </ol>
      </li>
    </ol>
  </li>
</ol>

CSS

css
ol {
  counter-reset: count;
}
li {
  counter-increment: count;
}
li::marker {
  content:
    counters(count, "-", decimal-leading-zero) ") ";
}
li::before {
  content:
    counters(count, "~", upper-alpha) " == "
    counters(count,  "*", lower-alpha);
}

Result

Specifications

Specification
CSS Lists and Counters Module Level 3
# counter-functions
CSS Counter Styles Level 3
# extending-css2

Browser compatibility

desktop mobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
counters()
Chrome – Full support
Chrome 1 (Release date: 2008-12-11)
footnote Full support
Edge – Full support
Edge 12 (Release date: 2015-07-29)
footnote Full support
Firefox – Full support
Firefox 1.5 (Release date: 2005-11-29)
footnote Full support
Opera – Full support
Opera 10 (Release date: 2009-09-01)
footnote Full support
Safari – Full support
Safari 3 (Release date: 2007-10-26)
footnote Full support
Chrome Android – Full support
Chrome Android 18 (Release date: 2012-06-27)
footnote Full support
Firefox for Android – Full support
Firefox for Android 4 (Release date: 2011-03-29)
footnote Full support
Opera Android – Full support
Opera Android 10.1 (Release date: 2010-11-09)
footnote Full support
Safari on iOS – Full support
Safari on iOS 1 (Release date: 2007-06-29)
footnote Full support
Samsung Internet – Full support
Samsung Internet 1 (Release date: 2013-04-27)
footnote Full support
WebView Android – Full support
WebView Android 4.4 (Release date: 2013-12-09)
footnote Full support
WebView on iOS – Full support
WebView on iOS 1 (Release date: 2007-06-29)
footnote Full support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

See also