5

I'm trying to create a table with headings that are vertical and without explicit sizing for height, is this currently possible with just HTML and CSS?

I'm avoiding using any JS as this HTML is being templated using Thymleaf & Spring. I'm avoiding explicit sizing for height as this will style multiple tables with different headings, so they will have different heights - otherwise there'll be wasted space above them or they'll be partially cut off.

Link to my codepen with a simple example of what I'm trying to achieve. I'd like the second heading to not overlap the rows below and for the whole heading to expand in height to accomdate it.

Code that can be found at the codepen link above:

<table>
  <thead>
    <tr>
      <th>First Heading</th>
      <th class="vertical">Second Heading</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Typical cell</td>
      <td>Typical cell</td>
    </tr>
    <tr>
      <td>Typical Cell cell</td>
      <td>Typical Cell</td>
    </tr>
  </tbody>
</table>
.vertical {
  transform: rotate(-90deg);
}

Edit: this has been marked as duplicate, but the question linked doesn't mention the height being an issue, and the answer includes a CSS property which is actually now deprecated. So I think this question is different enough that it shouldn't be considered a duplicate.

Josh Doug
  • 414
  • 1
  • 6
  • 13
  • If you set up a height to your vertical class you will solve it (height: 120px;). Also, I would recommend you to fix first header to the bottom (vertical-align: bottom;) – gengns Jan 21 '19 at 17:34
  • @gengns as I mentioned in the first sentence of my question, I want to do this `"without explicit sizing for height"`, although I could make it clearer why - it's because this will be styling multiple tables which will contain headings with different content so they'll need to be different heights or there'll be wasted space or headings partially cutoff. – Josh Doug Jan 21 '19 at 17:55
  • Why don't you set a min and max height? I would recommend you to check MDN "Browser compatibility table" approach here for example https://developer.mozilla.org/en-US/docs/Web/CSS/grid (at the bottom) if you are using long headings. If you want different directions, length can vary a lot and don't want to have big empty spaces, you can use CSS Grid. – gengns Jan 21 '19 at 18:11
  • @gengns I'd already checked that, sadly MDN is using an explicit height, probably because the headings are consistent so they can set the heading height specifically. I'm not sure how grid would help here? – Josh Doug Jan 21 '19 at 18:20

4 Answers4

11

Using a combination of my original solution and @pasan_jg's answer I've found the solution I was looking for!

The issue: text-orientation and writing-mode don't appear to support vertical orientated text that is read bottom to top and breaks left to right (at least my solution does this in Chrome, the line doesn't break in Firefox), i.e. they don't support rotating the text by 270deg.

The other solution is using a transform to rotate the text by 270deg, but this doesn't update the box sizing so it overlaps/get cutoff unless you manually set the height and width, which is no good if you're using the same style for multiple tables which may contain different length headings.

The solution: first nest the heading text you want to style vertically into a div within the th and vertically align the text using writing-mode like so:

thead tr th div, .vertical {
    writing-mode: vertical-rl;
}

This will resize the box, now we can flip this text 180 degrees with a transform but the box is already sized for it so we don't need to manually set the height or width, finished css:

thead tr th div, .vertical {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
}

Codepen solution: link.

Edit: removed text-orientation: sideways as it doesn't appear to be necessary.

Josh Doug
  • 414
  • 1
  • 6
  • 13
  • You must have had something else involved in your solution since, for example, in your [linked pen](https://codepen.io/JDS/pen/dabrGj), the headings are **not** bottom-aligned (more obvious if you copy the same style to both columns)... I tried both Firefox and Chrome. – ashleedawg Sep 15 '20 at 03:15
  • @ashleedawg not sure why bottom-aligned is important to this question and I didn't claim my solution had the headings bottom-aligned either? I wanted the text read from bottom to top, not bottom-aligned. – Josh Doug Sep 16 '20 at 08:39
2

Is this what you are looking for?

.vertical {
  writing-mode: vertical-rl;
  text-orientation: sideways-right;
}
<table>
  <thead>
    <tr>
      <th>
        <div class="vertical">First Heading</div>
      </th>
      <th>
        <div class="vertical">Second Heading</div>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Typical cell</td>
      <td>Typical cell</td>
    </tr>
    <tr>
      <td>Typical Cell cell</td>
      <td>Typical Cell</td>
    </tr>
  </tbody>
</table>

Learn more about text-orientation

pasanjg
  • 566
  • 5
  • 13
  • 1
    This is close but the text is flipped the wrong way. It just doesn't seem possible to flip the text the other way using any combination of writing mode and text orientation, which is annoying/surprising? – Josh Doug Jan 22 '19 at 09:35
  • FYI, this is the way I wanted to flip my text. It's the style used by Consumer Reports in their ratings tables. – Dogweather Jul 26 '23 at 21:19
1

Josh Doug's answer is great with one problem. Most vertical table headers have the text aligned on the bottom (which is what I think ashleedawg's comment was referencing). This may not be a problem if all your heading text is the same length, but if you have some longer and some shorter, it becomes hard to read. Easy enhancement. First use Josh's transform on the div:

thead tr th div, .vertical {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
}

Then add this style to the th:

thead tr th {
    vertical-align: bottom;
}

The result is a table with the headers formatted more like they would be in Excel if you rotate the headers.

MattPo
  • 36
  • 4
0

Change the CSS of your vertical class as mention below:

.vertical {
     writing-mode: vertical-lr;
     text-orientation: upright;
     display: block;
}

This will help you, if you have any other issue please feel free to contact me in comments. Thanks

vishulg
  • 149
  • 1
  • 6
  • 1
    Close, but I need the text to be orientated by 270deg/-90deg, not each character stacked vertically - it's quite hard to read like that unfortunately. – Josh Doug Jan 22 '19 at 09:37