Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Work around Safari table colspan/writing-mode width bug

I'd like a table to have a first cell which colspans several cells and the ones beneath to have vertical text, like the following example.

.second td * {
  writing-mode: tb-rl;
  -webkit-writing-mode: vertical-rl;
  writing-mode: vertical-rl;
}
<table border=1><tr>
<td colspan=4>This cell has colspan=4</td>
</tr><tr class="second">
<td><div>Writing-mode:vertical-rl inside block</div></td>
<td><div>Writing-mode:vertical-rl inside block</div></td>
<td><div>Writing-mode:vertical-rl inside block</div></td>
<td><div>Writing-mode:vertical-rl inside block</div></td>
</tr></table>

<table border=1><tr>
<td colspan=4>This cell has colspan=4</td>
</tr><tr class="second">
<td><a>Writing-mode:vertical-rl inside inline</a></td>
<td><a>Writing-mode:vertical-rl inside inline</a></td>
<td><a>Writing-mode:vertical-rl inside inline</a></td>
<td><a>Writing-mode:vertical-rl inside inline</a></td>
</tr></table>

In every browser except Safari, this produces properly-sized cells containing sideways text. Safari either collapses them (if the container is block) or expands them as if they were horizontal (if the container is inline).

I've submitted the bug to Webkit, but until then, I'd like to use this pattern, so I'm looking for a way around it that preserves most of this structure and the ability to use colspan above vertical text. The actual use case is more complex, so simply setting fixed widths somewhere is not a viable solution.

I attempted reimplementing the table as display: flex and nesting column within row-direction flex, but encountered the same bug, this time in Firefox as well.

like image 881
Lucent Avatar asked Feb 11 '17 07:02

Lucent


1 Answers

Simple fix with jQuery (you can use pure js if you want, I think you can also do it using css (sass/less) but this is the solution I have.

First I check the userAgent, if it is Firefox set display to inline-block for div and a. Else just use flex.

For each td div and td a get child div or a width and assign to the width of parent td

var display = 'flex';

if (navigator.userAgent.search("Firefox") > -1) {
  display = 'inline-block';
}

$("td div, td a").each(function() {
  self = $(this);
  self.css('display', display);
  self.closest('td').width(self.width());
});
.second td * {
  writing-mode: tb-rl;
  -webkit-writing-mode: vertical-rl;
  writing-mode: vertical-rl;
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table border=1>
  <tr>
    <td colspan=4>This cell has colspan=4</td>
  </tr>
  <tr class="second">
    <td>
      <div>Writing-mode:vertical-rl inside block</div>
    </td>
    <td>
      <div>Writing-mode:vertical-rl inside block</div>
    </td>
    <td>
      <div>Writing-mode:vertical-rl inside block</div>
    </td>
    <td>
      <div>Writing-mode:vertical-rl inside block</div>
    </td>
  </tr>
</table>

<table border=1>
  <tr>
    <td colspan=4>This cell has colspan=4</td>
  </tr>
  <tr class="second">
    <td id="thistd"><a id="this">Writing-mode:vertical-rl inside inline</a></td>
    <td><a>Writing-mode:vertical-rl inside inline</a></td>
    <td><a>Writing-mode:vertical-rl inside inline</a></td>
    <td><a>Writing-mode:vertical-rl inside inline</a></td>
  </tr>
</table>

Seems like vertical-rl is not supported very well... hummmmm try to avoid it for now I guess

https://www.w3.org/International/tests/repo/results/writing-mode-vertical

like image 69
Dalin Huang Avatar answered Nov 10 '22 23:11

Dalin Huang