1

Rotating text within a HTML table header and resizing width of the column

Hello, firstly thanks to the community for so much existing content to help with this but I haven't been able to get to the bottom of my issue. I am relatively inexperienced with html/css so any feedback it appreciated.

My workflow for this problem looks like this:

  • importing data as a dataframe
  • converting dataframe using to_html() with a class called 'myfavourite_table'
  • embedding that table in an existing html document and then using WeasyPrint to export it to a PDF.

The header titles for this table are substantially longer than the necessary width of the columns for the remaining data, so I have been working on rotating the text and resizing the columns appropriately. I have had two major issues with the html (this is prior to WeasyPrint pdf prep):

  1. The column widths will not reduce once the text is rotated
  2. The text keeps wrapping

.myfavourite_table {
  font-size: 9pt;
  font-family: Arial;
  border-collapse: collapse;
  border: 1px solid silver;
  border-spacing: 0px 10px;
  text-align: center;
  vertical-align: middle;
}


.myfavourite_table th:not(:nth-child(12)) {
  transform: rotate(-90deg) translate(0, 0px);
  writing-mode: vertical-rl;
  padding: 0;
  margin: 0;
  height: 150px;
  white-space: no-wrap;
  font-size: 8pt;

}

.myfavourite_table th:nth-child(12),
td:nth-child(12) {
  text-align: left;
}

.myfavourite_table td {
  padding-top: 0.8em;
  padding-bottom: 0.8em;
}

.myfavourite_table tr:nth-child(even) {
  background: #E0E0E0;
}
<table border="1" class="dataframe myfavourite_table">
  <thead>
    <tr style="text-align: right;">
      <th>Column Here</th>
      <th>Another Column</th>
      <th>Column Here</th>
      <th>Column Please</th>
      <th>Column Again</th>
      <th>Column</th>
      <th>Column</th>
      <th>Longer Column Var 1</th>
      <th>Longer Column Var 2</th>
      <th>Longer Column Var 3</th>
      <th>Longer Column Var 4</th>
      <th>Not vertical</th>
      <th>Binary1</th>
      <th>Binary2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>O</td>
      <td>NO</td>
      <td>1</td>
      <td>YES</td>
      <td>1</td>
      <td>O</td>
      <td>2</td>
      <td>0.0</td>
      <td>15.0</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel sem a nisl dignissim porta. Mauris non hendrerit sapien. Duis lobortis metus justo, accumsan fermentum nisl molestie eu.</td>
      <td>1</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>NO</td>
      <td>1</td>
      <td>NO</td>
      <td>1</td>
      <td>O</td>
      <td>2</td>
      <td>0.0</td>
      <td>1.0</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Maecenas ut est vitae eros tempor bibendum. Sed placerat vestibulum ornare.</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>I</td>
      <td>1</td>
      <td>I</td>
      <td>1</td>
      <td>T</td>
      <td>2</td>
      <td>0.0</td>
      <td>9.2</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Pellentesque nec ullamcorper neque. Morbi odio est, rutrum in massa non, venenatis vestibulum odio. Proin a sem venenatis, consectetur dolor eu</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>I</td>
      <td>1</td>
      <td>NO</td>
      <td>1</td>
      <td>C</td>
      <td>2</td>
      <td>0.0</td>
      <td>30.0</td>
      <td>10.0</td>
      <td>0.0</td>
      <td>Maecenas cursus viverra malesuada. Vivamus ipsum purus, hendrerit et cursus et, fringilla vel tortor. Donec fringilla lacus lacinia nisi posuere, in tincidunt massa tincidunt. Cras aliquet fermentum sapien non fringilla. Nunc sodales vitae nibh vitae bibendum. Curabitur pellentesque auctor magna, sed bibendum arcu laoreet facilisis
      </td>
      <td>1</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

I have formatted a target output in excel as shown below. For reference, I am not expecting this to be presented as a HTML (yet) but mainly for feeding into WeasyPrint.

Target Output

