1

I've searched everywhere, but the suggestions aren't doing what I'm looking for. Basically, I have my list inside a ul. The ul's height has been set to an exact size. I want the list items inside to have an equal spacing in relation to each other, as well as in relation to the top and bottom of the ul container (that's where the height comes in)—so the spaces are all the same size. How do you do this?

<ul id="nav">
    <li><a href="index.html" id="tab">Home</a></li>
    <li><a href="about.html">About</a></li>
    <li><a href="contact.html">Contact</a></li>
</ul>
ArrayOutOfBounds
  • 133
  • 4
  • 19
  • Are you saying that you have random number `li`s inside a fixed-height `ul`? – Passerby Jan 07 '13 at 05:00
  • Yes, I have the `ul` height set as `#nav { height: x px; }` – ArrayOutOfBounds Jan 07 '13 at 05:44
  • Then the only way I can think of right now is involving JavaScript. – Passerby Jan 07 '13 at 05:49
  • Is there no easy way to do it with just html and css? – ArrayOutOfBounds Jan 07 '13 at 05:54
  • It's even difficult (if possible) to do this with `width`. I would suggest to either make the `ul` expandable, or use fixed number of `li`s. – Passerby Jan 07 '13 at 07:02
  • I do have a fixed number of `li`s and I am using this solution right now: `li:first-child:nth-last-child(3), li:first-child:nth-last-child(3) ~ li { height: 33.3333%; }` but it doesn't seem to be evenly distributing it all. The space between the top of the `ul` and the first `li` item is not the same as the rest. – ArrayOutOfBounds Jan 08 '13 at 22:12
  • By "fixed number of `li`s", I mean the same number among **all** pages that will apply this CSS; my first comment asked if you have random number `li`s and you said "Yes", so by that I think it's impossible with pure CSS, unless you're OK with the flex box solution below. – Passerby Jan 09 '13 at 03:50
  • Sorry, I was really tired when I answered that question. By 'yes', I was answering the second part to your question. I do have a fixed number of `li` items. – ArrayOutOfBounds Jan 09 '13 at 17:30
  • If the number if `li`s is fixed, then I guess you applied `margin` to your `li`s? Because there's something called [margin collapse](http://stackoverflow.com/questions/1438114/for-what-reason-margin-collapse-rules-were-introduced-in-css) in CSS. – Passerby Jan 10 '13 at 03:03

3 Answers3

5

I have just answered a similar question here: https://stackoverflow.com/a/16745192.

Basically, to evenly distribute li's inside a ul, you could set the ul to display: table and the li's to display: table-row, and then use a pseudo element to render the bullet points, it works in IE8+ and all other browsers:

ul {
    height: 300px;
    display: table;
}
li {
    display: table-row;
}
li:before {
    content:'•';
    float: left;
    width: 20px;
    font-size: 1.8em;
    line-height: 0.75em;
}

Here's a jsFiddle

Community
  • 1
  • 1
Mathijs Flietstra
  • 12,563
  • 3
  • 35
  • 66
  • Awesome answer. Worth also noting that if you want to add a border to those LI elements you will need to use border-collapse: collapse as well on your UL - http://stackoverflow.com/a/10040881/802397 – netpoetica Apr 28 '14 at 19:48
1

The CSS Flexible Box Layout Module might what you want, below is a working sample works on my chrome now. (note since the spec might be changed, it is better do not use it for now)

<html>
    <head>
        <style>
            .flex-ul {
                height: 500px;
                width: 200px;
                border: 1px solid #ccc;
                display: -webkit-box;

                -webkit-box-orient: vertical;
                -webkit-box-pack: justify;
            }
            .inner {
                -webkit-flex: 1;
                -webkit-order: 0;
            }
        </style>
    </head>
    <body>
        <ul class="flex-ul">
            <li class="inner">Item one
            <li class="inner">Item two
            <li class="inner">Item three
            <li class="inner">Item four
        </ul>
    </body>
</html>
benbai123
  • 1,345
  • 1
  • 9
  • 11
  • The only problem with this solution is limited support for the as of now latest version of the flexbox. Actually your code is not conforming to the latest version of the flexbox spec. – βξhrαng Jan 07 '13 at 07:36
  • Yes, but the latest version is not work on my chrome. For example, I tried the latest 'flex-flow: column;' and also '-webkit-flex-flow: column;' but lis keep horizontal, the '-webkit-box-orient: vertical;' which I tried it 1 year ago works well. This is why I said 'it is better do not use it for now' :D – benbai123 Jan 07 '13 at 09:54
1

If the number of "li" items are random and could be anything, then a pure HTML + CSS solution looks impossible. Some JS code will be required for this to work.

<style>
#nav { height: x px; }
</style>

<ul id="nav">
    <li><a href="index.html" id="tab">Home</a></li>
    <li><a href="about.html">About</a></li>
    <li><a href="contact.html">Contact</a></li>
</ul>

<script>
var listItems = document.querySelectorAll("ul#nav > li");
for(var l = 0; l < listItems.length; l++) {
  listItems[l].style.height = Math.floor(x/listItems.length) + "px";
}
</script>

A temp example can be found at: http://jsfiddle.net/bKxUx/

Munish Poonia
  • 738
  • 4
  • 3
  • If I know the number of `li` items (which I do), is it possible to do it purely using HTML and CSS? – ArrayOutOfBounds Jan 07 '13 at 07:39
  • Then you can use something like explained here - http://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has – Munish Poonia Jan 07 '13 at 08:00
  • I've now have `li:first-child:nth-last-child(3), li:first-child:nth-last-child(3) ~ li { width: 33.3333%; }` but it doesn't seem to distribute them in relation to the `ul` height. My first list item is randomly positioned, and the rest are being distributed between the first `li` and the bottom of the `ul` height. – ArrayOutOfBounds Jan 07 '13 at 08:10
  • You need to adjust the height in your case, not the width. Check it out here - http://jsfiddle.net/HJ6X7/ – Munish Poonia Jan 07 '13 at 08:17
  • Sorry, I do have `height` in it. I gave the wrong code. It looks like: `#nav li:first-child:nth-last-child(3), #nav li:first-child:nth-last-child(3) ~ li { height: 33.3333%; }` But it still is the same problem I last described. – ArrayOutOfBounds Jan 07 '13 at 08:27
  • I have an that's the same code I have. I replaced the `width` with `height`, but like I said before, it doesn't seem to distribute them in relation to the `ul` height. The first `li` item is randomly positioned, and the rest are being distributed between the first `li` and the buttom of the `ul` height. So the spacing between the first, second, third `li` and bottom of the `ul` are even, but the spacing between the top of the `ul` and the first `li` is different. – ArrayOutOfBounds Jan 08 '13 at 09:44
  • In your jsfiddle, how would I make it so that the vertical space before the first `li` item has an equal spacing with the rest of the `li` items? – ArrayOutOfBounds Feb 01 '13 at 18:35