0

I'm looking for a way to make a horizontal menu in which the menu items are justified across the width, have padding, and overflow to a new line when the number of menu items exceed the container space.
HTML:

<div id='upper-menu-wrapper'>
<div id='upper-menu'>
    <ul>
        <li>About</li>
        <li>Parenting</li>
        <li>Receipes</li>
        <li>Devotional</li>
        <li>DIY Projects</li>
        <li>Home-making</li>
        <li>Pregnancy</li>
        <li>Frugal Living</li>
    </ul>
 </div>
</div>

CSS:

#upper-menu-wrapper {
    width: 100%;
}
#upper-menu {
    width: 1200px;
    margin: 0 auto;
    overflow: auto;
}
#upper-menu > ul {
    list-style-type: none;
    text-align: justify;
    width: 100%;
}
#upper-menu > ul > li {
    display: inline-block;
    padding: 1em;
    text-align: center;
}
preahkumpii
  • 1,301
  • 4
  • 21
  • 36
  • this may help you out. your best bet is probably to use table-cell. http://stackoverflow.com/questions/5060923/how-to-stretch-html-css-horizontal-navigation-items-evenly-and-fully-across-a?rq=1 – onestepcreative May 14 '14 at 13:58
  • Once the container space has been exceeded...how would it look? `text-align:center` might be a better option. – Paulie_D May 14 '14 at 13:58
  • See this: http://jsfiddle.net/abhitalks/MXZ6w/2/ (Taken from excellent solution from @SamGoody here: http://stackoverflow.com/a/15232761/1355315.) – Abhitalks May 14 '14 at 14:46
  • @onestepcreative, I don't think using the `table-cell` method allows the menu items to properly overflow. Otherwise, I think this would be the best solution. – preahkumpii May 15 '14 at 00:58
  • @abhitalks, I would rather avoid using js. – preahkumpii May 15 '14 at 00:59
  • @preahkumpii: There is no js in that solution!!. – Abhitalks May 15 '14 at 02:50
  • @abhitalks, lol. Sorry. I just glanced at the js window and mistook it for checking the size of the container, when it was actually setting the size for the select. – preahkumpii May 15 '14 at 06:30
  • @abhitalks, The solution is great, except for that dreadful space below the `
      `. It is caused by the `:after` css. Is there anyway to remove it, but keep the functionality and look?
    – preahkumpii May 15 '14 at 06:51
  • 1
    @preahkumpii: yup. that space is hard to get rid of. it indeed is caused by the pseudo-element, but without which justification of elements is not possible. choose the better evil :) – Abhitalks May 15 '14 at 07:49
  • @abhitalks, post the answer with the caveat, if you would. – preahkumpii May 15 '14 at 07:54
  • Sure, will take around an hour. – Abhitalks May 15 '14 at 08:07
  • 1
    @preahkumpii: done. added as an answer. hope that helps. – Abhitalks May 15 '14 at 08:45

1 Answers1

1

Getting the elements to justify with wrapping to next line is tricky. Using display:table and table-cell can justify elements like tables but only in one row. Because your requirement is to also keep elements justified while wrapping within a fixed width container, the table-cell won't work.

There is a hack based on :after pseudo-element which can make this possible with wrapping across rows.

Demo: http://jsfiddle.net/abhitalks/MXZ6w/3/

Apply a fixed width to the wrapping div, text-align:justify on the ul and display:inline-block on li are required.

#upper-menu-wrapper {
    width: 500px; /* fixed width on wrapping container */
}
#upper-menu { } /* this div is not really needed */

#upper-menu > ul {
    list-style-type: none; /* getting rid of bullets */
    margin: 0px; padding: 0px; /* getting rid of default indents */
    text-align: justify; /* important to justify contents */
}
#upper-menu > ul > li {
    display: inline-block; /* required. float won't work. */
    text-align: left; /* to properly align list items */
    white-space: no-wrap; /* to prevent wrapping of list items if required */
}

#upper-menu > ul:after { 
    /* this is the hack without which the list items won't get justified */
    content:''; display: inline-block; width: 100%; height: 0; 
}

Note 1: The display: inline-block is required, however it generates html white-spaces. In order to get rid of those white-spaces, html comments can be used in the markup of list items.

Note 2: The :after pseudo element in the hack is what seems to do the trick. However, that will create an unintended space below the ul. This space seems to be there because the elements are flushed across. If not justified, then this space does not appear.

IMPORTANT: Credit: @SamGoody from his answer here.

Community
  • 1
  • 1
Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • In regards to `Note 2`, I'm not sure how robust this solution is, but my `
      ` was within a `
    – user1063287 May 24 '14 at 11:06
  • So a containing element seems to collapse that. That's a good find @user1063287, thanks for pinging back. And regarding robustness, I already said that it is a hack, and hacks are by nature not robust. – Abhitalks May 24 '14 at 12:13