0

: )

I know this question has been asked a lot, but I tried many solutions and just couldn't make it work properly.

I need to make the tbody of my table scrollable with fixed headers.

To start my table is built dynamically and is very large. 19 columns and about 800 rows.

First I worked with the jquery datatables plugin. After the table is in the container:

var tbl = createFilter('readDataTbl', '', condition);
    $('#tableDiv').empty().append(tbl);

    $('#readDataTbl').dataTable({
        "scrollY": "200px",
        "scrollCollapse": true,
        "paging": false
    });

but that creates a scroll in x and the headers are frozen like that:

enter image description here

Then I tried a css solution as follows:

 <style>
        table {
    border-collapse: collapse;
    width: 100%;
}
thead {
    text-align:left;
    display: table;
    float: left;
    width: 100%;
}
thead tr {
    display: table-row;
    width: 100%;
}
tbody {
    display: block;
    height: 120px;
    overflow: auto;
    float: left;
    width: 100%;
}
tbody tr {
    display: table;
    width: 100%;
}
tbody tr {
    height: 18px;
}
tbody td {
    padding:1px 8px;
}
th, td {
    width: 25%;
}

tr:after{   /* IE8 fix */
    content: ".";
    margin-left: -3px; /* to hide the content above tr */ /* not necessary if you are ok with 1px gap */
    visibility: hidden;
}
     </style>

But that just creates a mess in the tbody like that:

enter image description here

Then I tried thie method from Here adjusting the THs width after: css:

<style>
        thead, tbody { display: block; }

        tbody {
            height: 100px;       /* Just for the demo          */
            overflow-y: auto;    /* Trigger vertical scroll    */
            overflow-x: hidden;  /* Hide the horizontal scroll */
        }
     </style>

js:

var tbl = createFilter('readDataTbl', '', condition);
    $('#tableDiv').empty().append(tbl);

    var $table = $('table');
    var $bodyCells = $table.find('tbody tr:first').children();
    

    // Get the tbody columns width array
    var colWidth = $bodyCells.map(function () {
        return $(this).width();
    }).get();

    // Set the width of thead columns
    $table.find('thead tr').children().each(function (i, v) {
        $(v).width(colWidth[i]);
    });

And then I noticed the THs long text made them bigger like that:

enter image description here

what could help me achieve my goal? Thought about inserting divs inside THs but not sure about it..

Thanks! : ]

Community
  • 1
  • 1
Dvirski
  • 321
  • 4
  • 16
  • 36

3 Answers3

0

You can do this with the help of flex-box layout. It certainly won't work on safari though. All other major browsers render it perfectly.

/* CSS */

html, body {
    height: 100%;
    width: 100%;
    overflow: hidden;
    margin: 0;
    padding: 0;
}

.table {
    height: 100%;
    width: 100%;
}

.table .tr {
    display: flex;
    flex-flow: row wrap;
}

.table .tr .td, .table .tr .th {
    flex: 1;
}

.table .thead {
    padding-right: 17px;
    /* this padding accounts for the width of the scroll bar
     * you could compute the default scrollbar width for any browser and set this padding accordingly
     * else the headers and records will be misaligned by that margin. */
}

.table .viewport {
    height: 640px;
    overflow: scroll;
}

/* HTML */

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="ftable.css" />
    <title>Flex tables</title>
</head>
<body>

<div class="table">
    <div class="thead">
        <div class="tr">
            <div class="th">Column 1</div>
            <div class="th">Column 2</div>
            <div class="th">Column 3</div>
            <div class="th">Column 4</div>
            <div class="th">Column 5</div>
        </div>
    </div>
    <div class="viewport tbody">
        <div class="canvas">
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
            <div class="tr">
                <div class="td">Value 1</div>
                <div class="td">Value 2</div>
                <div class="td">Value 3</div>
                <div class="td">Value 4</div>
                <div class="td">Value 5</div>
            </div>
        </div>
    </div>
</div>

</body>
</html>
  • I made one sample, with two or three lines of javascript you could make it work perfectly fine, atleast on most of the major browsers. I haven't been around stack for a few years. So bear with me in my editing. –  Feb 03 '15 at 20:53
  • I made a mistake while copying the snippet. Check for the last block in the css part. Its take care of. –  Feb 03 '15 at 21:18
0

You can't do this perfectly without some javascript. The best way to accomplish this would be to use a clone of the header, prepend it to the element, apply a fixed position on it and hide the original. Hope this helps. You might also need to bind each column width to the width of the original.

0

I think you can use bootstrap css and some table styles. You can adjust the th height and width for better results. Also you must calculate the percentage width of tbody td, thead th { ie if you have 19 columns then 100/19 which is around 5%. So your column width will be very less and you will need to increase the height for thead th {

        table {
          width: 100%;
        }
        thead,
        tbody,
        tr,
        td,
        th {
          display: block;
        }
        tr:after {
          content: ' ';
          display: block;
          visibility: hidden;
          clear: both;
        }
        thead th {
          height: 50px;
          /*text-align: left;*/
        }
        tbody {
          height: 120px;
          overflow-y: auto;
        }
        thead {
          /* fallback */
        }
        tbody td,
        thead th {
          width: 19.2%;
          float: left;
        }
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table class="table table-striped">
  <thead>
    <tr>
      <th>Make fg jfdg jfgj fgjfg jfgj fgj fgj g jfgj fgj dfgj fgjfg</th>
      <th>Model</th>
      <th>Color</th>
      <th>Year</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="filterable-cell">Fordfghdfg jfdgjfdgj fgj fdgj fgjfgj df</td>
      <td class="filterable-cell">Escort</td>
      <td class="filterable-cell">Blue</td>
      <td class="filterable-cell">2000</td>
    </tr>
    <tr>
      <td class="filterable-cell">Ford</td>
      <td class="filterable-cell">Escort</td>
      <td class="filterable-cell">Blue</td>
      <td class="filterable-cell">2000</td>
    </tr>
    <tr>
      <td class="filterable-cell">Ford</td>
      <td class="filterable-cell">Escort</td>
      <td class="filterable-cell">Blue</td>
      <td class="filterable-cell">2000</td>
    </tr>
    <tr>
      <td class="filterable-cell">Ford</td>
      <td class="filterable-cell">Escort</td>
      <td class="filterable-cell">Blue</td>
      <td class="filterable-cell">2000</td>
    </tr>
  </tbody>
</table>
abhiklpm
  • 1,603
  • 2
  • 16
  • 21