Search code examples
csspseudo-elementcss-content

CSS Pseudo Element Counters: can you increment an alphabet letter "a", "b", "c", etc instead of a number?


As defined here:

http://www.w3.org/TR/CSS21/generate.html#propdef-counter-increment

You can use code like the following to increment numbers in pseudo elements.

H1:before {
    content: "Chapter " counter(chapter) ". ";
    counter-increment: chapter;  /* Add 1 to chapter */
}
H1 {
    counter-reset: section;      /* Set section to 0 */
}
H2:before {
    content: counter(chapter) "." counter(section) " ";
    counter-increment: section;
}

Is there a way you can use the same code to increment letters like "a", "b", "c", etc?

Thank you!


Solution

  • Yes, the second argument to counter() defines the type of counter used, as for the list-style-type from a regular ul or ol; for example:

    content: counter(chapter, lower-alpha);
    

    ul {
      counter-reset: listStyle;
    }
    ul li {
      margin-left: 1em;
      counter-increment: listStyle;
    }
    ul li::before {
      margin-right: 1em;
      content: counter(listStyle, lower-alpha);
    }
    <ul>
      <li>one</li>
      <li>two</li>
      <li>three</li>
    </ul>

    JS Fiddle demo.

    Others include: decimal, decimal-leading-zero, lower-roman, upper-roman, lower-greek, lower-latin, upper-latin, armenian, georgian, lower-alpha, upper-alpha.

    As there seems to have been something of an update to the above list of styles, I chose to add a code snippet which allows the user to choose from the (currently-) available options, along with an 'output' area, to show how to use that style with CSS generated-content:

    let select = document.querySelector('select'),
      output = document.querySelector('#currentCounter'),
      changeEvent = new Event('change');
    
    select.addEventListener('change', function() {
      document.body.style.setProperty('--listStyleType', this.value);
      output.textContent = this.value;
    });
    
    select.dispatchEvent(changeEvent);
    body {
      --listStyleType: decimal;
    }
    
    ul {
      counter-reset: listStyle;
      columns: 2;
      margin-top: 0.5em;
      list-style-type: none;
    }
    
    ul li {
      counter-increment: listStyle;
    }
    
    ul li::before {
      content: counter(listStyle, var(--listStyleType));
      display: inline-block;
      margin-right: 0.5em;
      width: 1.5em;
      height: 1.5em;
      line-height: 2em;
      text-align: center;
    }
    
    code {
      display: block;
      white-space: pre-wrap;
      width: 80%;
      box-sizing: border-box;
      margin: 1em auto;
      padding: 0.5em;
      box-shadow: 0 0 0 3px limegreen;
    }
    
    code::after {
      content: '\A';
    }
    
    #currentCounter {
      color: #f90;
    }
    <label for="counterChoice">Please select a CSS counter:</label>
    <select id="counterChoice">
      <option value="arabic-indic">arabic-indic</option>
      <option value="armenian">armenian</option>
      <option value="bengali">bengali</option>
      <option value="cambodian">cambodian</option>
      <option value="circle">circle</option>
      <option value="cjk-decimal">cjk-decimal</option>
      <option value="cjk-earthly-branch">cjk-earthly-branch</option>
      <option value="cjk-heavenly-stem">cjk-heavenly-stem</option>
      <option value="decimal">decimal</option>
      <option value="decimal-leading-zero">decimal-leading-zero</option>
      <option value="devanagari">devanagari</option>
      <option value="disc">disc</option>
      <option value="disclosure-closed">disclosure-closed</option>
      <option value="disclosure-open">disclosure-open</option>
      <option value="ethiopic-numeric">ethiopic-numeric</option>
      <option value="georgian">georgian</option>
      <option value="gujarati">gujarati</option>
      <option value="gurmukhi">gurmukhi</option>
      <option value="hebrew">hebrew</option>
      <option value="hiragana">hiragana</option>
      <option value="hiragana-iroha">hiragana-iroha</option>
      <option value="japanese-formal">japanese-formal</option>
      <option value="japanese-informal">japanese-informal</option>
      <option value="kannada">kannada</option>
      <option value="katakana">katakana</option>
      <option value="katakana-iroha">katakana-iroha</option>
      <option value="khmer">khmer</option>
      <option value="korean-hangul-formal">korean-hangul-formal</option>
      <option value="korean-hanja-formal">korean-hanja-formal</option>
      <option value="korean-hanja-informal">korean-hanja-informal</option>
      <option value="lao">lao</option>
      <option value="lower-alpha">lower-alpha</option>
      <option value="lower-alpha">lower-alpha</option>
      <option value="lower-armenian">lower-armenian</option>
      <option value="lower-greek">lower-greek</option>
      <option value="lower-latin">lower-latin</option>
      <option value="lower-roman">lower-roman</option>
      <option value="malayalam">malayalam</option>
      <option value="mongolian">mongolian</option>
      <option value="myanmar">myanmar</option>
      <option value="oriya">oriya</option>
      <option value="persian">persian</option>
      <option value="simp-chinese-formal">simp-chinese-formal</option>
      <option value="simp-chinese-informal">simp-chinese-informal</option>
      <option value="square">square</option>
      <option value="tamil">tamil</option>
      <option value="telugu">telugu</option>
      <option value="thai">thai</option>
      <option value="tibetan">tibetan</option>
      <option value="trad-chinese-formal">trad-chinese-formal</option>
      <option value="trad-chinese-informal">trad-chinese-informal</option>
      <option value="upper-alpha">upper-alpha</option>
      <option value="upper-armenian">upper-armenian</option>
      <option value="upper-latin">upper-latin</option>
      <option value="upper-roman">upper-roman</option>
    </select>
    <ul>
      <li>one</li>
      <li>two</li>
      <li>three</li>
      <li>four</li>
      <li>five</li>
      <li>six</li>
      <li>seven</li>
      <li>eight</li>
      <li>nine</li>
      <li>ten</li>
    </ul>
    
    <code>
      li::before {
        content: counter(&lt;counterName&gt;, <span id="currentCounter"></span>)
      }
    </code>

    The currently-available (as of 2017-02-27):

    • arabic-indic
    • armenian
    • bengali
    • cambodian
    • circle
    • cjk-decimal
    • cjk-earthly-branch
    • cjk-heavenly-stem
    • decimal
    • decimal-leading-zero
    • devanagari
    • disc
    • disclosure-closed
    • disclosure-open
    • ethiopic-numeric
    • georgian
    • gujarati
    • gurmukhi
    • hebrew
    • hiragana
    • hiragana-iroha
    • japanese-formal
    • japanese-informal
    • kannada
    • katakana
    • katakana-iroha
    • khmer
    • korean-hangul-formal
    • korean-hanja-formal
    • korean-hanja-informal
    • lao
    • lower-alpha
    • lower-alpha
    • lower-armenian
    • lower-greek
    • lower-latin
    • lower-roman
    • malayalam
    • mongolian
    • myanmar
    • oriya
    • persian
    • simp-chinese-formal
    • simp-chinese-informal
    • square
    • tamil
    • telugu
    • thai
    • tibetan
    • trad-chinese-formal
    • trad-chinese-informal
    • upper-alpha
    • upper-armenian
    • upper-latin
    • upper-roman

    References: