Search code examples
htmlcsshtml-table

How to make table header pinned to top of HTML table?


I have a web page which is used to compare the features of multiple things, let's call them widgets. Each widget is represented as its own column, and the rows are each possible feature of the widgets. Each cell represents whether that feature is supported for each widget.

Now, there are a lot of features, making the page very high. There may also potentially be many widgets, thus making the table very wide with columns too. Therefore, scrolling is very important.

The problem is that when the user scrolls down, I would like to keep the header row pinned to the top at all times, and only scroll the rest of the table. There is some text above the table too, and I want that text to scroll off the page when the user scrolls down, but the headers should stop at the top.

Here's at least a mock-up of how this table is laid out:

    <div>

        <table id="compareTable">
            <tr class="compareTableHead" id="compareHead">
                <td>Widget One</td>
                <td>Widget Two</td>
                <td>Widget Three</td>
                <td>Widget Four</td>
                <td>Widget Five</td>
            </tr>
            <tbody id="compareTableBody">
                <tr>
                    <td class="ch">Feature One</td>
                    <td class="uch">Feature One</td>
                    <td class="uch">Feature One</td>
                    <td class="ch">Feature One</td>
                    <td class="uch">Feature One</td>
                </tr>
                <tr>
                    <td class="uch">Feature Two</td>
                    <td class="uch">Feature Two</td>
                    <td class="ch">Feature Two</td>
                    <td class="uch">Feature Two</td>
                    <td class="ch">Feature Two</td>
                </tr>
            </tbody>
        </table>
    </div>

How do I make the header row pinned to the top at all times?

NOTE: There's of course more on the real page than above, here's a screenshot:

Screenshot

Also, if you wish to see the actual full page itself, click here.


Solution

  • Create a class to lock the table head:

    .locked {
      position: fixed;
      top: 0;
      right: 0;
      width: 100%;
    }
    

    Use jQuery to add this class when the table head reaches the top of the window, and remove it when it is not at the top.

    var lockOffset = $('.compareTableHead').offset().top;
    
    $(window).scroll(function(){
      var locked = $('.compareTableHead'),
          scroll = $(window).scrollTop();
    
      if (scroll >= lockOffset) locked.addClass('locked');
      else locked.removeClass('locked');
    });
    

    Add a few extra CSS rules to .locked to ensure it displays correctly:

    .locked {
     ...
      display: table; // this ensures the table head spans full width of window
      padding: 0 8px; // to keep alignment with unfixed table head
      box-sizing: border-box; 
    }
    

    CODEPEN

    SNIPPET

    var lockOffset = $('.compareTableHead').offset().top;
    
    $(window).scroll(function() {
      var locked = $('.compareTableHead'),
        scroll = $(window).scrollTop();
    
      if (scroll >= lockOffset) locked.addClass('locked');
      else locked.removeClass('locked');
    });
    table {
      width: 100%;
      font-family: sans-serif;
    }
    table tr td {
      padding: 20px;
    }
    .compareTableHead td {
      font-weight: bold;
      text-transform: uppercase;
      background-color: lightblue;
      color: white;
    }
    .locked {
      position: fixed;
      top: 0;
      right: 0;
      margin: auto;
      width: 100%;
      display: table;
      padding: 0 8px;
      box-sizing: border-box;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="randomText">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem minima ad delectus nostrum dolor, maiores voluptates, repellat cupiditate officiis, libero modi. Corporis voluptatem incidunt consequuntur cupiditate a error reprehenderit. Accusantium!
      <br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Similique quis quod quos eaque nobis rerum sequi voluptate tempore harum fuga? Est laudantium nobis nam ad at! Repellendus officia minus ipsam.</div>
    <div>
    
      <table id="compareTable">
        <tr class="compareTableHead" id="compareHead">
          <td>Widget One</td>
          <td>Widget Two</td>
          <td>Widget Three</td>
          <td>Widget Four</td>
          <td>Widget Five</td>
        </tr>
        <tbody id="compareTableBody">
          <tr>
            <td class="ch">Feature One</td>
            <td class="uch">Feature One</td>
            <td class="uch">Feature One</td>
            <td class="ch">Feature One</td>
            <td class="uch">Feature One</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
          <tr>
            <td class="uch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
            <td class="uch">Feature Two</td>
            <td class="ch">Feature Two</td>
          </tr>
        </tbody>
      </table>
    </div>