Centering List Items Horizontally (Slightly Trickier Than You Might Think)

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Update April 2013: This article is pretty old. This isn’t very hard. Just give the list centered text (e.g. ul.nav { text-align: center; }) and the list items inline-block (e.g. ul.nav li { display: inline-block; }). If you want to do it with margin for whatever reason, look into width: fit-content;.

The current standard in coding menus is unordered lists. It’s not as semantic as a <nav> tag would be, but it’s not that bad. Navigation is, after all, a list of sorts.

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.
  • Float the list items. Since we very often want our list items to display as blocks so we are able to set fixed widths on them, we are forced to float them to the left or right to line them up horizontally.

Now let’s make a couple common decisions about how we want to display this menu:

  • We want the menu to be centered. Doesn’t matter if the menu is in a fixed or fluid width environment, we just want the menu elements to be centered in the parent element
  • The menu will be a horizontal bar, so we want to make sure that bar looks visually like a bar. We would like to use a repeating background image for this.

Now we are in trouble. The <ul> itself can’t be in charge of the background image, because it will only be as wide as it needs to be to help with centering. So we put it inside of a div at 100% width to to take care of the background image. But now our little centering trick doesn’t work. To be honest I’m not exactly sure why, but applying .ul {margin: 0 auto;} just doesn’t work here. This is where the trick comes in…

Wrap the list inside a table div

If we wrap the menu in a “table” div, we can solve this. If you are familiar with Stu Nicholls from CSSPlay, he uses this all the time on his awesome horizontal menus. Check out the HTML:

<div id="menu-outer">
  <div class="table">
    <ul id="horizontal-list">
      <li><a href="#"><img src="images/list-item-1.gif" alt="list item 1" /></a></li>
      <li><a href="#"><img src="images/list-item-2.gif" alt="list item 2" /></a></li>
      <li><a href="#"><img src="images/list-item-3.gif" alt="list item 3" /></a></li>
      <li><a href="#"><img src="images/list-item-4.gif" alt="list item 4" /></a></li>
    </ul>
  </div>
</div>

Now see the very simple CSS that makes it happen:

#menu-outer {
	height: 84px;
	background: url(images/bar-bg.jpg) repeat-x;
}

.table {
	display: table;   /* Allow the centering to work */
	margin: 0 auto;
}

ul#horizontal-list {
	min-width: 696px;
	list-style: none;
	padding-top: 20px;
	}
	ul#horizontal-list li {
		display: inline;
	}

It’s the table div that get the job done. Some days I think “Whatever works.” should be the slogan for CSS.

View Demo   Download Files