HTML table with fixed header and footer and scrollable body without fixed widths

I finally implemented a working solution!

The relevant CSS is the following:

.wrapper {
  width: 90%;
  position: relative;
  border: 1px solid #000;
  background: #efefef;
  overflow: hidden;
  border-radius: 7px;
}

.container {
  overflow-y: auto;
  height: 200px;
  border-top: 41px solid transparent;
  border-bottom: 41px solid transparent;
}

table {
  border-spacing: 0;
  border-collapse: collapse;
  width: 100%;
}

td + td {
  border-left: 1px solid #fff;
}

td, th {
  border-bottom: 1px solid #fff;
  background: #efefef;
  padding: 10px;
}

thead tr th,
tfoot tr td {
  height: 0;
  line-height: 0;
  margin: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}

thead tr th div,
tfoot tr td div {
  position: absolute;
  color: #fff;
  height: 20px;
  padding: 10px;
  margin-left: -10px;
  line-height: normal;
  width: 100%;
  z-index: 2;
  text-align: left;
  font-weight: bold;
}

thead tr th div {
  border-left: 1px solid #000;
  border-bottom: 1px solid #000;
}

tfoot tr td div {
  border-top: 1px solid #000;
}

tfoot tr td div.c1,
thead tr th div.c1 {
  background: violet;
}

tfoot tr td div.c2,
thead tr th div.c2 {
  background: green;
}

tfoot tr td div.c3,
thead tr th div.c3 {
  background: yellow;
}

thead tr th div {
  top: 0;
}

tfoot tr td div {
  bottom: 0;
}

thead tr th:first-child div,
tfoot tr td:first-child div {
  border-left: none;
}

And this is the markup:

<div class="wrapper">
  <div class="container">
    <table>
      <thead>
        <tr>
          <th>
            Header one *leads the width* (case 1)
            <div class="c1">
              Header one *leads the width* (case 1)
            </div>
          </th>
          <th>
            Header two
            <div class="c2">
              Header two
            </div>
          </th>
          <th>
            Header three
            <div class="c3">
              Header three
            </div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three [first]</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three</td>
        </tr>
        <tr>
          <td>Column one</td>
          <td>Column two *leads the width* (case 2)</td>
          <td>Column three [LATEST]</td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td>
            Footer one
            <div class="c1">
              Footer one
            </div>
          </td>
          <td>
            Footer two
            <div class="c2">Footer two</div>
          </td>
          <td>
            Footer three *leads the width* (case 3)
            <div class="c3">Footer three *leads the width* (case 3)</div>
          </td>
        </tr>
      </tfoot>
    </table>
  </div>
</div>

It works on Chrome, Firefox, Safari and IE11 (I don't know how it behaves on older browsers). See it on codepen: https://codepen.io/daveoncode/pen/LNomBE


HTML table with fixed header and footer and scrollable body without fixed widths using CSS only.

This is simple logic we can use table header put position: sticky method below the example:

table th {
position:sticky;
top: 0;
}

UPDATE 2022

Nowadays and for awhile browsers have full support for position: sticky

So we can apply it to thead th and tfoot tr

body {
  margin: 0
}

table {
  width: 100%
}

thead th,
tfoot tr {
  position: sticky;
  background: red
}

thead th {
  top: 0
}

tfoot tr {
  bottom: 0
}

th,
td {
  font-size: 12px;
  text-align: center
}


/*give some space between thead and tfoot*/

tbody tr:first-of-type td {
  padding-top:  10px;
}

tbody tr:last-of-type td {
  padding-bottom: 10px;
}
<table>
  <thead>
    <tr>
      <th>Header one *leads the width* (case 1)</th>
      <th>Header two</th>
      <th>Header three</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
    <tr>
      <td>Column one</td>
      <td>Column two *leads the width* (case 2)</td>
      <td>Column three</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Footer one</td>
      <td>Footer two</td>
      <td>Footer three *leads the width* (case 3)</td>
    </tr>
  </tfoot>
</table>

OLD Answer

you can achieve what you want by using a wrapper to your table (div) and make the tr from thead and tfoot a position:absolute

body {
  margin: 0
}

div {
  max-height: 500px;
  overflow-y: auto;
}

table {
  width: 100%
}

thead tr,
tfoot tr {
  position: absolute;
  left: 0;
  right: 15px;
  /* to not cover the scrollbar*/
  background: red
}

thead th,
tfoot td {
  display: inline-block;
}

thead tr {
  top: 0
}

tfoot tr {
  top: 500px/* same value has max-height from div */
}

th,
td {
  width: calc((100%/3) - 5px);
  font-size: 12px;
  text-align: center
}


/*give some space between thead and tfoot*/

tbody tr:first-of-type td {
  padding-top: 35px;
}

tbody tr:last-of-type td {
  padding-bottom: 35px;
}
<div>
  <table>
    <thead>
      <tr>
        <th>Header one *leads the width* (case 1)</th>
        <th>Header two</th>
        <th>Header three</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
      <tr>
        <td>Column one</td>
        <td>Column two *leads the width* (case 2)</td>
        <td>Column three</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>Footer one</td>
        <td>Footer two</td>
        <td>Footer three *leads the width* (case 3)</td>
      </tr>
    </tfoot>
  </table>
</div>