Nested Numbered Lists Mixed With Alphabet & Roman Characters - html

May I know is it possible to create something like this :
1. Food
1.1 Vege
a. Carrot
i. White Carrot
ii. Red Carrot
1.2 Meat
a. Chicken
b. beef
2. Beverages
I've seen many solution for mixed list with numbers and alphabets, but I can't make something like this which include number,nested number, alphabet, roman characters using simpler css code.
Refer to the solution on jsFiddle for this question, it only able to create nested number, but without alphabet and roman characters.
Below is what I did (to fake the effect) :
.primary {
list-style-type: none;
counter-reset: item;
margin: 0px;
padding: 0px;
}
/* Direct child under ol */
.primary>li {
counter-increment: item;
}
/* Before direct child under ol */
.primary>li:before {
content: counters(item, ".") ". ";
padding-right: 0.6em;
}
.primary>li li {
margin: 0px;
}
/* Before li of second level ol */
.primary>li li:before {
content: counters(item, ".") " ";
}
/* Third level ol */
.pri-inner {
list-style-type: lower-alpha;
padding-left:20px;
}
/* Hide the counter content on third level */
.pri-inner li:before {
content:none;
display:none;
}
/* Fourth level ol */
.pri-inner2{
list-style-type: lower-roman;
padding-left:25px;
}
The sample html code look like this
<ol class="primary">
<li>First
<ol class="primary">
<li>Inside First</li>
<li>
<ol class="pri-inner">
<li>Inside inside
<ol class="pri-inner2">
<li>Maximum inside</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li>Second</li>
</ol>
So, is there any better way to achieve that? Because I have to hide the counter on 3rd level.

counter() accepts a second parameter for the list type, i.e. counter(item, lower-alpha)
So the following CSS could do it, or could be tweaked to use your class names.
ol {
list-style-type: none;
counter-reset: item;
margin: 0;
padding: 0;
}
li {
display: table;
counter-increment: item;
margin-bottom: 0.6em;
}
li:before {
content: counters(item, ".") ". ";
display: table-cell;
padding-right: 0.6em;
}
li li {
margin: 0;
}
li li:before {
content: counters(item, ".") " ";
}
li li li:before {
content: counter(item, lower-alpha) ". ";
}
li li li li:before {
content: counter(item, lower-roman) ". ";
}
http://jsfiddle.net/eke4afd8/

Related

How to remove whitespace between ::before and actual content

I want to create a custom numbering style for an ordered list that immitates footnotes.
However, when I do this, via an li::before pseudoelement (see snippet below), if there is a whitespace between the <li> tag and its actual content in the HTML code, there is a space rendered between the custom number and the item content.
What do I have to do to get rid of the whitespace, or at least make it behave consistently (i.e. it always is or is not there), regardless of whether there is one in the HTML code?
ol {
list-style: none;
counter-reset: x;
}
ol li {
counter-increment: x;
}
ol li::before {
content: counter(x);
vertical-align: super;
font-size: smaller;
}
<ol>
<li>no leading space</li>
<li>
leading space
</li>
<ol>
Let's normalize it to be with white space. For all the good reasons. This is done by adding " " to the counter(x) content.
ol {
list-style: none;
counter-reset: x;
}
ol li {
counter-increment: x;
}
ol li::before {
content: " " counter(x) " ";
vertical-align: super;
font-size: smaller;
}
<ol>
<li>no leading space</li>
<li>
leading space
</li>
</ol>
Picking up on #IT goldman's answer: If you don't want that "normalized" space, you could still do it that way, but add position: relative; and a negative rightsetting to the ol li::before rule to move the number towards the beginning of the li contents:
ol {
list-style: none;
counter-reset: x;
}
ol li {
counter-increment: x;
}
ol li::before {
content: " " counter(x) " ";
vertical-align: super;
font-size: smaller;
position: relative;
right: -0.2em;
}
<ol>
<li>no leading space</li>
<li>
leading space
</li>
</ol>

Apply list-style-type only on the parent, not the children

I have an ordered list with a specific value for the list-style-type property and I want it to not affect its children.
Currently, the ordered list has another ordered list nested inside and it inherits the list-style-type value. How can I disable that?
<ol class='custom-ol'>
<li> cat1:
<ol style="list-style-type:lower-alpha">
<li>text 1</li>
<li>text2</li>
</ol>
</li>
<li>
cat2:
<ol style="list-style-type:lower-alpha">
<li>text 3</li>
<li>text 4</li>
</ol>
</li>
the css style
<style>
.custom-ol ol
{
counter-reset: custom-counter;
list-style-type: none;
}
.custom-ol ol li
{
counter-increment: custom-counter;
}
.custom-ol ol li:before
{
content:"(" counter(custom-counter) ") ";
font-weight:bold;
}
</style>
I tried to fix to that way but it's not working at all (update version)
that's what i get
ol.custom-ol
{
counter-reset: custom-counter;
list-style-type: none;
}
ol.custom-ol li
{
counter-increment: custom-counter;
}
ol.custom-ol li:before
{
content:"(" counter(custom-counter) ") ";
font-weight:bold;
}
ol ol {
list-style-type: lower-alpha;
}
I want the parent (where is 1 now will be (1) with the . custom-ol class
and his children be as they are a,b,c without the (1), (2)
You're not targeting your parent ol at all and you're targeting the children ol elements twice. Once through inline styling:
style="list-style-type:lower-alpha"
and once through your CSS file:
.custom-ol ol
{
counter-reset: custom-counter;
list-style-type: none;
}
If you want to disable list-style-type: none on the children elements, then change .custom-ol ol to .custom-ol. This will target your parent ol only.
Alternatively, try adding !important to style="list-style-type:lower-alpha" like this:
style="list-style-type: lower-alpha !important"
This will override any other styles applied to the child ol.
This is what your CSS should look like:
ol.custom-ol
{
counter-reset: custom-counter;
list-style-type: none;
}
ol.custom-ol li
{
counter-increment: custom-counter;
}
ol.custom-ol li:before
{
content:"(" counter(custom-counter) ") ";
font-weight:bold;
}
ol ol {
list-style-type: lower-alpha;
}
ol ol li:before {
content: "";
}

Add a "." after li numbering

I have an ordered list that I have incrementing by 1. What I am trying to do is get it to increment by 1 with a dot after the 1:
1.
2.
3.
4
Within my list I have it working like,
1
1.1
1.2
1.3
2
2.1
2.2
3
3.1
3.2
3.3
So that Is correct I just want the number at the beginning to also have a . at the end.
My current code looks something like this:
ol {
counter-reset: item ;
}
li {
display: block;
}
li:before {
content: counters(item, ".") " ";
counter-increment: item;
float: left;
}
<ol>
<li>
<ol>
</ol>
</li>
</ol>
So it should end up looking like:
1.
1.1
1.2
1.3
2.
2.1
2.2
2.3
3.
3.1
3.2
3.3
Here's a Fiddle of what you want.
All I did was change the CSS so that the ordered-list-items have a period at the end, unless they're deeper than 1 level. Fairly simple.
ol li::before {
content: counters(item, ".") ". ";
counter-increment: item;
}
ol ol li::before {
content: counters(item, ".") " ";
}
No need for extra, unnecessary classes.
Hope this helps
If you want the numbers to have a dot at the end change your css to
li:before {
content: counters(item, ".") ".\00a0 ";
}
\00a0 adds space (" " doesn't worked for me).
Edit: Regarding the discussion: give an extra class to the first level and use above CSS (see Codepen).
http://codepen.io/anon/pen/MKOOjv
There is already a topic solving this issue
Achieving sub numbering on ol items html
Credits to Joey
ol { counter-reset: item }
ol>li { display: block }
ol>li:before { content: counters(item, ".") ". "; counter-increment: item }
<ol>
<li>
Tome 1
<ol>
<li>Chapter 1</li>
<li>Chapter 2</li>
</ol>
</li>
</ol>
ol {
counter-reset: item ;
}
li {
display: block;
}
li:before {
content: counters(item, ".") ".";
counter-increment: item;
float: left;
margin-right:10px;
}
<ol>
<li>Test1
<ol>
<li>Test1.1</li>
<li>Test1.2</li>
<li>Test1.3</li>
</ol>
</li>
<li>Test2</li>
<li>Test3</li>
</ol>
I've amended the snippet above. You simply needed to add a "." in the second part of the "content" attribute. I also stuck a margin in there to make it obvious.

Markers is a nested list

I want to find out whether it is possible to make out the markers to create a counter.
Just what I was able to achieve can be seen here: http://jsfiddle.net/Jeen/w6V74/1/
ol {
counter-reset: level-1;
list-style: none;
padding-left: 0;
}
ol li:before {
counter-increment: level-1;
content: counter(level-1) '. ';
}
ol ol {
counter-reset: level-2;
padding-left: 15px;
}
ol ol li:before {
counter-increment: level-2;
content: counter(level-1) '.' counter(level-2) '. ';
}
ol ol ol {
counter-reset: level-3;
padding-left: 30px;
}
ol ol ol li:before {
counter-increment: level-3;
content: counter(level-1) '.' counter(level-2) '.' counter(level-3) '. ';
}
In the end, I want to get what is shown in the second image
You might want to check this page and change the way to nest your <ol>:
Proper way to make HTML nested list?
After you properly nest the list, add css below:
ol {
display: table;
}
ol > li {
display: table-row;
}
ol > li::before {
display: table-cell;
}
DEMO: http://jsfiddle.net/naokiota/95xha/
Hope this helps.
Here is one way of styling the indentations.
Modify your CSS by adding the following rules:
ol > li {
padding-left: 1.0em;
position: relative;
}
ol > ol > li {
padding-left: 2.0em;
position: relative;
}
ol > ol > ol > li {
padding-left: 3.0em;
position: relative;
}
ol li:before {
counter-increment: level-1;
content: counter(level-1) '. ';
position: absolute;
left: 0;
}
Take the generated content (ol li:before) out of the regular flow by using position: absolute.
The trick is to add some padding to the left with a suitable length to accommodate the counter label.
For each list item (ol>li, ol>ol>li, ol>ol>ol>li), set the padding-left to 1.0em, 2.0em, 3.0em respectively (or some similar values) and use position: relative to allow the generated content elements to be positioned with respect to the appropriate li parent element.
See fiddle: http://jsfiddle.net/audetwebdesign/m2vZd/

Are letter/number combinations in HTML lists possible?

Quite simply, I want an ordered list to work like this:
1. Foo
2. Bar
3a. Baz
3b. Qux
4. Etc...
Is there any way to easily do something along these lines in HTML?
Given the following mark-up:
<ol>
<li>Foo</li>
<li>
<ol>
<li>bar</li>
<li>baz</li>
</ol>
</li>
<li>Something else...</li>
</ol>​
The following CSS almost works:
ol {
counter-reset: topLevel;
}
li {
counter-increment: topLevel;
margin-left: 1em;
}
li::before {
content: counter(topLevel) '. ';
margin-right: 0.3em;
}
ol ol {
counter-reset: secondLevel;
}
ol ol li {
counter-increment: secondLevel;
}
ol ol li::before {
content: counter(topLevel) counter(secondLevel, lower-alpha) '. ';
}
JS Fiddle demo.
The only problem with this, so far, is that it contains the topLevel count against both the inner li elements (as you wanted), but also against the outer li (that contains those inner elements), so...not quite there, yet.
And the above problem resolved! ...in those browsers that support the CSS :not() selector:
ol {
counter-reset: topLevel;
}
li {
counter-increment: topLevel;
margin-left: 1em;
}
li:not(.hasChild)::before {
content: counter(topLevel) '. ';
margin-right: 0.3em;
}
ol ol {
counter-reset: secondLevel;
}
ol ol li {
counter-increment: secondLevel;
}
ol ol li::before,
ol li.hasChild ol li::before {
content: counter(topLevel) counter(secondLevel, lower-alpha) '. ';
}
JS Fiddle demo.
I forgot (originally) to note that for this to work (because CSS doesn't have a parent selector (as yet) I had to add a specific class to those li elements with child ol elements in order to appropriately hide the duplication of the number. In this case I chose the class-name .hasChild (as can be seen in the Fiddle).
Incidentally, a small change to the li:not(.hasChild)::before rules, allows for the right-aligned text:
li:not(.hasChild)::before {
content: counter(topLevel) '. ';
width: 2em;
margin-right: 0.3em;
display: inline-block;
text-align: right;
}
JS Fiddle demo.
It doesn't meet your requirements fully and requires some (annoying) changes to your html, but I think it's about as close as you'll get.
http://jsfiddle.net/qGCUk/30/
<ol>
<li>one</li>
<li class="has_children">
<ol>
<li>two.one</li>
<li>two.two</li>
<li>two.three</li>
</ol>
</li>
</ol>
ol,li{
padding:0;
margin:0;
}
ol { counter-reset: item }
li { display: block; padding-left: 0 }
li:before {
content: counters(item, ".") " ";
counter-increment: item
}
LI.has_children:before {
content: " ";
counter-increment: item
}
This is only numbers, as I don't think you can mix numbers and letters. And since there is no selector to select and li which contains and ol, you have to add a class to any li which has a child ol.