[html] Freeze the top row for an html table only (Fixed Table Header Scrolling)

I want to make an html table with the top row frozen (so when you scroll down vertically you can always see it).

Is there a clever way to make this happen without javascript?

Note that I do NOT need the left column frozen.

This question is related to html css

The answer is


My concern was not to have the cells with fixed width. Which seemed to be not working in any case. I found this solution which seems to be what I need. I am posting it here for others who are searching of a way. Check out this fiddle

Working Snippet:

_x000D_
_x000D_
html, body{_x000D_
  margin:0;_x000D_
  padding:0;_x000D_
  height:100%;_x000D_
}_x000D_
section {_x000D_
  position: relative;_x000D_
  border: 1px solid #000;_x000D_
  padding-top: 37px;_x000D_
  background: #500;_x000D_
}_x000D_
section.positioned {_x000D_
  position: absolute;_x000D_
  top:100px;_x000D_
  left:100px;_x000D_
  width:800px;_x000D_
  box-shadow: 0 0 15px #333;_x000D_
}_x000D_
.container {_x000D_
  overflow-y: auto;_x000D_
  height: 160px;_x000D_
}_x000D_
table {_x000D_
  border-spacing: 0;_x000D_
  width:100%;_x000D_
}_x000D_
td + td {_x000D_
  border-left:1px solid #eee;_x000D_
}_x000D_
td, th {_x000D_
  border-bottom:1px solid #eee;_x000D_
  background: #ddd;_x000D_
  color: #000;_x000D_
  padding: 10px 25px;_x000D_
}_x000D_
th {_x000D_
  height: 0;_x000D_
  line-height: 0;_x000D_
  padding-top: 0;_x000D_
  padding-bottom: 0;_x000D_
  color: transparent;_x000D_
  border: none;_x000D_
  white-space: nowrap;_x000D_
}_x000D_
th div{_x000D_
  position: absolute;_x000D_
  background: transparent;_x000D_
  color: #fff;_x000D_
  padding: 9px 25px;_x000D_
  top: 0;_x000D_
  margin-left: -25px;_x000D_
  line-height: normal;_x000D_
  border-left: 1px solid #800;_x000D_
}_x000D_
th:first-child div{_x000D_
  border: none;_x000D_
}
_x000D_
<section class="">_x000D_
  <div class="container">_x000D_
    <table>_x000D_
      <thead>_x000D_
        <tr class="header">_x000D_
          <th>_x000D_
            Table attribute name_x000D_
            <div>Table attribute name</div>_x000D_
          </th>_x000D_
          <th>_x000D_
            Value_x000D_
            <div>Value</div>_x000D_
          </th>_x000D_
          <th>_x000D_
            Description_x000D_
            <div>Description</div>_x000D_
          </th>_x000D_
        </tr>_x000D_
      </thead>_x000D_
      <tbody>_x000D_
        <tr>_x000D_
          <td>align</td>_x000D_
          <td>left, center, right</td>_x000D_
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>bgcolor</td>_x000D_
          <td>rgb(x,x,x), #xxxxxx, colorname</td>_x000D_
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>border</td>_x000D_
          <td>1,""</td>_x000D_
          <td>Specifies whether the table cells should have borders or not</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>cellpadding</td>_x000D_
          <td>pixels</td>_x000D_
          <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>cellspacing</td>_x000D_
          <td>pixels</td>_x000D_
          <td>Not supported in HTML5. Specifies the space between cells</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>frame</td>_x000D_
          <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>_x000D_
          <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>rules</td>_x000D_
          <td>none, groups, rows, cols, all</td>_x000D_
          <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>summary</td>_x000D_
          <td>text</td>_x000D_
          <td>Not supported in HTML5. Specifies a summary of the content of a table</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
          <td>width</td>_x000D_
          <td>pixels, %</td>_x000D_
          <td>Not supported in HTML5. Specifies the width of a table</td>_x000D_
        </tr>_x000D_
      </tbody>_x000D_
    </table>_x000D_
  </div>_x000D_
</section>
_x000D_
_x000D_
_x000D_


The Chromatable jquery plugin allows a fixed header (or top row) with widths that allow percentages--granted, only a percentage of 100%.

http://www.chromaloop.com/posts/chromatable-jquery-plugin

I can't think of how you could do this without javascript.

update: new link -> http://www.jquery-plugins.info/chromatable-00012248.htm


I use this:

tbody{
  overflow-y: auto;
  height: 350px;
  width: 102%;
}
thead,tbody{
    display: block;
}

I define the columns width with bootstrap css col-md-xx. Without defining the columns width the auto-width of the doesn't match the . The 102% percent is because you lose some sapce with the overflow


You can use CSS position: sticky; for the first row of the table MDN ref:

.table-class tr:first-child>td{
    position: sticky;
    top: 0;
}

It is possible using position:fixed on <th> (<th> being the top row).

Here's an example


Using css zebra styling

Copy paste this example and see the header fixed.

       <style>
       .zebra tr:nth-child(odd){
       background:white;
       color:black;
       }

       .zebra tr:nth-child(even){
       background: grey;
       color:black;
       }

      .zebra tr:nth-child(1) {
       background:black;
       color:yellow;
       position: fixed;
       margin:-30px 0px 0px 0px;
       }
       </style>


   <DIV  id= "stripped_div"

         class= "zebra"
         style = "
            border:solid 1px red;
            height:15px;
            width:200px;
            overflow-x:none;
            overflow-y:scroll;
            padding:30px 0px 0px 0px;"
            >

                <table>
                   <tr >
                       <td>Name:</td>
                       <td>Age:</td>
                   </tr>
                    <tr >
                       <td>Peter</td>
                       <td>10</td>
                   </tr>
                </table>

    </DIV>

Notice the top padding of of 30px in the div leaves space that is utilized by the 1st row of stripped data ie tr:nth-child(1) that is "fixed position" and formatted to a margin of -30px


you can use two divs one for the headings and the other for the table. then use

#headings {
  position: fixed;
  top: 0px;
  width: 960px;
}

as @ptriek said this will only work for fixed width columns.


I know this has several answers, but none of these really helped me. I found [this article][1] which explains why my sticky wasn't operating as expected.

Basically, you cannot use position: sticky; on <thead> or <tr> elements. However, they can be used on <th>.

The minimum code I needed to make it work is as follows:

table {
  text-align: left;
  position: relative;
}

th {
  background: white;
  position: sticky;
  top: 0;
}

With the table set to relative the <th> can be set to sticky, with the top at 0 [1]: https://css-tricks.com/position-sticky-and-table-headers/

NOTE: It's necessary to wrap the table with a div with max-height:

<div id="managerTable" >
...
</div>

where:

#managerTable {
    max-height: 500px;
    overflow: auto;
}

According to Pure CSS Scrollable Table with Fixed Header , I wrote a DEMO to easily fix the header by setting overflow:auto to the tbody.

table thead tr{
    display:block;
}

table th,table td{
    width:100px;//fixed width
}


table  tbody{
  display:block;
  height:200px;
  overflow:auto;//set tbody to auto
}