Any help is greatly appreciated :)

EDIT: I have reviewed the proposed duplicate [https://stackoverflow.com/questions/272799/vertical-rotated-text-in-html-table] and ran it in my code and it does not address the issue as described in my question.

  • 1
    Whenever you are tempted to link to a jsFiddle, don’t. Copy the code into a [snippet](https://meta.stackoverflow.com/a/358993/2518285) instead, then we can run it right here within Stack Overflow. – Brett Donald Jun 28 '23 at 23:08

2 Answers2

0

You may use transform:scale(-1) to reset other way your rotated text ( FF has sideways-xx that could be used).

padding and line-height can help too to tune text-position in the cell.

Here a possible example to play with:

.myfavourite_table {
  font-size: 9pt;
  font-family: Arial;
  border-collapse: collapse;
  border: 1px solid silver;
  border-spacing: 0px 10px;
  text-align: center;
  vertical-align: middle;
}


.myfavourite_table th:not(:nth-child(12)) {
  writing-mode: vertical-rl;
  padding: 0;
  margin: 0;
  white-space: no-wrap;
  font-size: 8pt;
  /* added */
  text-align: center;
  transform:scale(-1);
  padding:0.25em 1em;
  line-height:0.5;  
  vertical-align: top;

}

.myfavourite_table th:nth-child(12) {
  text-align: center;
}
.myfavourite_table td:nth-child(12) {
  text-align: left;
}

.myfavourite_table td {
  padding-top: 0.8em;
  padding-bottom: 0.8em;
}

.myfavourite_table tr:nth-child(even) {
  background: #E0E0E0;
}
<table border="1" class="dataframe myfavourite_table">
  <thead>
    <tr style="text-align: right;">
      <th>Column Here</th>
      <th>Another Column</th>
      <th>Column Here</th>
      <th>Column Please</th>
      <th>Column Again</th>
      <th>Column</th>
      <th>Column</th>
      <th>Longer Column Var 1</th>
      <th>Longer Column Var 2</th>
      <th>Longer Column Var 3</th>
      <th>Longer Column Var 4</th>
      <th>Not vertical</th>
      <th>Binary1</th>
      <th>Binary2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>O</td>
      <td>NO</td>
      <td>1</td>
      <td>YES</td>
      <td>1</td>
      <td>O</td>
      <td>2</td>
      <td>0.0</td>
      <td>15.0</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel sem a nisl dignissim porta. Mauris non hendrerit sapien. Duis lobortis metus justo, accumsan fermentum nisl molestie eu.</td>
      <td>1</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>NO</td>
      <td>1</td>
      <td>NO</td>
      <td>1</td>
      <td>O</td>
      <td>2</td>
      <td>0.0</td>
      <td>1.0</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Maecenas ut est vitae eros tempor bibendum. Sed placerat vestibulum ornare.</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>I</td>
      <td>1</td>
      <td>I</td>
      <td>1</td>
      <td>T</td>
      <td>2</td>
      <td>0.0</td>
      <td>9.2</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Pellentesque nec ullamcorper neque. Morbi odio est, rutrum in massa non, venenatis vestibulum odio. Proin a sem venenatis, consectetur dolor eu</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>I</td>
      <td>1</td>
      <td>NO</td>
      <td>1</td>
      <td>C</td>
      <td>2</td>
      <td>0.0</td>
      <td>30.0</td>
      <td>10.0</td>
      <td>0.0</td>
      <td>Maecenas cursus viverra malesuada. Vivamus ipsum purus, hendrerit et cursus et, fringilla vel tortor. Donec fringilla lacus lacinia nisi posuere, in tincidunt massa tincidunt. Cras aliquet fermentum sapien non fringilla. Nunc sodales vitae nibh vitae bibendum. Curabitur pellentesque auctor magna, sed bibendum arcu laoreet facilisis
      </td>
      <td>1</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

for FF , you could use : https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode#sideways-rl

.myfavourite_table th:not(:nth-child(12)) {
  writing-mode: sideways-lr;/* modified */
  padding: 0;
  margin: 0;
  white-space: no-wrap;
  font-size: 8pt;
  /* added */
  text-align: center;
  padding:0.25em 1em;
  line-height:0.5;  
}

No idea then how that will be converted within your PDF. It would be nice to let us know ;)

G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
-1

It appears that the CSS writing-mode property has a value sideways-lr which should arrange the text as per your target output. Unfortunately, browser support for that value is limited to Firefox at present. You could just go with vertical-rl — it’s not as neat as sideways-lr would be, but it’s usable.

But to get exactly what you want, use writing-mode: vertical-rl in combination with transform: scale(-1) and text-align: left. Negative scale values perform a point reflection of an element. scale(-1) has the same effect on an object as rotating it 180 degrees around its centre.

.myfavourite_table {
  font-size: 9pt;
  font-family: Arial;
  border-collapse: collapse;
  border: 1px solid silver;
  border-spacing: 0px 10px;
  text-align: center;
  vertical-align: middle;
}

.myfavourite_table th:not(:nth-child(12)) {
  writing-mode: vertical-rl;
  font-size: 8pt;
  transform: scale(-1);
  text-align: left;
}

.myfavourite_table th:nth-child(12),
td:nth-child(12) {
  text-align: left;
  vertical-align: bottom;
}

.myfavourite_table td {
  padding-top: 0.8em;
  padding-bottom: 0.8em;
}

.myfavourite_table tr:nth-child(even) {
  background: #E0E0E0;
}
<table border="1" class="dataframe myfavourite_table">
  <thead>
    <tr style="text-align: right;">
      <th>Column Here</th>
      <th>Another Column</th>
      <th>Column Here</th>
      <th>Column Please</th>
      <th>Column Again</th>
      <th>Column</th>
      <th>Column</th>
      <th>Longer Column Var 1</th>
      <th>Longer Column Var 2</th>
      <th>Longer Column Var 3</th>
      <th>Longer Column Var 4</th>
      <th>Not vertical</th>
      <th>Binary1</th>
      <th>Binary2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>O</td>
      <td>NO</td>
      <td>1</td>
      <td>YES</td>
      <td>1</td>
      <td>O</td>
      <td>2</td>
      <td>0.0</td>
      <td>15.0</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel sem a nisl dignissim porta. Mauris non hendrerit sapien. Duis lobortis metus justo, accumsan fermentum nisl molestie eu.</td>
      <td>1</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>NO</td>
      <td>1</td>
      <td>NO</td>
      <td>1</td>
      <td>O</td>
      <td>2</td>
      <td>0.0</td>
      <td>1.0</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Maecenas ut est vitae eros tempor bibendum. Sed placerat vestibulum ornare.</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>I</td>
      <td>1</td>
      <td>I</td>
      <td>1</td>
      <td>T</td>
      <td>2</td>
      <td>0.0</td>
      <td>9.2</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>Pellentesque nec ullamcorper neque. Morbi odio est, rutrum in massa non, venenatis vestibulum odio. Proin a sem venenatis, consectetur dolor eu</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <td>O</td>
      <td>I</td>
      <td>1</td>
      <td>NO</td>
      <td>1</td>
      <td>C</td>
      <td>2</td>
      <td>0.0</td>
      <td>30.0</td>
      <td>10.0</td>
      <td>0.0</td>
      <td>Maecenas cursus viverra malesuada. Vivamus ipsum purus, hendrerit et cursus et, fringilla vel tortor. Donec fringilla lacus lacinia nisi posuere, in tincidunt massa tincidunt. Cras aliquet fermentum sapien non fringilla. Nunc sodales vitae nibh vitae bibendum. Curabitur pellentesque auctor magna, sed bibendum arcu laoreet facilisis
      </td>
      <td>1</td>
      <td>0</td>
    </tr>
  </tbody>
</table>
Brett Donald
  • 6,745
  • 4
  • 23
  • 51