How to increment ordered list with numbers and alphabet letters in CSS:
ol.nested {
margin-bottom: 0;
counter-reset: item;
}
ol.nested li {
display: block;
position: relative;
}
ol.nested li:before {
content: counters(item, ".", decimal) ".";
counter-increment: item;
position: absolute;
margin-right:100%;
right: 10px;
}
<ol class="nested">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ol class="nested">
<li>Show Item 3.a instead of 3.1</li>
<li>Show Item 3.b instead of 3.2</li>
<li>Show Item 3.c instead of 3.3</li>
</ol>
</li>
<li>Item 4
<ol class="nested">
<li>Show Item 4.a instead of 4.1</li>
<li>Show Item 4.b instead of 4.2</li>
<li>Show Item 4.c instead of 4.3</li>
</ol>
</li>
<li>Item 5</li>
</ol>
Is there a way to combine numbers with letters (2.a, 2.b, 2.c) and increment them in ordered list? With content and counters-increment the list will be incremented only with one type either decimal or lower-alpha. How to combine decimal with lower-alpha incrementing? Thank you!
you can use multiple counters with multiple counter-reset, and apply a counter-increment to ::before and ::after
.nested {
margin-bottom: 0;
counter-reset: number letter; /* default reset for number and letter */
}
.nested.third li {
counter-reset: number 2; /* reset all child li in order to keep 3.x */
}
.nested.fourth {
counter-reset: letter /* reset the letter to restart at A */
}
.nested.fourth li {
counter-reset: number 3; /* reset all child li in order to keep 4.x */
}
.nested li {
display: block;
position: relative;
}
.parent li::before {
content: counter(number)".";
counter-increment: number; /* increment the numbers in general */
position: absolute;
margin-right: 100%;
right: 20px;
background: lightgreen
}
.child li::after {
content: counter(letter, lower-alpha); /* increment the letters in general */
counter-increment: letter;
position: absolute;
margin-right: 100%;
right: 10px;
background: lightblue;
width: 10px
}
<ol class="nested parent">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ol class="nested child third">
<li>Show Item 3.a instead of 3.1</li>
<li>Show Item 3.b instead of 3.2</li>
<li>Show Item 3.c instead of 3.3</li>
</ol>
</li>
<li>Item 4
<ol class="nested child fourth">
<li>Show Item 4.a instead of 4.1</li>
<li>Show Item 4.b instead of 4.2</li>
<li>Show Item 4.c instead of 4.3</li>
</ol>
</li>
<li>Item 5</li>
</ol>
OP's comment
Sorry, you're right. The numbers are exactly as I asked. Is there no way to have generic css class for the next items 5, 6, 7 and
so on? Hm.
As #Mr Lister answered below you can do it, so I'm updating my answer to meet your specs.
As you can see by the colors, the difference from one snippet to another is that in the first one you have more control over each item, in this one is more general.
.nested li {
display: block;
position: relative;
}
.nested {
margin-bottom: 0;
counter-reset: number;
}
.parent .nested {
counter-reset: letter;
}
.parent .nested li::before {
content: counter(number) "." counter(letter, lower-alpha);
counter-increment: letter;
background: lightblue
}
.nested li::before {
content: counter(number) ".";
counter-increment: number;
position: absolute;
margin-right: 100%;
right: 10px;
background: lightgreen
}
<ol class="nested parent">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ol class="nested">
<li>Show Item 3.a instead of 3.1</li>
<li>Show Item 3.b instead of 3.2</li>
<li>Show Item 3.c instead of 3.3</li>
</ol>
</li>
<li>Item 4
<ol class="nested">
<li>Show Item 4.a instead of 4.1</li>
<li>Show Item 4.b instead of 4.2</li>
<li>Show Item 4.c instead of 4.3</li>
</ol>
</li>
<li>Item 5</li>
</ol>
Is this what you need? It doesn't rely on any specific class names for the different nested lists, so you can have as many lists as you want.
The trick is to use items for the outer list and subitems for the inner ones.
ol.nested {
margin-bottom: 0;
counter-reset: item;
}
ol.nested li {
display: block;
position: relative;
}
ol.nested li:before {
content: counters(item, ".", decimal) ".";
counter-increment: item;
position: absolute;
margin-right: 100%;
right: 10px;
}
.nested .nested {
counter-reset: subitem;
}
.nested .nested li:before {
content: counter(item) "." counter(subitem, lower-alpha);
counter-increment: subitem;
}
<ol class="nested">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ol class="nested">
<li>Show Item 3.a instead of 3.1</li>
<li>Show Item 3.b instead of 3.2</li>
<li>Show Item 3.c instead of 3.3</li>
</ol>
</li>
<li>Item 4
<ol class="nested">
<li>Show Item 4.a instead of 4.1</li>
<li>Show Item 4.b instead of 4.2</li>
<li>Show Item 4.c instead of 4.3</li>
</ol>
</li>
<li>Item 5</li>
</ol>
Related
Is it possible to create an ordered list with positive to negative without zero using only CSS?
Example:
3. Highest
2. Higher
1. High
-1. Low
-2. Lower
-3. Lowest
I understand the presentation is highly unusual. The intent is to create, with one field, a list of most and least favorites.
Some technical background: The field is generated in Joomla! CMS via FLEXIcontent's Text Field. The field is configured to be able to take multiple entries, and is restricted to only be able to take an even number of entries. The user is required to input an equal number of pros and cons for the given field. I'd like to be able to control everything exclusively in CSS so I don't have to create template overrides, if at all possible.
I've chosen this approach as I don't want to require multiple fields for one set.
I've found various resources for styling the numbers. I believe the following wouldn't work as I'd have to control some factors with PHP or there's limits to the markup:
<ol>
<li value=#>List Item</li> <!--needs value populated by PHP-->
</ol>
<ol reversed> <!--Stays positive and ends at 1-->
<li>Reversed List</li>
</ol>
<ol reversed start=2> <!--Can I control where to start based on number of children?-->
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
<li>List Item 5</li>
</ol>
If the task is completely impossible, it may be more practical to style based on number of children and color the first and last half differently. Still, it'd be very interesting to see if this is possible with CSS exclusively.
Great question! This is something a little different and an interesting example of what CSS can do.
See the code below for a solution to your problem. If you are using SASS you could easily create a mixin to generate all the selectors you need.
By using CSS counters you can fake the list number and then use nth-child to reset the counter to avoid displaying a 0 item.
Solution with a starting number
ol {
list-style: none;
margin: 0;
padding: 0 0 0 1.5em;
}
ol[start="1"] {
counter-reset: ol 2;
}
ol[start="1"] li:nth-child(2) {
counter-reset: ol 0;
}
ol[start="2"] {
counter-reset: ol 3;
}
ol[start="2"] li:nth-child(3) {
counter-reset: ol 0;
}
ol[start="3"] {
counter-reset: ol 4;
}
ol[start="3"] li:nth-child(4) {
counter-reset: ol 0;
}
ol li::before {
counter-increment: ol -1;
content: counter(ol) '.';
text-align: right;
margin: 0 .5em 0 -1.5em;
display: inline-block;
width: 1em;
}
<h2>Start at 1</h2>
<ol start="1">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li>List item 6</li>
</ol>
<h2>Start at 2</h2>
<ol start="2">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li>List item 6</li>
</ol>
<h2>Start at 3</h2>
<ol start="3">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li>List item 6</li>
</ol>
Solution without starting number but with same number of positive and negative list items
If you want this to work without having to add the start attribute to the ol and always have the same number of positive and negative list items you can use this CSS - but again it requires that you write it out the selectors for all the required numbers of items.
ol {
list-style: none;
margin: 0;
padding: 0 0 0 1.5em;
}
/* two items */
ol li:nth-child(1):nth-last-child(2) {
counter-reset: ol 2;
}
ol li:nth-child(2):nth-last-child(1) {
counter-reset: ol 0;
}
/* fouritems */
ol li:nth-child(1):nth-last-child(4) {
counter-reset: ol 3;
}
ol li:nth-child(3):nth-last-child(2) {
counter-reset: ol 0;
}
/* six items */
ol li:nth-child(1):nth-last-child(6) {
counter-reset: ol 4;
}
ol li:nth-child(4):nth-last-child(3) {
counter-reset: ol 0;
}
ol li::before {
counter-increment: ol -1;
content: counter(ol) '.';
text-align: right;
margin: 0 .5em 0 -1.5em;
display: inline-block;
width: 1em;
}
<h2>Two Items</h2>
<ol>
<li>List item 1</li>
<li>List item 2</li>
</ol>
<h2>Four Items</h2>
<ol>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
</ol>
<h2>Six Items</h2>
<ol>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li>List item 6</li>
</ol>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am using ol>li in an HTML file, added styling to it to use the hierarchical numbering like 1, 1.1,1.2, 1.2.1 etc. It works perfectly fine sometimes, but sometimes the numbering gets messy. Instead of starting with next number, it continues the same hierarchy. Refer the attached image, instead of using number 3, the numbering continues as 2.6 and then uses 2.6.1 and so on
here is my css -
ol {
list-style-type: none;
counter-reset: item;
margin: 0;
padding: 0
}
ol>li {
display: table;
counter-increment: item;
margin-bottom: .6em
}
ol>li:before {
content: counters(item, ".") ". ";
display: table-cell;
padding-right: .3em;
font-size: 14px;
}
li ol>li {
margin: 0
}
li ol>li:before {
content: counters(item, ".") " "
}
li ol>li:before {
content: counters(item, ".") " ";
font-size: small
}
<ol>
<li>List Item 1
<ol>
<li>Indented List Item 1</li>
<li>Indented List Item 2</li>
<li>Indented List Item 3</li>
</ol>
</li>
<li>List Item 2
<ol>
<li>Indented List Item 1</li>
<li>Indented List Item 2</li>
<li>Indented List Item 3</li>
</ol>
</li>
<li>List Item 3
<ol>
<li>Indented List Item 1</li>
<li>Indented List Item 2</li>
<li>Indented List Item 3</li>
</ol>
</li>
<li>List Item 4
<ol>
<li>Indented List Item 1</li>
<li>Indented List Item 2</li>
<li>Indented List Item 3</li>
</ol>
</li>
</ol>
Here is clean 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</li>
<ol>
<li>three.two.one</li>
<li>three.two.two</li>
</ol>
</ol>
</li>
<li>
four
<ol>
<li>Four.one</li>
<li>Four.two</li>
</ol>
</li>
</ol>
Background
The Tinymce editor supports nested numbered lists. Naturally something like this is possible with the editor,
Now the requirement is to show numbers like this,
So far
This is doable by modifying the stylesheet associated with the editor with following list styles (from this answer)
ol { counter-reset: item }
li { display: block }
li:before { content: counters(item, ".") " "; counter-increment: item }
Question
Now the issue is if I select some other number format (for example lower Greek from the editor it looks like following)
how do I get the nested lists also to use the same format as the parent list?
This is the solution for the problem,
ol {
counter-reset: item
}
ol li {
display: block
}
ol li:before {
content: counters(item, ".") ". ";
counter-increment: item
}
ol[style*="list-style-type: lower-alpha;"] li:before {
content: counters(item, ".", lower-alpha) ". ";
counter-increment: item
}
<ol>
<li>Level 1</li>
<li>Level 1
<ol>
<li>Level 2</li>
<li>Level 2</li>
<li>Level 2
<ol>
<li>Level 3</li>
<li>Level 3</li>
<li>Level 3
<ol>
<li>Level 4</li>
<li>Level 4</li>
<li>Level 4</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li>Level 1</li>
<li>Level 1</li>
</ol>
How to get those li that have children ul. I want to set CSS to those li. I can't set class because li are dynamically print. When I set CSS as below so it set all parent li to plus.
.ul{
width:200px;
position:relative;
}
.ul li{
position:relative;
}
.ul > li:before{
content : '+';
position: absolute;
top: 0;
right: 7px;
}
<ul class="ul">
<li>List 1</li>
<li>List 2</li>
<li>List 3
<ul>
<li>Sub List 1</li>
<li>Sub List 2</li>
<li>Sub List 3</li>
</ul>
</li>
<li>List item 4</li>
</ul>
This is style for that.
You're very close actually. The trick is to style simply each ul that is inside a .ul. Then move the + to where you want it to appear (i.e. after the first line of the parent li).
.ul {
width: 200px;
position: relative;
}
.ul li {
position: relative;
}
.ul ul::before {
content: '+';
position: absolute;
top: 0;
right: 7px;
}
<ul class="ul">
<li>List 1</li>
<li>List 2</li>
<li>List 3
<ul>
<li>Sub List 1</li>
<li>Sub List 2</li>
<li>Sub List 3</li>
</ul>
</li>
<li>List item 4</li>
</ul>
This is style for that.
You can't do that because in CSS, you don't have a parent selector.
For instance you can't do something like:
ul < li { color: #ddd; }
or even something like:
ul:has(li) { color: #ddd; }
This is because there are a lot of performance issues like re-rendering the page if you have such a parent selector. That's why W3C guys have not added the parent selector tool.
Look here for reading more into it:
Is there a CSS parent selector?
Parent selectors in CSS
How can I create custom counter styles for a reversed ordered list:
C10. Item 10
C9. Item 9
C8. Item 8
C7. Item 7
C6. Item 6
C5. Item 5
C4. Item 4
C3. Item 3
C2. Item 2
C1. Item 1
I found this link which perfectly describes how to achieve a custom numbering in ascending order. How can I modify the following to get a reverse custom numbering and apply it to only a specific listing?
<!DOCTYPE html>
<html>
<style>
ol.cp {
counter-reset: item;
margin-left: 0;
padding-left: 0;
}
ol.cp li {
display: block;
margin-bottom: .5em;
margin-left: 2em;
}
ol.cp:before {
display: inline-block;
content: "C"counter(item)". ";
counter-increment: item;
width: 3em;
margin-left: -2em;
}
</style>
<body>
<h2>My Items</h2>
<p>
<ol reversed>
<li>item 10</li>
<li>item 9</li>
<li>item 8</li>
<li>item 7</li>
<li>item 6</li>
<li>item 5</li>
<li>item 4</li>
<li>item 3</li>
<li>item 2</li>
<li>item 1</li>
</ol>
</p>
<p>
<ol class="cp" reversed>
<li>item 10</li>
<li>item 9</li>
<li>item 8</li>
<li>item 7</li>
<li>item 6</li>
<li>item 5</li>
<li>item 4</li>
<li>item 3</li>
<li>item 2</li>
<li>item 1</li>
</ol>
</p>
</body>
</html>
The result of the above code is illustrated in the following picture.
The only solution I can come up with, with out using JS, is mostly a brute force solution. But if all of your lists are under 20 or 50... how ever many of these you feel like writing. You can match the length of the list and set the counter to that value then decrement the counter.
example for list of 10 items:
ol.cp {
counter-reset: item;
margin-left: 0;
padding-left: 0;
}
ol.cp li {
display: block;
margin-bottom: .5em;
margin-left: 2em;
}
ol.cp li:before {
display: inline-block;
content:"C"counter(item)". ";
counter-increment: item -1;
width: 3em;
margin-left: -2em;
}
ol.cp li:first-child:nth-last-child(10) {
counter-reset: item 11;
}
the problem is you need to create one for each length you want to match. Here are 1-10 and a sample - http://jsfiddle.net/Ue7dG/
ol.cp li:first-child:nth-last-child(1) {
counter-reset: item 2;
}
ol.cp li:first-child:nth-last-child(2) {
counter-reset: item 3;
}
ol.cp li:first-child:nth-last-child(3) {
counter-reset: item 4;
}
ol.cp li:first-child:nth-last-child(4) {
counter-reset: item 5;
}
ol.cp li:first-child:nth-last-child(5) {
counter-reset: item 6;
}
ol.cp li:first-child:nth-last-child(6) {
counter-reset: item 7;
}
ol.cp li:first-child:nth-last-child(7) {
counter-reset: item 8;
}
ol.cp li:first-child:nth-last-child(8) {
counter-reset: item 9;
}
ol.cp li:first-child:nth-last-child(9) {
counter-reset: item 10;
}
ol.cp li:first-child:nth-last-child(10) {
counter-reset: item 11;
}
As #durbnpoisn mentioned, you can use the reversed property. the order is controlled by the HTML and not by the CSS.
Also, notice that it's an HTML5 property.
For XHTML you will need javascript.
edit
The reverse is changing only the counter, not the content.
For content manipulation you must use javascript.
edit #2
Check this, but note that you must supply the upper bound for the list.
Change these lines:
ol{
counter-reset: item 3; /* set the upper boundry for the list, where to start the countdown */
}
/* note that i've changed it to li:before */
ol li:before{
counter-increment: item -1; /* negative counter */
}
To reverse the order of custom numbering, we need to know the total number of items in the list and instruct the counter to start from that number and then decrement.
From your example, with 10 numbers in the list, we'll tell the counter to start at 11.
ol.cp {
counter-reset: item 11;
margin-left: 0;
padding-left: 0;
}
And then set the counter to decrement by 1 on each item.
ol.cp:before {
display: inline-block;
content: "C"counter(item)". ";
counter-increment: item -1;
width: 3em;
margin-left: -2em;
}
When you create our list, reverse the order:
<ol reversed>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ol>