How to keep indent for second line in ordered lists via CSS?
Asked Answered
O

14

345

I want to have an "inside" list with list bullets or decimal numbers being all flush with superior text blocks. Second lines of list entries have to have the same indent like the first row!

E.g.:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 
Aenean commodo ligula eget dolor. Aenean Aenean massa. 
Cum sociis natoque penatibus et magnis dis parturient montes, 
nascetur ridiculus mus. Donec quam felis,

1. Text
2. Text
3. longer Text, longer Text, longer Text, longer Text, longer Text, longer Text
   second line of longer Text
4. Text

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 
Aenean commodo ligula eget dolor. 

CSS provides only two values for its "list-style-position" - inside and outside. With "inside" second lines are flush with the list points not with the superior line:

3. longer Text, longer Text, longer Text, longer Text, longer Text, longer Text
second line of longer Text
4. Text

Width "outside" my list is not flush with superior text blocks anymore.

Experiments width text-indent, padding-left and margin-left work for unordered lists but they fail for ordered lists because it depends on the list-decimal's number of characters:

 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 
 Aenean commodo ligula eget dolor. 

 3. longer Text, longer Text, longer Text, longer Text, longer Text, longer Text
    second line of longer Text
 4. Text
11. Text
12. Text

"11." and "12." aren't flush with the superior text block compared to "3." and "4.".

So where's the secret about ordered lists and the second-line-indent? Thank's for your effort!

Olsen answered 3/5, 2012 at 9:35 Comment(4)
User Pali Madra added this as an answer, but it got deleted for containing no further exlpanation. He said the jsfiddle may be what you're looking for: jsfiddle.net/palimadra/CZuXY/1Messapian
Try to set padding-left only ...Maros
In case somebody stumbles upon this question, who is just looking for "basic list indention", take a look at this question (#17556996) and Natasha Banegas answer.Tolu
Not a single answer addresses the actual question. The actual question is how to left-align the digits in the list, while separately left-aligning the text of the list item with the item text above it when that text overflows to a second or subsequent line. By default -- and in almost every answer -- the list's digits are right-aligned and the text of the list items are left-aligned.Psaltery
D
332

Update

This answer is outdated. You can do this a lot more simply, as pointed out in another answer below:

ul {
  list-style-position: outside;
}

See https://www.w3schools.com/cssref/pr_list-style-position.asp

Original Answer

I'm surprised to see this hasn't been solved yet. You can make use of the browser's table layout algorithm (without using tables) like this:

ol {
    counter-reset: foo;
    display: table;
}

ol > li {
    counter-increment: foo;
    display: table-row;
}

ol > li::before {
    content: counter(foo) ".";
    display: table-cell; /* aha! */
    text-align: right;
}

Demo: http://jsfiddle.net/4rnNK/1/

enter image description here

To make it work in IE8, use the legacy :before notation with one colon.

Downgrade answered 7/7, 2013 at 18:55 Comment(15)
Looks great - I don't get the "foo" value - shouldn't it have a numeric property or?Sharisharia
@Perelli foo is just an arbitrary string (id), it is used to connect the counter-reset, counter-increment and counter() properties.Downgrade
That works nicely. What if I want to have another list embedded in this list? Any recommendations?Unmoving
@Unmoving No problem, you can use the same CSS: jsfiddle.net/4rnNK/44 This is because CSS counters are self-nesting: w3.org/TR/CSS21/generate.html#scopeDowngrade
This has the side effect of also numbering unordered lists. Would you mind editing to accommodate them?Hairraising
You can also avoid the wonky table stuff by using position: relative on the <li>and position: absolute on the generated content. See jsfiddle.net/maryisdead/kgr4k for an example.Radioluminescence
@Radioluminescence Why 40px? That will break when the counters are wider than that. The whole point of using table layout is that the browser will automatically fit the content.Downgrade
Yeah, it sure does, but in most cases you can accommodate for that. Just showing another way and in addition you can do much more style-wise with an element that is not display: table-cell.Radioluminescence
This is clever, but not as clear and concise as JTOrlando's answer ol { text-indent: -1em; padding-left: 1em; }Crescentia
Nice, but how do you control <li> bottom margin? The height of the <li> is solely determined by the height of the table-cell elements in it. Thus, margin, padding, and height on those elements have no effect. How to work around this limitation?Sirocco
If you have multiple-line list items, and need consistent vertical spacing, the solution is to add vertical border-spacing to the ol selector, e.g. border-spacing: 0 3px; Normal padding on the table-cell does not work because the number is always only one line.Detent
This works but an easier method would be ol { padding-left: 1em }.Countershaft
Regarding ol { text-indent: -1em; padding-left: 1em; } solution — try to check that in different browsers (say, Safari vs. Chrome) and font-sizes. It's just essentially saying ol { text-indent: -Npx; padding-left: Npx; } and is very fragile.Baba
this is very bad... margin after the LI won't work - we basically messed up the li 'display' mode and it is not a valid element grabbing the line anymore. You need to fix this according to @ChuckLeButt answerChristi
The updated answer using "list-style-position: outside;" is completely wrong. "outside" is the default value and will push the marker beyond the left edge. It does not solve the problem and doesn't even do anything. You can see the default value is "outside" here: developer.mozilla.org/en-US/docs/Web/CSS/list-style-positionCheese
A
241

I believe this will do what you are looking for.

.cssClass li {
  list-style-type: disc;
  list-style-position: inside;
  text-indent: -1em;
  padding-left: 1em;
}

JSFiddle: https://jsfiddle.net/dzbos70f/

enter image description here

Arbitrator answered 7/7, 2013 at 17:29 Comment(14)
better if you also add padding-left: 1em;Holman
This is by far the best answer of all the solutions in this page. It is much more convenient than others. If you're hesitating with which answer to choose, pick this one.Wandis
the use of padding-left:1em did it for me. simplest solution is usually the best.Styrene
Added padding-left: 1em; :)Jacie
This should be the accepted answer - it's way more simple and just works!Charlsiecharlton
@loremmonkey This is quick and dirty but isn't a real solution. First, 1em doesn't equal the space of the indent. The lines won't align perfectly pixel-wise. Second, what about when the list reaches the number 10? 100? The text-indent won't work, it will not be aligned. This answer should be down-voted.Barn
@Barn It's a disc list not a numbered one, so why count to 100? I see no problems at all with my lists using the code above.Charlsiecharlton
@loremmonkey The indent isn't 1em. oi60.tinypic.com/a0eyvs.jpg The first list-item is using the text-indent technique above. Compared with how it normally looks with list-style-position: outside it's misaligned, off by a pixel in this case.Barn
@Barn I don't know what you are referring to. Here's a screenshot of a list with the code above, no problems anywhere: imgur.com/Y1Y3oQc Maybe you need a better reset for you lists or there are other problems :/Charlsiecharlton
Couldn't you combine the first two lines to list-style: disc inside;?Ornamented
Definitely agree, best answer. Very simple and works well - thanks!Consolidation
This is a good answer but only for unordered lists. This does not answer the original request to indent the second line of ORDERED lists via CSS.Matthus
Man, some people get so whiny and picky on here. I think it's a great solution. In regards for a numbered list system, you could always add different padding for the numbers with 2 digits, the same for 3 digits. Otherwise, this solution works really well.Doorbell
This is problematic in content editable. If you hit enter after being in an element with text-indent, then your next element will have text-indent set.Louls
P
52

The easiest and cleanest way, without any hacks, is to just to indent the ul (or ol), like so:

ol {
  padding-left: 40px; // Or whatever padding your font size needs
  list-style-position: outside; // Usually not needed, but just incase you've changed it elsewhere
}

This gives the same result as the accepted answer: https://jsfiddle.net/5wxf2ayu/

Or with Tailwind:

list-outside list-disc pl-5

Screenshot:

enter image description here

Thanks to the commenters @John and @Alex

Parodic answered 18/8, 2015 at 13:22 Comment(3)
You may need to apply list-style-position: outside to <li>.Ningpo
@Ningpo You should only need to do this if you're forcing the overwrite of an existing style (developer.mozilla.org/en/docs/Web/CSS/list-style-position).Parodic
Tailwind: html <ul class="list-outside list-disc pl-5"><!-- ... --></ul> Cohdwell
H
27

Check this fiddle:

http://jsfiddle.net/K6bLp/

It shows how to manually indent ul and ol using CSS.

HTML

<html>
  <head>
    <title>Lines</title>
  </head>
  <body>
    <ol type="1" style="list-style-position:inside;">
      <li>Text</li>
      <li>Text</li>
      <li>longer Text, longer Text, longer Text, longer Text    second line of longer Text</li>
    </ol>  
    <br/>
    <ul>
      <li>Text</li>
      <li>Text</li>
      <li>longer Text, longer Text, longer Text, longer Text    second line of longer Text</li>
    </ul>
  </body>
</html>

CSS

ol 
{
    margin:0px;
    padding-left:15px;
}

ol li 
{
    margin: 0px;
    padding: 0px;
    text-indent: -1em;
    margin-left: 1em;
}

ul
{
    margin:0;
    padding-left:30px;
}

