vertical table headers

by Laurens Maneschijn

HTML

<table class="vertical_auto">
  <thead>
    <tr>
      <th>1 Ipsum</th>
      <th>2 Ipsum</th>
      <th>3 Ipsum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th>1 Ipsum</th>
      <th>2 Ipsum</th>
      <th>3 Ipsum</th>
    </tr>
  </tfoot>
</table>

<hr>

<table class="vertical_auto">
  <thead>
    <tr>
      <th>1 Ipsum</th>
      <th>2 Ipsum</th>
      <th>3 Long text showing line breaks.</th>
      <th>4 Long text showing line breaks.</th>
      <th>5 Ipsum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>long text filling up table cell</td>
      <td>long text filling up table cell</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
      <td>e</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th>1 Ipsum</th>
      <th>2 Ipsum</th>
      <th>3 Long text showing line breaks.</th>
      <th>4 Long text showing line breaks.</th>
      <th>5 Ipsum</th>
    </tr>
  </tfoot>
</table>

<hr>

<table class="vertical_manual">
  <thead>
    <tr>
      <th>1 <vert>Ipsum</vert> a</th>
      <th>2 <vert>Ipsum</vert> b</th>
      <th>3 <vert>Long text showing line breaks.</vert> c</th>
      <th>4 <vert>Long text showing line breaks.</vert> d</th>
      <th>5 <vert>Ipsum</vert> e</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>long text filling up table cell</td>
      <td>long text filling up table cell</td>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
      <td>e</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th>1 <vert>Ipsum</vert> a</th>
      <th>2 <vert>Ipsum</vert> b</th>
      <th>3 <vert>Long text showing line breaks.</vert> c</th>
      <th>4 <vert>Long text showing line breaks.</vert> d</th>
      <th>5 <vert>Ipsum</vert> e</th>
    </tr>
  </tfoot>
</table>

CSS

/*
For another example see the compatibility table at the bottom of mdn pages, e.g. :
https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode#browser_compatibility
*/

/*
First some unrelated css to make the example more clear.
Also set max height and width to show what happens with line breaks more clearly.
See css for vertical text below.
*/
table {
	border-collapse: collapsed;
}
td, th {
	border: 1px solid #8888;
	margin: 0;
	padding: 2px;
	max-height: 80px;
	max-width: 80px;
}
th {
	font-weight: normal;
	background: #8882;
}

/*
Vertical text in table headers.
For tfoot:
  writing-mode: vertical-rl; vertical text, and new lines go from right-to-left.
  text-align: left; to make text align from the top so the header text starts closest to the body.
For thead:
  As tfoot, but use rotate(180deg). This makes vertical text, new lines go from left-to-right (rotated), text align left to make text align from bottom (rotated).
*/
table.vertical_auto tfoot th,
table.vertical_auto thead th {
	writing-mode: vertical-rl;
	text-align: left;
}
table.vertical_auto thead th {
	transform: rotate(180deg);
}

/*
A more complex variation manually marking the vertical text containers, keeping other things (text) right way up.
Note that there are some caveats. Alignment is odd with single vs multiline headers and varied column widths.
Also note the 1,2,3,4,5 vs a,b,c,d,e in the headers (e.g. "1 <vert>Ipsum</vert> a" :
in tfoot the 1,2,3,4,5 (begin of innerhtml) is closest to tbody,
in thead the a,b,c,d,e (end of innerhtml) is closest to tbody.
*/
table.vertical_manual thead th {
	vertical-align: bottom;
}
table.vertical_manual tfoot th {
	vertical-align: top;
}

table.vertical_manual tfoot vert,
table.vertical_manual thead vert {
	display: block;
	writing-mode: vertical-rl;
	text-align: left;
	margin-inline: 3px 3px;
}
table.vertical_manual thead vert {
	transform: rotate(180deg);
}