May 11, 2010

center div cssAt some point, you may have a situation where you want to center multiple elements (maybe elements, or other block elements) on a single line in a fixed-width area. Centering a single element in a fixed area is easy. Just add margin: auto and a fixed width to the element you want to center, and the margins will force the element to center.

There really should be a similar simple way to center multiple elements evenly spaced. It would be nice if CSS had a property called “box-align” which you could set to “center” then the child elements would be centered evenly within their parent.

Well, you can achieve something similar by taking advantage of CSS’s flexibity with “recasting” elements (for lack of a better term). View a demo of what I’ll be describing in this short tutorial.

The Usual Way

Normally, in such a situation, you would just float the boxes, then add left and right margins to space them out accordingly. But that can get a little messy, because IE6 doesn’t like margins on floats, and you always have to have a different id or class for elements on which you don’t want margins (like the last and/or the first).

You can get around the IE6 problem by adding display: inline in an IE6-only declaration, but your code will still be somewhat messy because of the extra code to get the first and/or last item to behave. Also, the last box could fall to the next line in IE.

There’s another solution to this that might work better in certain circumstances.

Use inline-block and control white space

To achieve the same effect as adding floats and margins, you can simply “recast” your block-level elements as inline blocks, and then manipulate the white space between them. Here is how the CSS might look:

#parent {
    width: 615px;
    border: solid 1px #aaa;
    text-align: center;
    font-size: 20px;
    letter-spacing: 35px;
    white-space: nowrap;
    line-height: 12px;
    overflow: hidden;
}
.child {
    width: 100px;
    height: 100px;
    border: solid 1px #ccc;
    display: inline-block;
    vertical-align: middle;
}

In my example above, I’m assuming there are four child boxes, each with the class child, and each 100 pixels by 100 pixels. The boxes are naturally block-level elements, but the CSS changes them to <span style="color: #3366ff;"><code>inline-block, which allows them to flow naturally with text and white space. Of course, since we don’t have any text in the parent container, controlling the text and white space will not be a problem.

The parent element (with the id parent in this example) has four key text properties set, and the children have two:

  • text-align makes all inline child elements centered
  • letter-spacing controls the size of each white space unit between boxes
  • white-space: nowrap keeps the last element from potentially dropping to the next line
  • overflow: hidden prevents the box from stretching in IE6
  • vertical-align: middle (on the children) keeps the boxes on the same vertical plane as each other when content is added
  • display: inline-block (obviously)

Internet Explorer Rears its Ugly Head

What would a CSS solution be without an Internet Explorer issue to work around? While this method works exactly the same in every browser (including IE8), IE6 and IE7 don’t cooperate, because they don’t fully support inline-block. To get those browsers to show virtually the same result, you need to add the following CSS:

.child {
    *display: inline;
    *margin: 0 20px 0 20px;
}

The CSS above must apply only to IE6 and IE7, and it has to appear after the other CSS. In my code (and in the code example above) I’ve accomplished this by using the star hack. The asterisk (or star) at the beginning of each line hides both lines from every browser except IE6 and IE7. The margins added here help us get the same visual result, and the new display property is taking advantage of a bug in those browsers that makes a block element work like its inline when you declare <code>display: <span style="color: #3366ff;">inline-block</span> followed by display: inline.

Drawbacks / Final Thoughts

Not many drawbacks to this. You just have to make sure the white space and text settings that you apply are reset on any child elements inside the boxes. So, while this may work when you have straight images or other non-text content, it may be more trouble than its worth if your boxes are fully loaded with diverse content.

But nonetheless a good technique to know when you have to center some block elements with equal spacing, and you don’t want to apply extra classes on the end units. And this technique will be even more important when the older versions of IE disappear from general use. But I’m not holding my breath.

Comments

  • There are no comments, be first to comment! Please note that older comments are archived automatically.