Don’t Mess With Tables – Pure CSS Fixed-Header Left-Aligned Tables

See the Demo Page for examples and view the source for markup and CSS.

Update 9/3/13: I just added Zupa’s suggestion to the demo.

I am working on a project with a requirement for fixed-headers tables (the headers don’t scroll but the body does) which expand to fit the width of the page. We were using a JavaScript plugin which had to be called every time a page was loaded or resized. Last week one of the tables needed to have a second table within it, and I looked into CSS alternatives without JavaScript.

If you’ve ever tried to keep a table header fixed while letting the body scroll, you will find out that many solutions take the “stretch” out of the width of the table.  Tables are special and different from other HTML elements.  Browsers look at the table’s contents and then calculate from the inside out.  After much frustration, I decided not to mess with tables.

My solution is to mess with divs inside of tables. I took the divs inside the th and gave them “position: absolute; top: 0;“.  That pulls the div straight up to the top of the outer container and out of the flow of the table.  The rest of the table is a normal table and continues happily along.  The header divs retain the top left coordinate from the table, and you can even resize the page and see them shift with the columns. Unfortunately, the header divs completely loose the width they got from the th container.

My solution is a table with a scrolling body but fixed header, no JavaScript, and variable width and height.  Should you use this method? It all depends on the style of your table headers.

CONS:

  • All the problems are in the header styles.
  • No right or center aligned headers (unless you do something to set column width and hack the headers).
  • No using the column width in the style.
  • If text in a header is longer then the content in that  column it might look clipped. This is fixed by setting a min-width on the tds or content in that column.
  • The height of the table headers has to be a fixed height.
  • Horizontal scroll bars or really long non-breaking content breaks it (as well as most other methods of making a fixed-header table). (See full post.)

PROS:

  • Other then the table headers, the rest of the table is totally normal and without any hacks.
  • The table has flexible width and height.
  • No JavaScript needed, you can add JavaScript for other stuff if you like.
  • The browser will take care of everything for you on page load and resize.

SUPPORT:

  • It works in IE7+, FF, Safari, and Chrome, and Opera.
  • Some td or content in the tds need a minimum width if the header is wider then the column content.
  • IE6 has some bugs.

The th-inner divs can be styled within themselves, they can be given a fixed width, padding, margin, height, etc.  They just can’t depend on the width of the th, they use the outer container to calculate their width (which isn’t particularly helpful).  There seem to be some bugs in calculation the widths of spans within the divs as well.

I have styled a table using the jQuery plugin Table Sorter written by Christian Bach. (Please see his site for documentation. )  I used my method to keep the headers fixed but styled them to show the sorting.