Can I get the CSS counter value of the parent? - css

I need to implement the following list style:
01 Item 1
02 Item 2
02a Item 2a
02b Item 2b
03 Item 3
How can I get the counter value of the parent to use in the :before content of my sub item? (02 in my above example)

You use two different counters: one for the li parents and one for the li subitems. Then, in each li subitem, concatenate multiple counter() functions using each counter, like this:
ol {
counter-reset: item;
}
ol ol {
counter-reset: subitem;
}
li {
display: block;
}
/* First level of parent items */
li:before {
content: counter(item, decimal-leading-zero) ' ';
counter-increment: item;
}
/* Second level of subitems */
li li:before {
/* counter(item) for the parents, counter(subitem) for the subitems */
content: counter(item, decimal-leading-zero) counter(subitem, lower-alpha) ' ';
counter-increment: subitem;
}
jsFiddle demo, tested in all browsers that support :before and CSS2.1 counters including IE8+
Useful reading: W3C CSS2.1 generated content spec, §12.4.1 Nested counters and scope

See this: there is no way to do such things in CSS, obviously you would need to use JavaScript for it but pseudo-elements are not in the DOM afaik.
As for the other answers: he wants the value of the counter that appears before the list items.

No, CSS doesn't support such "variable" things.
All you can do is set the same style as parent.

Related

Using CSS to style a numbered list

I need HTML to produce output similar to:
1. Some title
1.1 blah blah
(a) blah blah blah
(b) blah blah
1.2 blah blah
I believe that because of the need for parenthesis round the letters that I cannot use the ordered list tag for this. Obviously it can be done with a table, but I'd much rather use CSS. However I'm at a loss as to how to do this.
If lines wrap to the next line, they should continue under the text like an ordered list would.
UPDATE
I have tried
OL {
counter-reset: numeric
}
OL LI OL LI OL {
counter-reset: latin
}
LI {
display: block
}
LI:before {
content: counters(numeric, ".") " ";
counter-increment: numeric
}
OL LI OL LI OL LI:before {
content: "(" counter(latin, lower-latin) ") ";
counter-increment: latin
}
and HTML such as:
xxx
<ol>
<li>one
<ol>
<li>onedotone</li>
<li>onedottwo
<ol>
<li>A</li>
</ol>
</li>
</ol>
<li>two</li>
</ol>
produces this
xxx
1 one
1.1 onedotone
1.2 onedottwo
(a) A
2 two
Unfortunately, my requirements are exactly as stated in the original question. So my CSS fails in these areas.
There needs to be a full stop after 1 and after 2 but not after 1.1 and 1.2
1 and 1.1 should not be indented and the text for both of them needs to be aligned to the same place. So the word onedotone needs to be exactly below the word one. Also there needs to be a bigger gap than one space between the number and the text.
The (a) needs to line up with the words onedottwo, and again there needs to be a bigger gap than one space between (a) and A.
padding-left is not the answer, as it does not help line up the text after the numbers, You get
1 one
1.1 onedotone
instead of
1. one
1.1 onedotone
This is beyond my CSS capabilities. Unless anyone has the expertise to point me in the right direction, I fear that I will have to fall back on using a table.
Below is a sample on how the desired result can be achieved using <ol> (ordered lists) and CSS counters. It has a bit of a hack-ish feel about it because of the expectation that when a line is wrapped around, it should not start from under the numberings. Otherwise, I feel this method is much better than manually keying in the numbers (or) using tables.
Consistent spacing between the numbering and text is obtained by setting a width to the li:before pseudo-element and making its display as display: inline-block. Modify the width based on how much spacing is required. Note that when modifying the width, the margin-left and padding-left also have to be modified accordingly to maintain the styling.
CSS Counters have reasonably good browser support also.
.level1, .level2, .level3 {
list-style-type: none;
}
.level1 {
counter-reset: level1; /* first level counter - for 1, 2, 3 */
}
.level2 {
counter-reset: level2; /* second level counter - for 1.1, 1.2 */
}
.level3 {
counter-reset: level3; /* third level counter - for (a), (b) */
}
li {
display: block;
}
li:not(:last-child):after, li > ol:before{
content: " ";
display: block;
position: relative;
height: 20px; /* this is filler where height should be equal to required line height */
left: 0px; top: 100%;
}
.level1, .level2, .level3 {
margin: 0;
padding: 0;
}
.level1 > li, .level3 > li {
padding-left: 40px;
}
li:before {
margin-left: -40px;
/* following 2 props are for consistent spacing between numbering and text */
width: 40px;
display: inline-block;
}
.level1 > li{
font-weight: bold;
}
.level1 > li:before, .level1 > li * {
font-weight: normal;
}
.level1 > li:before {
content: counter(level1)"."; /* display current item number + dot */
counter-increment: level1; /* increment counter everytime a new element of that level is encountered */
}
.level2 > li:before {
content: counter(level1)"." counter(level2); /* format level 1 counter + dot + level 2 counter */
counter-increment: level2;
}
.level3 > li:before {
content: "(" counter(level3, lower-latin)") "; /* format ( + level3 counter + ) */
counter-increment: level3;
}
<ol class='level1'>
<li>one
<ol class='level2'>
<li>one dot one - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
<li>one dot two
<ol class='level3'>
<li>A</li>
<li>B - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
</ol>
</li>
</ol>
</li>
<li>two - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
</ol>
Feedback to comments:
The {content: "\a"; white-space: pre;} trick does not quite work with inline-block elements. The inner level li tags are inline-block in our case (for reasons explained above in 2nd paragraph) and hence that particular trick doesn't work. The alternate is to insert a blank filler line with height of the line equal to the required line-height and position it below the li tag. Note that the selector used is li:not(:last-child):after because we don't need an extra line break after the last li (if we do not do it, we will have double line space after the inner li ends). This is a CSS3 selector and so might not work with lower versions of IE. If you need to support those versions also then we would need to tweak it further (or simpler would be to use br).
You were on the correct path here, but the :before pseudo-element (which has the numbering) is not on the element with class='level1'. It was on the .level1 > li and hence doing a reset of font-weight for selector .level1 > li:before, .level1 > li * would fix it. As you would have already known/guessed, .level1 > li * means every element under the level one li.

