There are plenty of techniques for reordering content horizontally in CSS (by reordering content I mean visually laying out content in an order different than the one in the source code). Usually those rely on a combination of clever floats and negative margins. YAML has a few examples.
A different objective would be to reorder content vertically, though. This could be particularly interesting for responsive design, where you would want to present content in a different order at different breakpoints, or maybe for a print stylesheet. After a bit of research I came across an interesting technique that relies on the fact that most browsers tend to render <caption>
<thead>
table elements above the table contents, even if the <caption>
<thead>
itself is at the bottom of the table in the markup. Of course, you don’t need real <table>
and <caption>
<thead>
elements; instead making use of CSS’s table-caption
table-row-header
value for the display
property.
Update: I got it a bit wrong; the technique used by Marat on his blog used display: table-header-group
, not table-caption
. Marat did some research into the problems of using table-caption
; I was unfortunate to find a few other when using table-header-group
.
I was not quite satisfied with the solution above — although it saved my backside a couple of times. It didn’t work in IE, and it revealed a few browser bugs on Chrome (I guess display: table-row-header
is not the most well tested CSS feature). So, a bit more experimenting and I struck at this idea:
So, we simply rotate a container 180° (upside down) and then rotate each child in-place another 180°. Magic! Seems to work wonders in Firefox, Safari, Chrome… and IE9.
Of course, IE versions less than 9 don’t understand the CSS transform
property, but there’s still something we can do if we need to support those browsers (which, remember, we might not have to do if we are using this technique to target responsive design). Yes, we have to rely on the icky filter
property… specifically, the “matrix” filter: it allows for rotation, scaling and skewing. We just need rotation. Unfortunately, it’s been a long time since I did anything to do with matrices. Fortunately, someone else has made it easy — as easy as copy and paste. We also need to be a bit careful with preventing overlap of the filter
property with transform
in IE9 (since it supports both), so we use IE’s conditional comments to keep the CSS clean. Here we go:
The filter
solution should play well with IE6-8, but filter
is notoriously buggy. In my quick testing I found at least two issues that might be deal breakers for you:
<input>
fields within the rotated sections don’t display the input caret correctly (the field works as normal but the blinking cursor renders in the original position — go figure)- rotated sections must have a background or they render as black squares, or with badly aliased text
A few more words of warning about this technique in general:
- your markup must make semantic sense regardless of how it is presented (this might actually help towards that, if used correctly)
- remember keyboard navigation: you might need to re-assign
tabindex
attributes for it to make sense to tab between links/fields - this is not a tried-and-tested method; expect “issues”!
> I came across an interesting technique that relies on the fact that most
> browsers tend to render table elements above the table contents,
> even if the itself is at the bottom of the table in the markup.
> Of course, you don’t need real and elements; instead
> making use of CSS’s table-caption value for the display property.
The interesting technique does _not_ use `table-caption` exactly because latter is buggy. Instead, `table-row-group`, `table-header-group`, and `table-footer-group` are used.
Transforms and filters are probably much slower than tably layout.
You are right; it had been a while since I read your post. I still ran into problems using your solution in Chrome (it will sometimes fully hide the swapped “top” element in complex layouts with floats), so this one was definitely helpful too.
Not sure about this being “much slower” to be honest. It seems to be a form of “post-processing” by the browser, which won’t affect the flow of the page.
Pingback: CSS - Elitist