JSFiddle - React, Tailwind, and code Playground

by mrmamen

HTML

<p>Leading lines</p><p>1</p><p>2</p><p>3</p><p>4</p>
<p>1111111111111111111111111111111111111111111111111
 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    11111111111</p>

<table class="tableWithFloatingHeader" style="border: 3px">
<thead>
<tr>
    <th>table1 col header</th>
    <th>table1 col header</th>
</tr>
</thead>
<tbody>
<tr>
    <td>table1 data1 with some extra long text. I would like to be able to "tweak" an HTML table's presentation to add a single feature: when scrolling down through the page so that the table is on the screen but the header rows are off-screen, I would like the headers to remain visible at the top of the viewing area.</td>
    <td>table1 data1</td>
</tr>
<tr>
    <td>table1 data2</td>
    <td>table1 data2</td>
</tr>
<tr>
    <td>table1 data3</td>
    <td>table1 data3</td>
</tr>
<tr>
    <td>table1 data4</td>
    <td>table1 data4</td>
</tr>
<tr>
    <td>table1 data5</td>
    <td>table1 data5</td>
</tr>
<tr>
    <td>table1 data6</td>
    <td>table1 data6</td>
</tr>
<tr>
    <td>table1 data7</td>
    <td>table1 data7</td>
</tr>
<tr>
    <td>table1 data8</td>
    <td>table1 data8</td>
</tr>
<tr>
    <td>table1 data9</td>
    <td>table1 data9</td>
</tr>
<tr>
    <td>table1 data10</td>
    <td>table1 data10</td>
</tr>
</tbody>
</table>

<p>Between lines</p><p>1</p><p>2</p><p>3</p><p>4</p>

<table class="tableWithFloatingHeader" style="border: 3px">
<thead>
<tr>
    <th>t2 col header</th>
    <th>t2 col header</th>
</tr>
</thead>
<tbody>
<tr>
    <td>t2 data1</td>
    <td>t2 data1</td>
</tr>
<tr>
    <td>t2 data2</td>
    <td>t2 data2</td>
</tr>
<tr>
    <td>t2 data3</td>
    <td>t2 data3</td>
</tr>
<tr>
    <td>t2 data4</td>
    <td>t2 data4</td>
</tr>
<tr>
 ...

CSS

th {
    background-color: lightgrey;
    border: 1px solid black;
}
td {
    border: 1px solid black;
}

JavaScript

function UpdateTableHeaders() {
            $("div.divTableWithFloatingHeader").each(function() {
                var originalHeaderRow = $(".tableFloatingHeaderOriginal", this);
                var floatingHeaderRow = $(".tableFloatingHeader", this);
                var offset = $(this).offset();
                var scrollTop = $(window).scrollTop();
                if ((scrollTop > offset.top) && (scrollTop < offset.top + $(this).height())) {
                    floatingHeaderRow.css("visibility", "visible");
                    floatingHeaderRow.css("top", Math.min(scrollTop - offset.top, $(this).height() - floatingHeaderRow.height()) + "px");

                    // Copy cell widths from original header
                    $("th", floatingHeaderRow).each(function(index) {
                        var cellWidth = $("th", originalHeaderRow).eq(index).css('width');
                        $(this).css('width', cellWidth);
                    });

                    // Copy row width from whole table
                    floatingHeaderRow.css("width", $(this).css("width"));
                }
                else {
                    floatingHeaderRow.css("visibility", "hidden");
                    floatingHeaderRow.css("top", "0px");
                }
            });
        }

        $(document).ready(function() {
            $("table.tableWithFloatingHeader").each(function() {
                $(this).wrap("<div class=\"divTableWithFloatingHeader\" style=\"position:relative\"></div>");

                var originalHeaderRow = $("tr:first", this)
                originalHeaderRow.before(originalHeaderRow.clone());
                var clonedHeaderRow = $("tr:first", this)

                clonedHeaderRow.addClass("tableFloatingHeader");
                clonedHeaderRow.css("position", "absolute");
                clonedHeaderRow.css("top", "0px");
                clonedHeaderRow.css("left", $(this).css("margin-left"));
               ...