Jerry Dodge
Jerry Dodge

Reputation: 27276

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.

Upvotes: 0

Views: 1993

Answers (6)

Jacques Mulder
Jacques Mulder

Reputation: 11

This pure css solution worked the best for me and it keeps the columns aligned correctly.

thead {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
}

background-color:#FFF;

Add color to the css if you want it not to be transparent.

Remember to add thead opening and closing tags to your table head for it to work.

Credit to Adrian Roselli https://adrianroselli.com/2020/01/fixed-table-headers.html

Upvotes: 0

sol
sol

Reputation: 22919

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>

Upvotes: 1

Zainul Abideen
Zainul Abideen

Reputation: 1900

try this

#compareHead{
    position: fixed;
}

Upvotes: 0

CodeByZach
CodeByZach

Reputation: 11

Something like this

$(window).scroll(function(){ 

var a = 112;
var pos = $(window).scrollTop();
if(pos > a) {
    $("#compareHead").css({
                position: 'fixed',
                top: '51px'
            });
}
});

Upvotes: 0

easy
easy

Reputation: 318

Add style property position:fixed to the element.

Upvotes: -1

fernando
fernando

Reputation: 822

Try to use this JS plugin to get that effect. You can see loads of demos how to use it.

Upvotes: -1

Related Questions