How to distribute HTML list items evenly in an unordered list
Asked Answered
C

5

21

I want my li elements that form a horizontal menu to be distributed evenly across the width of my ul element. I normally float my li elements to the left and add some margin. But how do I put the proper spacing so they extend from the left of my ul element to the right edge?

Here's an example jsfiddle of a menu not distributed across the ul.

The spacing has to be the same between each li. But the li elements may be different lengths.

Courtenay answered 12/11, 2012 at 9:58 Comment(0)
V
45

Yet another approach. This is something I use when trying to span a menu evenly across the page. It is nice if you have a dynamic menu that will change depending on certain conditions (like an admin page that only shows up if you are logged in as an admin).

CSS:

nav div ul {
display: table;
width: 100%;
list-style: none;
}
nav div ul li {
display: table-cell;
text-align: center;
}
nav div ul li a {
display: block;
}

I was kinda lazy, and just copied this from my current project, so you will have to adapt it to fit your code, but it is my preferred method of creating a horizontal menu

EDIT: You can make it look like it spans better by adding this:

CSS:

nav div ul li:first-child {
    text-align: left;
}
nav div ul li:last-child {
    text-align: right;
}

again, untested, just typed.

Velum answered 14/11, 2012 at 19:9 Comment(3)
I had to make the nav display: table, the ul display:table-row and the li display:table-cell, then it all worked amazingly well.Courtenay
I tested it (in Chrome), then I moved it in to my evernote snippet library :) Thanks @Velum that's some hella CSS right there.Plum
I made a .distributed-navigation class with the code above as it's contents. When using this class I'm also overriding the width of the navigation so the nav element is wider than it's containing parent. This way you do not have to left/right align the 'li:first/last-child'. I adjust the position of the nav. For example: 'nav{ width: 932px; position:relative; left:-6px; }'. Now my nav exceeds the width of it's containing element, but both first and last 'li' are perfectly aligned with the left/right borders of my main block. Every item looks justified correctly.Vladi
J
2

You'll need to set the width of the li elements to force them to fill the space:

ul {
    width: 100%;
}
li {
    float: left;
    width: 33%;
}

(Fiddle demo)

If you add more items to the list, you'll need to adjust the percentage width - eg with four items, the width will be 25%.

Jeaz answered 12/11, 2012 at 10:15 Comment(1)
No, that doesn't work. The spacing has to be the same between each li.Courtenay
I
1

I have two answers for you.

If you want to stick with the float model:

Your ul element needs to have the overflow property set (without this property, your ul (or any element containing floated elements) is not given a height (this is expected behavior, mind you: http://www.quirksmode.org/css/clearing.html) and will therefore default to a height of 0 - the effect of this will be that if you set different background colors for your ul/li and body, the background of your ul will not seem to display).

ul {
    text-align: center;
    width: 300px;
    overflow: auto;
}

Your li elements need to have widths set, otherwise - as floated elements - their width will be set to whatever they contain. I've used pixels, below, but you can use a percentage value too.

li {
    float: left;
    margin: 5px 0 5px 0;
    width: 100px;
    text-align: center;
}

Use the display:inline-block property for your li elements (if support for old browsers isn't a priority). IE 7 does not support this, so it's not useful if you need wide cross-browser support, but it creates the effect you want - though make sure you then delete any spaces between your </li> and <li> tags, otherwise they will be counted in the overall width and will show up as spaces between the elements.

One advantage that this method has is that you don't have to know or set the width of the container ul if you use percentage widths on your contained li elements, you still get the centering for free with the text-align property you already have. This makes your layout very responsive.

Here's markup and CSS that works the way I think you are requesting:

Markup:

<ul>
<li>banana</li><li>orange</li><li>apple</li>
</ul>

CSS:

li {
    display:inline-block;
    margin:5px 0 5px 0;
    width:33.33%;
}
ul {
    text-align: center;
}
  • If you'd rather keep the markup on multiple lines, then you'll have to fiddle with the left and right margins of your li elements in the CSS.
  • If you add li elements, you'll have to change the percentage width to match (for example, with four li elements in your markup, you'd need to change your CSS to have a width of 25% for each one).
Impressionable answered 14/11, 2012 at 19:2 Comment(0)
R
1

Html:

 <ul>
    <li>1</li>
    <li>2 <br>4</li>
    <li>3</li>
</ul>

Css:

ul {
    list-style: none;
    font-size: 0;
    text-align: justify;
}

ul:after {
    content: '';
    display: inline-block;
    width: 100%;
}

li {
    font-size: 100px;
    display: inline-block;
}

codepen

Radiogram answered 18/5, 2019 at 13:52 Comment(1)
This is the correct solution..the key is in the justify :) Good answerPokey
R
0

I don't get your question clearly so I assumed that you might want this:

li {
    border:solid 1px red;
    clear:both;
    display:block;
    float: left;
    margin: 5px;
    width:100%;
}
ul {
    text-align: center;
    width:300px;
}
Relume answered 12/11, 2012 at 10:8 Comment(1)
That seems to make the menu vertical (up and down). I want a horizontal menu with the same spacing between elements.Courtenay

© 2022 - 2024 — McMap. All rights reserved.