ul li 
{
    margin: 0px;
    padding: 0px;
    text-indent: 0.5em;
    margin-left: -0.5em;
}

Also I edited your fiddle:

http://jsfiddle.net/j7MEd/3/

Make a note of it.

Hyozo answered 3/5, 2012 at 14:3 Comment(4)
thank you, it works great for UL and for OL up to 9 list entries. This is the main problem I described in my question width the 11/12-thing. In my example above I run an other technique so the problem looks different but the core of the problem stays the same: There is a difference if my decimal-list-point has one or two or more numerics - e.g. 1., 11. or 111.! I see no point where I'm able to react via CSS and adjust the text-indent and the margin-left to the number of numerics.Olsen
For the second line indent of ol(more than a digit), I think CSS won't solve it. We should only go for jquery.Hyozo
Also note that the type attribute for <ol> appears to be deprecated in HTML 5. Use style="list-style-type: " instead.Hexahydrate
are 21 of you people even serious? this does not work. Not sure if you changed your code since you posted.Insistency
O
15

You can set the margin and padding of either an ol or ul in CSS:

ol {
  margin-left: 0;
  padding-left: 3em;
  list-style-position: outside;
}
Overwrought answered 3/5, 2012 at 9:44 Comment(4)
unfortunatly the problem is not solved by this solution: the second lines are flush with the list points not width the superior row, see example aboveOlsen
11 and 12 in jsfiddle.net/j7MEd/1 line up with the top and bottom paragraphs and I didn't change the code. Am I missing something?Overwrought
no, thats not the point. The main problem is that the second (and third, etc...) line of each list point has not the same "indent" like the first line! (see jsfiddle-example). In my question above I think about a workaround with padding, margin etc but it works only for UNordered lists. On ordered list new problems like this 11/12 thing occur. So my main question is: How can I get the indent-thing (like I present in my very first example of my uestion) done for ordered lists without having problems like the 11/12 thing.Olsen
Ok sorry got ya! This is one way.. only problem is to achieve cross-browser you will need to set the margin in IE and the padding in Firefox. jsfiddle.net/j7MEd/2Overwrought
W
9

The following CSS did the trick:

ul {
  margin-left: 1em;
}
    
li {
  list-style-position: outside;
  padding-left: 0.5em;
}
Weisbrodt answered 17/7, 2018 at 19:48 Comment(0)
S
8

You can use CSS to select a range; in this case, you want list items 1-9:

ol li:nth-child(n+1):nth-child(-n+9) 

Then adjust margins on those first items appropriately:

ol li:nth-child(n+1):nth-child(-n+9) { margin-left: .55em; }
ol li:nth-child(n+1):nth-child(-n+9) em,
ol li:nth-child(n+1):nth-child(-n+9) span { margin-left: 19px; }

See it in action here: http://www.wortfm.org/wort-madison-charts-for-the-week-beginning-11192012/

Stressful answered 30/11, 2012 at 14:34 Comment(0)
N
8

My solution is quite the same as Pumbaa80's one, but I suggest to use display: table instead of display:table-row for li element. So it will be something like this:

ol {
  counter-reset: foo; /* default display:list-item */
}

ol > li {
  counter-increment: foo;
  display: table; /* instead of table-row */
}

ol > li::before {
  content: counter(foo) ".";
  display: table-cell;
  text-align: right;
}

So now we can use margins for spacing between li's

Ningpo answered 10/9, 2014 at 15:30 Comment(1)
The absolute best answer.Hip
D
8

I believe you just need to put the list 'bullet' outside of the padding.

li {
  list-style-position: outside;
  padding-left: 1em;
}
Debate answered 24/3, 2015 at 23:23 Comment(0)
C
2

I'm quite fond of this solution myself:

ul {
  list-style-position: inside;
  list-style-type: disc;
  font-size: 12px;
  line-height: 1.4em;
  padding: 0 1em;
}

ul li {
  margin: 0 0 0 1em;
  padding: 0 0 0 1em;
  text-indent: -2em;
}
Chlorophyll answered 20/10, 2016 at 10:35 Comment(1)
only problem font sizeGavelkind
R
0

The ol, ul lists will work if you want you can also use a table with border: none in the css.

Relation answered 6/6, 2012 at 20:4 Comment(1)
i think this is not a good solution concerning semantic rulesOlsen
P
0

CSS provides only two values for its "list-style-position" - inside and outside. With "inside" second lines are flush with the list points not with the superior line:

In ordered lists, without intervention, if you give "list-style-position" the value "inside", the second line of a long list item will have no indent, but will go back to the left edge of the list (i.e. it will left-align with the number of the item). This is peculiar to ordered lists and doesn't happen in unordered lists.

