How to stick table header(thead) on top while scrolling down the table rows with fixed header(navbar) in bootstrap 3?
Asked Answered
P

11

88

Bootstrap layout with fixed-navbar. Having table with so many rows in body.

Issue? As i scroll the page navigation-bar will be there because it is fixed. as i scroll more i want table header to be fixed under navigation-bar and the content of table(table-body) scrolls without scroll bar!

Something like This - Codepen


**Fiddle ** Bootstrap table


Working Fiddle after referring to the answer!


HTML


<!-- Wrap all page content here -->
<div id="wrap">

  <!-- Fixed navbar -->
  <div class="navbar navbar-default navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">Project name</a>
      </div>
      <div class="collapse navbar-collapse">
        <ul class="nav navbar-nav">
          <li class="active"><a href="#">Home</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#contact">Contact</a></li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
            <ul class="dropdown-menu">
              <li><a href="#">Action</a></li>
              <li><a href="#">Another action</a></li>
              <li><a href="#">Something else here</a></li>
              <li class="divider"></li>
              <li class="dropdown-header">Nav header</li>
              <li><a href="#">Separated link</a></li>
              <li><a href="#">One more separated link</a></li>
            </ul>
          </li>
        </ul>
      </div><!--/.nav-collapse -->
    </div>
  </div>

  <!-- Begin page content -->
  <div class="container">
    <div class="page-header">
      <h1>Sticky footer with fixed navbar</h1>
    </div>
    <p class="lead">Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added within <code>#wrap</code> with <code>padding-top: 60px;</code> on the <code>.container</code>.</p>

  </div>
<table class="table">
        <thead>
          <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1</td>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <td>2</td>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <td>3</td>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
          </tr>
          <tr>
            <td>1</td>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <td>2</td>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <td>3</td>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
          </tr>
          <tr>
            <td>1</td>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <td>2</td>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <td>3</td>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
          </tr>
          <tr>
            <td>1</td>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
          </tr>
          <tr>
            <td>2</td>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
          </tr>
          <tr>
            <td>3</td>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
          </tr>
        </tbody>
      </table>
</div>

<div id="footer">
  <div class="container">
    <p class="text-muted credit">Example courtesy <a href="http://martinbean.co.uk">Martin Bean</a> and <a href="http://ryanfait.com/sticky-footer/">Ryan Fait</a>.</p>
  </div>
</div>
Pitarys answered 19/7, 2014 at 11:49 Comment(9)
You should look into affixLewie
This plugin does what you are trying to do codepen.io/MeghdadHadidi/pen/rpiavNyaya
how to implement it? @charliePitarys
Sticky Menu might help you.Jost
Hey lila! how to do that! please help!Pitarys
I guess what you want to do is keep a menu to stay at top while scrolling, right?Jost
In that case follow @charlie 's linkJost
This is very simple with the right plugin. See my answerJohore
If using Bootstrap 4, you can just use .sticky-top on all the th. If you also have a sticky nav, then you will have to add CSS for table tr th.sticky-top { top: 70px; }.Kilowatt
J
66

Use: https://github.com/mkoryak/floatThead

Docs: http://mkoryak.github.io/floatThead/examples/bootstrap3/

$(document).ready(function(){
  $(".sticky-header").floatThead({top:50});
});

DEMO with 2 Tables and Fixed Header: http://jsbin.com/zuzuqe/1/

http://jsbin.com/zuzuqe/1/edit


HTML

<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Project name</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#contact">Contact</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li class="dropdown-header">Nav header</li>
            <li><a href="#">Separated link</a></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
    </div>
    <!--/.nav-collapse -->
  </div>
</div>

<!-- Begin page content -->
<div class="container">
  <div class="page-header">
    <h1>Sticky footer with fixed navbar</h1>
  </div>
  <p class="lead">Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added within <code>#wrap</code> with <code>padding-top: 60px;</code> on the <code>.container</code>.</p>
  <table class="table table-striped sticky-header">
    <thead>
      <tr>
        <th>#</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Username</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
    </tbody>
  </table>

  <h3>Table 2</h3>

  <table class="table table-striped sticky-header">
    <thead>
      <tr>
        <th>#</th>
        <th>New Table</th>
        <th>Last Name</th>
        <th>Username</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
    </tbody>
  </table>
</div>

CSS

