Search code examples
htmlcsshtml-tablerotationcss-grid

Vertical alignment and positioning of rotated text in a table or grid


I'm trying to rotate some text in an html table, but no matter what I do I end up with some alignment and text-flow issues.

I've tried using various combinations of writing-mode and rotate in css, but cannot sort out the issue. Here's the test table: https://universaltheosophy.com/hpb/test-table.htm

Here's the code:

table {
  margin-left: auto;
  margin-right: auto;
}

.c10 {
  font-variant: small-caps;
}

.text-body-2-western {
  text-align: center;
  text-indent: 0em;
}

.c90bt {
  -webkit-transform: rotate(270deg);
  -moz-transform: rotate(270deg);
  -ms-transform: rotate(270deg);
  -o-transform: rotate(270deg);
  transform: rotate(270deg);
}
<table cellpadding="2" cellspacing="0">
  <col>
  <col>
  <col>
  <tr>
    <td rowspan="3">
      <p class="text-body-2-western c90bt"><span class="c10">test title.</span><br>this is a test string of text rotated vertically that should fit within the table td limits.</p>
    </td>
    <td>
      <p class="text-body-2-western">MAIN TITLE OF THE TABLE SHOULD CENTER HORIZONTALLY</p>
    </td>
    <td rowspan="3">
      <p class="text-body-2-western c90bt"><span class="c10">test title.</span><br>this is a test string of text rotated vertically that should fit within the table td limits but for some reason reaches outside of it.</p>
    </td>
  </tr>
  <tr>
    <td>
      <p class="text-body-2-western"><img src="https://universaltheosophy.com/resources/sd-2-300-blank.png"></p>
    </td>
  </tr>
  <tr>
    <td>
      <p class="text-body-2-western text-body-no-spacing"><span class="c10">bottom title in small caps.</span></p>
    </td>
  </tr>
</table>

The issue is primarily in two places:

  1. the rotated text doesn't properly align within the top and bottom boundary of the table td element. Either the text extends outside of the td boundary or it gets squished together (when you run the code snippet here, see the difference between the normal view and the full page view)

  2. the text aligns horizontally far away from the image at the center (I want the rotated text on either side of the image in the center to be tight against it).

Edit

To address the first comment here (re: the rowspans), here's the same table without rowspans, with the same result:

table {
  margin-left: auto;
  margin-right: auto;
}

.c10 {
  font-variant: small-caps;
}

.text-body-2-western {
  text-align: center;
  text-indent: 0em;
}

.c90bt {
  -webkit-transform: rotate(270deg);
  -moz-transform: rotate(270deg);
  -ms-transform: rotate(270deg);
  -o-transform: rotate(270deg);
  transform: rotate(270deg);
}
<table cellpadding="5" cellspacing="0">
  <col>
  <col>
  <col>
  <tr>
    <td colspan="3">
      <p class="text-body-2-western">MAIN TITLE OF THE TABLE SHOULD CENTER HORIZONTALLY.</p>
    </td>
  </tr>
  <tr>
    <td>
      <p class="text-body-2-western c90bt"><span class="c10">test title.</span><br>this is a test string of text rotated vertically that should fit within the table td limits.</p>
    </td>
    <td>
      <p class="text-body-2-western"><img src="https://universaltheosophy.com/resources/sd-2-300-blank.png" class="img1"></p>
    </td>
    <td>
      <p class="text-body-2-western c90bt"><span class="c10">test title.</span><br>this is a test string of text rotated vertically that should fit within the table td limits but for some reason reaches outside of it.</p>
    </td>
  </tr>
  <tr>
    <td colspan="3">
      <p class="text-body-2-western text-body-no-spacing"><span class="c10">bottom title in small caps.</span></p>
    </td>
  </tr>
</table>


Solution

  • I have a different solution to your problem using CSS grid layout:

    1. Note the change in markup without using tables. Create a grid layout using display: grid - note that the &nbsp in the markup is for an empty grid item.
    2. Make a three-column layout with min-content width using grid-template-columns: repeat(3, min-content) on the outer container.
    3. Fit the second row to the height of the middle element by using grid-template-rows: 1fr min-content
    4. For the vertical alignment, I am using writing-mode:

      .wmode {
         writing-mode: tb-rl;
         transform: rotate(-180deg);
      }
      

    See demo below:

    .container {
      display: grid;
      grid-template-columns: repeat(3, min-content);
      grid-template-rows: 1fr min-content;
      justify-content: center;
    }
    
    .c10 {
      font-variant: small-caps;
    }
    
    .text-body-2-western {
      text-align: center;
      text-indent: 0em;
    }
    
    .wmode {
      writing-mode: tb-rl;
      transform: rotate(-180deg);
    }
    <div class="container">
      &nbsp;
      <p class="text-body-2-western">MAIN TITLE OF THE TABLE SHOULD CENTER HORIZONTALLY</p>
      &nbsp;
      <p class="text-body-2-western wmode"><span class="c10">test title.</span><br>this is a test string of text rotated vertically that should fit within the table td limits.</p>
      <img src="https://via.placeholder.com/400x338?text=image">
      <p class="text-body-2-western wmode"><span class="c10">test title.</span><br>this is a test string of text rotated vertically that should fit within the table td limits but for some reason reaches outside of it.</p>
      &nbsp;
      <p class="text-body-2-western text-body-no-spacing"><span class="c10">bottom title in small caps.</span></p>
      &nbsp;
    </div>