Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I *really* justify a horizontal menu in HTML+CSS?

Tags:

html

css

You find plenty of tutorials on menu bars in HTML, but for this specific (though IMHO generic) case, I haven't found any decent solution:

#  THE MENU ITEMS    SHOULD BE    JUSTIFIED     JUST AS    PLAIN TEXT     WOULD BE  # #  ^                                                                             ^  # 
  • There's an varying number of text-only menu items and the page layout is fluid.
  • The first menu item should be left-aligned, the last menu item should be right-aligned.
  • The remaining items should be spread optimally on the menu bar.
  • The number is varying,so there's no chance to pre-calculate the optimal widths.

Note that a TABLE won't work here as well:

  • If you center all TDs, the first and the last item aren’t aligned correctly.
  • If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.

Isn’t it strange that there is no obvious way to implement this in a clean way by using HTML and CSS?

like image 722
flight Avatar asked Sep 08 '08 11:09

flight


People also ask

How do I align a menu horizontally in CSS?

If you want to make this navigational unordered list horizontal, you have basically two options: Make the list items inline instead of the default block. .li { display: inline; } This will not force breaks after the list items and they will line up horizontally as far as they are able.

How do I make a horizontal menu in HTML?

Set the list items to display as blocks, give them a width, and float them to the left so that they'll each display to the right of the preceding item. Change the a elements to block elements. We'll also add some formatting styles and remove the underline with text-decoration: none .

What is justified alignment in HTML?

HTML | <p> align Attribute It is a default value. right: It sets the text right-align. center: It sets the text center-align. justify: It stretch the text of paragraph to set the width of all lines equal.


2 Answers

The simplest thing to do is to is to force the line to break by inserting an element at the end of the line that will occupy more than the left available space and then hiding it. I've accomplished this quite easily with a simple span element like so:

#menu {    text-align: justify;  }    #menu * {    display: inline;  }    #menu li {    display: inline-block;  }    #menu span {    display: inline-block;    position: relative;    width: 100%;    height: 0;  }
<div id="menu">    <ul>      <li><a href="#">Menu item 1</a></li>      <li><a href="#">Menu item 3</a></li>      <li><a href="#">Menu item 2</a></li>    </ul>    <span></span>  </div>

All the junk inside the #menu span selector is (as far as I've found) required to please most browsers. It should force the width of the span element to 100%, which should cause a line break since it is considered an inline element due to the display: inline-block rule. inline-block also makes the span possible to block-level style rules like width which causes the element to not fit in line with the menu and thus the menu to line-break.

You of course need to adjust the width of the span to your use case and design, but I hope you get the general idea and can adapt it.

like image 51
Asbjørn Ulsberg Avatar answered Sep 21 '22 21:09

Asbjørn Ulsberg


Modern Approach - Flexboxes!

Now that CSS3 flexboxes have better browser support, some of us can finally start using them. Just add additional vendor prefixes for more browser coverage.

In this instance, you would just set the parent element's display to flex and then change the justify-content property to either space-between or space-around in order to add space between or around the children flexbox items.

Using justify-content: space-between - (example here):

ul {      list-style: none;      padding: 0;      margin: 0;  }  .menu {      display: flex;      justify-content: space-between;  }
<ul class="menu">      <li>Item One</li>      <li>Item Two</li>      <li>Item Three Longer</li>      <li>Item Four</li>  </ul>

Using justify-content: space-around - (example here):

ul {      list-style: none;      padding: 0;      margin: 0;  }  .menu {      display: flex;      justify-content: space-around;  }
<ul class="menu">      <li>Item One</li>      <li>Item Two</li>      <li>Item Three Longer</li>      <li>Item Four</li>  </ul>
like image 34
Josh Crozier Avatar answered Sep 21 '22 21:09

Josh Crozier