This is an archive site. For the recent posts, visit

Ordered List


Dec 2 2005

Semantics and Design

The other day while working on a Notre Dame site, our group came up against an interesting CSS dilemma. The design called for a fixed-height box with editable text inside that centered both horizontally and vertically. Seems simple, right?

Option 1: Semantic Markup

  <h3>Centered Title Text</h3>

Ok, on to the XHTML. We’ve got a div with an h3 inside. Good. Now to the CSS. This is where things get a little unclear. Horizontal centering is easy enough with a text-align:center; on the enclosing div. But how can we vertically align something when we don’t know the height? The obvious answer to this would be to add vertical-align:middle; to the h3 element. Here’s what the W3C has to say about what this declaration should mean.

The element [with vertical-align:middle] is placed in the middle of the parent element.

Ok, so we try that… no dice. Almost no browser renders properly. So what are some other options?

We could use line-height on the h3 to match the height of the parent box. That would stick the text in the middle. But what if the text wraps? Well, then you’ve got one ugly situation there, as the wrapped line of text would be underneath the parent div, if it showed up at all.

So what about top and bottom padding on the enclosing div? Same situation, only a little better if the text wraps. The text would be readable, but not centered, as the top padding wouldn’t change, so our text would be a little south of center. Probably the best solution of any using this structure. But still not perfect.

If only there was an element who’s default nature in every browser was to vertically-align all enclosed elements to the middle. The only one I can think of is [GASP] the table (or more appropriately the td). Which leads us to…

Option 2: Not-so-semantic Markup

&lt;table&gt;<br /> &nbsp;&nbsp;&lt;tr&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;h3&gt;Centered Title Text&lt;/h3&gt;&lt;/td&gt;<br /> &nbsp;&nbsp;&lt;/tr&gt;<br /> &lt;/table&gt;

Yes, I know, even typing this I’m getting a little nauseated. But with only a few little CSS declarations, we have a cross-browser solution matching exactly what the design is calling for. Sure it’s a little ugly. But it solves the problem, doesn’t it.

Deciding on the lesser of two…

In option 1, semantics took the lead, while design had to give. In option 2, just the opposite. In one sense, why should designers have to bend just to make up for browser inconstancies? On the other hand, why should proper code give way because of the same? It’s hard for me to pick a solution here. In fact, I’m not going to tell you what we picked. What would you choose? I’d like to hear what you think.