简体   繁体   中英

Sticky table header

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?

I have updated your fiddle .

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

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM