Search code examples
htmlcsssafari

Table element width using column widths - Safari


I have a table element with its column widths set to 120px. The table element width is automatically calculated by aggregating all the column widths: 3 x 120 = 360px. This appears to work fine across all browsers, however in Safari when I insert text to one of its cells with a width that exceeds the column width (and requires wrapping) - all of the column's and the table's widths appear to expand and ignore the 120px column width. The expansion appears to be directly linked to how long the table width would be if the width restrictions weren't set.

Chrome and Firefox appear to honour the pre-set column widths and do not expand them when there is a cell with wrapped text.

I am not quite sure if this is a Safari bug, but would ideally like to find a way to get it to work the same as it does in the other browsers.

To note, one way I found to get around this is to manually set the table width, however I am not able to use this solution as my component facilitates functionality that allows users to dynamically control the column widths, hence I would like to find a way to automatically set the table width just like in the other browsers.

table {
  border-spacing: 0px;
}

th {
  width: 120px;
  padding: 0px;
}

th, td {
  border: 1px solid grey;
  word-wrap: anywhere;
}
Table with wrapping text:
<table>
  <tr>
    <th>Name</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>
    
<br>
Table with no wrapping text:
<table>
  <tr>
    <th>Name</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Magazzini</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>


Solution

  • I was able to fix the problem by adding table-layout: fixed and width: min-content properties into the table style tag.

    Additionally, the word-wrap: anywhere property was no longer needed as the above properties forced the cells to automatically wrap text in all browsers.

    It is worth noting that width: fit-content could not be used as it causes the tables to expand their width to the parent element width in Firefox, hence creating another inconsistency in cross-browser behaviour. However, width: max-content can be used as a valid substitute.

    table {
      border-spacing: 0px;
      /* solution */
      table-layout: fixed;
      width: min-content;
    }
    
    th {
      width: 120px;
      padding: 0px;
    }
    
    th, td {
      border: 1px solid grey;
      /* no longer need this
        word-wrap: anywhere; */
    }
    <table>
      <tr>
        <th>Name</th>
        <th>Contact</th>
        <th>Country</th>
      </tr>
      <tr>
        <td>Alfreds Futterkiste</td>
        <td>Maria Anders</td>
        <td>Germany</td>
      </tr>
      <tr>
        <td>Island Trading</td>
        <td>Helen Bennett</td>
        <td>UK</td>
      </tr>
      <tr>
        <td>Magazzini Alimentari Riuniti</td>
        <td>Giovanni Rovelli</td>
        <td>Italy</td>
      </tr>
    </table>
        
    <br>
    Table with no wrapping text:
    <table>
      <tr>
        <th>Name</th>
        <th>Contact</th>
        <th>Country</th>
      </tr>
      <tr>
        <td>Alfreds</td>
        <td>Maria Anders</td>
        <td>Germany</td>
      </tr>
      <tr>
        <td>Island Trading</td>
        <td>Helen Bennett</td>
        <td>UK</td>
      </tr>
      <tr>
        <td>Magazzini</td>
        <td>Giovanni Rovelli</td>
        <td>Italy</td>
      </tr>
    </table>