Create a centred horizontal navigation

Centring block level elements is easy, just define a width and set margin:0 auto;, but what if you don’t know that fixed width? You could use text-align:center;, but that won’t work on 100%-width block-level elements either… that’ll only work on text-level elements.

Defining explicit widths and heights should always be avoided wherever possible, as doing so will make the document a lot less future-proof, flexible and extensible… Suppose you have four items in your navigation menu—you can work out the width of these and use margin:0 auto; to centre them. Adding a fifth will increase the width, meaning you’d need to alter the CSS, too. This is far from ideal, and more so with a CMS to power the site (a client can add pages, but perhaps can’t edit CSS).

However, there is a way to have a centred horizontal navigation without knowing an explicit width, and without adding CSS. It’s also remarkably easy.

The markup:

<ul id="nav">
  <li><a href="/">Home</a></li>
  <li><a href="/about/">About</a></li>
  <li><a href="/work/">Work</a></li>
  <li><a href="/clients/">Clients</a></li>
  <li><a href="/contact/">Contact</a></li>
</ul>

Pretty standard, an unordered list of menu items. The CSS is where it’s at. I have highlighted the bits that do the majority of the work:

#nav{
  border:1px solid #ccc;
  border-width:1px 0;
  list-style:none;
  margin:0;
  padding:0;
  text-align:center;
}
#nav li{
  display:inline;
}
#nav a{
  display:inline-block;
  padding:10px;
}

What I’ve done here is simply create a navigation list and given it a border top and bottom (purely to highlight its centred text). Instead of floating the block-level <li>s left I’ve given them display:inline;, that is to say they no longer occupy 100% the available width and they now stack up nicely against each other.

Next we use (the much underused) display:inline-block; to make sure the links themselves don’t break onto new lines but still obey any padding values accordingly. Here I have given them a larger hit area by adding padding:10px;

You could have, if you wanted, applied inline-block to the <li>s. however IE6–7 will only allow inline-block to work on elements that are inherently inline elements. display:inline-block; will not work on block-level elements.

Demo

Here’s a quick demo. Try using Firebug or similar to add other list items on the fly, and watch as they seamlessly centre in the list. I have tested this in IE7–8 to find it works perfectly. I haven’t checked IE6 but I imagine it’ll be fine.

Update

You asked and I heard; I have made a CSS powered dropdown version of this for you. The line top:100%; will make the dropdown work in IE7, but kinda ruins the experience a little in all other browsers. Whether you leave it in or not is up to you. Again, view source for the how-to…

By Harry Roberts on Saturday, January 29th, 2011 in Web Development. Tags: | 29 Comments »

+