body{
  padding-top:50px;
}
table.floatThead-table {
  border-top: none;
  border-bottom: none;
  background-color: #fff;
}
Johore answered 6/10, 2014 at 21:47 Comment(6)
looks great! but not working in my fiddle! trying...! If you can please update my fiddle with your code!Pitarys
You need to show the fiddle you tried to get work this is basic stuff. Link to an external resource of the script, loaded after jQuery, if you can't load the external resource, post the full script, then paste in the initialization and CSS. However, Fiddle is a really poor environment compared to JSBin.Johore
It's Working Great ,,, Take a look my jsfiddle.net/ashikjsTana
Thank you. FYI, in the current version it appears the parameter is now simply called top instead of scrollingTop. It can be either an int, or a function. If a function, it is run again every time floatThead('reflow') is called.Knp
We dont need jQuery for this. -1Median
. . . voted down since, although it used to be a great answer, it's now out of date. There are much more simple ways to accomplish this.Subside
C
110

This can now be done without JS, just pure CSS. So, anyone trying to do this for modern browsers should look into using position: sticky instead.

Currently, both Edge and Chrome have a bug where position: sticky doesn't work on thead or tr elements, however it's possible to use it on th elements, so all you need to do is just add this to your code:

th {
  position: sticky;
  top: 50px;  /* 0px if you don't have a navbar, but something is required */
  background: white;
}

Note: you'll need a background color for them, or you'll be able to see through the sticky title bar.

This has very good browser support.

Demo with your code (HTML unaltered, above 5 lines of CSS added, all JS removed):

body {
    padding-top:50px;
}
table.floatThead-table {
    border-top: none;
    border-bottom: none;
    background-color: #fff;
}

th {
  position: sticky;
  top: 50px;
  background: white;
}
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">

<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>

            </button> <a class="navbar-brand" href="#">Project name</a>

        </div>
        <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Home</a>

                </li>
                <li><a href="#about">About</a>

                </li>
                <li><a href="#contact">Contact</a>

                </li>
                <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>

                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a>

                        </li>
                        <li><a href="#">Another action</a>

                        </li>
                        <li><a href="#">Something else here</a>

                        </li>
                        <li class="divider"></li>
                        <li class="dropdown-header">Nav header</li>
                        <li><a href="#">Separated link</a>

                        </li>
                        <li><a href="#">One more separated link</a>

                        </li>
                    </ul>
                </li>
            </ul>
        </div>
        <!--/.nav-collapse -->
    </div>
</div>
<!-- Begin page content -->
<div class="container">
    <div class="page-header">
         <h1>Sticky Table Headers</h1>

    </div>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <table class="table table-striped sticky-header">
        <thead>
            <tr>
                <th>#</th>
                <th>First Name</th>
                <th>Last Name</th>
                <th>Username</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
        </tbody>
    </table>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
    <p class="lead">If the page is tall and all of the table is visible, then it won't stick. Make your viewport short.</p>
     <h3>Table 2</h3>

    <table class="table table-striped sticky-header">
        <thead>
            <tr>
                <th>#</th>
                <th>New Table</th>
                <th>Last Name</th>
                <th>Username</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
            <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
                <td>@mdo</td>
            </tr>
            <tr>
                <td>2</td>
                <td>Jacob</td>
                <td>Thornton</td>
                <td>@fat</td>
            </tr>
            <tr>
                <td>3</td>
                <td>Larry</td>
                <td>the Bird</td>
                <td>@twitter</td>
            </tr>
        </tbody>
    </table>
</div>
Cholla answered 24/8, 2018 at 16:19 Comment(6)
Nice thorough answer for current browsers.Zerelda
this doesn't work if you have overflow in the parentsBedrock
Doesn't work if the parent is a bootstrap responsive divDashpot
You should be able to add different offsets for each row, no?Cholla
Thank you about the "thead bug" hint!Druci
I've run into more situations where position sticky fails than it works. If you've got a really simple container go for it but something like highly nested admin templates it never works the way you want it to.Thrombin
J
66

Use: https://github.com/mkoryak/floatThead

Docs: http://mkoryak.github.io/floatThead/examples/bootstrap3/

$(document).ready(function(){
  $(".sticky-header").floatThead({top:50});
});

DEMO with 2 Tables and Fixed Header: http://jsbin.com/zuzuqe/1/

http://jsbin.com/zuzuqe/1/edit


HTML

<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Project name</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#contact">Contact</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li class="dropdown-header">Nav header</li>
            <li><a href="#">Separated link</a></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
    </div>
    <!--/.nav-collapse -->
  </div>
</div>

