I use the following css to generate nested numeration in ol:
ol{
counter-reset: item;
}
ol li{
display: block;
}
ol li:before{
content: counters(item, ".")". ";
counter-increment: item;
float: left;
margin-right: 5px;
}
On some level of nesting I want to reset the nesting. How can I achieve it?
For example,
<ol>
<li>
<ol>
<li>
<ol>
<li>
<ol class="reset">
<li>
<ol>
<li></li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
Gives the following:
1.
1.1
1.1.1
1.1.1.1
1.1.1.1.1
But I want such structure
1.
1.1
1.1.1
1 # reset here
1.1
Related
Current result:
1. Item
1.1 Subitem
1.2 Subitem2
1.2.1 something more
1.2.2 another point
Desired result:
1. Item
1.1 Subitem
1.2 Subitem2
a. something more
b. another point
How do I modify my code to get the third level as letters instead of 3 numbers. I added the type="a" to the correct <ol> element in the HTML but it got overwritten.
ol {
list-style-type: none;
counter-reset: item;
margin: 0;
padding: 0;
}
ol>li {
display: table;
counter-increment: item;
margin-bottom: 0.6em;
}
ol>li:before {
content: counters(item, ".");
display: table-cell;
padding-right: 0.6em;
}
li ol>li {
margin: 0;
}
<ol>
<li>
<b>
Our rights if you breach this policy
</b>
<ol>
<li>
We will decide whether there has been a breach of this policy by you.
</li>
<li>
If we decide that you are in breach of any part of this policy, we may:
<ol type="a">
<li>
issue a warning to you;
</li>
<li>
immediately stop your right to use our Service;
</li>
<li>
take legal action against you to recover any of our losses caused by your breach; or
</li>
<li>
notify law enforcement authorities if we decide that you have broken any law; or
</li>
<li>
take any other action that we think is appropriate.
</li>
</ol>
</li>
</ol>
</li>
</ol>
You can use list-style-type: lower-alpha; and cancel out your counters with the :not() pseudo class:
At the end of your stylesheet create a rule that targets your type="a" and assigns the list style type you want (lower-alpha).
Your counters will override this declaration so an easy solution is to only apply them to <ol> elements that are :not([type="a"]) (Not one of your alpha lists).
Hopefully this works for you:
ol {
list-style-type: none;
counter-reset: item;
margin: 0;
padding: 0;
}
ol:not([type="a"]) > li {
display: table;
counter-increment: item;
margin-bottom: 0.6em;
}
ol:not([type="a"]) > li::before {
content: counters(item, ".");
display: table-cell;
padding-right: 0.6em;
}
ol[type="a"] {
list-style-type: lower-alpha;
}
<ol>
<li>
<b>
Our rights if you breach this policy
</b>
<ol>
<li>
We will decide whether there has been a breach of this policy by you.
</li>
<li>
If we decide that you are in breach of any part of this policy, we may:
<ol type="a">
<li>
issue a warning to you;
</li>
<li>
immediately stop your right to use our Service;
</li>
<li>
take legal action against you to recover any of our losses caused by your breach; or
</li>
<li>
notify law enforcement authorities if we decide that you have broken any law; or
</li>
<li>
take any other action that we think is appropriate.
</li>
</ol>
</li>
</ol>
</li>
</ol>
I have problem to remove indent on the elements 2.1 , 2.2 , 2.3 etc... probably the third numbering level indent will be moved to left after solving that problem.
My code:
ol {
counter-reset: item
}
li {
display: block
}
li:before {
content: counters(item, ".") " ";
counter-increment: item
}
<ol>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
I tried a lot of ways, but nothing is not correct. Someone do have idea , how to solve that, please?
Add these styles
ol ol {
padding: 0;
}
ol ol ol {
padding: 20px;
}
ol {
counter-reset: item
}
ol ol {
padding: 0;
}
ol ol ol {
padding: 20px;
}
li {
display: block
}
li:before {
content: counters(item, ".") " ";
counter-increment: item
}
<ol>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
Assuming you can't change the markup, you could apply your styles to the list's parent element and target the second numbering level using the child combinator (>):
.list-parent > ol > li > ol {
padding-left: 0;
}
.list-parent ol {
counter-reset: item
}
.list-parent li {
display: block
}
.list-parent li:before {
content: counters(item, ".") " ";
counter-increment: item
}
<div class="list-parent">
<ol>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
</div>
This would be the best approach concerning maintainability as well, as applying global styles to every <ol> list on your website would only result in unwanted behavior sooner or later.
Here is an easy solution:
(See the comments in the code)
ol {
counter-reset: item;
padding-left: 0; /* Remove the padding of all ol elements */
}
ol ol ol {
padding-left: 1em; /* Set the padding of third level ol elements */
}
li {
display: block;
}
li:before {
content: counters(item, ".") " ";
counter-increment: item;
}
<ol>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
Hope it helps.
I use Nested counter to create a html ordered list.
This is my code:
http://jsfiddle.net/Katalhama/YpgfF/
I expect this output
0. zero
0.1 zero.one
1. one
1.1. one.one
1.2. one.two
1.3. one.three
2. two
2.1 two.one
2.2 two.two
2.2.1 two.two.one
2.2.2 two.two.two
3. three
But instead I got this:
0. zero
0.0 zero.one
1. one
1.0 one.one
1.1 one.two
1.2 one.three
2. two
2.0 two.one
2.1 two.two
2.1.0 two.two.one
2.2.1 two.two.two
3. three
I want to start with a 0 index, but i wanna sublists index start at 1. My only thought is using two counters, but i'm not familiar with advanced CSS yet and i don't know howw to manage them :(
Thanks all!
There are 2 problems in your code. The first is very serious. The HTML code is in fact invalid. The ol can only contains li elements as direct children. But you added ol elements as direct children of ol. You have to wrap the ol elements inside the li elements. The second problem is the problem you asked for. To achieve what you want, we can set the counter-reset differently for the outermost ol and others ol:
HTML:
<ol id='list'>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three</li>
<li>four
<ol>
<li>four.one</li>
<li>four.two
<ol>
<li>four.two.one</li>
<li>four.two.two</li>
</ol>
</li>
</ol>
</li>
<li>five</li>
</ol>
CSS:
#list {
counter-reset: item -1;
}
ol {
counter-reset: item;
padding-left: 10px;
}
LI { display: block }
LI:before {
content: counters(item, ".") " ";
counter-increment: item;
}
Demo 1
Without using an id for the outermost ol, you can do something like this:
ol {
counter-reset: item -1;
}
ol ol {
counter-reset: item;
padding-left: 10px;
}
LI { display: block }
LI:before {
content: counters(item, ".") " ";
counter-increment: item;
}
Demo 2
Here is another approach:
ol {
counter-reset: item -1;
}
LI { display: block }
LI:before {
content: counters(item, ".") " ";
counter-increment: item;
}
ol ol li:first-child:before {
counter-increment: item 2;
}
Demo 3
To get the correct numbers for the example on JS Fiddle, change the counter-reset to item 0;
CSS
OL {
counter-reset: item 0;
padding-left: 10p;
}
LI {
display: block
}
LI:before {
content: counters(item, ".") " ";
counter-increment: item;
}
And your OL's need to be inside your LIs, you can't have an OL inside an OL
HTML:
<body>
<ol>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
</body>
No no your HTML (in the fiddle) is broken. As you mentioned in the title your <ol>'s should be nested, so that means inside other li's, like this
<ol>
<li>Two
<ol>
<li>Two.one</li>
</ol>
</li>
</ol>
At the moment your ol's are direct children of your other ol's. Ol's may only have li's as children (or script tags). So at the moment you have this.
<ol>
<li>Two</li>
<ol>
<li>Two.one</li>
</ol>
</ol>
When you've changed it to the first codeblock in this answer, you can apply different CSS for nested li's, like this:
ol { counter-reset: item -1 }
ol li ol { counter-reset: item 0 }
Demo here: http://jsfiddle.net/kevinvanlierde/YpgfF/1/
By editing Tyblitz HTML structure..which was not showing proper result.
<body>
<ol>
<li>zero</li>
<li>one
<ol>
<li>one.one</li>
<li>one.two</li>
<li>one.three</li>
</ol>
</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two
<ol>
<li>two.two.one</li>
<li>two.two.two</li>
</ol>
</li>
</ol>
</li>
<li>three</li>
</ol>
</body>
CSS
OL { counter-reset: item -1; padding-left: 10px; }
ol li ol { counter-reset: item 0; }
LI { display: block }
LI:before { content: counters(item, ".") " "; counter-increment: item }
JSFiddel
I use nested counters and scope to create an ordered list:
ol {
counter-reset: item;
padding-left: 10px;
}
li {
display: block
}
li:before {
content: counters(item, ".") " ";
counter-increment: item
}
<ol>
<li>one</li>
<li>two</li>
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
<li>three</li>
<ol>
<li>three.one</li>
<li>three.two</li>
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</ol>
<li>four</li>
</ol>
I expect the following outcome:
1. one
2. two
2.1. two.one
2.2. two.two
2.3. two.three
3. three
3.1 three.one
3.2 three.two
3.2.1 three.two.one
3.2.2 three.two.two
4. four
Instead, this is what I see (wrong numbering):
1. one
2. two
2.1. two.one
2.2. two.two
2.3. two.three
2.4 three <!-- this is where it goes wrong, when going back to the parent -->
2.1 three.one
2.2 three.two
2.2.1 three.two.one
2.2.2 three.two.two
2.3 four
I have no clue, does anyone see where it goes wrong?
Here is a JSFiddle: http://jsfiddle.net/qGCUk/2/
Uncheck "normalize CSS" - http://jsfiddle.net/qGCUk/3/
The CSS reset used in that defaults all list margins and paddings to 0
UPDATE http://jsfiddle.net/qGCUk/4/ - you have to include your sub-lists in your main <li>
ol {
counter-reset: item
}
li {
display: block
}
li:before {
content: counters(item, ".") " ";
counter-increment: item
}
<ol>
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
Use this style to change only the nested lists:
ol {
counter-reset: item;
}
ol > li {
counter-increment: item;
}
ol ol > li {
display: block;
}
ol ol > li:before {
content: counters(item, ".") ". ";
margin-left: -20px;
}
Check this out :
http://jsfiddle.net/PTbGc/
Your issue seems to have been fixed.
What shows up for me (under Chrome and Mac OS X)
1. one
2. two
2.1. two.one
2.2. two.two
2.3. two.three
3. three
3.1 three.one
3.2 three.two
3.2.1 three.two.one
3.2.2 three.two.two
4. four
How I did it
Instead of :
<li>Item 1</li>
<li>Item 2</li>
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ol>
Do :
<li>Item 1</li>
<li>Item 2
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ol>
</li>
This is a great solution! With a few additional CSS rules you can format it just like an MS Word outline list with a hanging first line indent:
OL {
counter-reset: item;
}
LI {
display: block;
}
LI:before {
content: counters(item, ".") ".";
counter-increment: item;
padding-right:10px;
margin-left:-20px;
}
Keep it Simple!
This is a Simpler and Standard solution to increment the number and to retain the dot at the end.
Even if you get the CSS right, it will not work if your HTML is not correct. see below.
CSS
ol {
counter-reset: item;
}
ol li {
display: block;
}
ol li:before {
content: counters(item, ". ") ". ";
counter-increment: item;
}
SASS
ol {
counter-reset: item;
li {
display: block;
&:before {
content: counters(item, ". ") ". ";
counter-increment: item
}
}
}
HTML Parent Child
If you add the child make sure it is under the parent li.
Will not work ✘
Notice the parent li and the child ol li are individual here, this will not work.
<ol>
<li>Parent 1</li> <!-- Parent has open and close li tags -->
<ol>
<li>Child</li>
</ol>
<li>Parent 2</li>
</ol>
Will work ✔
You need to place the ol li child element inside parent li. Notice the parent li is hugging the child.
<ol>
<li>Parent 1 <!-- Parent open li tag -->
<ol>
<li>Child</li>
</ol>
</li> <!-- Parent close li tag -->
<li>Parent 2</li>
</ol>
After going through other answers I came up with this, just apply class nested-counter-list to root ol tag:
sass code:
ol.nested-counter-list {
counter-reset: item;
li {
display: block;
&::before {
content: counters(item, ".") ". ";
counter-increment: item;
font-weight: bold;
}
}
ol {
counter-reset: item;
& > li {
display: block;
&::before {
content: counters(item, ".") " ";
counter-increment: item;
font-weight: bold;
}
}
}
}
css code:
ol.nested-counter-list {
counter-reset: item;
}
ol.nested-counter-list li {
display: block;
}
ol.nested-counter-list li::before {
content: counters(item, ".") ". ";
counter-increment: item;
font-weight: bold;
}
ol.nested-counter-list ol {
counter-reset: item;
}
ol.nested-counter-list ol > li {
display: block;
}
ol.nested-counter-list ol > li::before {
content: counters(item, ".") " ";
counter-increment: item;
font-weight: bold;
}
ol.nested-counter-list {
counter-reset: item;
}
ol.nested-counter-list li {
display: block;
}
ol.nested-counter-list li::before {
content: counters(item, ".") ". ";
counter-increment: item;
font-weight: bold;
}
ol.nested-counter-list ol {
counter-reset: item;
}
ol.nested-counter-list ol>li {
display: block;
}
ol.nested-counter-list ol>li::before {
content: counters(item, ".") " ";
counter-increment: item;
font-weight: bold;
}
<ol class="nested-counter-list">
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
And if you need trailing . at the end of the nested list's counters use this:
ol.nested-counter-list {
counter-reset: item;
}
ol.nested-counter-list li {
display: block;
}
ol.nested-counter-list li::before {
content: counters(item, ".") ". ";
counter-increment: item;
font-weight: bold;
}
ol.nested-counter-list ol {
counter-reset: item;
}
<ol class="nested-counter-list">
<li>one</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
I think that these answers are over-complicating this. If you don't need to support Internet Explorer, then the solution is a one-liner:
ol > li::marker { content: counters(list-item, '.') '. '; }
<ol>
<li>one</li>
<li>two</li>
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
<li>three</li>
<ol>
<li>three.one</li>
<li>three.two</li>
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</ol>
<li>four</li>
</ol>
See the ::marker CSS pseudo-element page and the Using CSS counters page on MDN's CSS reference website for more information.
I encountered similar problem recently. The fix is to set the display property of the li items in the ordered list to list-item, and not display block, and ensure that the display property of ol is not list-item. i.e
li { display: list-item;}
With this, the html parser sees all li as the list item and assign the appropriate value to it, and sees the ol, as an inline-block or block element based on your settings, and doesn't try to assign any count value to it.
Moshe's solution is great but the problem may still exist if you need to put the list inside a div. (read: CSS counter-reset on nested list)
This style could prevent that issue:
ol > li {
counter-increment: item;
}
ol > li:first-child {
counter-reset: item;
}
ol ol > li {
display: block;
}
ol ol > li:before {
content: counters(item, ".") ". ";
margin-left: -20px;
}
<ol>
<li>list not nested in div</li>
</ol>
<hr>
<div>
<ol>
<li>nested in div</li>
<li>two
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
<li>three
<ol>
<li>three.one</li>
<li>three.two
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</li>
</ol>
</li>
<li>four</li>
</ol>
</div>
You can also set the counter-reset on li:before.
Thank you everyone above for their answers!
As I needed RTL solution, I found out that this can solve it:
ol.nested-counter-list li {
display: block;
unicode-bidi: bidi-override;
}
So you would use any of the solution above, but also update the specific CSS selector for RTL cases.
I want to create HTML nested lists that has the following format:
1
1.1
1.2
1.3
1.4
2
2.1
I tried a solution that I found on the internet:
OL { counter-reset: item }
LI { display: block }
LI:before { content: counters(item, ".") " "; counter-increment: item }
But it didnt work for me.
Any help please??
If the counter solution is too complicated, is there a way to fake the nested list effect, by writing them manually but being sure that the formatting looks like a real list
EDIT
need full IE6 support
this answer is for the first question. I suggest use this method if you are not going below IE8 (IE7 => ?). for below IE7 you can use same logic with jquery.
Original Post from
http://www.w3schools.com/cssref/pr_gen_counter-reset.asp
CSS
ul.numeric-decimals { counter-reset:section; list-style-type:none; }
ul.numeric-decimals li { list-style-type:none; }
ul.numeric-decimals li ul { counter-reset:subsection; }
ul.numeric-decimals li:before{
counter-increment:section;
content:counter(section) ". ";/*content:"Section " counter(section) ". ";*/
}
ul.numeric-decimals li ul li:before {
counter-increment:subsection;
content:counter(section) "." counter(subsection) " ";
}
HTML
<ul class="numeric-decimals">
<li>Cats</li>
<li>Dogs
<ul>
<li>Birds</li>
<li>Rats</li>
</ul>
</li>
<li>Rabbits</li>
<li>Ants
<ul>
<li>Lions</li>
<li>Rats</li>
</ul>
</li>
<li>Ducks</li>
This should work. It is a bad way to do this but if you MUST support IE6 not much choice.
<ol>
<li><span>1</span> Item
<ol>
<li><span>1.1</span> Item</li>
<li><span>1.2</span> Item</li>
<li><span>1.3</span> Item</li>
<li><span>1.4</span> Item</li>
</ol>
</li>
<li><span>2</span> Item
<ol>
<li><span>2.1</span> Item</li>
</ol>
</li>
</ol>
with css
ol {list-style:none;}
After your comment I've redone it a bit.
<ol>
<li><span>1</span> Item
<ol>
<li><span>1.1</span> <p>ItemItemItem ItemItemItemItemItemItemItemItem ItemItemItemItemItemItemItemItem ItemItemItemItemItemItemItemItem</p></li>
<li><span>1.2</span> <p>ItemItemItem ItemItemItemItemItemItemItemItem ItemItemItemItemItemItemItemItem ItemItemItemItemItemItemItemItem</p></li>
<li><span>1.3</span> <p>ItemItemItem ItemItemItemItemItemItemItemItem ItemItemItemItemItemItemItemItem ItemItemItemItemItemItemItemItem</p></li>
<li><span>1.4</span> <p>Item</p></li>
</ol>
</li>
<li><span>2</span> Item
<ol>
<li><span>2.1</span> Item</li>
</ol>
</li>
</ol>
And the css would be
ol {list-style:none;}
ol li span
{
display: block;
float: left;
width: 30px;
}
ol li
{
clear:both;
width: 400px;
}
ol li p
{
float: left;
width: 370px;
margin: 0;
}
You may have to adjust the widths.
You can use counters to do so:
Example
ol { counter-reset: item }
li{ display: block }
li:before { content: counters(item, ".") " "; counter-increment: item }
<ol>
<li>li element
<ol>
<li>sub li element</li>
<li>sub li element</li>
<li>sub li element</li>
</ol>
</li>
<li>li element</li>
<li>li element
<ol>
<li>sub li element</li>
<li>sub li element</li>
<li>sub li element</li>
</ol>
</li>
</ol>
The before element doesn't work in IE6, but it's the correct way of doing it. I'd recommend using IE7.js, a javascript library that makes IE6 behave like IE7 where javascript and CSS are concerned. Another way could be using a javascript hack that runs only if the browser is IE6 and traverses de DOM modifying the list items...
In For A Beautiful Web you can find more information regarding IE6-compatible websites.
Works perfectly for me, in FF 3.6.6, so:
Which browser is it not working in?
What does your markup look like (i.e. are you nesting the lists correctly)?
This example uses IE6-specific CSS attribute behavior to add a static marker before each li. There must be some MS specific magic that can replace a static dash with a counter.
If you want it to be a CSS solution, use this as a starting point and then google "MSDN".
ul.example { margin: 0.5em 0; padding: 0 0 0 2em; }
ul.example li
{
margin: 0.5em 0; padding: 0 0 0 20px;
list-style-type: none;
behavior: expression( !this.before
? this.before = this.innerHTML = '— ' + this.innerHTML : '' );
text-indent: -1.24em;
}
ul.example li:before { content: '\2014\a0'; }