JSFiddle - React, Tailwind, and code Playground

by Ilmv

HTML

<div id="container">
    <table>
        <thead>
            <tr>
                <th>A</th>
                <th>B</th>
                <th>C</th>
                <th>D</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>Some Really Long String</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
                <td>3</td>
                <td>4</td>
            </tr>
            <tr>
               ...

CSS

#container {
    height: 500px;
    overflow-y: auto;  
    border: 1px solid red;
    //position: relative;
}

table {
    margin: 50px 0 5000px 0;  
    width: 75%;
}

td, th {
    border: 1px solid #ccc; 
    padding: 2px;
}

th {
    border-bottom: 2px solid orange;   
}

thead tr {
    background-color: white;   
}

table.sticky-header thead {
    position: relative;   
    width: 75%;
}

JavaScript

// *****
// NOTES

// the thead element loses it's width when set to absolute
// cannot even set as same width because th elements have no width
// might be dangerous explicitly setting widths on float event
// ^ especially with colspans etc

// possible to clone (1) the table, hide (2) the tbody + tfoot and
// display at the top? Leaving the existing thead to float on by.
// 1) Don't want to 

$(document).ready(function() {

    var table_margin_top = parseInt($('table').css('marginTop'));

    $('#container').scroll(function() {

        var $self = $(this),
            $table = $self.find('table'),
            $thead = $table.find('thead'),
            offset = $table.position(),
            container_position = $self.position();
        
        console.log(offset.top + (container_position.top - table_margin_top));
        
        
        
        // now we're not relative, include container position
        if (offset.top + table_margin_top < 0 + container_position.top) {
            
            $table.addClass('sticky-header');

            
            
            // position doesn't include things like borders
            // probably not padding either
            $thead.css('top', parseInt(container_position.top));

            $table.css('marginTop', table_margin_top + $thead.height());

        } else {

            $table.removeClass('sticky-header');
            $table.css('marginTop', table_margin_top);

        }

    });

});