1

The table I am trying to design is going to end up to be somewhat dynamic. I would like the table header cells to appear rotated (to save horizontal space). I am aware there might be better methods to save some table space, but as I was playing around with some HTML, I got interested in something that seemed quite impossible.

Within following piece of code I tried to rotate the cells:

th {
  background-color: #ccc;
}

th,
td {
  border: 1px solid #000;
}

.rotate {
  transform: rotate(-90deg);
  text-align: center;
  margin-bottom: 100px;/* <-- Anything I could do here? */
}
<table cellspacing="0" cellpadding="0">
  <thead>
    <tr>
      <th class="rotate">
        Foo
      </th>
      <th class="rotate">
        Bar
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        Foo collection
      </td>
      <td>
        Bar collection
      </td>
    </tr>
  </tbody>
</table>

I found some code in a couple other questions in order to address my issue(s), however most of these questions do not address the issue(s) I am having:

Whenever given table cell's content would increase (e.g. more characters and/or words), content would flow either outside of the given cell or break the appearance of the cell.

First off I would like my table cells to stay where they are supposed to (so no hovering over other cells like what is happening in my fiddle above):

Example table #1

and secondly I would like to be able to adjust the text inside these cells, meaning that the cells must be able to resize without breaking the table's layout:

Example table #2

In other words: I would like to create rotated table header cells without losing any of HTML's table default functionalities. Is it possible to rotate a table header cell (<th> element) without breaking the table?

Barrosy
  • 1,407
  • 2
  • 25
  • 56

2 Answers2

4

When you want to change the write direction of the text, you can use writing-mode. In this case I use writing-mode: vertical-lr;, which makes the text vertical, and the container height will change to fit the text. We also need to rotate the text in place, but in the future I would use sideways-lr, which lacks support now.

th {
  background-color: #ccc;
}

th,
td {
  border: 1px solid #000;
}

.rotate span {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}
<table cellspacing="0" cellpadding="0">
  <thead>
    <tr>
      <th class="rotate">
        <span>Foo</span>
      </th>
      <th class="rotate">
        <span>Foo Bar Bazz</span>
      </th>
      <th class="rotate">
        <span>FooBar</span>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        Foo collection
      </td>
      <td>
        Foo Bar Bazz collection
      </td>
      <td>
        Foo Bar collection
      </td>
    </tr>
  </tbody>
</table>

As noted by @AlRo, you need the span to center the text horizontally in Firefox.

Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • One problem though: If a `` table header contains multiple words, the order of words appearing shows incorrect (due to the `transform: rotate(180deg)`) (e.g. if it contains the words "foo bar" it will display as "bar foo" instead).Would you happen to know how I could fix this? – Barrosy Jul 08 '19 at 13:10
  • 1
    It's not caused by the rotation. The cause is the way the `write-mode: vertical-lr;` is rendered. You can change the direction with `vertical-rl`. (see updated answer). – Ori Drori Jul 08 '19 at 13:46
  • 1
    note that for this to work right on both firefox and webkit the span you included is required. It's easy to miss that as a required step so I think it's worth calling out. on webkit you can just rotate the td or th and it centers it properly. – Al Ro Feb 19 '22 at 06:16
0

If you mean to change them dynamically then create a CSS class and add:

.rotate-text {
    //for old browsers
    -moz-transform: rotate(90deg);
    -webkit-transform: rotate(90deg) ;
    -o-transform: rotate(90deg) ;
    -ms-transform: rotate(90deg) ;
    //for all modern browsers
    transform: rotate(90deg);
}

Now use jQuery to check if number of words increased the target, if true toggle the class created above inside your TD or TH

jQuery("th").toggleClass("rotate-text");

I hope this helps you.

Masood
  • 1,545
  • 1
  • 19
  • 30