How can I reset a CSS-counter to the start-attribute of the given list
Asked Answered
M

10

29

I am using a self-styled, numbered list. How can I read the start-attribute and add it to the counter with CSS?

ol {
  list-style-type: none;
  /* this does not work like I expected */
  counter-reset: lis attr(start, number, 0);
}

li {
  counter-increment: lis
}

li:before {
  content: counter(lis)". ";
  color: red;
}
<ol>
  <li>Number One</li>
  <li>Number Two</li>
  <li>Number Three</li>
</ol>
<ol start="10">
  <li>Number Ten</li>
  <li>Number Eleven</li>
  <li>Number Twelve</li>
</ol>
Midyear answered 16/5, 2014 at 15:27 Comment(5)
What result do you want? att it to the counter? You want something like this w3schools.com/cssref/… ?Endeavor
The counter should match the text numbers =)Archean
in that specific case ol[start="10"] { counter-increment: lis 9; } will work, but I would like to have a generic way.Archean
the generic way will be through javascript to retrieve start value and then reuse it to generate CSS rules. CSS cannot do this , it can only print at screen attribute value via content:attr(myattribute).Cholecalciferol
@AamirAfridi I'm afraid that the demo you linked no longer exists. Sadly, the page wasn't archived with Wayback Machine, I'm not aware of other archiving sites.Barfield
C
19

You may just use the attribute start as a filter :

ol[start="10"] {
   counter-reset: lis 9;
}

Demo , but this will only apply for this ol attribute. You would need some javaScript in order to retrieve attribute value to apply, generate the correct counter-reset.


<ins data-extra="Use of Scss">

see this : DEMO to generate 100 rules from these lines :

@for $i from 1 through 100 {
  .ol[start="#{$i}"] {
    counter-reset: lis $i ;
  }
}

Then just copy paste the rules generated if Scss is not avalaible on your hosting .

</in>


<ins data-extra="jQueryFix">:

A jQuery solution can be easily set up :

$( "ol" ).each(function() {
  var   val=1;
    if ( $(this).attr("start")){
  val =  $(this).attr("start");
    }
  val=val-1;
 val= 'lis '+ val;
$(this ).css('counter-increment',val );
});

Notice that : $(this ).css('counter-reset',val ); works too :)

.</ins>

Cholecalciferol answered 16/5, 2014 at 15:53 Comment(9)
@Midyear okay , i see it now. As i advise you, you need javascript to retrieve start value. CSS cannot do reuse it like you tried (it is a shame, if attributes value could be reuse this way, there will be lots of easier way to manage things :) )Cholecalciferol
...and there must be already an internal function for the default behaviour. Too bad =/Archean
@Midyear Yep, really too bad . A jQuey would do ? codepen.io/gc-nomade/pen/mCJsdCholecalciferol
I need a CSS only solution =/. Due this is not possible at the moment I will generate all possibilities in a seperated stylesheet. I noticed that 100x will waste only ~2KB zipped. But thanks for your idea - think it will help other people.Archean
@Midyear then for the CSS thing, use a preprocessor to generate the css, so no need to edit dozens of similar rules . see codepen.io/gc-nomade/pen/cEafh , click on the eye to see 100 rules generated via ScssCholecalciferol
happily my IDE can do this for me =)Archean
Dear god, generating 100 CSS rules is the most upvoted answer. Please don't do that.Upswell
@Zopieux what about tons of javscript library and plugins loaded just for a few features ... crazy world in'it ! :)Cholecalciferol
The demos now 404.Sungsungari
C
14

I see that this is an old question, but I'm putting this here because it may come to help someone yet.

You cannot read an attribute in css counter properties. Instead, you could use inline css with counter-reset to define the starting number for a particular list.
(Yes, I know it is not a best practice to use inline css, but it can and should be used for edge cases like this one)

The first item increments the reset value by 1, so besides providing the counter name, you will need to subtract the number you want the list to start at by 1:

HTML

<ol>
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>

