Using css counters to generate ordinal values?
Asked Answered
U

3

7

I'm guessing this isn't possible, but wondering if anybody has attempted to produce ordinal numbers (1st, 2nd, 3rd etc) using CSS Counters with any success?

Obviously this would be trivial in JavaScript, but was hoping to find a style-only solution.

Ure answered 4/3, 2019 at 11:57 Comment(0)
L
7

It will be easy if you have to add th on every number. But in this case you will need to change the 1st, 2nd, 3rd, 21st, 22nd, 23rd, 31st, 32nd, etc...

So you will need to use nth child concept here. Use :nth-child to target the element.

You will also need to use :not selector to not change the 11th, 12th, 13th element

body {
  margin: 0;
  font: 13px Verdana;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: item;
}

ul li {
  margin-bottom: 5px;
  position: relative;
}

ul li:before {
  counter-increment: item;
  content: counter(item)"th. ";
  color: red;
  font-weight: bold;
}

ul li:nth-child(10n+1):not(:nth-child(11)):before {
  content: counter(item)"st. ";
}

ul li:nth-child(10n+2):not(:nth-child(12)):before {
  content: counter(item)"nd. ";
}

ul li:nth-child(10n+3):not(:nth-child(13)):before {
  content: counter(item)"rd. ";
}
<ul>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
  <li>listItem</li>
</ul>
Leighannleighland answered 4/3, 2019 at 12:10 Comment(2)
@Bhuwan, the secondary nth-child needs to be (100n+11), etc to account for 11, 111, 211, etc. Similarly needs to be applied for the other two styles. I've submitted an edit for the answer.Archdeacon
Worth noting: :nth-child-based approaches are going to fail miserably if the start property is used on the ol, or if value is used on any of the lis. Of course, I don’t believe there is any alternative that will work in that situation (though I am looking/trying!), but it would be worth mentioning the limitation. Otherwise this looks great.Lettielettish
D
1

Like this?

body {
  counter-reset: section;
}

h3::before {
  counter-increment: section;
  content: counter(section);
}

h3:nth-child(1)::before {
  content: counters(section, "") "st ";
}

h3:nth-child(2)::before {
  content: counters(section, "") "nd ";
}

h3:nth-child(3)::before {
  content: counters(section, "") "rd ";
}

h3:nth-child(n+4)::before {
  content: counters(section, "") "th ";
}
h3:nth-child(10n+1)::before {
  content: counters(section, "") "st "
}
h3:nth-child(10n+2)::before {
  content: counters(section, "") "nd "
}
h3:nth-child(10n+3)::before {
  content: counters(section, "") "rd "
}
h3:nth-child(11)::before {
  content: counters(section, "") "th "
}
h3:nth-child(12)::before {
  content: counters(section, "") "th "
}
h3:nth-child(13)::before {
  content: counters(section, "") "th "
}
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
<h3>Introduction</h3>
<h3>Body</h3>
<h3>Conclusion</h3>
Dar answered 4/3, 2019 at 12:7 Comment(1)
you can simply explain that you have used nth-child to differentiate between each case. No need to write a detailed explanation since the code is simple, but you can still avoid the like this? ;) ... you may also link to the documentation where we can read more about nth-child for exampleLeucopoiesis
I
0

As of Chrome 86 and Firefox 68 you can drop the manual margin/padding by using ::marker

ol.ordinal {
    list-style: none;

    li::marker {
        content: counter(list-item)"th";
        font-variant-numeric: ordinal;
    }

    li:nth-child(10n+1):not(:nth-child(11))::marker {
        content: counter(list-item)"st";
    }

    li:nth-child(10n+2):not(:nth-child(12))::marker {
        content: counter(list-item)"nd";
    }

    li:nth-child(10n+3):not(:nth-child(13))::marker {
        content: counter(list-item)"rd";
    }
}
Invent answered 6/1, 2023 at 21:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.