1

I'm using React, trying to create a table with the header fixed on screen while the body scrolls.

I have checked many solutions but they do not satisfy my requirements below:

  1. the table must remain print friendly (all rows in the table must be printable)
  2. the column width must not be fixed (it should be based on width of col content)

This solution satisfies point 2 but not 1: https://jsfiddle.net/flytrap/g2cxd0jj/

/* this is for the main container of the table, also sets the height of the fixed header row */
.headercontainer {
  position: relative;
  border: 1px solid #222;
  padding-top: 37px;
  background: #000;
}
/* this is for the data area that is scrollable */
.tablecontainer {
  overflow-y: auto;
  height: 200px;
  background: #fff;
}

/* remove default cell borders and ensures table width 100% of its container*/
.tablecontainer table {
  border-spacing: 0;
}

/* add a thin border to the left of cells, but not the first */
.tablecontainer td + td {
  border-left:1px solid #eee; 
}

/* cell padding and bottom border */
.tablecontainer td, th {
  border-bottom:1px solid #eee;
  padding: 10px;
}

/* make the default header height 0 and make text invisible */
.tablecontainer th {
    height: 0px;
    padding-top: 0;
    padding-bottom: 0;
    line-height: 0;
    visibility: hidden;
    white-space: nowrap;
}

/* reposition the divs in the header cells and place in the blank area of the headercontainer */
.tablecontainer th div{
  visibility: visible;
  position: absolute;
  background: #000;
  color: #fff;
  padding: 9px 10px;
  top: 0;
  margin-left: -10px;
  line-height: normal;
   border-left: 1px solid #222;
}
/* prevent the left border from above appearing in first div header */
th:first-child div{
  border: none;
}

/* alternate colors for rows */
.tablecontainer tbody  tr:nth-child(even){
     background-color: #ddd;
}
Avery235
  • 4,756
  • 12
  • 49
  • 83

1 Answers1

4

Try this code

use translate to make header fixed

document.getElementById("table-container").addEventListener("scroll", function() {
  var translate = "translate(0," + this.scrollTop + "px)";
  this.querySelector("thead").style.transform = translate;

});

to print all rows in the table add this in css

   @media print {
       #table-container{
         height:100%;
       }
   }

DEMO

updation


update css with below to avoid mess up printing after scrolling

@media print {
       #table-container{
         height:100%;
       }
       #table-container thead{
         transform: none!important;
       }
   }

DEMO

Amal
  • 3,398
  • 1
  • 12
  • 20
  • This solution would require me to include JQuery in my React project? – Avery235 Aug 03 '17 at 04:22
  • Just strongly discouraged by React. Pure CSS/HTML/React solution is much preferred. – Avery235 Aug 03 '17 at 04:28
  • scrolling the table will mess up the printing. any trick to reset it to top before print? – Avery235 Aug 04 '17 at 05:51
  • Thanks so much for the help so far! Just have one last problem: http://i.imgur.com/AdaBTa1.png as soon as i start scrolling, the th borders disappeared, and when i scroll back to the top, only partial border is shown: http://i.imgur.com/ez71b6l.png. Been trying to isolate the problem for an hour without luck. My CSS is very similar to yours and the project is proprietary so I'm not able to show the source. Any clue what might possibly be wrong? – Avery235 Aug 04 '17 at 06:53
  • Hi found the issue,adding `border-spacing: 0;` to table will fix this problrm – Amal Aug 04 '17 at 07:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/151033/discussion-between-avery235-and-amal). – Avery235 Aug 04 '17 at 07:43
  • 1
    This was a great idea! I can't believe I didn't think of this immediately. Will be implementing this in React. Thanks! – Michael Paccione Apr 07 '19 at 03:32