I tried to create a custom Ordered List (OL) using "CSS Counters" taking as example this Mozilla article.
I need to slightly modify it, wrapping last OL in a DIV containter named .foo, as shown in this jsFiddle.
<div id='foo'>
<ol>
<li>item</li> <!-- 1 -->
<li>item</li> <!-- 2 -->
</ol>
</div>
ol {
counter-reset: section;
list-style-type: none;
}
li::before {
counter-increment: section;
content: counters(section,".") " ";
}
Adding wrapper, counter does not reset anymore and numbers continue from 4.1 and 4.2. Why? How to reset new counter even if is wrapped inside a container? Thanks
Add counter reset to the div and assign a new value to the wrapped ol.
Fiddle: http://jsfiddle.net/mbmg52sz/3/
ol{
counter-reset: sectionA;
list-style-type: none;
}
li::before {
counter-increment: sectionA;
content: counters(sectionA,".") " ";
}
div{
counter-reset: sectionA;
}
div > ol{
counter-reset: sectionB;
}
div > ol > li{
counter-increment: sectionB;
content: counters(sectionB,".") " ";
}
Related
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>
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: "";
}
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/
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.
I am working on the content for an online class I am developing and need to include college-specified course objectives. Each week, I will have a page that will list the course objectives. The objectives are listed using OL with CSS to create a list of the form UnitNum.1, UnitNum.2, etc. I was able to get that working based on the advice at Can ordered list produce result that looks like 1.1, 1.2, 1.3 (instead of just 1, 2, 3, ...) with css?.
Here is a portion of my page:
<html>
<head>
<title></title>
<style type="text/css">
.dottedlist {
counter-reset: dottedlistcnt;
}
.dottedlist li {
list-style-type: none;
}
.dottedlist li::before {
counter-increment: dottedlistcnt;
content: "1." counter(dottedlistcnt) " ";
}
.dottedlist li {
list-style-position: outside;
}
</style>
</head>
<body>
<ol class="dottedlist">
<li>Identify the major constraints that impact Project Management: scope, time and cost. </li>
<li>Differentiate between IT projects and other kinds of projects: skills; turnover rates; uniqueness and complexity; visualization; requirements gathering; changing requirements; technology changes; software testing; and training.</li>
<li>Elaborate essential functions of the Project Manager: manage project scope; manage human resources; manage communications; manage schedule; manage quality; and manage costs. </li>
<li>Discuss the influence of organizational structure on Project Management effectiveness. </li>
</ol>
</body>
</html>
The problem in the rendering are where the text wraps around for items 1.2 and 1.3 and is below the numbering, whereas I would like it to be aligned with the text above (each) line.
Additionally, does anyone know if there is a way I can parameterize the number 1 in .dottedlist li::before, so that on the other pages when I am dealing with other units I can simply add that in?
That's not possible since the :before is placed inside the li, not outside.
Consider JavaScript. Here's a jQuery based demo. You can copy'n'paste'n'run it.
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 4503825</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('ol.dottedlist').each(function(i, ol) {
$ol = $(ol);
$ol.children('li').each(function(i, li) {
$li = $(li);
var level = '1.' + ($li.index() + 1);
$li.prepend('<span>' + level + '</span>');
});
});
});
</script>
<style>
ol.dottedlist {
list-style-type: none;
}
ol.dottedlist li span {
margin: 0 5px 0 -25px;
}
</style>
</head>
<body>
<ol class="dottedlist">
<li>Identify the major constraints that impact Project Management: scope, time and cost. </li>
<li>Differentiate between IT projects and other kinds of projects: skills; turnover rates; uniqueness and complexity; visualization; requirements gathering; changing requirements; technology changes; software testing; and training.</li>
<li>Elaborate essential functions of the Project Manager: manage project scope; manage human resources; manage communications; manage schedule; manage quality; and manage costs. </li>
<li>Discuss the influence of organizational structure on Project Management effectiveness. </li>
</ol>
</body>
</html>
As an extra bonus: it works on older browsers (IE6/7/etc) as well.
I'm unsure, exactly, of your use-case, but with the following mark-up:
<ol>
<li>
<ol>
<li>The first nested item</li>
<li>The second nested Item</li>
</ol>
</li>
<li>
<ol>
<li>More nesting</li>
<li>And even more...</li>
</ol>
</li>
</ol>
And CSS:
ol {
list-style-position: outside;
counter-reset: section;
padding: 0.5em 1em;
margin: 0 1em;
}
ol li {
counter-increment: section;
}
ol li ol {
counter-reset: subsection;
}
ol li ol li {
counter-increment: subsection;
}
ol li:before {
content: "Section: " counter(section);
width: 3em;
margin: 0 1em 0 0;
}
ol li ol li:before {
content: counter(section) "." counter(subsection);
}
It's certainly possible (though I'm not sure exactly what your question is), but here's a JS Fiddle demo
Edited to address the text-wrapping issue that (somehow) passed me by the first time.
My approach to this is to give the containing li position: relative; and move it left by 1em, then giving the li:before content position: absolute; and left: -1em (which is a bit unclean, to my tastes, but it works). The revised CSS is below:
ol {
list-style-position: outside;
counter-reset: section;
padding: 0.5em 1em;
margin: 0 1em;
}
ol li {
counter-increment: section;
}
ol li ol {
counter-reset: subsection;
}
ol li ol li {
counter-increment: subsection;
position: relative;
left: 1em;
}
ol li:before {
content: "Section: " counter(section);
width: 3em;
margin: 0 1em 0 0;
}
ol li ol li:before {
content: counter(section) "." counter(subsection);
position: absolute;
left: -2em;
width: 2em;
}
And comes with a revised JS Fiddle demo
Alright, starting with apologies for misreading the question: Sorry for that.
You can get the spacing you want by giving the list-items some padding, and positioning the counter within the padding.
You can parameterize the values by creating some id's that can be tied to different counter-reset values
#counter-1
{
counter-reset: 1;
}
#counter-2
{
counter-reset: 2;
}
etc...
It will take some work, but I believe it works.
Actually, in CSS 2.0 and previous this isn't directly possible - you can't really mess with the numbering other than the start number.
CSS 3.0 might support it, but I'm not sure of browser support for CSS 3.0 and above.