<!-- Begin page content -->
<div class="container">
  <div class="page-header">
    <h1>Sticky footer with fixed navbar</h1>
  </div>
  <p class="lead">Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added within <code>#wrap</code> with <code>padding-top: 60px;</code> on the <code>.container</code>.</p>
  <table class="table table-striped sticky-header">
    <thead>
      <tr>
        <th>#</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Username</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
    </tbody>
  </table>

  <h3>Table 2</h3>

  <table class="table table-striped sticky-header">
    <thead>
      <tr>
        <th>#</th>
        <th>New Table</th>
        <th>Last Name</th>
        <th>Username</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
    </tbody>
  </table>
</div>

CSS

body{
  padding-top:50px;
}
table.floatThead-table {
  border-top: none;
  border-bottom: none;
  background-color: #fff;
}
Johore answered 6/10, 2014 at 21:47 Comment(6)
looks great! but not working in my fiddle! trying...! If you can please update my fiddle with your code!Pitarys
You need to show the fiddle you tried to get work this is basic stuff. Link to an external resource of the script, loaded after jQuery, if you can't load the external resource, post the full script, then paste in the initialization and CSS. However, Fiddle is a really poor environment compared to JSBin.Johore
It's Working Great ,,, Take a look my jsfiddle.net/ashikjsTana
Thank you. FYI, in the current version it appears the parameter is now simply called top instead of scrollingTop. It can be either an int, or a function. If a function, it is run again every time floatThead('reflow') is called.Knp
We dont need jQuery for this. -1Median
. . . voted down since, although it used to be a great answer, it's now out of date. There are much more simple ways to accomplish this.Subside
M
27

You can do it easily with puse CSS without any kind of JS. you have to add position: sticky; top: 0; z-index:999; in table th . But this won't work on Chrome Browser but other browser. To work on chrome you have to add those code in table thead th

.table-fixed {
  width: 100%;
}

/*This will work on every browser but Chrome Browser*/
.table-fixed thead {
  position: sticky;
  position: -webkit-sticky;
  top: 0;
  z-index: 999;
  background-color: #000;
  color: #fff;
}

/*This will work on every browser*/
.table-fixed thead th {
    position: sticky;
    position: -webkit-sticky;
    top: 0;
    z-index: 999;
    background-color: #000;
    color: #fff;
}
<table class="table-fixed">
  <thead>
    <tr>
        <th>Table Header 1</th>
        <th>Table Header 2</th>
        <th>Table Header 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
    <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
    </tr>
  </tbody>
</table>
Melanism answered 3/9, 2018 at 6:26 Comment(4)
Does "This will work on every browser" mean that I don't need the "This will work on every browser but Chrome Browser" version, or that I need both to support (nearly) everything and Chrome?Lawton
I made some working example using this technique. Handling x/y scrolling. codepen.io/oswee/pen/xMQJVmJabez
Works in Chrome but not in SafariEffusion
top: 0 was the trick for meStatism
P
22

Anyone looking for this functionality past 2018: it's much cleaner to do this with just CSS using position: sticky.

position: sticky doesn't work with some table elements (thead/tr) in Chrome. You can move sticky to tds/ths of tr you need to be sticky. Like this:

thead tr:nth-child(1) th {
  background: white;
  position: sticky;
  top: 0;
  z-index: 10;
}
Piling answered 24/7, 2018 at 16:51 Comment(0)
A
9

I faced the same issue and as majority of the answers indicated, you have to apply position: sticky; and top: 0; ( mostly but can vary if there is a navbar which is fixed as well) to 'th' element. These properties do not apply to thead or tr.

One more thing, if it still doesn't work, you have to look for 'overflow' properties of the parent. If any parent component has an overflow set, i.e. overflow: hidden, then position: sticky just doesn't work. Make sure to remove all such parent properties. Chao!

Allopatric answered 19/5, 2020 at 9:59 Comment(5)
Applying overflow: initial on my table wrapper made it appear on top! That tip was increbily useful! Thanks! EDIT: On a further note, I had set overflow-x: auto earlier, that's why initial did the trick (equivalent of removing it)Proudhon
You @Proudhon are a true hero! After going through the whole internet for answers, your tip fixed my problem!Archivist
@TimDaubenschütz Happy to know it worked for you :)Proudhon
I was having overflow-x: hidden; on the body, and that prevented it to work too!Lanthanide
overflow on a parent element was messing me up. This helped. Thank you!Mendez
D
4

.contents {
  width: 50%;
  border: 1px solid black;
  height: 300px;
  overflow: auto;
}

table {
  position: relative;
}