Seemingly over-complicated CSS list styling that SHOULD be easy

I need to create a style for ordered lists that follows this format:
(a) List Item 1
(b) List Item 2
(1) List Item 2.1
(2) List Item 2.2
(i) List Item 2.2.1
(ii) List Item 2.2.2
Unfortunately, list-style-type doesn't work because there are no options that show the numbers as listed above, with parentheses.
LOTS of researching has brought about nothing but ugly hacks, for example:
ol {
list-style-type: none;
}
ol>li:before {
content: "(" counter(lvl1, lower-alpha) ") ";
}
ol li {
counter-increment: lvl1;
}
ol ol>li:before {
content: "(" counter(lvl2, decimal) ") ";
}
ol ol>li {
counter-increment: lvl2;
}
ol ol ol>li:before {
content: "(" counter(lvl3, lower-roman) ") ";
}
ol ol ol>li {
counter-increment: lvl3;
}
which works to some extent, removing the list numbering with list-style-type: none; and inserting the number surrounded with parentheses at the beginning of the li. This makes modifying other related styling horrific, as I can't figure out how to line things up nicely etc (I don't think its even possible). It also makes list-style-position redundant, because the numbers are ALWAYS inside the li.
Basically, I'm looking for a way to reproduce this kind of list numbering in CSS: (note text alignment etc)
ANY help VERY MUCH appreciated!!
You're almost there.
Since you're removing list-style, you can restore the position of the counters by applying padding to the list items and then pulling the counters into that padding with a negative margin (or one of many similar techniques e.g. hanging indent)
li {
padding: 2em;
}
li:before {
/* Take counter out of flow and pull it into padding space */
float: left;
margin-left: -2em;
}
You also need to sprinkle some counter-reset into the mix for each level of ol nesting.
JSFiddle showing a full working example with all the nesting code here: http://jsfiddle.net/thefrontender/tzzbh/2/

How to use CSS counters in lists without resetting the counters?

I want to have multiple "ol" lists where the counter value does not reset between lists. Another way to say this is that I want the counter for the first "li" in the second list to be one higher than the counter value from the last element of the previous list. Is there some CSS magic that will do this?
While Su's answer would work, you don't need to be so heavy-handed. Just reset the counter at the top, and everywhere you use it, it will increment.
body {
counter-reset: item;
}
li {
display: block;
}
li:before {
display: inline-block;
content: counter(item) ". ";
counter-increment: item;
}
see this example
Not quite with just CSS. It does provide you with some control over counters (and support is pretty good), but it's still static in it's behavior. So this works:
<html>
<head>
<style>
#list-one {
counter-reset : item;
}
#list-two {
counter-reset : item 3;
}
li {
display : block;
}
li:before {
display : inline-block;
content : counter(item) ". ";
counter-increment : item;
}
</style>
</head>
<body>
<ol id="list-one">
<li>One</li><li>Two</li><li>Three</li>
</ol>
<ol id="list-two">
<li>Four</li><li>Five</li><li>Six</li>
</ol>
</body>
</html>
…but you can't just drop two lists after each other and have the second one automatically pick up where the other left off(see the "3" in the second CSS rule). With a little creativity, though, you could probably wrap the counter-reset styling with a bit of PHP or whatever you're using to build your site. This is dependent upon the particulars of your situation, of course.

Can we stylize the number in an ordered list without changing the entire li?

Is it possible with CSS to change the style of the number in an ­<ol> without changing the entire text in the <li> without adding extra markup around the li content?
You can disable the original <ol> style, then use :before selector with counters to add whatever style you want. Like here:
ol {
counter-reset: i 0;
}
ol li:before {
content: counter(i);
counter-increment: i;
padding-right: 0.5em;
color: red;
}
If you wish, you can even override some styles for particular elements of the list with nth-child selector (JS Fiddle):
ol li:nth-child(3):before {
color: violet;
}
... as cascading rules are still applied here. Note, though, that nth-child is not supported by IE8.

counter-increment in CSS

I am trying to get an ordered list first item shouldn't start with number. The number should start from second item.
please check this URL what I am trying to achieve-- http://jsfiddle.net/kheema/tXtQF/5/
here using counter-reset and counter-increment first item shows 0 and second item starts from 1.. and if anyhow I could remove a 0 my problem will solve.
Does anyone have a better idea on this?
Regards,
Kheema
just change last css rule into
ol li:before {content: ""; color: green; display: inline-block; width: ... ; }
ol li + li:before {content: counter(chapter) "."; }
in this way you insert the content starting from second li element (I used li + li so it can work also with IE8)
see fiddle: http://jsfiddle.net/WwNqN/
Try to add this rule:
ol li:nth-of-type(1):before{content: "";}
This will remove the zero at the first element.

Resources