Search code examples
cssbootstrap-4html-tablevertical-alignment

Bootstrap table: Vertical row header overlaps cells as cell content grow


In the first cell of each row I have a header cell with vertically aligned text.

It is displayed as it is supposed to be with plain HTML + CSS. But when using Bootstrap 4 tables, if one of the cell's content grows and the table row height increases, the vertical header text moves right, towards the other cells, overlapping content. This is not happening when not using Bootstrap.

https://jsfiddle.net/onurmatik/y9tLk6dz/13/

HTML

<table class="table table-borderless" id="grid">
  <tbody>
    <tr class="border-0">
      <td class="vertical">
        regularly
      </td>
      <td class="border">
        <ul class="list-group list-group-flush">
        </ul>
      </td>
      <td class="border">
        <ul class="list-group list-group-flush">
          <li class="list-group-item">Tua</li>
          <li class="list-group-item">Onur</li>
          <li class="list-group-item">Hanna</li>
          <li class="list-group-item">Sine</li>
          <li class="list-group-item">Fred</li>
          <li class="list-group-item">Anna</li>
          <li class="list-group-item">Floris</li>
        </ul>
      </td>
    </tr>
    <tr>
      <td class="vertical">
        sometimes
      </td>
      <td class="border">
        <ul class="list-group list-group-flush"></ul>
      </td>
      <td class="border">
        <ul class="list-group list-group-flush"></ul>
      </td>
    </tr>
  </tbody>
</table>

CSS

#grid li {
    width: 100%;
}
.vertical {
    text-align:center;
    vertical-align: bottom!important;
    white-space:nowrap;
    transform-origin:50% 50%;
    -webkit-transform: rotate(-90deg);
    -moz-transform: rotate(-90deg);
    -ms-transform: rotate(-90deg);
    -o-transform: rotate(-90deg);
    transform: rotate(-90deg);
    writing-mode:tb-rl;
}
#grid td {
    width: 200px;
    height: 200px;
}

Solution

  • This happens as long as the rendered height of a cell is more than its width. This is because:

    • Rotating a "tall" rectangle (e.g. 1:2 ratio) by 90deg results in a "wide" rectangle (e.g. 2:1 ratio).
    • The transformation applied to the td elements, rotates them in their current positions without affecting the width and height of the table as a whole.

    This animation should demonstrate this better.

    I imagine the problem would be the same even without Bootstrap as long as the exact same sizes and ratios are replicated.

    One approach to work around this is to wrap the content of the header cells in <span> elements:

    <td class="vertical">
      <span>regularly</span>
    </td>
    

    ...and apply the rotation and writing-mode to the <span> elements instead:

    .table .vertical {
      vertical-align: middle;
      text-align: right;
    }
    
    .table .vertical span {
      white-space: nowrap;
      writing-mode: vertical-lr;
      transform-origin: 50% 50%;
      -webkit-transform: rotate(180deg);
      -moz-transform: rotate(180deg);
      -ms-transform: rotate(180deg);
      -o-transform: rotate(180deg);
      transform: rotate(180deg);
    }
    

    Here's a live demo for your quick reference. Please note that I've added the .table class in front of the .table .vertical selector to overwrite some of Bootstrap's default styles.