Velth
Velth

Reputation: 1108

Unable to have li items take all space within ul

Provided is the following jsfiddle: http://jsfiddle.net/rPJ49/1/

I'm trying to have all the li-items inside the ul-list take a % of space so that in the end they take all space. Between every li-item there should be a margin of .xx%, expect the last child.

So what's wrong with this example? If you resize the panel horizontally, you'll see 1px(?) is not filled at the most right.

See (bad): enter image description here

See (good): enter image description here

All items have a % width, see:

.items li
{
    display: inline-block;
    margin-right: .25%;
    text-transform: uppercase;
    width: 16.41666666666667%;
}

.items li:last-child
{
    margin-right: 0%;
    width: 16.66666666666667%;
}


Which would lead to: 
5 * 16,41666666666667  = 82,08333333333335%
5 * .25%               = 1.25%
1 * 16,66666666666667  = 16,66666666666667%
Adding them
100%

Any ideas how to solve or for a better way to create multi line li's that take 100% height and together 100% width (with a margin)?

Upvotes: 2

Views: 2989

Answers (3)

zessx
zessx

Reputation: 68790

I finally got a solution...

Here's your new (simpler) structure :

<div class="items">
    <ul>
        <li>
            <div class="element">
                <a href="javascript:void(0);" class="mini">Mini's</a>
            </div>
        </li>
        <!-- ... -->
    </ul>
</div>

And the CSS :

.items
{
    border: 3px solid rgba(235, 235, 235, 0.6);
}

.items ul
{
    width: 100%;
    display: table;            /* consider your list as a table */
    table-layout: fixed;       /* fix equal width on every column */
}

.items li
{
    display: table-cell;       /* consider your element as a table cell */
    text-transform: uppercase;
}

.items li + li
{
    padding-left: 3px;         /* add the transparent space between elements */
}

.items li .element
{
    display: table;            /* use the multiline trick */
    float: left;               /* IMPORTANT : avoid crasy margins */
    height: 40px;
    width: 100%;
    background: rgba(235, 235, 235, 0.6);
}

.items li .element a
{
    display: table-cell;
    vertical-align: middle;
    text-align: center;
    font-family: 'nexa_lightregular';
    color: #000;
    text-decoration: none;
    font-size: 60%;
}

Updated JSFiddle

EDIT I:

It seems to have a browser issue with percent calculation (see here for details).
Here's a workaround : add a one pixel box-shadow on the right side of the last element to hide this extra pixel margin :

.items li:last-child
{
    box-shadow: 1px 0 rgba(235, 235, 235, 0.6);
}

EDIT II:

Finally, that wasn't a good idea x) You'll have this additionnal box-shadow even when there's no extra pixel, and it'll be visible (because of your semi-transparent background).

Instead, play on the width to remove the extra pixel :

.items {
    width: 90.05%; /* instead of 90% */
}

Updated JSFiddle

Upvotes: 2

Brett Weber
Brett Weber

Reputation: 1907

This will keep your last li from having a right margin, and is more supported that using :last-child I haven't tested this, but I use this method personally

.items li
{
   /* apply general styles + float : right */
}

.items li + li
{
   /* apply your margin-right + float : inherit */
}

Upvotes: 1

JoeJ
JoeJ

Reputation: 940

The trick, which I learned from the fantastic Harry Roberts, is to use display: table on the container and display: table-cell on the list items. Table cells stretch take up the full width of the container, depending on how many there are.

His original demo didn't have margins in between the items, but I've forked it and made a new version with the margins:

http://jsfiddle.net/zfSt4/400/

Upvotes: 3

Related Questions