Reputation: 4701
I'm trying to do something that used to be really easy before the start
attribute on ol tags was deprecated. I'd just like to have a pair of ordered lists in my page, but start the numbering of the second list where the first one finished. Something like:
1. do stuff
2. do stuff
Here's a paragraph
3. do stuff
I've seen that the counter-reset
and counter-increment
CSS properties should be able to achieve this, but I can't get it working. Here's my code so far:
<html>
<head>
<style type="text/css">
ol li { counter-increment: mycounter; }
ol.start { counter-reset: mycounter; }
ol.continue { counter-reset: mycounter 2; }
</style>
</head>
<body>
<ol class="start">
<li>You can't touch this</li>
<li>You can't touch this</li>
</ol>
<p>STOP! Hammer time.</p>
<ol class="continue">
<li>You can't touch this</li>
</ol>
</body>
</html>
To be honest, even if that worked, it wouldn't be ideal. I don't want to have to specify the number reached by the first list in my ol.continue
selector.
What am I doing wrong? What's the minimal HTML/CSS combination required to achieve the desired effect?
Upvotes: 68
Views: 69037
Reputation: 4051
I use a mix of all the answers:
body {
counter-reset: cant-touch-this-counter;
}
ol li {
counter-increment: cant-touch-this-counter;
}
ol ::marker {
content: counter(cant-touch-this-counter) ". ";
}
<ol>
<li>You can't touch this</li>
<li>You can't touch this</li>
</ol>
<p>STOP! Hammer time.</p>
<ol>
<li>You can't touch this</li>
</ol>
Upvotes: 2
Reputation: 31
Can you not just nest the paragraph inside the list item before you close it?
<ol>
<li>You can't touch this</li>
<li>You can't touch this
<p>STOP! Hammer time.</p>
</li>
<li>You can't touch this</li>
</ol>
Upvotes: 3
Reputation: 88
Instead of resetting the counter, here is a pure CSS way to achieve what you wanted:
ol {
padding: 0;
}
li {
margin-left: 24px;
}
You can then add other elements in the ordered list. These elements will not be indented because the ol padding is set to 0. The list items are still indented because of the margin-left setting of the li. The value of the margin-left of li should match with the default value of the padding of the ol.
Upvotes: 0
Reputation: 1697
A minimalistic solution I found was using ol.continued { counter-reset: none; }
. Use class="continued"
to comprehensibly indicate that some ol
is the continuation of the ol
before.
Apparently, that works because the browser does ol { counter-reset: list-item }
by default (with the language-defined list-item
counter) that makes lists reset and count anew when a new list starts. Overriding this gets us the behavior we want.
<style>
ol.continued {
counter-reset: none;
}
/* To prove a point */
ol ::marker {
color: grey;
content: "[" counters(list-item, ".") "] ";
}
</style>
<ol>
<li>First step
<ol>
<li>One sub-step
<li>Another sub-step
</ol>
<li>Second step
</ol>
<p>Some comment in between.</p>
<ol class="continued">
<li>Obvious step after the aforementioned comment
<li>Last step
<ol>
<li>A sub-step
<li>Last sub-step
</ol>
</ol>
In contrast to assigning value
or start
, it naturally allows for extending the previous list, i.e. if you add a <li>Third step
or remove <li>Second step
, counters for the continued
list will behave as expected without change. It is maintainable. It works with nested lists and you can style the ::marker
whatever you want. Also, this solution does not require boilerplate to remove ::marker
and add ::before
to replace it.
Note: As of writing this, the presented solution works on Mozilla Firefox only. (Edit: It works on Firefox 92.1.1 on Android, too.) I do not know if this is a bug in Firefox that should not be relied upon, or if this is standard conforming behavior that can reasonably be expected to be followed by and Chrome, Edge and other browsers in the future. MDN promptly suggests that it is intended, as counter-reset: none
“can be used to override a counter-reset
defined in a less specific rule”. So use it at your own discretion.
This is a screenshot of how the snippet renders on Mozilla Firefox 92.0.1:
Upvotes: 2
Reputation: 597
A much easier solution to the OP's problem is the following:
<ol start="X">
Where X is the value of the list you want to continue, so in his sample:
<ol>
<li>You can't touch this</li>
<li>You can't touch this</li>
</ol>
<p>STOP! Hammer time.</p>
<ol start="3">
<li>You can't touch this</li>
</ol>
Upvotes: 48
Reputation: 16065
A similar thing can be achieved using the li
tag's value
attribute and non-marked list elements.
https://www.w3schools.com/tags/att_li_value.asp
In this approach the insert text becomes an unmarked list item. This is not idiomatic and would make some list-specific defaults about margins and alignment and what not. However this idiomatically keeps the "sparse" list a single tag. Whether this makes the solution better or worse than actually using TWO lists and simulating single list using the ol
tag's start
attribute - is up to reader to decide.
<ol>
<li>You can't touch this
<li>You can't touch this
<li style="list-style: none"><b>STOP!</b> Hammer time.
<li value="3">You can't touch this
<li>This neither
</ol>
You can also add vertical outlines using <br/>
or <p>
or CSS, same for any other added visual cues.
Example with CSS:
<ol>
<li>You can't touch this
<li>You can't touch this
<li style="list-style: none; margin-top:10px; margin-bottom: 10px"><b>STOP!</b> Hammer time.
<li value="3">You can't touch this
<li>This neither
</ol>
Example with HTML tags:
<ol>
<li>You can't touch this
<li>You can't touch this
<li style="list-style: none"><hr/><b>STOP!</b> Hammer time.<hr/>
<li value="3">You can't touch this
<li>This neither
</ol>
Upvotes: 1
Reputation: 369
Today you can use the native start
attribute - check it here
https://www.w3schools.com/tags/att_ol_start.asp
<ol class="start" start="1">
<li>You can't touch this</li>
<li>You can't touch this</li>
</ol>
<p>STOP! Hammer time.</p>
<ol class="continue" start="3">
<li>You can't touch this</li>
</ol>
Upvotes: 0
Reputation: 482
There is another approach that I've stumbled across when trying to answer my own question (Remove indent for element within an ordered list <ol>).
I should note that the discussion here helped me answer my question there, although they are different questions they have similar answers; so, thank you to those contributing to the discussion on this thread for your help.
My solution, instead of attributing classes to the list parts of the HTML, attributes a class to the element which is breaking the <ol>
elements in two. I used the class name mid-ol
. The combination of ol + .mid-ol + ol
can then be used in the CSS.
To me this was more satisfactory than changing the character of the <ol>
elements, as the list may exist and persist despite the breaking element. For example, the breaking element might be moved, removed, etc., but there's then little maintenance required for the <ol>
.
To not duplicate discussion in two places, I'll let anyone interested peruse the discussion and example code on the other thread.
Upvotes: 0
Reputation: 1662
The start attribute is valid in html5. I would just use that.
http://w3c.github.io/html/grouping-content.html#the-ol-element
Also http://dev.w3.org/html5/spec/Overview.html#the-ol-element States that it is still supported in all browsers. You would have to test to be sure I guess.
some jquery to set the start attribute dynamically if you are into that sort of thing..
// assuming all your ol's have the class mylist
$(function(){
var counter=1;
$('ol.mylist').each(function(){
$this = $(this);
$this.attr('start',counter);
counter += $(this).find('li').length;
});
});
Upvotes: 8
Reputation: 335
Here is an different version of the answer that the OP devised. It makes the text line up if you have more than 9 list items. The pattern could be extended to more than 99 items, more than 999 items, etc.
ol.split { list-style-type: none; }
ol.split li.less-than-ten:before {
counter-increment: mycounter;
content: counter(mycounter) ".\00A0\00A0\00A0\00A0";
}
ol.split li.ten-or-greater:before {
counter-increment: mycounter;
content: counter(mycounter) ".\00A0\00A0";
}
ol.split li {
display: list-item;
text-indent: -2em;
}
ol.start { counter-reset: mycounter; }
To use this put the classes "start" and "split" on the first ol. Put the class "split" on subsequent ol's that you want to include in the continuous numbering. On the 1st through the 9th li tags, put the class "less-than-ten". On the 10th through 99th li tags, put the class "ten-or-greater". If you want to apply the pattern to the 100th through 999th li tags, you will have to create something like this:
ol.split li.more-than-99:before {
counter-increment: mycounter;
content: counter(mycounter) ".\00A0\00A0\00A0\00A0\00A0\00A0";
}
I believe the 6 "\00A0" tags will be enough. You may have to fiddle with the number of "\00A0" tags and the text-indent number to make all the text line up.
Upvotes: 0
Reputation: 11318
The Opera DevNet has a nice example for exactly this use-case available here: http://devfiles.myopera.com/articles/501/counters-start-example.html (which is part of their article about counters)
So your code should look somehow like this:
<html>
<head>
<style type="text/css">
ol li { counter-increment: mycounter; }
ol.start { counter-reset: mycounter; }
ol.continue { /*counter-reset: mycounter 2; */}
ol li {
counter-increment: mycounter;
list-style-type: none;
}
ol li:before { content: counter(mycounter) ". "; }
</style>
</head>
<body>
<ol class="start">
<li>You can't touch this</li>
<li>You can't touch this</li>
</ol>
<p>STOP! Hammer time.</p>
<ol class="continue">
<li>You can't touch this</li>
</ol>
</body>
</html>
But, as Lee mentioned, ol@start seems no longer again deprecated, I'd personally prefer that approach since this is not only a styling but also an issue of semantics in your markup.
Upvotes: 2
Reputation: 816910
As already said, you need :before
and content
, but you also need to disable the default list numbering. This is your fixed CSS:
ol.start {
counter-reset: mycounter;
}
ol.start li, ol.continue li {
list-style: none;
}
ol.start li:before, ol.continue li:before {
content: counter(mycounter) ". ";
counter-increment: mycounter;
}
You don't need to reset the counter for ol.continue
, just continue to use your custom counter. The above code makes sure that the counter is only used for the ol.start
and ol.continue
lists.
Upvotes: 29
Reputation: 12243
you also need to use a :before rule with a content tag that references the counter:
see here: http://www.w3schools.com/css/pr_gen_counter-reset.asp
Upvotes: -1