How to display vertical text in table headers with auto height / without text overflow?

Viewed 112304

I want to display rotated text as table headers, using the CSS transform property. The header row should adjust its height as needed, but instead the rotated text just overflows:

example wrong

demo fiddle

My question is, how to get the table header to grow as needed? Essentially it should look like this:

example right

12 Answers

I struggled to get my <th>'s aligned exactly how I wanted them (even if some are multiple lines).
This is what worked for me:

example image of table

html    { font-family: Helvetica; }
table   { border-collapse: collapse; }
td, th  { border: 1px solid BurlyWood; }
td      { text-align: center; }
th      { background-color: NavajoWhite; 
          color: SaddleBrown; 
          width:50px;  
          vertical-align: bottom; }
th span { writing-mode: sideways-lr; /* +90°: use 'tb-rl' */
          text-align: left;          /* +90°: use 'right' */
          padding:10px 5px 0; }
<table>
    <tr>
      <th><span>First</span></th>
      <th><span>Second</span></th>
      <th><span>Third<br>Column</span></th>
    </tr>
    <tr>
      <td>foo</td>
      <td>foo</td>
      <td>foo</td>
    </tr>
    <tr>
      <td>foo</td>
      <td>foo</td>
      <td>foo</td>
    </tr>
</table>

I figured I'd share, partly as reference for "future me".

try this:

.vertical-header span {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  text-align: left;
  max-height: 150px;
}
<table border=1>
  <tr>
    <th class="vertical-header"><span>Firstname</span></th>
    <th class="vertical-header"><span>Lastname</span></th>
    <th class="vertical-header"><span>Age</span></th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
</table>

To avoid js using I can propose to use flex in first table row. A little messy with borders in headers, but it could be fixed in thin setup:

.header-row {
  display: flex;
  flex-direction: row;
}

span {
    writing-mode: vertical-lr;
    transform: rotate(180deg);
    width: 23px;
    border-left: 1px solid black;
}

table {
  border: 1px solid black;
  border-spacing: 0px;
}

td {
  border: 1px solid black;
  width: 20px;
}
<table>
  <tr>
    <td></td>
    <td colspan="5" style="padding:0;border:none">
      <div class="header-row">
        <span>Header fsdafasd</span>
        <span>Header fsda</span>
        <span>Header fsdafa fsdaf</span>
        <span>Header asdf</span>
        <span>Header fsda</span>
      </div>
    </td>
  </tr>
  <tr>
    <td>Test name fadsf</td>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>4</td>
  </tr>
  <tr>
    <td>Test name</td>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>4</td>
  </tr>
  <tr>
    <td>Test name</td>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>4</td>
  </tr>
</table>

I created something similar, I needed the text to be vertically aligned but without rotation, I did it with the following CSS attributes:

writing-mode: vertical-lr;
text-orientation: upright;

See the example below:

thead {
  background-color: black;
  color: white;
}
tbody tr td:nth-child(1) {
  text-align: center;
}
.vertical {
  writing-mode: vertical-lr;
    text-orientation: upright;
  background-color: silver;
  font-weight: bold;
}
<table width="100%">
  <thead>
    <th>Week</th>
    <th colspan="2">Content</th>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td rowspan="3" class="vertical">BASICS</td>
      <td>Topic 1</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Topic 2</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Topic 3</td>
    </tr>
  </tbody>
</table>

<thead><tr><th class="rotate"><div>header 1></div></th><th class="rotate"><div>header 2></div></th></tr></thead>

apply CSS to rotate class

th.rotate {
        height: 110px; /* header height */
        white-space: nowrap;
    }

th.rotate > div {
    transform:
       translate(25px, 51px)
       rotate(90deg);
       /* rotate(315deg); for diagnol */
    width: 30px;
    margin-left: -35px;
    margin-top: -30px;
}

This works for me

css

.v-text {
    transform: rotate(270deg);
    display: block;
 }

html

<table>
  <th>HEADER 1</th>
  <th>
    <p class="v-text">VERTICAL</p>
  </th>
<table>

enter image description here

<style type="text/css">
        

.rotate > div {
    text-align: center;
    white-space:nowrap;
    g-origin:50% 50%;
    -webkit-transform: rotate(-90deg);
    -moz-transform: rotate(-90deg;
    -ms-transform: rotate(-90deg;
    -o-transform: rotate(-90deg;
    transform: rotate(-90deg);
}
       

https://jsfiddle.net/amrangry/w4ja3qo2/1/

I had a hard time getting these tweaks to work in a consistent manner. Just in case this helps someone, my solution was to create images of vertical text.

Related