CSS positioning and tables (or, it’s a list whether you like it or not)
Wednesday, May 20th, 2009
Marking up web pages semantically is normally more or less a doddle. Most tags are named (or have abbreviated names) that are straightforward. If you’re writing a paragraph, wrap it in a <p> tag. If you’re writing an ordered list put it in an <ol>… and so on and so forth. And it’s actually less effort than typing eg <div class=”list”>.
But there are nevertheless lots of examples where the tags offered by (x)html seem hopelessly limited in their semantic meaning. Recently I worked on this site. On the home page is a list of holiday offers, and I ummed and aahed over how to mark it up for a while. Previously I would always follow the same practice – lists of complex items would be marked up as a list, and whatever more complicated markup needed would be placed inside the <li> items. But I’ve read somewhere that putting too much information within a list item can actually be a hindrance to accessibility, so this time things would be different.
The design superficially lent itself to a simple nested list:
<ul>
<li><h3>Blue Reef Resort</h3>
<ul>
<li>All inclusive</li>
<li>8, 15 dagen</li>
<li>Marsa Alam</li>
...
</ul>
</li>
</ul>
But it’s hardly satisfactory. The items in the sub-list are in fact properties of the particular holiday offer. In fact, the whole thing is more like a table, which becomes clear if we just move some bits around.
So to achieve the required design all we need is to hide the table header and move some of the cells around. The first task is easily completed with a display:none, but the second is alas not very feasible. While support for floating and positioning table, tr and td elements is supported in ie8 and other good browsers, in ie6 and ie7 there are big problems as they more or less ignore that the <tr> element is there. You can’t float a tr, you can’t give it position:relative (in order to absolutely position td’s within it) but, bizarrely, you can absolutely position a tr, though this is of limited use. Racking my brains for a use the only one I’ve come up with is in order to give you the ability to absolutely position the tr’s td’s absolutely in relation to the tr, but then you would need a different style for each tr to avoid them layering on top of each other. Which admiteddly could be generated dynamically as an inline style, so perhaps not all that hopeless a situation.
ie6 and ie7 also don’t support floating on table cells either, in case you were thinking that was an option.
As it turns out, I may have discovered a new bug in Internet Explorer 8. While writing this I set up a test page to make sure what I thought was the case was correct (turns out I was, in my main thesis, incorrect, as I thought HTML/CSS had no provision for positioning table elements). Here are 3 screenshots:
Once again, ie has problems dealing with relative positioning on tr’s. On the face of it it’s not as bad in ie8 as in ie6/7, but what’s happening is that instead of letting the tr’s confuse the positioning completely, it just ignores them, and goes ahead and positions relative to the next positioned ancestor, which is een worse if you look at where the cells get put relative to where they shoudl be – ie6 and ie7 nearly get it right (but this might be a fluke that a larger table would unmask), but ie8 is completely wrong.
The long and short of this article is that there are lots of instances where a table should be the natural choice of markup (given a little thought about what the content’s structure is), but once again thanks to Internet explorer, it’s going to have to be a nice idea that will have to be shelved for the time being.
So, unless you fancy individually positioning each tr with its own style rule, nested lists it is for now.





