Horizontal alignment, HTML, CSS, standards, your browser – and you.

It happens alot, when designing Web interfaces, that you’ll want things… aligned (horizontally).

I’m a show you how I do it…

You’ll often see things…

aligned to the left,
centered or
aligned to the right.

Cascading Stylesheets (styles, for short) will do this easily using the text-align property.

text-align works wonders for inline elements (opposed to block elements, such as div and table).

In the following example, there’s a 100 pixels-wide div block (in green) that’s inside a 300 pixels-wide div
block (in red). The red block tries to center the green block using text-align:center.

Block!

Here’s where the funky shit starts to hit the stainless fan.

If you’re presently using Internet Explorer, you’re seeing what you’d expect to see (using common sense):

  • The text-align command has propagated to its children (what’s inside the green div is also centered because its
    parent is centered.
  • The green block is centered

If you’re presently using Firefox, you’re seeing what you’d expect to see (providing you’re aware of how the standard works):

  • The text-align command has propagated to its children (what’s inside the green div is also centered because its
    parent is centered.
  • The green block sticks to the left. Because it’s a block and not an inline element
    (such as span or the anchor (a) tag.

And thus is born the frustration that comes with cross-browser development. I’m not for or against how
Internet Explorer’s or Firefox’s implementation. This post is not about that.

Implementing standards according to common sense – the behavior a newcommer to the world of style sheet would expect
is great. It eases development. And it promotes enhancements to the standards.

On the other hand, it prevents people from realizing they’re working against the standard and really messes
their shit up if they don’t make themselves aware to other browser’s behavior.

Sticking to standards greatly eases cross-browser development. It makes the browser a good starting platform for developing.
It behaves in an harmonious ways with other browsers that also stick to standards (especially if you live
anywhere near Utopia.)

On the other hand, not going further that the standard prevents you from transcending standards – from making it evolve
in a truly organic way.

I ‘ll save the philosophical debate about this for a later article – let’s get back to the point of horizontal alignment.
(Oh and the above, centered block of text is done using the technique I’m about to describe…)

Is there a cross-browser, standard way of doing this alignment thingie?

Yes, there sure is.

The first thing that might come to mind is to turn the child div block into an inline element
(using display:inline;.

You most likely don’t want to be doing this. Turning a div into inline effectively turns in into a span.
And if it’s a span you want, then you should use a span – and not have this whole alignment problem.

There’s another workaround. And it involves margins.

The real, actual, profound, technical reason the div won’t center is because its margins won’t allow it to.
You’ve got to reach into these margins (the left and right ones) and teach’em the way!.

That magic is done by telling the left and right margins to use their auto setting.

Block!

See? Now the inside block is centered. Its left margin pushed it the right way for it to be centered!
And you get the same results for both browsers!

But there’s a drawback. You’d kind of expect it to align right if you switch the red block’s text-align
from center to right. Wrong.

Wrong. Wrong. Wrong.

Unless you’re using Internet Explorer.

Who implements using common sense.

Using Firefox, your green box remains centered but it’s content’s alignment changes.

If you would’ve wanted a surefire cross-browser way to align right, you’d use another variation of this technique,
which I’ll dub the “weird-ass technique”.

Block!

Voilà: cross-browser right-alignment. How did I do it?

The technique I used tells the outer block (the red one), to use text-align:right. Makes Internet Explorer happy.

Then, the inner block (the green one) as margin-left:auto. Notice something? No margin-right!.
That uses the standard telling the block : “Hey yo, biatch. Have a big margin on ya left. No stinkin’ margin on the right
to cramp your style and force you to be centerd”.


The bottom line

Standards want you to use margins to center blocks. If you don’t know the proper placement (or, like me, feel you shouldn’t have to
describe your design in terms of pixels), you can have the margin duke it out by setting’em both to auto, which’ll center
them – or set only the left one to align to the right. Setting a margin only to the right is the same thing as having no margin.

Internet Explorer, on the other hand, implemented a much more intuitive method. Which uses the same text-align tags you
were used of. Only it centers something else than text.

If you want to be pissed at Internet Explorer’s implementation, please be pissed because the margin implementation is non-standard.
If you’re pissed because they augmented text-align’s reach (which I believe is a very cool addition), then you and I don’t agree
on how standards actually progresses: on the field.

Update

Following Patrice Lévesque‘s comments, here’s an update on the subject of standards and text-align.

1 – The main reason to be pissed at Internet Explorer, regarding horizontal alignment of blocks remains the fact that Internet Explorer does not follow the margin standards. This sucks to no end and will remain sucking until it’s fixed and two or three generations of browsers come to pass.

2 – The “augmentation” to the text-align standard from Internet Explorer can be very annoying. After all, text-align is expected to work only on… text. However, I do maintain that this is a great big deal more intuitive than the margins. It took me quite some time, back in the days, figuring out why it didn’t work on other browsers.

It can be argued, with pretty strong, valid and good arguments, that it’s not an “augmentation” of the standard, but it’s rather “breaking” the standard. Which brings forth the question: is the boost in intuitivity (is that even a word?) worth the breaking of the standard.

Once you learned that “text-align” applies to text (or inline elements) and that block elements are not text, the text-align standard makes a lot of sense. I would’ve liked to see an extra property such as “block-align:right” (and I’ll get to that on later articles). But the standard went the way of the margin – which also makes some kind of sense. Just not the intuitive kind of sense.

If centering would’ve been achived by setting “margins-horizontal:center” or something like that, intuition would’ve played a great role in understanding. “margin-left:auto;margin-right:auto;” feels more like a trick you’ve got to learn. No clues about what this’ll do. I would never have figured that out without finding articles on “how to center blocks” that came up on google.

But now, I’m at criticising the standards, which I’ll keep for later subjects.

Let it just be said that I place great value on intuitive standards.

11 thoughts on “Horizontal alignment, HTML, CSS, standards, your browser – and you.

  1. In the last sample the green box is indeed to the right, but "Block!" is also right-aligned inside the green box! Is this intended? I’m using firefox 😀 But it’s the same in IE

  2. I’m pissed because they augmented text-align’s reach!

    There is absolutely no need for this "extension" as margin already does what we want, text-align on a block introduces confusion { margin: 0 auto; text-align: left; /* where is my block? */ }, and anyway margin is more flexible (20% to the left? no problem sir).

    text-align to position a block only confuses developers. Every freakin’ CSS coder must go through the mental hoops just like you did. Those who don’t are confused because their layouts don’t work on every browser. What an absolute waste of time.

    I have an other case in the same vein. { text-decoration: underline; } on a block. It could draw a border on the bottom side of a block. It would be weird because border-{width,style,color} already do that and are more flexible, eh?

    You get my drift. I have nothing against extensions that don’t share the official namespace (MSIE introduced the "filter:alpha(opacity=N)" CSS property, fine with me). But reinventing an offical spec just gives headaches and doubles the work that has to be done.

  3. In the last sample the green box is indeed to the right, but “Block!” is also right-aligned inside the green box! Is this intended? I’m using firefox 😀 But it’s the same in IE

    Yes, this behavior is standard – the outer block has “right-align” set on it and it propagates to all children. If I had wanted the inner block’s content to be left-aligned, I would’ve have to add a text-align:left to its style.

  4. Patrice Levesque said :

    I’m pissed because they augmented text-align’s reach!

    There is absolutely no need for this “extension” as margin already does what we want, text-align on a block introduces confusion { margin: 0 auto; text-align: left; /* where is my block? */ }, and anyway margin is more flexible (20% to the left? no problem sir)

    […]

    You get my drift. I have nothing against extensions that don’t share the official namespace (MSIE introduced the “filter:alpha(opacity=N)” CSS property, fine with me). But reinventing an offical spec just gives headaches and doubles the work that has to be done.

    Good points there. I think I’ll update my article with some of these ideas.

    One thing, though, I somewhat disagree with:

    text-align to position a block only confuses developers. Every freakin’ CSS coder must go through the mental hoops just like you did. Those who don’t are confused because their layouts don’t work on every browser. What an absolute waste of time.

    It’s the actual standard that had made me loose all this time. The intuitive way goes the way of using the text-align. I had to do quit a bit of research and digging to learn (and especially understand) the margin trick. My mental hoops were caused by the standard – not by the discutable “extension” made by IE.

    (Though it could be argued that if IE did not put up this addition, I would’ve figured out sooner that it’s just not how it works 😛 )

  5. Nevermind what I said – I thought it was couter-intuitive to what you were saying, but it actually goes with the text with propagation and all that 😉

    Note to self: keep comments for _after_ the first shot of caffeine and/or sugar of the day.

  6. The block center technique can also be achieved with {margin:auto;}, instead of {margin-left:auto;margin-right:auto;}.

  7. If you want to align the green block to the right, you can use float:right . I tought about it 2 hours before realize…

  8. You are right – float will work…

    But not with the same result: using float, the inner “div” is no longer considered when calculating the height of the parent div.

    See for yourself:

    Block!

    Float can sometimes be used in this way, but its most common use is to place a picture on the side of some text and have the text wrap around.
    Otherwise, if you are using “float” and really need the parent div to resize to the inner content, you’ll have to set it a min-height matching the height of the inner div – which will work on some browsers but not others.

    Depending on the situation, I will use the margin trick described above, the float trick you suggested or will just revert to the “evil” tables.

Comments are closed.