sticky table header

by gvee

HTML

<div class="faking-content"></div>
<table>
    <thead>
        <th>A</th>
        <th>B</th>
        <th>C</th>
        <th>D</th>
    </thead>
    <tr>
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
    </tr>
    <tr>
        <td>2</td>
        <td>2</td>
        <td>2</td>
        <td>2</td>
    </tr>
    <tr>
        <td>3</td>
        <td>3</td>
        <td>3</td>
        <td>3</td>
    </tr>
    <tr>
        <td>4</td>
        <td>4</td>
        <td>4</td>
        <td>4</td>
    </tr>
    <tr>
        <td>5</td>
        <td>5</td>
        <td>5</td>
        <td>5</td>
    </tr>
    <tr>
        <td>6</td>
        <td>6</td>
        <td>6</td>
        <td>6</td>
    </tr>
    <tr>
        <td>7</td>
        <td>7</td>
        <td>7</td>
        <td>7</td>
    </tr>
    <tr>
        <td>8</td>
        <td>8</td>
        <td>8</td>
        <td>8</td>
    </tr>
    <tr>
        <td>9</td>
        <td>9</td>
        <td>9</td>
        <td>9</td>
    </tr>
</table>
<div class="faking-content"></div>
<table class="second">
    <thead>
        <th>W</th>
        <th>X</th>
        <th>Y</th>
        <th>Z</th>
    </thead>
    <tr>
        <td>1</td>
        <td>1</td>
        <td>1</td>
        <td>1</td>
    </tr>
    <tr>
        <td>2</td>
        <td>2</td>
        <td>2</td>
        <td>2</td>
    </tr>
    <tr>
        <td>3</td>
        <td>3</td>
        <td>3</td>
        <td>3</td>
    </tr>
    <tr>
        <td>4</td>
        <td>4</td>
        <td>4</td>
        <td>4</td>
    </tr>
    <tr>
        <td>5</td>
        <td>5</td>
        <td>5</td>
        <td>5</td>
    </tr>
    <tr>
        <td>6</td>
        <td>6</td>
        <td>6</td>
        <td>6</td>
    </tr>
    <tr>
        <td>7</td>
        <td>7</td>
        <td>7</td>
        <td>7</td>
    </tr>
    <tr>
        <td>8</td>
        <td>8</td>
        <td>8</td>
        <td>8</td>
    </tr>
    <tr>
        <td>9</td>
        <td>9</td>
        <td>9</td>
    ...

CSS

* {
    margin: 0;
    border: 0;
    padding:0;
}
table {
    border-collapse: collapse;
    margin: 10px;
}
table.second {
    margin-left: 100px;
}
th, td {
    width: 50px;
    height: 50px;
    background-color: #eee;
    text-align: center;
    border: 1px solid #ddd;
}
.sticky-header {
    display: none;
    position: fixed;
    top: 0px;
}
.sticky-header th {
    background-color: red;
}
.faking-content {
    height: 200px;
}

JavaScript

// Generate our sticky-headers on page load.
$('thead').each(function() {
    $(this).children().clone(true).insertBefore($(this)).wrap('<tr class="sticky-header"></tr>');
});

$(document).scroll(function () {
    var docTop = $(this).scrollTop();

    $('table').each(function () {

        var t = $(this);
        var th = t.find('.sticky-header');
        var thead = t.find('thead');

        if (docTop >= thead.offset().top && docTop < t.offset().top + t.height() - th.height()) {
            th.show();
        } else {
            th.hide();
        }

    });
});