Search code examples
htmlcssrotation

Consistently align text at different rotations with CSS


I am creating a grid using an HTML <table>. I have labels for each row, column, and diagonal. In particular, I would like the label text to be aligned with the edge of the grid, so larger numbers expand outwards. Here's a rough design of what I'd like to achieve:

enter image description here

I'm struggling to make this work in CSS for the diagonal and vertical labels. I've tried different combinations of text-align, vertical-align, and transform rules.


Solution

  • I've come up with a working example using display: inline and position: absolute:

    .number-vertical {
      display: inline;
      position: absolute;
      transform: translateX(-100%) translateY(-50%) rotate(90deg);
      transform-origin: 100% 50%;
    }
    
    .number-diagonal {
      display: inline;
      position: absolute;
      transform: translateX(-100%) translateY(-50%) rotate(45deg);
      transform-origin: 100% 50%;
    }
    
    .number-other-diagonal {
      display: inline;
      position: absolute;
      transform: translateX(-100%) translateY(-50%) rotate(-45deg);
      transform-origin: 100% 50%;
    }
    
    .number-horizontal {
      text-align: right;
    }
    
    .cell-rotated-center {
      text-align: center;
      vertical-align: bottom;
      height: 6ch;
    }
    
    .cell-rotated-right {
      text-align: right;
      vertical-align: bottom;
    }
    
    .number-input {
      width: 4ch;
      height: 4ch;
      text-align: center;
    }
    <table>
      <tbody>
        <tr>
          <td class="cell-rotated-right">
            <div class="number-diagonal">
              <span>10</span>
            </div>
          </td>
          <td class="cell-rotated-center">
            <div class="number-vertical">
              <span>72</span>
            </div>
          </td>
          <td class="cell-rotated-center">
            <div class="number-vertical">
              <span>720</span>
            </div>
          </td>
          <td class="cell-rotated-center">
            <div class="number-vertical">
              <span>100000</span>
            </div>
          </td>
        </tr>
        <tr>
          <td>
            <div class="number-horizontal">
              <span>36</span>
            </div>
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
        </tr>
        <tr>
          <td>
            <div class="number-horizontal">
              <span>360</span>
            </div>
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
        </tr>
        <tr>
          <td>
            <div class="number-horizontal">
              <span>360000</span>
            </div>
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
          <td>
            <input class="number-input" type="text" value="">
          </td>
        </tr>
        <tr>
          <td class="cell-rotated-right">
            <div class="number-other-diagonal">
              <span>5000</span>
            </div>
          </td>
        </tr>
      </tbody>
    </table>