You've probably come across the problem of displaying these kind of tables:
- many columns
- header column at the top
- content cells display narrow data - flags (yes/no, true/false, y/n, on/off, finite states like yes/no/maybe etc.) or just icons that denote some sort of state as in feature list tables where each cell displays either a check-mark or nothing or green and empty cirles or similar...
- header cells contain much wider data than content cells - more words that take much valuable horizontal space
Anyway. So if you did struggle with this and also wanted it to display approximately the same on all three major nowadays browsers than you did spend some time solving it. If you didn't but you think you may in the future, then just use the code I'll provide here and off you go.
Why is it such a problem?
As always the main problem lies in the fact that Internet Explorer has to work completely differently compared to other browsers. Even though developers ranted about this fact for years Microsoft never really managed to completely catch up to specification or competition. It's kind of like the Achilles and the tortoise paradox really but unfortunately in reality they really seem to always stay behind. The same is still true with their latest version 9 (latest as of August 2011). Their CSS3 support is still missing. They should at least implement what competition did, because no browser is perfect. But it's still better to be as good as your competition than worse. Because in the end you'll just be worse.
Why is rotation not enough?
CSS3 defines transform
property which is nicely supported in Mozilla (Firefox) and Webkit (Chrome and Safari) browsers. You can set transform rotation and your element will render rotated as you desire. But that is not just as simple as you may think it is. No. Element's space will still be determined as if it wasn't rotated at all so it will seemingly still take just one line height (or 1em
). If you're rotating more than 1em wide amount of text your rotated element will be rendered above your other content. That's why it's best to contain your rotated element within another container that is sized in the correct (vertical) dimensions. So it will be height as much as you need it to be and wide 1em (or more if you need it to be wider). Visually your rotated element will take just as much space as it needs because it's container sets its dimensions so other content will correctly flow around as per definition.
But there's more problems with Internet Explorer that doesn't work as nicely as other browsers. IE version 9 supports CSS3 transforms all right, but I'm not as lucky with my users so I have to support version 8 as well. Hence I rather provide a solution for IE that works equally well in both versions than a separate solution for each. That's why I have to resort to filters for IE.
Resulting HTML and stylesheet
Let's write a simple example that we can reuse whenever we need to display vertical text in your markup. This is our HTML with two vertical headers and some text before and after:
1: Some text before
2: <div class="container">
3: <div class="head">
4: <div class="vert">Vertical text example</div>
5: </div>
6: <div class="head">
7: <div class="vert">Vertical text example</div>
8: </div>
9: </div>
10: Some text after
CSS settings have to be this way (I've put extensinve comments inside so you will now what to change to suit your needs):
1: .container
2: {
3: /* this will give container dimension, because floated child nodes don't give any */
4: /* if your child nodes are inline-blocked, then you don't have to set it */
5: overflow: auto;
6: }
7: .container .head
8: {
9: /* float your elements or inline-block them to display side by side */
10: float: left;
11: /* these are height and width dimensions of your header */
12: height: 10em;
13: width: 1.5em;
14: /* set to hidden so when there's too much vertical text it will be clipped. */
15: overflow: hidden;
16:
17: /* these are not relevant and are here to better see the elements */
18: background: #eee;
19: margin-right: 1px;
20: }
21: .container .head .vert
22: {
23: /* line height should be equal to header width so text will be middle aligned */
24: line-height: 1.5em;
25: /* setting background may yield better results in IE text clear type rendering */
26: background: #eee;
27: display: block;
28:
29: /* this will prevent it from wrapping too much text */
30: white-space: nowrap;
31: /* so it stays off the edge */
32: padding-left: 3px;
33:
34: /* IE specific rotation code */
35: writing-mode: tb-rl;
36: filter: flipv fliph;
37:
38: /* CSS3 specific totation code */
39: /* translate should have the same negative dimension as head height */
40: transform: rotate(270deg) translate(-10em,0);
41: transform-origin: 0 0;
42: -moz-transform: rotate(270deg) translate(-10em,0);
43: -moz-transform-origin: 0 0;
44: -webkit-transform: rotate(270deg) translate(-10em,0);
45: -webkit-transform-origin: 0 0;
46: }
Example based on upper code
Lets see how it works:
Reuse at your own will and please suggest better alternatives
It took me some time to make this a browser wide solution (that also works in IE8) but here it is. If you need it, just copy the code and do whatever you please with it. If you have any suggestion of how to do the same thing better and easier (and maybe even more browser wide) then please leave a comment so I'll learn new things.
Thanks, this works excellent!
ReplyDeleteThis sol is not working fine in chrome and firefox.In these two browsers it is rotating the text properly but if the text is having only 25 characters but for longer text it is not working .
ReplyDeletePlz let me know if anyone is having this problems sol
You have to of course resize elements to display longer text. This technique doesn't work with arbitrary long strings, but with predefined size only.
DeleteAbove example shows boxes of 9.5em high (container is 0.5em larger). If you'd like to display longer texts, resize accordingly so it fits your text...
Is this the problem you're having or is it something else?
Thank you for your quick response.I got the solution.
ReplyDeleteFor that problem I have added two more lines
top:95px;
position:relative;
Now it is coming fine in other browsers also.
Hello, the solution is elegant :). I have a little question. In IE 8 text is aligned to top of table header (I use it in "th" in a table) and not to bottom.
ReplyDeleteHow can I change vertical align for me?
Many thanks for reply.
I've checked in IE8 display mode and it seem to be aligned to the bottom. Can you please provide a JSFiddle so we can talk about concrete example that you're having?
DeleteThanks for quickly answer. I've tested it now on JSFiddle and it seems good. Strange. I've pasted my html code under http://pastebin.com/9GwrGbH6. Screenshot for my example is under http://s18.postimage.org/ef8v6lcx5/vertical_text.png available.
DeleteThe problem is only in IE 8. Chrome, Firefox show all right.
Thanks for your time, that you spend and sorry for my uggly english :).
When I test your Pastebin code I can see an issue only in IE7 mode, but not in IE8. Strangely enough when I do the same with this blog post, vertical text always display as it should. In any IE mode that is.
DeleteYou should look for differences between CSS presented on this post and in your code. And one more thing. You're using tables, so there's no need for float: left style setting. When you write CSS for your vertical text make sure that you understand it completely because that's the only way to make it reliable.
I've tested it again and found that I have not "DOCTYPE"-tag in my html. That was the solution of my problem.
DeleteMany thanks again for your brilliant solution with vertical text in html.
Bye!
I'm glad you've found the problem. Thanks for the info for any future visitors that may face the same problem.
DeleteI have a table with some long header names. Can this work with tables also?
ReplyDeleteOf course it can, as long as you change some CSS styles accordingly. For instance float:left should be omitted from .container .head because your headers are already side by side... But apart from that I suppose it should work as is.
DeleteIE works great but its not working correctly in firefox. Any chance you can add a tables example?
ReplyDeleteCould it be that you're having similar issues as the last commentator, that didn't set HTML DOCTYPE correctly? Can you also check that?
DeleteHow about elements displayed in this blog post? Do they display as expected in all browsers that you require?
DOCTYPE is being set. The div example displays ok in both browsers, but the table version doesnt display properly in Firefox (IE works perfectly). In Firefox the width of the box looks the same as the height despite forcing the cell width to be 25px wide.
DeleteHere is a sample code
.container {
/* this will give container dimension, because floated child nodes don't give any */
/* if your child nodes are inline-blocked, then you don't have to set it */
overflow: auto;
}
.container .head {
/* float your elements or inline-block them to display side by side */
/*float: left;*/
/* these are height and width dimensions of your header */
height: 10em !important;
width: 25px !important;
/* set to hidden so when there's too much vertical text it will be clipped. */
overflow: hidden;
/* these are not relevant and are here to better see the elements */
background: #eee;
/*margin-right: 1px;*/
vertical-align:baseline;
}
.container .head .vert {
/* line height should be equal to header width so text will be middle aligned */
line-height: 1.5em;
/* setting background may yield better results in IE text clear type rendering */
background: #eee;
display: block;
/* this will prevent it from wrapping too much text */
white-space: nowrap;
/* so it stays off the edge */
padding-left: 3px;
/* IE specific rotation code */
writing-mode: tb-rl;
filter: flipv fliph;
/* CSS3 specific totation code */
/* translate should have the same negative dimension as head height */
transform: rotate(270deg) translate(-10em,0);
transform-origin: 0 0;
-moz-transform: rotate(270deg) translate(-10em,0);
-moz-transform-origin: 0 0;
-webkit-transform: rotate(270deg) translate(-10em,0);
-webkit-transform-origin: 0 0;
}
<table class="ContentData_List fullwidth">
<thead>
<tr>
<td colspan="5">Group heading </td>
</tr>
<tr class="container">
<th class="head" nowrap><div class="vert">Skill 1</div></th>
<th class="head" nowrap><div class="vert">Skill 2</div></th>
<th class="head" nowrap><div class="vert">Skill 3</div></th>
<th class="head" nowrap><div class="vert">Skill 4</div></th>
<th class="head" nowrap><div class="vert">Skill 5</div></td>
</tr>
</thead>
<tbody>
<tr>
<td>value 1</td>
<td>value 2</td>
<td>value 3</td>
<td>value 4</td>
<td>value 5</td>
</tr>
</tbody>
</table>
Any ideas?
I appreciate you sending over all this code but I suggest you rather put it into a JSFiddle so I can directly manipulate your code and test it on various browsers. And in the end also commit it for you to use.
DeleteWould that be ok?
Hi,
ReplyDeleteI want to have vertical table header for a table. So I tried tinkering with this solution a little bit. But I got a problem with the width of the td in the table body. The first cell has the width of all vertical headers. The following cells are attached to the end of the row.
Could you please have a look at http://jsfiddle.net/Mrgaj/8/
Well you've been playing just a little bit too much with your styles. You should keep table displays styles as they are, because otherwise if you don't change them all it will break your table as it did in your case.
DeleteCheck my updated version of your code:
http://jsfiddle.net/Mrgaj/9/
I haven't tested in various browsers but in Chrome it displays all right. You should tinker with it on other browsers, to make it work as expected if it doesn't already.
Hi,
ReplyDeleteFirst of all : of all the methods I tried, this is the one that really works!
Now, what I'd still like to see : how to use it with webfonts,
and how to use it with jquery ( e.g. for handling hover )
great script! ( -: roland :- )
hi,
ReplyDeleteVery Good solution ..!! Appreciated .
I have very tinny is issue the text is not coming in the middle of Div. It is on the top of it.
i try
/* float your elements or inline-block them to display side by side */
float: left; to right . But there is not center ? if i go padding it increase col width . any idea ??
This script works great, first one I found that was easy and simple.
ReplyDeleteI am having one problem however, the text does not go vertical in IE 10.
Here is my page - http://hoffcomm.com/mc/chart/
Is there is a quick fix to this?
Any help is appreciated, thanks.
BHAVA THANK YOU BAHVA, THIS WORKED FOR ME........
ReplyDeleteIt worked for me. Thank you very much
ReplyDeleteIn IE10 and IE9, it is not working. IE8 and for other browsers it is working fine.
ReplyDeleteHave you tried adding -ms-transform styles? IE9 requires those, but IE10 doesn't. I'm not sure what exactly doesn't work for you, but it may be that IE9+ is applying transforms as well as older stuff so it does too much. Play with it a bit.
Delete