th {
  position: sticky;
  top: 0;
  background: #ffffff;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="contents">
  <table class="table">
    <thead>
      <tr>
        <th>colunn 1</th>
        <th>colunn 2</th>
        <th>colunn 3</th>
        <th>colunn 4</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Example 1</td>
        <td>Example 2</td>
        <td>Example 3</td>
        <td>Example 4</td>
        <tr>
          <tr>
            <td>Example 1</td>
            <td>Example 2</td>
            <td>Example 3</td>
            <td>Example 4</td>
            <tr>
              <tr>
                <td>Example 1</td>
                <td>Example 2</td>
                <td>Example 3</td>
                <td>Example 4</td>
                <tr>
                  <tr>
                    <td>Example 1</td>
                    <td>Example 2</td>
                    <td>Example 3</td>
                    <td>Example 4</td>
                    <tr>
                      <tr>
                        <td>Example 1</td>
                        <td>Example 2</td>
                        <td>Example 3</td>
                        <td>Example 4</td>
                        <tr>
                          <tr>
                            <td>Example 1</td>
                            <td>Example 2</td>
                            <td>Example 3</td>
                            <td>Example 4</td>
                            <tr>
                              <tr>
                                <td>Example 1</td>
                                <td>Example 2</td>
                                <td>Example 3</td>
                                <td>Example 4</td>
                                <tr>
                                  <tr>
                                    <td>Example 1</td>
                                    <td>Example 2</td>
                                    <td>Example 3</td>
                                    <td>Example 4</td>
                                    <tr>
                                      <tr>
                                        <td>Example 1</td>
                                        <td>Example 2</td>
                                        <td>Example 3</td>
                                        <td>Example 4</td>
                                        <tr>
                                          <tr>
                                            <td>Example 1</td>
                                            <td>Example 2</td>
                                            <td>Example 3</td>
                                            <td>Example 4</td>
                                            <tr>
    </tbody>
  </table>
</div>
Diazole answered 19/8, 2020 at 14:21 Comment(2)
can you please explain further how it will work? or convert this code to snipped where the user can see it working.Pitarys
I made an example here codepen.io/pen/?template=poyrbGwDiazole
P
3

Here is a jsfiddle HERE (not created by me) that does what you are looking for with pure css in a table. The thing to note here is the th header is set to a height of 0. Inside each th is and absolute positioned div that puts the header above the table and the scollable div that the table is in.

<thead>
  <tr>
    <th>#<div>#</div></th>
    <th>First Name<div>First Name</div></th>
    <th>Last Name<div>Last Name</div></th>
    <th>Username<div>Username</div></th>
  </tr>
</thead>
Pabulum answered 2/10, 2014 at 14:57 Comment(2)
As i scroll the page navigation-bar will be there because it is fixed. as i scroll more i want table header to be fixed under navigation-bar and the content of table(table-body) scrolls without scroll bar!Pitarys
Thank you for the answer but i wanted this jsfiddle.net/DTcHh/1360 it is working nowPitarys
F
2

I accomplished something similar using jQuery Waypoints.

There's a lot of moving parts, and quite a bit of logic (that I hope to get on GitHub some day soon), but essentially what you could do is...

  1. Duplicate the table DOM structure in JavaScript and add a class called fixed.
  2. Add styles for table.fixed that make it invisible.
  3. Set a way point at the bottom of the header navigation that adds a class called sticky to table.fixed
  4. Add styles for table.sticky.fixed that position it just below the navbar and also make just the thead content visible. This also has a z-index so it is laid above the rest of the content.
  5. Add another waypoint, but in the downward scroll event, that removes .sticky from the table.fixed

You have to duplicate the entire table DOM in order to ensure column widths line up appropriately.

If that sounds really complicated, you might want to try playing around with the DataTables plugin and the FixedHeader extension: https://datatables.net/extensions/fixedheader/

Flocculent answered 4/10, 2014 at 6:26 Comment(1)
Thank you for your answer it was helpful! See working Fiddle jsfiddle.net/DTcHh/1360Pitarys
H
2

Okku's post worked for me in Edge. In order to get desired result on the iPhone, I had to use:

<thead class="sticky-top">

which didn't effect Edge.

Hedgcock answered 19/8, 2019 at 7:3 Comment(0)
C
0

If you want to have an affix on your header you can use this tricks, add position: relative on your th and change the position in eventListener('scroll')

I have created an example: https://codesandbox.io/s/rl1jjx0o

I use vue.js but you can use this, without vue.js

Celinecelinka answered 1/2, 2019 at 9:46 Comment(1)
I downvoted because of link only answer which in this case meant that the link got broken rendering this answer null and void by SO standard.Kisner
V
0

For anyone looking for a modern JS framework support like ReactJS or Vue try this one instead https://github.com/johngerome/js-sticky-table-headers. Which supports overflow layout.

I'm using this one on my Svelte project.

Vintner answered 20/9, 2022 at 12:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.