0

I have the following table (based on this answer: https://stackoverflow.com/a/22177247/10461973):

http://jsfiddle.net/e5khjfsu/1/

<table border="1">
    <tr>
      <th class="verticalTableHeader">0</th>
      <th class="verticalTableHeader">10</th>
      <th class="verticalTableHeader">100</th>
      <th class="verticalTableHeader">1000</th>
      <th class="verticalTableHeader">10000</th>
      <th class="verticalTableHeader">100000</th>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
      <td>e</td>
      <td>f</td>
    </tr>
</table>
.verticalTableHeader {
    min-width: 15px;
    text-align:center;
    white-space:nowrap;
    transform-origin:50% 50%;
    transform: rotate(90deg);
    
}
.verticalTableHeader:before {
    content:'';
    padding-top:110%;/* takes width as reference, + 10% for faking some extra padding */
    display:inline-block;
    vertical-align:middle;
}

This leads to the following output:

enter image description here

The width of a column seems to depend on the length of the text. However, I would like that only the height depends on the length of the text (which might be different from the text in the example above), and that all columns have the minimum width (i.e., a width similar to the leftmost column). How can I achieve this?

Andreas Abel
  • 1,376
  • 1
  • 10
  • 21

3 Answers3

2

You could safely use writing-mode nowdays http://jsfiddle.net/wh1jt3ox/

.verticalTableHeader span {
  display:inline-block;
  min-width:1em;
  text-align: center;
  white-space: nowrap;
  writing-mode: vertical-rl;
}
<table border="1">
  <tr>
    <th class="verticalTableHeader">
      <span>0</span>
    </th>
    <th class="verticalTableHeader">
      <span>10</span>
    </th>
    <th class="verticalTableHeader">
      <span>100</span>
    </th>
    <th class="verticalTableHeader">
      <span>1 000</span>
    </th>
    <th class="verticalTableHeader">
      <span>10 000</span>
    </th>
    <th class="verticalTableHeader">
      <span>1 000 000</span>
    </th>
  </tr>
  <tr>
    <td>a</td>
    <td>b</td>
    <td>c</td>
    <td>d</td>
    <td>e</td>
    <td>f</td>
  </tr>
  </table>

Sorry for that old average trick ;) (while 7 years ago, writing-mode was still a left over from IE5)

Andreas Abel
  • 1,376
  • 1
  • 10
  • 21
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • This appears to only work in Firefox. It does not work in Chrome and Edge. – Andreas Abel Apr 21 '21 at 21:03
  • 1
    @AndreasAbel Oh yes sorry, i forgot to mention that the text wrapper is still a need to avoid disturbing the table-layout. are used here , p are not the best within a th :) – G-Cyrillus Apr 21 '21 at 22:04
  • @AndreasAbel Hello, just noticed your message & that missing brackets. fixed. Take care. – G-Cyrillus Apr 25 '21 at 13:08
0

You can calculate the dimensions needed to display the header with raw JavaScript. Your rotated element can then be absolute positioned inside the container. Example using positioning

    <style>
    .tbl-hdr-container {
        position: relative;
        width: 20px;
    }

    td {
        width: 20px;
    }

    .tbl-hdr-rotate {
        position: absolute;
        top: -1px;
        left: 20px;
        text-align: center;
        white-space: nowrap;
        transform-origin: top left;
        transform: rotate(90deg);
    }
</style>

<table border="1">
    <tr>
        <th class="tbl-hdr-container"><span class="tbl-hdr-rotate">0</span></th>
        <th class="tbl-hdr-container"><span class="tbl-hdr-rotate">10</span></th>
        <th class="tbl-hdr-container"><span class="tbl-hdr-rotate">100</span></th>
        <th class="tbl-hdr-container"><span class="tbl-hdr-rotate">1000</span></th>
        <th class="tbl-hdr-container"><span class="tbl-hdr-rotate">10000</span></th>
        <th class="tbl-hdr-container"><span class="tbl-hdr-rotate">100000</span></th>
    </tr>
    <tr>
        <td>a</td>
        <td>b</td>
        <td>c</td>
        <td>d</td>
        <td>e</td>
        <td>f</td>
    </tr>
</table>
<script>
const spans = document.getElementsByClassName("tbl-hdr-rotate");
const maxSize = Math.max.apply(Math, Array.from(spans).map(function(o) 
{ return o.offsetWidth; }));
const ths = document.getElementsByClassName("tbl-hdr-container");
for(i = 0; i < ths.length; i++) {
    ths[i].style.height = maxSize + 'px';
    ths[i].childNodes[0].style.width = maxSize + 'px';
}
</script>
tmcc
  • 1,010
  • 8
  • 12
  • In this solution, the height doesn't depend on the text, but it is hard coded. For longer texts (e.g., 100000000000) it doesn't work. – Andreas Abel Apr 21 '21 at 20:45
  • @AndreasAbel I have updated my answer. If you are ok using minimal js this should work for you. – tmcc Apr 23 '21 at 20:10
0

So, my approach here was to flip the text and the table heads. See how this work for you :

.verticalTableHeader {
  display: flex;
  padding: 5px 0;
  justify-content: center;
  width: 25px;
  transform: rotate(90deg);
  max-height: 120px
}

<table border="1">
    <tr>
     <th><p class="verticalTableHeader">0</p></th>
     <th><p class="verticalTableHeader">10</p></th>
     <th><p class="verticalTableHeader">100</p></th>
     <th><p class="verticalTableHeader">1000</p></th>
     <th><p class="verticalTableHeader">10000</p></th>
     <th><p class="verticalTableHeader">100000</p></th>
    </tr>
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
      <td>e</td>
      <td>f</td>
    </tr>
  </table>

I made an edit to the original post. Replace the span with p tags and apply the new css. Change the max-height as needed.

Rolando Yera
  • 820
  • 4
  • 12