29 Responses to ‘Create a centred horizontal navigation’


  1. bruno said on 29 January, 2011 at 7:11 pm

    just checked IE6…it works like a charm


  2. Brooke said on 29 January, 2011 at 10:55 pm

    Ooh I love you for this. I’m definitely going to give this technique a go on the next project that requires this. Thanks for sharing!


  3. M2 said on 30 January, 2011 at 4:29 pm

    Haha =) Thank you very much! I don’t know why, but i thought that inline-block is not working in IE6 at all, you discovered a very nice feature for me


  4. Gareth said on 30 January, 2011 at 4:41 pm

    Nice.

    I tested the demo page in IE6 (Using IETester) and it worked fine :)


  5. Patrick said on 30 January, 2011 at 6:38 pm

    Many thanks! For “centered ul based navigation” this is the shortest solution I’ve seen so far.


  6. Palash said on 30 January, 2011 at 8:31 pm

    quote: You could have, if you wanted, applied inline-block to the <li>s. however IE6–7 will only allow inline-block to work on elements that are inherently inline elements. display:inline-block; will not work on block-level elements.

    That’s where the genius lies! I tried on many an occasion with applying inline-block to the <li>. Thanks for this! :D


  7. Russell Bishop said on 31 January, 2011 at 10:31 am

    Cool solution, I too thought that the inline-block would fail for IE6.


  8. Scott said on 31 January, 2011 at 2:11 pm

    This seems like an adaptation of this CSS http://www.cssportal.com/horizontal-menus/minitabs.htm (originally posted at now-defunct web-graphics.com) with the addition of the inline-block portion to give it a proper height.

    While IE 6 does not support inline-block, it has the sometimes-useful quirk that containers expand to fit their contents automatically (the same principal behind the min-height hack.) Pretty elegant solution you’ve got here.


  9. Josh said on 31 January, 2011 at 10:06 pm

    Is it possible for this navigation to work with drop-downs ?


  10. Jack Osborne said on 1 February, 2011 at 5:21 pm

    This is very clever, Harry. Nice job.


  11. boom said on 2 February, 2011 at 7:19 am

    We have similar approach on the code but I have hard time implementing the drop down menu. So I turn to jQuery as my solution and I’m still looking for pure css without hacks.


  12. Stephen Young said on 2 February, 2011 at 10:28 am

    I actually did this for my personal website:

    http://www.sydesign.co.uk


  13. Henrique Erzinger said on 2 February, 2011 at 12:09 pm

    “IE6–7 will only allow inline-block to work on elements that are inherently inline elements.”

    This information alone sums all the usefulness of the entire article.


  14. Andre said on 2 February, 2011 at 1:47 pm

    Lovely post, thank you for this!


  15. Dale M said on 2 February, 2011 at 2:43 pm

    Heck. Yes. I did not know that IE6-7 could use inline-block, so I avoided using it. Now I know why people said that… How in the world could this info be so unknown?


  16. hmmm said on 2 February, 2011 at 2:44 pm

    nice solution, but am i really the only one that has a problem with the title vs the solution? title says a “vertically centred” navigation which in my neck of the woods would mean a navigation that sits in the center of the page in regards to its vertical position. iow there would be the same amount of space above & below it. the solution on the other hand is for horizontal centering, where the navigation has the same amount of space on either side (left/right) of it. surely this is the standard meaning of vertical and horizontal centering, or am i totally missing something here?


  17. FlowerMountain said on 2 February, 2011 at 5:16 pm

    This is brilliant, thanks a lot. And very clearly explained too :)


  18. dtownsend said on 2 February, 2011 at 7:18 pm

    I agree with hmmm. I got excited seeing the title, thinking there was a cool technique for vertically aligning elements that I’d missed out on. This technique would fail if the font height for each a element were different, or images were used with different heights.

    That’s not to say this isn’t a useful snippet, but the title needs to be changed imo.


  19. Todd said on 2 February, 2011 at 8:33 pm

    Agree with @dtwonsend and @hmmm. Title of this useful tip should be corrected. It should read:

    Create a Horizontally Centered Horizontal Navigation

    Or perhaps more usefully (and capturing the value of the tip):

    Create Fluid Width Centered Horizontal Navigation


  20. 57 Degrees North said on 2 February, 2011 at 9:07 pm

    Great little bit of css, could come in handy, thanks!


  21. onioneye said on 8 February, 2011 at 2:24 pm

    Brilliant stuff, mate! :)

    I had a problem with centrally positioning the pagination beneath the slider because I didn’t how many pagination links the unordered list is going to contain, so this worked perfectly.

    Thanks :)


  22. Thom said on 17 February, 2011 at 11:21 pm

    Looks great but trying this in IE (8), it’s very, very difficult to actually get to the submenus. They disappear before you can mouse over them.
    In FF no problems.


  23. Mike H said on 24 February, 2011 at 3:03 am

    Great solution. I’ve never used inline-block before, so it’s good to see how it works. Hopefully I retain the knowledge.

    I agree with ‘hmmm’ above…this is horizontally centered navigation. It’s centered on the horizontal axis.


  24. Clodagh said on 25 February, 2011 at 9:26 am

    Thank you so much for this, it is a great clean solution. Setting widths is just not the right way.
    Thanks for sharing your work


  25. Gregg said on 9 June, 2011 at 6:13 pm

    @Thom If you give #nav ul a background IE will allow you to hover over it.


  26. Chris said on 20 July, 2011 at 10:03 am

    For some reason the dropdown menu won’t appear over top of a JPEG in internet explorer. is anyone else having this issue/ can offer help?


  27. Daniel Crean said on 10 August, 2011 at 10:48 am

    Thank you for explaining this tutorial in such a concise manner. Was stuck on how to do a centred nav bar for a while now.


  28. Gorka said on 5 December, 2011 at 2:11 pm

    Excellent tutorial, thank you very much.

    However, I was trying to integrate this with HTML5 Boilerplate and had an issue with the second level ul inside your #nav: some reset css files include ul, ol { top: whatever } declarations that mess up the layout of the second level menu.

    So, your code would be even more bulletproof if you add the following:

    #nav ul { top: auto; }


  29. Richard Dale said on 12 December, 2011 at 12:23 pm

    Thank you very much, found a few solutions and only yours worked properly so I guess they weren’t solutions but you know what I mean.


Leave a Reply

Respond to Create a centred horizontal navigation

Hi there, I am Harry Roberts. I am a 21 year old web developer from the UK. I Tweet and write about web standards, typography, best practices and everything in between. You should browse and search my archives and follow me on Twitter, 7,791 people do.

via Ad Packs