Scrolling table body

In the practice log web application, I had a large table of data to display. I wanted to table to scroll, but I didn’t want the table header row to scroll off the screen. Especially since users will be looking at the most recent data at the bottom of the table most of the time.

The key to making this work is to put the table into a containing div and to set a hard coded height for the table and header. The containing div needs to have a specific height and an overflow of hidden. The table body needs to have a height that is smaller than the containing div by the height of the header. It needs to have a display of block, overflow of auto and vertical-align of middle:

.tableContainer {
  height: 600px;
  overflow: hidden;
}
.tableContainer table tbody {
  height: 575px;
  display: block;
  overflow: auto;
  vertical-align: middle;
}

This works, but now the table header columns aren’t lined up with the table body columns. This is because the scroll bar width is taken from the body and not from the header. I didn’t find a perfect solution to this problem. First you want to move the header over by the width of the scroll bar. Then you have to adjust the width of each th to be a fraction less than the width of each td. The fraction depends on how many columns you have. I had 10 columns, so this was the code I ended up with:

.tableContainer table thead tr {
  display: block;
  position: relative;
  margin-right: 10px;
}.tableContainer td {
  width: 100px;
}
.tableContainer th {
  width: 98px;
}

Then, I prettied things up a bit with some borders and ended up with the following css:

.tableContainer {
  height: 600px;
  margin-top: 10px;
  margin-left: 15px;
  overflow: hidden;
}
.tableContainer table {
  border: 1px solid #555;
  border-collapse: separate;
  border-spacing: 0px;
  border-width: 0px;
}
.tableContainer table thead tr {
  display: block;
  position: relative;
  margin-right: 10px;
}

.tableContainer table tbody {
  height: 575px;
  display: block;
  overflow: auto;
  vertical-align: middle;
}
.tableContainer td {
  width: 100px;
  border-bottom: none;
  border-left: none;
  border-right: 1px solid #DDD;
  border-top: 1px solid #DDD;
}
.tableContainer th {
  width: 98px;
  border-bottom: none;
  border-left: none;
  border-right: 1px solid #555;
}

I also wanted the table to scroll to the bottom on startup. That was done with one line of javascript:

$(#tableBody).scrollTop(9999);

The final results looks like this:

Leave a Reply