Skip to content Skip to sidebar Skip to footer

Vertically Rotate Text Inside An HTML Table Header Cell

I am using the following css to rotate the text inside table header cells but the header cells is of the same width as if the text were horizontal.How can I just rotate the text an

Solution 1:

If you need to adjust just the width of the cells and they contain only one line of text each you can do this: http://jsfiddle.net/sSP8W/3/ — set width of an element to it's line-height.

The problem with CSS3-transforms is that they work like as CSS' position: relative: their original box stays the same, so rotating, skewing etc. don't cause the changes in the element's dimensions. So: there is really no perfect CSS solution, you can use JS to adjust the dimensions, or try to find hackety workarounds. So if you have only links in a table, you can do something like that: http://jsfiddle.net/sSP8W/4/ — rotating the table itself.

If your case have another content that you don't want to rotate — update the post, so we could try to find a better solution.

upd: Just found out a solution to the rotated text in tables: using some magic with vertical paddings we could make cells stretch to the content, so look at this almost final example: http://dabblet.com/gist/4072362


Solution 2:

I solved it this using a jQuery plugin by David Votrubec and the comment by Mike below the blog post.

Put this in a .js-file:

(function ($) {
  $.fn.rotateTableCellContent = function (options) {
  /*
Version 1.0
7/2011
Written by David Votrubec (davidjs.com) and
Michal Tehnik (@Mictech) for ST-Software.com
*/

var cssClass = ((options) ? options.className : false) || "vertical";

var cellsToRotate = $('.' + cssClass, this);

var betterCells = [];
cellsToRotate.each(function () {
var cell = $(this)
, newText = cell.text()
, height = cell.height()
, width = cell.width()
, newDiv = $('<div>', { height: width, width: height })
, newInnerDiv = $('<div>', { text: newText, 'class': 'rotated' });

newInnerDiv.css('-webkit-transform-origin', (width / 2) + 'px ' + (width / 2) + 'px');
newInnerDiv.css('-moz-transform-origin', (width / 2) + 'px ' + (width / 2) + 'px');
newDiv.append(newInnerDiv);

betterCells.push(newDiv);
});

cellsToRotate.each(function (i) {
$(this).html(betterCells[i]);
});
};
})(jQuery);

And this at the top of your page:

<script src="rotatetablecellcontent.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function(){
        $('.yourtableclass').rotateTableCellContent();
    });
</script>

And this in your CSS:

/* Styles for rotateTableCellContent plugin*/
table div.rotated {
    -webkit-transform: rotate(270deg);
    -moz-transform: rotate(270deg);
    writing-mode:tb-rl;
    white-space: nowrap;
}

thead th {
    vertical-align: top;
}

table .vertical {
    white-space: nowrap;
}

Then make sure your table has the class "yourtableclass", and that all the TDs you want rotated have the class "vertical".

Here's a demo running in a jsFiddle.

Hope it helps someone, even though I'm a year late!


Solution 3:

In IE and Chrome (Blink and Webkit), you can put the text in a child with a vertical writing mode rather than using a transform. Saves you all the CSS and JavaScript tricks. Chrome has a minor display bug at the moment (Chrome 37), but it's been reported.

.vertical { 
    -webkit-writing-mode:vertical-rl; 
    -ms-writing-mode:tb-rl; 
    writing-mode:vertical-rl; 
 }

 <td><span class="vertical">This text should be vertical.</span></td>

I recommend using white-space:nowrap on the vertical text within the table.


Solution 4:

The solution by jobjorn above now breaks in Chrome, because it supports writing-mode as of early 2016, so essentially tries to rotate the text twice, and ends up with mispositioned horizontal text. From my understanding, Firefox and Safari will probably support this soon too, which will cause them to break too. After some banging my head against the wall, I fixed it by changing the CSS to:

@supports not (writing-mode:vertical-rl) {
    table div.rotated {
        -webkit-transform: rotate(270deg);
        -moz-transform: rotate(270deg);
        white-space: nowrap;
    }
}

@supports (writing-mode:vertical-rl) {
    table div.rotated {
        writing-mode:vertical-rl;
        -webkit-transform: rotate(180deg) translate(8px,0px);
        -moz-transform: rotate(180deg) translate(8px,0px);
        white-space: nowrap;
    }
}

The 8 pixel translation was what it took for the alignment to look right in my particular example. You mileage may vary. The 180 degree rotation was to make the top of the text face left instead of right. If you don't need that, you can probably skip the transforms in the second part.

In the JavaScript, you also need to make sure that you don't move the origin for those last transforms, as that was only needed if you were using a transform to do the vertical orientation itself, so I wrapped that part in a conditional:

var supportsWM = CSS.supports('writing-mode', 'vertical-rl');
if (!supportsWM) {
    newInnerDiv.css('-webkit-transform-origin', (width / 2) + 'px ' + (width / 2) + 'px');
    newInnerDiv.css('-moz-transform-origin', (width / 2) + 'px ' + (width / 2) + 'px');
}

Solution 5:

Mods: sorry that this post "responds to an answer". But I don't have the karma necessary to comment on it. Catch-22.

The code in @jobjorn's answer and fiddl depends on cell width to calculate header height, which leads to erroneous heights when any cell is wide. This modified fiddle uses the header text width instead: http://jsfiddle.net/marvmartian/76z82/

    cellsToRotate.each(function () {
        var cell = $(this);
        var s = '<div id="killme" style="position:absolute; top:-10000px; left:-10000px;"><span id="string_span" style="font-weight: bold; font-size: 1em">'+
            cell.text()+'</span></div>';
        $(window).append(s);
        var width = $('#string_span').width();
        var newText = cell.text()
            , height = cell.height()
            //, width = cell.width()
            , newDiv = $('<div>', {  height: width,  width: height })
            , newInnerDiv = $('<div>', { text: newText, 'class': 'rotated' });

Post a Comment for "Vertically Rotate Text Inside An HTML Table Header Cell"