CSS - Set overall width of table when columns have set widths

Hi all

I have a codepen here - https://codepen.io/anon/pen/LdaKEe

I need a table with a sticky header that also scrolls left to right at smaller screen sizes.

I think this is the best way to do it with thead and tbody set the display: block; and overflow-y: scroll; on the tbody

The problem with this is I have to set the widths of all the th and td and I also have the set the width of table.

Setting the widths of the th and td is fine but setting a width on the table means I could have space after the table on the right unless I work out the width of the table with the set widths of the columns.

body{
  background: grey;
  font-family: sans-serif;
}
.page{
  background: white;
  width: 800px;
  margin: 0 auto;
}
.table-con{
  overflow: scroll;
  width: 800px;
  height: 500px;
} 

thead th, tbody td{
  border: 1px solid red;
}

table{
  border-collapse: collapse; 
  width: 1500px;
}

thead th:first-child{
  width: 20px;
  padding: 0;
}

th{
  text-align: left;
}

thead{
  border-bottom: 5px solid red;

  tr{
      display: block;
      position: relative;
    }
}

tbody{
  display: block;
  height: 400px;
  overflow-y: scroll;
}

tbody tr:nth-child(even) td:not(:first-child){
  background: yellow;
}

tbody td:first-child{
  background: none;
  border: none;
  padding: 0;
}

th, td{
  padding: 10px 5px;
}

th:nth-child(1),
td:nth-child(1){
    background: none;
    border: none;
    width: 20px;
}
th:nth-child(2),
td:nth-child(2){
    width: 90px;
}
th:nth-child(3),
td:nth-child(3){
    width: 200px;
}
th:nth-child(4),
td:nth-child(4){
    width: 90px;
}
th:nth-child(5),
td:nth-child(5){
    width: 90px;
}
th:nth-child(6),
td:nth-child(6){
    width: 90px;
}
th:nth-child(7),
td:nth-child(7){
    width: 90px;
}
th:nth-child(8),
td:nth-child(8){
    width: 90px;
}
th:nth-child(9),
td:nth-child(9){
    width: 100px;
}
th:nth-child(10),
td:nth-child(10){
    width: 100px;
}

Setting the tbody to display:block breaks the relationship between the cells in the table and the header and although you can set widths the way that tables work mean that widths can change and may not always match up unless you use the table-layout:fixed algorithm but then you lose any fluidity at all (other than percentage widths).

The only usable solutions are JS solutions (although I do have some old CSS demos that are close but none really maintain the integrity between the header and the body unless you fix the widths).

These days with position:sticky available in modern browsers a more elegant way is to use position:sticky and just let older browsers naturally fall back to a normal table.

Edge, Firefox, Chrome, Safari/Webit (with prefix) are now supporting this so support is pretty good. As this is an enhancement then older browser still get a usable table but just without the fixed header.

2 Likes

Yes I think I will have to go with a JS solution as I need to support IE10

But how does the position: sticky; work

I have a codepen where I have tried to use it.

Do it like this:

Hardly anyone uses IE10 these days and it will do no harm if they just get a normal table. However IE11 doesn’t use position:sticky either so if you need to support IE11 then a js solution would be best.

If you don’t mind equal cells then you can do it without js at all.

However that doesn’t look good if you have variable data so you would need to size the cells in percentages.

Remember not to fix the width of your page either but use a max-width instead otherwise the table will not compress and you will lock out smaller screens.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.