2

I using html-table to present some information. This table can be very long. So, if the user scroll down, the header of the rows is going outside of the screen.

What I trying to do is to make the header of the table - sticky, when the user is scroll down.

This is how my HTML + CSS + JS (jquery) looks like: https://jsfiddle.net/d3h7mxLf/2/

HTML:

<table id="the-table">
    <thead>
        <tr>
            <th class="domain-col">Name</th>
            <th>Size</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
        <tr>
            <td>Joe</td>
            <td>40</td>
        </tr>
    </tbody>
</table>

CSS:

th {
    background-color:red;
}
#the-table {
    width: 100%;
}

JQuery:

var topPos;

function AncorControlMatches() {
    topPos = Math.max(0, $("#the-table").offset().top - $(this).scrollTop());
    if (topPos == 0) {
        $("#the-table thead tr").css("top", topPos);
        $("#the-table thead tr").css("position", "fixed");
    } else {
        $("#the-table thead tr").removeAttr("style");
    }
}


$(window).scroll(function () {
    AncorControlMatches();
});

$(document).ready(function () {
    setTimeout(function () {
        AncorControlMatches();
        $(window).trigger('resize');
    }, 300);
});

The problem is when the user is scroll down, the header column width is being wrong. The width of the elements became very small.

How I can solve this problem?

No1Lives4Ever
  • 6,430
  • 19
  • 77
  • 140
  • possible duplicate of [Freezing/Fixing the Top Header Row of a table](http://stackoverflow.com/questions/15307135/freezing-fixing-the-top-header-row-of-a-table) – Palpatim Feb 10 '15 at 18:04
  • This is not the same question\answers. They are implementing this in different ways. – No1Lives4Ever Feb 10 '15 at 18:54
  • Please check your solution here where I have answered. https://stackoverflow.com/questions/54044479/table-with-sticky-header-and-resizable-columns-without-using-jquery/54105499#54105499 – Ravi Apr 11 '19 at 11:33

2 Answers2

16

I know this is an already solved old question, but its name is easy to search for so I think it's appropriate to add a solution of today.

For modern browsers you could use the sticky position to achieve the same without any Javascript at all!

Sticky: https://caniuse.com/#search=sticky

th {
    background-color:red;
}
#the-table {
    width: 100%;
    position: relative;
}
#the-table thead th {
    position: sticky;
    top: 0;
}

Example: https://jsfiddle.net/omsa8xt1/

Erik.J
  • 586
  • 4
  • 7
3

I have updated your fiddle.

You need position: absolute not fixed since fixed position is anchored to the viewport, not the containing positioned element.

slashsharp
  • 2,823
  • 2
  • 19
  • 26