Reputation: 12619
I am trying to achieve a table which has text rotated -90degrees. Up until now I have been using images of the text, however I was hoping to change this over to text.
There are a few problems I cannot seem to fix.
Here is a jsFiddle of it in action
http://jsfiddle.net/CoryMathews/ZWBHS/
I need it to work and have gotten it to the same point in IE7+, Chrome, FF, and Opera.
Any ideas on how to improve this method making it actually usable? Some of my ideas are:
I could calculate the widths, height, etc with some javascript on page load, this would solve problems 2 and 3 above but not 1. However I hate to rely on javascript for display.
Perhaps I am misusing the transform-origin that would give me better control. The number I am currently using "0 0" allows me to easily calculate the needed sizes.
Upvotes: 8
Views: 3835
Reputation: 7122
This solution fixes some of your problems, but it's not perfect:
whitespace: nowrap
to disable text flowing to the next line.width: 1em
. Columns are always wide enough for 1 line of vertical text. You can freely adjust the font size.Manually set the height of the table to fully display the rotated content (by -90 degrees). Hard-coding heights is not great, but there are advantages: no need for fixed widths and negative margins to counter the fixed widths / transform origins / relative positioning / JavaScript; text automatically snaps to bottom of column.
See 2.
This works in Firefox, Chrome, Opera, IE9+. Vertical text does not work on IE8 and earlier. I tried rotating the table using:
filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3)
and the result looks horrible, so I added fallback style to display a simple horizontal table.
body {
font-family: sans-serif;
padding: 10px;
font-size: 12px;
}
td, tr, th, table { border: 1px solid #333; }
td:nth-child(odd) { background: #eee; }
td {
overflow: hidden;
white-space: nowrap; /* text on one line only */
vertical-align: bottom;
height: 300px; /* to be adjusted: column is not always tall enough for text */
}
td > div {
padding: 10px;
width: 1em; /* column is always wide enough for text */
}
td > div > div {
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-ms-transform: rotate(-90deg) !important;
transform: rotate(-90deg);
}
<!--[if LT IE 9]>
<style>
table { width: 100px; }
td {
white-space: normal;
vertical-align: baseline;
height: auto;
}
td > div {
width: auto;
}
</style>
<![endif]-->
<table>
<tr>
<th>01</th>
<th>02</th>
<th>03</th>
<th>04</th>
<th>05</th>
<th>06</th>
<th>07</th>
<th>08</th>
<th>09</th>
<th>10</th>
<th>11</th>
<th>12</th>
</tr>
<tr>
<td><div><div>Report Results 1</div></div></td>
<td><div><div>Shinanigans</div></div></td>
<td><div><div>CSS Transforms Suck</div></div></td>
<td><div><div>Lorem Ipsum</div></div></td>
<td><div><div>So Damn Pixelated</div></div></td>
<td><div><div>This font looks Terrible</div></div></td>
<td><div><div>Too Long to read on 1 line Set dimensions suck</div></div></td>
<td><div><div>Grumble Grumble.</div></div></td>
<td><div><div>Homebrew!</div></div></td>
<td><div><div>Spotify Commercial Suck</div></div></td>
<td><div><div>Grooveshark FTW!</div></div></td>
<td><div><div>Beer time yet?</div></div></td>
</tr>
</table>
Upvotes: 6
Reputation: 24988
First let's fix overlapping text: td{white-space:nowrap;}
CSS transformations are somewhat similar to "position:relative" in one aspect, they modify the rendering of an object rather than its position in the flow. This means there is currently no way to dynamically adjust the cell height based on the div width (at least until css expressions start being implemented).
With that finding in mind, we now are free to take the div out of flow all we want. I'm gonna go and set it absolutely to top left corner of the parent cell. Being a trained professional, I'm allowed to do this: td{position:relative;} td>div{position:absolute;top:0;left:0;}
Well look at this, now the entire content of the cell has been shifted way up. We can't just adjust the position of the block as it will affect the way it's transformed; instead we'll adjust block displacement: margin:100% 0 -100%;
We've taken the element out of the flow above (and for a good reason, too), now we'll just apply a height to the parent cell and we're good to go:
Update:
You could always add text-overflow property and fix the text&cell size so that it requires minimum work updating like http://jsfiddle.net/ZWBHS/3/
So that truncated text is not lost, maybe throw in a title attribute duplicating it?
Upvotes: 1
Reputation: 11
as Duopixel , (unrotate)
<style>
body { font-family: "Times New Roman", Times, serif; padding:10px; }
td, tr, th, table { border:1px solid #333; }
td:nth-child(odd) { background:#eee; } /* No IE, No Cares */
td.title { width:200px; }
table {
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-ms-transform: rotate(-90deg) !important;
transform: rotate(-90deg);
-webkit-transform-origin:0 0;
-moz-transform-origin:0 0;
-ms-transform-origin:0 0;
-o-transform-origin:0 0;
transform-origin:0 0;
background-color:transparent;
width:250px;
position:relative;
top:250px;
}
td > div {
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg) !important;
transform: rotate(90deg);
-webkit-transform-origin:0 0;
-moz-transform-origin:0 0;
-ms-transform-origin:0 0;
-o-transform-origin:0 0;
transform-origin:0 0;
background-color:transparent;
position:relative; /*Needed to position in the correct columns*/
height:20px; /* Need to not set this, needed for columns to fill*/
left:20px; /*Needed to line up, .5 of width - padding*/
}
</style>
<!--[if LT IE 9]>
<style>
table {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
top:0px;
}
td div { /* ah..? didn't action of filter..? by td > div..? */
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
overflow:hidden;
width:20px; /* fix to number.. */
height:20px; /* fix to number.. */
}
</style>
<![endif]-->
<table>
<tr>
<td class=title >Report Results 1</td>
<td><div>01</div></td>
</tr>
<tr>
<td class=title >Shinanigans</td>
<td><div>02</div></td>
</tr>
<tr>
<td class=title >CSS Transforms Suck</td>
<td><div>03</div></td>
</tr>
<tr>
<td class=title >Lorem Ipsum</td>
<td><div>04</div></td>
</tr>
<tr>
<td class=title >So Damn Pixelated</td>
<td><div>05</div></td>
</tr>
<tr>
<td class=title >This font looks Terrible</td>
<td><div>06</div></td>
</tr>
<tr>
<td class=title >Too Long to read on 1 line Set dimensions suck</td>
<td><div>07</div></td>
</tr>
<tr>
<td class=title >Grumble Grumble.</td>
<td><div>08</div></td>
</tr>
<tr>
<td class=title >Homebrew!</td>
<td><div>09</div></td>
</tr>
<tr>
<td class=title >Spotify Commercial Suck</td>
<td><div>10</div></td>
</tr>
<tr>
<td class=title >Grooveshark FTW!</td>
<td><div>11</div></td>
</tr>
<tr>
<td class=title >Beer time yet?</td>
<td><div>12</div></td>
</tr>
</table>
Upvotes: 1
Reputation: 72385
Applying transformations on tables makes all browsers go bonkers. I've encountered the multiline problem too and the only workaround I found was to change the table markup so that it's not the div that is rotated, it's the entire table.
You then "unrotate" your table headers with the reverse transformation:
I have no idea if this works with IE7-8 filters.
Upvotes: 3