If you instead give "list-style-position" the value "outside", the second line will have the same indent as the first line.

I had a list with a border and had this problem. With "list-style-position" set to "inside", my list didn't look like I wanted it to. But with "list-style-position" set to "outside", the numbers of the list items fell outside the box.

I solved this by simply setting a wider left margin for the whole list, which pushed the whole list toward the right, back into the position it was in before.

CSS:

ol.classname {margin:0;padding:0;}

ol.classname li {margin:0.5em 0 0 0;padding-left:0;list-style-position:outside;}

HTML:

<ol class="classname" style="margin:0 0 0 1.5em;">
Primordial answered 25/11, 2013 at 17:24 Comment(0)
I
-1

Ok, I've gone back and figured some things out. This is a ROUGH SOLUTION to what I was proposing, but it seems to be functional.

First, I made the numbers a series of unordered lists. An unordered list will normally have a disc at the beginning of each list item (

  • ) so you have to set the CSS to list-style: none;

    Then, I made the whole list display: table-row. Here, why don't I just paste you the code instead of gabbing about it?

    <html>
    <head>
    <link type="text/css" rel="stylesheet" href="stylesheet.css"/>
        <title>Result</title>
    </head>
    <body>
        <div><ul>
            <li>1.</li>
            <li><p>2.</p></li>
            <li>10.</li>
            <li><p>110.</p></li>
            <li>1000.</li>
        </ul>
        </div>
        <div>
            <p>Some author</p>
            <p>Another author</p>
            <p>Author #10</p>
            <p>Author #110</p>
            <p>The one thousandth author today will win a free i-Pod!!!! This line also wraps around so that we can see how hanging indents look.</p>
            </div>
    </body>
    </html>'
    

    CSS:

    ul li{
    list-style: none;
    display: table-row;
    text-align: right;
    

    }

    div {
    float: left;
    display: inline-block;
    margin: 0.2em;
    

    }

    This seems to align the text in the 2nd div with the numbers in the ordered list in the first div. I've surrounded both the list and the text with a tag so that I can just tell all divs to display as inline-blocks. This lined them up nicely.

    The margin is there to put a space between the period and the start of the text. Otherwise, they run right up against one another and it looks like an eyesore.

    My employer wanted wrapped-around text (for longer bibliograhical entries) to line up with the start of the first line, not the left-hand margin. Originally I was fidgeting with a positive margin and a negative text indent, but then I realized that when I switched to two different divs, this had the effect of making it so that the text all lined up because the left-hand margin of the div was the margin where text naturally began. Thus, all I needed was a 0.2em margin to add some space, and everything else lined up swimmingly.

    I hope this helps if OP was having a similar issue...I had a hard time understanding him/her.

  • Irresoluble answered 15/10, 2013 at 19:35 Comment(0)
    T
    -1

    I had this same issue and started using user123444555621's answer. However, I also needed to add padding and a border to each li, which that solution doesn't allow because each li is a table-row.

    First, we use a counter to replicate the ol's numbers.

    We then set display: table; on each li and display: table-cell on the :before to give us the indentation.

    Finally, the tricky part. Since we aren't using a table layout for the whole ol we need to ensure each :before is the same width. We can use the ch unit to roughly keep the width equal to the number of characters. In order to keep the widths uniform when the number of digits for the :before's differ, we can implement quantity queries. Assuming you know your lists won't be 100 items or more, you only need one quantity query rule to tell :before to change its width, but you can easily add more.

    ol {
      counter-reset: ol-num;
      margin: 0;
      padding: 0;
    }
    
    ol li {
      counter-increment: ol-num;
      display: table;
      padding: 0.2em 0.4em;
      border-bottom: solid 1px gray;
    }
    
    ol li:before {
      content: counter(ol-num) ".";
      display: table-cell;
      width: 2ch; /* approximately two characters wide */
      padding-right: 0.4em;
      text-align: right;
    }
    
    /* two digits */
    ol li:nth-last-child(n+10):before,
    ol li:nth-last-child(n+10) ~ li:before {
      width: 3ch;
    }
    
    /* three digits */
    ol li:nth-last-child(n+100):before,
    ol li:nth-last-child(n+100) ~ li:before {
      width: 4ch;
    }
    <ol>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
      <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur facere veniam saepe vel cumque, nobis quisquam! Velit maiores blanditiis cum in mollitia quas facere sint harum, officia laborum, amet vero!</li>
    </ol>
    Tops answered 30/6, 2016 at 22:0 Comment(0)

    © 2022 - 2024 — McMap. All rights reserved.