0

When a width value is applied to table cell, once the table width reaches the viewport width, the rule then becomes ignored, e.g.

td, th { width: 400px; }

I would expect a 10-column table to be (around) 4000px, but Firefox and Chrome only stretch out the table to the viewport width (see Fiddle). Upon which, the cell width isn't actually set to 400px. I read in the question below that table-layout:fixed is used to force cell widths, but it doesn't work here.

Two similar questions exist here and here, but they only address initial widths, and don't discuss the viewport limitation.

Why does this happen please? I see there is a workaround...

td, th { min-width: 400px; max-width:400px; }

...but it just seems odd when width alone should achieve exactly that purpose.

EvilDr
  • 8,943
  • 14
  • 73
  • 133

2 Answers2

1

display:table-cell ( which is the default for td element ) makes the td have widths restricted to the table width. if the table has 100px width, they will stay in 100px width. but if you set them a width of 400px and table has 100px width, they will ignore the width of table and expand without restriction. see first answer

  1. add width:0 to table and it will work because the table-cells can't collapse relative to a width:0 so they expand without restriction

see snippet below or jsFIddle

table {
  table-layout:fixed;
  border-collapse: collapse;
  background-color: white;
width:0;
}

td,
th {
  border: 1px solid #999;
  padding: 0.25em;
  text-align: left;
  width: 400px; // If uncommented, rule is ignored
}
<div>
  <table>
    <thead>
      <tr>
        <th>&nbsp;</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
    </tbody>

  </table>
</div>
  1. you can set the width of the div that wraps the table and set overflow auto to it ( thats a fix not a neat solution )

see snippet below or jsFiddle

table {
  table-layout:fixed;
  border-collapse: collapse;
  background-color: white;
}
div {
 width:4000px;
 overflow:auto;
}

td,
th {
  border: 1px solid #999;
  padding: 0.25em;
  text-align: left;
  width: 400px;
}
<div>
  <table>
    <thead>
      <tr>
        <th>&nbsp;</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
    </tbody>

  </table>
</div>
  1. i know you didn't set the jQuery tag in your question , but you might want to use it so you calculate the width of the div dynamically depending on the sum of the td widths

see snippet below or jsFiddle

var tdWidthTotal = 0;

$('td').each(function(index) {
    tdWidthTotal += parseInt($(this).width(), 10);
});
$("div").width(tdWidthTotal)
table {
  table-layout:fixed;
  border-collapse: collapse;
  background-color: white;
}
div {
 overflow:auto;
}

td,
th {
  border: 1px solid #999;
  padding: 0.25em;
  text-align: left;
  width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <table>
    <thead>
      <tr>
        <th>&nbsp;</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
        <th>aaa</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
    </tbody>

  </table>
</div>
Mihai T
  • 17,254
  • 2
  • 23
  • 32
  • Thanks. The *fix* I put in the question is good enough to be honest. I'm more interested in *why* this even happens? Its just plain confusing to me... – EvilDr May 26 '17 at 09:12
  • because that's how display:table-cell work. they get their widths relative to the table width , but you can also use `width:0` on table and it will work :) see my no 1 answer – Mihai T May 26 '17 at 09:24
0

Apparently display: table-cell ignores width. You can add an element with display: block and width: 400px inside your th elements and it will work:

th div{
  width: 400px;
}

https://jsfiddle.net/abogvgsb/11/

gaynorvader
  • 2,619
  • 3
  • 18
  • 32
  • *Apparently display: table-cell ignores width.* It doesn't appear to ignore it until the table width reaches the viewport's width, which is confusing...! While the fixes work fine, I keen to understand *why* this happens - is there a rationale for it? – EvilDr May 26 '17 at 09:25