<!-- NOTE: List numbering starts at counter-reset + 1 -->
<ol style="counter-reset: lis 9;" start="10">
    <li>Number Ten</li>
    <li>Number Eleven</li>
    <li>Number Twelve</li>
</ol>

CSS

ol {
    list-style-type: none;
    counter-reset: lis; /* Resets counter to zero unless overridden */
}
li {
    counter-increment: lis
}
li:before {
    content: counter(lis)". ";
    color: red;
}

FIDDLE (http://jsfiddle.net/hcWpp/308/)

[EDIT]: kept start attribute as suggested to address accessibility and progressive enhancement

Cuthburt answered 31/10, 2018 at 15:51 Comment(2)
I would still drop in the "start" attribute value for progressive enhancement or if a user prints the page. <ol start="10" style="counter-reset: lis 9;"> This inline style works better than any attribute or even any CSS variable approach.Swami
You need the start attribute for accessibility so that screen reader users get the correct number.Visayan
V
6

Just providing a streamlined version of GCyrillus JS solution

$('ol[start]').each(function() {
    var val = parseFloat($(this).attr("start")) - 1;
    $(this).css('counter-increment','lis '+ val);
});

I wish CSS could read and use numeric values from HTML attributes :(

Visayan answered 6/10, 2015 at 5:59 Comment(0)
P
5

ol {
    list-style-type: none;

    counter-reset: lis var(--start-value, 0);
}
li {
    counter-increment: lis;
}
li:before {
    content: counter(lis)". ";
    color: red;
}
<ol>
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>

<ol style="--start-value: 1;">
    <li>Number Two</li>
    <li>Number Three</li>
    <li>Number Four</li>
</ol>

You can use CSS custom properties (variables), see.

For example, use inline styles for list and add custom property --start-value: 1;. In CSS you can use it like var(--start-value, 0); with fallback value (0). If you skip this custom property, list will start by default.

HTML

<ol style="--start-value: 1;">
    <li>Number Two</li>
    <li>Number Three</li>
    <li>Number Four</li>
</ol>

CSS

ol {
    list-style-type: none;

    counter-reset: lis var(--start-value, 0);
}
li {
    counter-increment: lis;
}
li:before {
    content: counter(lis)". ";
    color: red;
}
Planogamete answered 9/8, 2021 at 12:24 Comment(1)
This is the answer to my problem/question: #69219023Maris
C
2

Back on an old question i have forgotten about.

Nowdays there is the CSS custom properties that could be used , even then , it requires to add a style attribute aside your start attribute

Custom properties (sometimes referred to as CSS variables or cascading variables) are entities defined by CSS authors that contain specific values to be reused throughout a document. They are set using custom property notation (e.g., --main-color: black;) and are accessed using the var() function (e.g., color: var(--main-color);).

example (if the code is generated it seems easier to set both value the same for start=x and var(--s:x) to avoid mistake):

ol {
    list-style-type: none;
    /* this does not work like I expected
    counter-reset: lis attr(start, number, 0); */
    
    /* update using the css varaiable from html */
    counter-reset: lis calc(var(--s) - 1) ;
    /* calc() is used to keep html attributes values coherent */

}
li {
    counter-increment: lis
}
li:before {
    content: counter(lis)". ";
    color: red;
}
<ol>
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>
<ol start="10" style="--s:10"><!-- or set it right away to nine to get rid of calc() in the css rule-->
    <li>Number Ten</li>
    <li>Number Eleven</li>
    <li>Number Twelve</li>
</ol>
<ol start="30" style="--s:30"><!-- or set it right away to twenty nine to get rid of calc() in the css rule -->
    <li>Number Thirty</li>
    <li>Number Thirty one</li>
    <li>Number Thirty two</li>
</ol>

That's far to late to be an answer but could be useful to anyone else from now.

Cholecalciferol answered 25/9, 2019 at 11:48 Comment(1)
Wow, I love it! Still not the final solution, but the best generic one. With this code you don't need JS or additional style rules.Archean
M
1

Simply add:

ol:not(:nth-of-type(1)){
    counter-increment: lis 10;
}

Demo Fiddle

You cant use attr in counter-reset unfortunately, but you can add rules to alter the increment amount.

Alternative 1

If you are going to have multiple lists, a more resilient version would be:

ol {
    list-style-type: none;
    /* this does not work like I expected */
    counter-reset: lis;

}
ol:not(:first-of-type){
     counter-increment: ol
}
li {
    counter-increment: lis
}
li:before {
    content: counter(lis)". ";
    color: red;
}
ol:not(:first-of-type) li:before {
    content: counter(ol) counter(lis)". ";
    color: red;
}

Alternative 2

If the numerical prefix can be anything, the below will provision for this:

HTML

<ol>
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>
<ol>
    <li data-prefix="1">Number Ten</li>
    <li data-prefix="1">Number Eleven</li>
    <li data-prefix="1">Number Twelve</li>
</ol>
<ol>
    <li data-prefix="a">Number Ten</li>
    <li data-prefix="b">Number Eleven</li>
    <li data-prefix="c">Number Twelve</li>
</ol>

CSS

ol {
    list-style-type: none;
    counter-reset: lis;
}
li {
    counter-increment: lis
}
li:before {
    content: attr(data-prefix) counter(lis)". ";
    color: red;
}
Mononuclear answered 16/5, 2014 at 15:36 Comment(4)
9 no? counter-increment: lis 9;Translatable
@Translatable - The start of 10 is at the ol level, then it increments at li, so the first would be 11. If the actual designated start is to be 10, then 9 is a better increment for sureMononuclear
@Midyear - Have you tried the alternatives noted above?Mononuclear
@Mononuclear nope, it just appeared now, but still I see no real solution because the offset can be anything like "17"Archean
S
1

You're trying to do a list with custom bullets using the natural numbering, correct? There's a built-in counter called list-item you can use, you don't need to define your own counter.

ol {
    list-style: none;
}
li::before {
    content: counter(list-item) '. ';
}

If you set this programatically though, Chrome and Safari currently don't apply the changes without a repaint (e.g. toggle display:none).

Secern answered 13/1, 2023 at 15:45 Comment(0)
T
0

To support <ol start="10"> even if counter-reset was enabled in Firefox:

$('ol[start]').each(function() {
    var val = parseFloat($(this).attr("start"));
    $(this).find("li").first().attr("value", val);
});

jQuery script is based on Daniel Tonon's input.

Terchie answered 6/8, 2019 at 12:6 Comment(0)
A
0

My solution is: add class no-reset. It's worked for me!

<ol>
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>
<ol start="10" class="no-reset">
    <li>Number Ten</li>
    <li>Number Eleven</li>
    <li>Number Twelve</li>
</ol>

CSS

ol {
    list-style-type: none;
    counter-reset: lis;
}    
li:before {
    content: counter(lis)". ";
    counter-increment:lis;
    color: red;
}
ol.no-reset{
  counter-reset: none;
}
Amid answered 23/7, 2021 at 9:48 Comment(0)
R
0

The above code is a life saver. Quick modification: incorporate the attribute [start] into the CSS selector using the calc so that we can discriminate between which list numbers need calculating. Otherwise you have to set a start and a style attribute for every list (following the first instance of using these attributes).

ol {
    list-style-type: none;
    
    /* update using the css variable from html */
    counter-reset: lis;
}

ol[start] {
    /* select using "start" attribute so we only mod this increment */
    counter-reset: lis calc(var(--s) - 1);
    /* calc() is used to keep html attributes values coherent */
}

li {
    counter-increment: lis
}

li:before {
    content: counter(lis)". ";
    color: red;
}
<ol>
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>

<ol start="10" style="--s:10"><!-- or set it right away to nine to get rid of calc() in the css rule-->
    <li>Number Ten</li>
    <li>Number Eleven</li>
    <li>Number Twelve</li>
</ol>

<ol><!-- numbers won't start from end of prior increment -->
    <li>Number One</li>
    <li>Number Two</li>
    <li>Number Three</li>
</ol>
Rosemare answered 23/2, 2023 at 14:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.