Archive for September, 2010

HTML vertical text (Safari, Firefox, Chrome, and Opera)

I recently had a requirement to display a large amount of tabular data in a small space – and to get it looking right, some of the text simply had to be vertical. My first solution was to use javascript on page load to replace the text with svg code, which essentially drew an svg image of the vertical text in place. While this looked fine, it resulted in quite a bit of client-side code running at page load, which resulted in a noticeable delay when the page got large.
My second solution was considerably neater however: css transforms.

HTML Vertical Text example

- – Before – -
- – After – -

Examples above. The first block is an image (screenshot of this in Safari), the second block is the real thing. If your browser supports this, the two should look broadly similar. The CSS for this is as follows:

.vText {
   -moz-transform: rotate(-90deg) translate(0, 100%);
   -moz-transform-origin: 0% 100%;
   -o-transform: rotate(-90deg) translate(0, 100%);
   -o-transform-origin: 0% 100%;
   -webkit-transform: rotate(-90deg) translate(0, 100%);
   -webkit-transform-origin: 0% 100%;
   transform: rotate(-90deg) translate(0, 100%);
   transform-origin: 0% 100%;

The first two lines (the -moz lines) are for current versions of firefox, the next two (the -o lines) are for recent versions of opera, the next two (the -webkit lines) are for Safari & Chrome, and the last two are for the future (assuming this gets beyond a working draft).

And no, this CSS doesn’t work with IE at present.

So how does it work?

  • transform-origin sets the, wait for it, origin, at the bottom-left corner. This will be the centre of the rotation when we rotate.
  • translate(0, 100%) moves the block vertically down by its own height (i.e. y = 100%), so that its top border is where its bottom border was.
  • rotate(-90deg) rotates the text 90° counter-clockwise.

The big caveat here is that the transforms do not change the original element dimensions (e.g. if it’s 100px wide before the transform, it will still take up 100px width after the transform), so you will generally need to put your vText element in a containing block which has the required width and height (i.e. after the transform) set.

, , , ,