Search code examples
htmlcssvertical-alignmentjustify

Vertically centered text, in 8 item justified, fluid width menu in 2 rows and gutters


I'm creating an 8 item justified, fluid width menu in 2 rows with centered text and gutters.

This means 4 items per row with approximately 24% width. Gutters are transparent. Everything is in place except for centering long menu texts that wraps. As soon as the text wraps, the second text-row "falls" beneath the menu item.

How do I set some kind of line-height for the menu item so that longer texts gets wrapped but still are vertically centered?

I'm using pseudo elements on both ul and li tags, but if there are better solutions (including javascrip) I'm open for it. No menu item i s longer than 2 lines and the menu will have mobile menu solution for smaller screens. Ordinary browser support and IE8+

HTML is generated by WordPress so can't change to much there.

Code, image and fiddle below.

HTML:

<div id="wrapper">
    <ul >
        <li><a href="#">Normal text</a></li>
        <li><a href="#">Normal text</a></li>
        <li><a href="#">Normal text</a></li>
        <li><a href="#">Normal text</a></li>
        <li><a href="#">Longer text Longer text Longer text</a></li>
        <li><a href="#">Normal text</a></li>
        <li><a href="#">Normal text</a></li>
        <li><a href="#">Normal text</a></li>
    </ul>
</div>

CSS:

#wrapper {
    max-width: 1000px;
    background: grey;
}

ul {
    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;
    padding: 0;
    margin: 0;
    font-size: 0.1px;
}

ul:after {
    content: '';
    width: 100%;
    display: inline-block;
    font-size: 0;
    line-height: 0
}

li {
    width: 24%;
    height: 100px;
    vertical-align: top;
    display: inline-block;
    *display: inline;
    zoom: 1
    border: 1px solid black;
    background-color: #ddd;
    font-size: 22px;
    color: #000000;
    margin-bottom: 1%;
    text-align: center;
}

li a {
    text-decoration: none;
}

li a:before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    line-height: 1px;
    text-align: center;
}

the menu

Fiddle: http://jsfiddle.net/A347a/


Solution

  • For such a structure I would use a table, way more handy:

    HTML

    <table id="wrapper">
        <tbody >
            <tr>
              <td><a href="#">Normal text</a></td>
              <td><a href="#">Normal text</a></td>
              <td><a href="#">Normal text</a></td>
              <td><a href="#">Normal text</a></td>
            </tr>
            <tr>
              <td><a href="#">longer text longer text longer text</a></td>
              <td><a href="#">Normal text</a></td>
              <td><a href="#">Normal text</a></td>
              <td><a href="#">Normal text</a></td>
            </tr>
        </tbody>
    </table>
    

    CSS

    #wrapper {
        col {
            max-width: 250px;
        }
        background: grey;
        border-spacing:0;
        border-collapse:collapse;
    }
    
    tbody {
        text-align: justify;
        -ms-text-justify: distribute-all-lines;
        text-justify: distribute-all-lines;
        padding: 0;
        margin: 0;
        font-size: 0.1px;
    }
    
    
    td {
        width: 25%;
        height: 100px;
        vertical-align: middle;
        background-color: #ddd;
        font-size: 22px;
        color: #000000;
        margin-bottom: 1%;
        text-align: center;
        border: 1px solid black;
    }
    
    li a {
        text-decoration: none;
    }
    

    Fiddle