[css] How to add a scrollbar to an HTML5 table?

I have an table in HTML5 that I would like to add a scrollbar to. I want the table to show ten rows and then the user can scroll down to see other songs. How can I add the scrollbar?

Here is my code for the table in HTML5:

<table id="my_table" table border="5">
  <tr>
    <th>URL</th>
  </tr>
  <tr>
    <td>http://www.youtube.com/embed/evuSpI2Genw</td>
  </tr>
  <tr>
    <td>http://www.youtube.com/embed/evuSpI2Genw</td>
  </tr>
</table>

Here is my CSS code:

#my_table {
    border-radius: 20px;
    background-color: transparent;
    color: black;
    width: 500px;
    text-align: center;
}

This question is related to css html

The answer is


you can try this

CSS:

          #table-wrapper {
                height:150px;
                overflow:auto;  
                margin-top:20px;
                  }
          #table-wrapper table {
                 width:100%;
                 color:#000;    
                 }
          #table-wrapper table thead th .text {
                  position:fixed;   
                  top:0px;  
                  height:20px;
                  width:35%;
                  border:1px solid red;
               }

HTML:

<div id="table-wrapper">

    <table>
        <thead>
            <tr>
                <th><span class="text">album</span></th>
                <th><span class="text">song</span></th>
                <th><span class="text">genre</span></th>
            </tr>
        </thead>
        <tbody>
<tr> <td> album 0</td> <td> song0</td> <td> genre0</td> </tr>
<tr> <td>album 1</td> <td>song 1</td> <td> genre1</td> </tr>
<tr> <td> album2</td> <td>song 2</td> <td> genre2</td> </tr>
<tr> <td> album3</td> <td>song 3</td> <td> genre3</td> </tr>
<tr> <td> album4</td> <td>song 4</td> <td>genre 4</td> </tr>
<tr> <td> album5</td> <td>song 5</td> <td>genre 5</td> </tr>
<tr> <td>album 6</td> <td> song6</td> <td> genre6</td> </tr>
<tr> <td>album 7</td> <td> song7</td> <td> genre7</td> </tr>
<tr> <td> album8</td> <td> song8</td> <td>genre 8</td> </tr>
<tr> <td> album9</td> <td> song9</td> <td> genre9</td> </tr>
<tr> <td> album10</td> <td>song 10</td> <td> genre10</td> </tr>
<tr> <td> album11</td> <td>song 11</td> <td> genre11</td> </tr>
<tr> <td> album12</td> <td> song12</td> <td> genre12</td> </tr>
<tr> <td>album 13</td> <td> song13</td> <td> genre13</td> </tr>
<tr> <td> album14</td> <td> song14</td> <td> genre14</td> </tr>
<tr> <td> album15</td> <td> song15</td> <td> genre15</td> </tr>
<tr> <td>album 16</td> <td> song16</td> <td> genre16</td> </tr>
<tr> <td>album 17</td> <td> song17</td> <td> genre17</td> </tr>
<tr> <td> album18</td> <td> song18</td> <td> genre18</td> </tr>
<tr> <td> album19</td> <td> song19</td> <td> genre19</td> </tr>
<tr> <td> album20</td> <td> song20</td> <td> genre20</td> </tr>    
        </tbody>
    </table>
  </div>

Check this fiddle : http://jsfiddle.net/Kritika/GLKxB/1/

this will keep the table head fixed ,and scroll only the table content .


HTML :

    <h1>&darr; SCROLL &darr;</h1>
<table class="blue">
  <thead>
    <tr>
      <th>Colonne 1</th>
      <th>Colonne 2</th>
      <th>Colonne 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
  </tbody>
</table>

<h1 class="scrollMore">&darr; SCROLL MORE &darr;</h1>
<table class="purple">
  <thead>
    <tr>
      <th>Colonne 1</th>
      <th>Colonne 2</th>
      <th>Colonne 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
    <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
       <tr>
      <td>Non</td>
      <td>Mais</td>
      <td>Allo !</td>
    </tr>
  </tbody>
</table>
<h1 class="up scrollMore">&uarr; UP &uarr;</h1>

CSS:

body{
  font:1.2em normal Arial,sans-serif;
  color:#34495E;
}

h1{
  text-align:center;
  text-transform:uppercase;
  letter-spacing:-2px;
  font-size:2.5em;
  margin:20px 0;
}

.container{
  width:90%;
  margin:auto;
}

table{
  border-collapse:collapse;
  width:100%;
}

.blue{
  border:2px solid #1ABC9C;
}

.blue thead{
  background:#1ABC9C;
}

.purple{
  border:2px solid #9B59B6;
}

.purple thead{
  background:#9B59B6;
}

thead{
  color:white;
}

th,td{
  text-align:center;
  padding:5px 0;
}

tbody tr:nth-child(even){
  background:#ECF0F1;
}

tbody tr:hover{
background:#BDC3C7;
  color:#FFFFFF;
}

.fixed{
  top:0;
  position:fixed;
  width:auto;
  display:none;
  border:none;
}

.scrollMore{
  margin-top:600px;
}

.up{
  cursor:pointer;
}

JS (jQuery):

;(function($) {
   $.fn.fixMe = function() {
      return this.each(function() {
         var $this = $(this),
            $t_fixed;
         function init() {
            $this.wrap('<div class="container" />');
            $t_fixed = $this.clone();
            $t_fixed.find("tbody").remove().end().addClass("fixed").insertBefore($this);
            resizeFixed();
         }
         function resizeFixed() {
            $t_fixed.find("th").each(function(index) {
               $(this).css("width",$this.find("th").eq(index).outerWidth()+"px");
            });
         }
         function scrollFixed() {
            var offset = $(this).scrollTop(),
            tableOffsetTop = $this.offset().top,
            tableOffsetBottom = tableOffsetTop + $this.height() - $this.find("thead").height();
            if(offset < tableOffsetTop || offset > tableOffsetBottom)
               $t_fixed.hide();
            else if(offset >= tableOffsetTop && offset <= tableOffsetBottom && $t_fixed.is(":hidden"))
               $t_fixed.show();
         }
         $(window).resize(resizeFixed);
         $(window).scroll(scrollFixed);
         init();
      });
   };
})(jQuery);

$(document).ready(function(){
   $("table").fixMe();
   $(".up").click(function() {
      $('html, body').animate({
      scrollTop: 0
   }, 2000);
 });
});

For beginner programmer: If you don't want to download and host jQuery yourself, you can include it from a CDN (Content Delivery Network).

<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head> 

Adding jQuery to Your Web Pages click here.

Reference: HERE


My simplest solution is based on fixed columns layout. You'll have to set the width of each column, for example: 4 columns 100px each is equal to 400px total width.

table {
  table-layout: fixed;
  width: 400px;
}
td, th {
  width: 100px;
}

The fixed table layout algorithm has many advantages over the automatic table layout algorithm (for example: the horizontal layout only depends on the table's width and the width of the columns, not the contents of the cells; allows a browser to lay out the table faster than the automatic table layout; the browser can begin to display the table once the first row has been received; etc.)

Then, you'll have to separate the thead from the tbody by forcing their display style to block rather than to the default table-*

thead tr {
  display: block;
}
tbody {
  display: block;
  height: 256px;
  overflow-y: auto;
}

That what will make the tbody scrollable as a separate box and the thead unrelated from it. And that's the main reason why you had to fix the column widths as done above.

Working JsFiddle: https://jsfiddle.net/angiolep/65q1gdcy/1/


This was a challenging question. I think I finally have a solution that satisfies complete requirements: a vertical and horizontal scrollable dynamic table (dynamic because you can change the amount of rows and columns, and no cells have fixed width or height).

The HTML and CSS layout is quite simple as other people have mentioned. The key issue is recalculating (JavaScript) cell widths. And to make sure horizontal scrolling works, I also recalculate theader and tbody width.

Here's a fiddle https://jsfiddle.net/jmarcos00/6hv0dsj8/1/

HTML code:

<!--
thead and tbody have identifiers
table is inside a div container
-->
<div>
  <table>
    <thead id="mythead">
      <tr>
        <th>header one</th>
        <th>two</th>
        <th>header three</th>
        <th>header one</th>
        <th>two</th>
        <th>header three</th>
      </tr>
    </thead>
    <tbody id="mytbody">
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
      <tr>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
        <td>one</td>
        <td>data two</td>
        <td>three</td>
      </tr>
    </tbody>
  </table>
</div>

CSS code:

/* table border rule */
table, td, th { border: 1px solid black; }

/* display as block plus display vertical scroll bars */
thead, tbody { display: block; overflow-y: scroll; }

/* sample height */
tbody { height: 100px; }

/* sample width and horizontal scroll bar */
div { width: 200px; overflow-x: auto; }

JavaScript code:

var i, w, wtot, thtot, thw, tdw, theadtr, tbodytr;
var th_rect, td_rect, theadtr_rect, tbodytr_rect;
var safe = new Array();

// get thead and tbody
var mythead = document.getElementById("mythead");
var mytbody = document.getElementById("mytbody");

// get first tr of thead and tbody
theadtr = mythead.children[0];
tbodytr = mytbody.children[0];
theadtr_rect = theadtr.getBoundingClientRect();
tbodytr_rect = tbodytr.getBoundingClientRect();

// get width difference of longer first tr
//   difference between tr and parent
if (tbodytr_rect.width > theadtr_rect.width)
    wtot = mytbody.getBoundingClientRect().width - tbodytr_rect.width;
else
    wtot = mythead.getBoundingClientRect().width - theadtr_rect.width;

// get width difference between tr and total th width (first step)
thtot = theadtr_rect.width;

// get th thead array and td tbody array
theadtr = theadtr.children;
tbodytr = tbodytr.children;

// get loop
for (i = 0; i < theadtr.length; i++)
{
    // second step for width difference between tr and total th width
    th_rect = theadtr[i].getBoundingClientRect();
    td_rect = tbodytr[i].getBoundingClientRect();
    thtot -= th_rect.width;

    // get width of each th and first row td (without paddings etc)
    tdw = parseFloat(window.getComputedStyle(tbodytr[i]).getPropertyValue("width"));
    thw = parseFloat(window.getComputedStyle(theadtr[i]).getPropertyValue("width"));

    // get bigger width
    w = (tdw > thw) ? tdw : thw;
    safe.push(w);

    // add to width total (decimal value with paddings etc)
    w = (tdw > thw) ? td_rect.width : th_rect.width;
    wtot += w;
}

// consider tr width and total th width difference
wtot += thtot;

// set loop
for (i = 0; i < theadtr.length; i++)
{
    // set width to th and first row td
    w = safe[i] + "px";
    theadtr[i].style.width = w;
    tbodytr[i].style.width = w; 
}

// set width for thead and tbody
wtot = wtot + "px";
mythead.style.width = wtot;
mytbody.style.width = wtot;

@jogesh_pi answer is a good solution, i've created a example here http://jsfiddle.net/pqgaS/5/, check it, hope this help

<div id="listtableWrapperScroll">
    <table id="listtable">
        <tr>
            <td>Data Data</td>
            <td>Data Data</td>
            <td>Data Data</td>                
        </tr>
    </table>
</div>

#listtableWrapperScroll{
    height:100px;
    width:460px;
    overflow-y:scroll;
    border:1px solid #777777;
    background:#FFFFF2;
}
#listtableWrapperScroll #listtable{
    width:440px;       
}
#listtableWrapperScroll #listtable tr td{
    border-bottom:1px dashed #444;
}

<!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Scrollable Table</title>
    <style type="text/css">
      * { padding: 0; margin: 0; }
      table.my_table { 
        font-family: verdana, arial, helvetica, sans-serif;
        font-size: 11px;
        cellspacing: 0; 
        border-collapse: collapse; 
        width: 283px;    
        }
      table.my_table th, table.my_table td { 
        border-bottom: 1px solid #999; 
        border-right: 1px solid #999; 
        }
      table.my_table th { background: #ffb; }
      table.my_table td { background: #ffe; }

      div.scrollableContainer { 
        height: 100px; 
        overflow: auto;  
        width: 300px; 
        margin: 40px;    
        border: 1px solid #999;
        background: #ffb;     
        }

    </style>
    </head>
    <body>
    <div class="scrollableContainer">
        <table class="my_table scrollable">
          <thead>
            <tr>
              <th>URL</th>
                </tr>
        </thead>

        <tbody>
                <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td> 
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td>                   
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td> 
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td>                   
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td> 
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td>                   
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td> 
                    </tr>

                    <tr>
              <td>http://www.youtube.com/embed/evuSpI2Genw</td>                   
                    </tr>
            </tbody>
          </table>
        </div>
      </body>
    </html>

You can use a division class with the overflow attribute using the value scroll. Or you can enclose the table inside an iframe. The iframe works well with old and new IE browsers, but it may not work with other browsers and probably not with the latest IE.

 #myid { overflow-x: scroll; overflow-y: hide; width:200px; /* Or whatever the amount of pixels */ }
.myid { overflow-x: scroll; overflow-y: hide; width:200px; /* Or whatever the amount of pixels */ }

<div class="myid">
     <div class="row">Content1</div>
     <div class="row2">Content2</div>
</div>

<table id="myid"><tr><td>Content</td></tr></table>

Using flexboxes, no javascript, and it is responsive.

_x000D_
_x000D_
/* styles */_x000D_
_x000D_
table {_x000D_
  font-family: sans-serif;_x000D_
  border-collapse: collapse;_x000D_
  max-height: 300px;_x000D_
  overflow: auto;_x000D_
}_x000D_
_x000D_
td,_x000D_
th {_x000D_
  border: 1px solid #ddd;_x000D_
  text-align: left;_x000D_
  padding: 8px;_x000D_
  background: #fff;_x000D_
}_x000D_
_x000D_
tr:nth-child(odd) td {_x000D_
  background-color: #eee;_x000D_
}_x000D_
_x000D_
/* fixed headers */_x000D_
_x000D_
table,_x000D_
thead,_x000D_
tbody {_x000D_
  display: block;_x000D_
}_x000D_
_x000D_
thead {_x000D_
  position: sticky;_x000D_
  top: 0;_x000D_
}_x000D_
_x000D_
tr {_x000D_
  display: flex;_x000D_
}_x000D_
_x000D_
th,_x000D_
td {_x000D_
  flex: 1;_x000D_
  min-width: 100px;_x000D_
  overflow: hidden;_x000D_
  text-overflow: ellipsis;_x000D_
}
_x000D_
<h2>HTML Table</h2>_x000D_
<div class=wrap>_x000D_
  <table>_x000D_
    <thead>_x000D_
      <tr>_x000D_
        <th>#</th>_x000D_
        <th>Firstname</th>_x000D_
        <th>Lastname</th>_x000D_
        <th>Age</th>_x000D_
        <th>City</th>_x000D_
        <th>Country</th>_x000D_
        <th>Sex</th>_x000D_
        <th>Example</th>_x000D_
        <th>Example</th>_x000D_
        <th>ExampleReallyReallyLong</th>_x000D_
        <th>Example</th>_x000D_
      </tr>_x000D_
    </thead>_x000D_
    <tbody>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Example Really Really Long</td>_x000D_
        <td>ExampleReallyReallyLong</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
      <tr>_x000D_
        <td>1</td>_x000D_
        <td>Anna</td>_x000D_
        <td>Pitt</td>_x000D_
        <td>35</td>_x000D_
        <td>New York</td>_x000D_
        <td>USA</td>_x000D_
        <td>Female</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
        <td>Yes</td>_x000D_
      </tr>_x000D_
    </tbody>_x000D_
  </table>_x000D_
</div>
_x000D_
_x000D_
_x000D_


I first tried the accepted answer by Mr Green, but I found my columns didn't align, that float:left seems very suspicious. When I went from no scollbar to scrollbar -- my table body shifted a few pixels and I lost alignment.

CODE PEN https://codepen.io/majorp/pen/gjrRMx

CSS

.width50px {
    width: 100px !important;
}

.width100px {
    width: 100px !important;
}


.fixed_headers {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
}

th {
    padding: 5px;
    text-align: left;
    font-weight:bold;
    height:50px;
}

td {
    padding: 5px;
    text-align: left;
}

thead, tr 
{
    display: block;
    position: relative;
}


tbody {
    display: block;
    overflow: auto;
    width: 100%;
    height: 500px;
}

.tableColumnHeader {
    height: 50px;
    font-weight: bold;
}




.lime {
    background-color: lime;
}

Instead of assuming as fixed width columns.

CSS

table.tableSection {
  display: table;
  width: 100%;
}

table.tableSection thead,
table.tableSection tbody {
  width: 100%;
}

table.tableSection thead {
  overflow-y: scroll;
  display: table;
  table-layout: fixed;
  width: calc(100% - 16px); /* assuming scrollbar width as 16px */
}

table.tableSection tbody {
  overflow: auto;
  height: 150px;
  display: block;
}

table.tableSection tr {
  width: 100%;
  text-align: left;
  display: table;
  table-layout: fixed;
}

Working Fiddle


A year or so has passed since the question was asked, but I wasn't satisfied with the answers. I fiddled for a while, and here is a code that:

  • works in IE8+ and all other browsers;
  • is very easy to understand;
  • lines up the cell borders perfectly (fixed-width cells);
  • fixes the head while the body scrolls;
  • automatically adapts to touch screens.

Live demo here: http://jsbin.com/bagaro/1/edit?html,output.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Scrollabe table</title>
    <!-- Substantially simplified and improved version of the table on
    http://www.cssbakery.com/2010/12/css-scrolling-tables-with-fixed.html -->
    <script>
        if ('ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch)) {
            document.documentElement.className += ' touchScreen';
        }
    </script>
    <style>
        /* BASICS: */
    * {
        padding: 0;
        margin: 0;
        box-sizing: border-box; /* in case block elements are used inside table cells */
    }
    html {
        font-size: 62.5%; /* standardizes older IEs */
    }
    body {
        font: normal 1.3em Verdana; /* = 13px */
    }
    table {
        border-collapse: collapse;
        table-layout: fixed;
        empty-cells: show;
    }
    td {
        border: 1px solid black;
        padding: 4px;
    }
        /* SCROLL TABLE ESSENTIALS (+ SOME ADDITIONAL CSS): */
    div#scrollTableContainer {
        width: 617px;
        margin: 40px; /* just for presentation purposes */
        border: 1px solid black;
    }
    .touchScreen div#scrollTableContainer {
        width: 600px; /* touch devices do not form scrollbars (= 17 px wide) */
    }
    #tHeadContainer {
        background: #CC3600;
        color: white;
        font-weight: bold;
    }
    #tBodyContainer {
        height: 240px;
        overflow-y: scroll;
    }
    .touchScreen #tBodyContainer {
        -webkit-overflow-scrolling: touch; /* smooths scrolling on touch screens */
    }
        /* FINER LAYOUT MATTERS: */
    tr:first-child td {
        border-top: 0;
    }
    #tBody tr.lastRow td {
        border-bottom: 0;
    }
    td:first-child {
        min-width: 108px; /* Firefox needs min- and max-widths */
        max-width: 108px;
        border-left: 0;
    }
    td:first-child + td {
        min-width: 125px;
        max-width: 125px;
    }
    td:first-child + td + td {
        min-width: 90px;
        max-width: 90px;
    }
    td:first-child + td + td + td {
        min-width: 95px;
        max-width: 95px;
    }
    td:first-child + td + td + td + td {
        width: 180px; /* here, Firefox messes up with only min- and max-widths */
        border-right: 0;
    }
        /* AND SOME CSS TO INFORM TOUCH SCREEN USERS: */
    p#touchDeviceText {
        display: none;
    }
    .touchScreen p#touchDeviceText {
        display: block;
    }
    </style>
</head>
<body>
    <p id="touchDeviceText">This table is scrollable</p>
    <div id="scrollTableContainer">
        <div id="tHeadContainer">
            <table id="tHead">
                <tr>
                    <td>Name</td>
                    <td>Operator</td>
                    <td>Began operation</td>
                    <td>Tonnage</td>
                    <td>Status</td>
                </tr>
            </table>
        </div><!-- tHeadContainer -->
        <div id="tBodyContainer">
            <table id="tBody">
                <tr>
                    <td>Seabourne Sun</td>
                    <td>Seabourn Cruise Line</td>
                    <td>1988</td>
                    <td>?</td>
                    <td>Ended service in 2002, currently operating as Prinsendam</td>
                </tr>
                <tr>
                    <td>Adventures of the Seas</td>
                    <td>Royal Caribbean International</td>
                    <td>2001</td>
                    <td>138,000</td>
                    <td>Operating</td>
                </tr>
                <tr>
                    <td>Oceanic Independence</td>
                    <td>American Hawaiian Cruises / American Global Line</td>
                    <td>1974</td>
                    <td>23,719</td>
                    <td>Named formerly (1951-1974) and subsequently renamed (1982-2006) the Independence, renamed the Oceanic (2006), sold for scrap in 2008 but remains in mothballs</td>
                </tr>
                <tr>
                    <td>Cunard Ambassador</td>
                    <td>Cunard Line</td>
                    <td>1972</td>
                    <td>14,160</td>
                    <td>Burnt 1974, rebuilt into a livestock carrier, renamed Linda Clausen, later Procyon, Raslan. Scrapped 1984 after a second fire.</td>
                </tr>
                <tr>
                    <td>Aegean Beauty</td>
                    <td>Voyages to Antiquity</td>
                    <td>1973</td>
                    <td>11,563</td>
                    <td>Formerly Aegean Dolphin and Aegean I. Operating</td>
                </tr>
                <tr>
                    <td>Serenade of the Seas</td>
                    <td>Royal Caribbean International</td>
                    <td>2003</td>
                    <td>90,090</td>
                    <td>Operating</td>
                </tr>
                <tr>
                    <td>Queen Elizabeth 2</td>
                    <td>Cunard Line</td>
                    <td>1969</td>
                    <td>70,327</td>
                    <td>Left fleet in November 2008</td>
                </tr>
                <tr>
                    <td>National Geographic Endeavour</td>
                    <td>Lindblad Expeditions</td>
                    <td>1996</td>
                    <td></td>
                    <td>Operating, also known as Endeavour</td>
                </tr>
                <tr class="lastRow">
                    <td>Liberty of the Seas</td>
                    <td>Royal Caribbean International</td>
                    <td>2007</td>
                    <td>154,407</td>
                    <td>Operating</td>
                </tr>
            </table>
        </div><!-- tBodyContainer -->
    </div><!-- scrollTableContainer -->
</body>
</html>

This is technique I have used on a number of occasions. It is originally based on this fiddle with a number of modifications. It is also fluid and column widths can be fixed by adding a width style to the <th>.

_x000D_
_x000D_
/* this is for the main container of the table, also sets the height of the fixed header row */_x000D_
.headercontainer {_x000D_
  position: relative;_x000D_
  border: 1px solid #222;_x000D_
  padding-top: 37px;_x000D_
  background: #000;_x000D_
}_x000D_
/* this is for the data area that is scrollable */_x000D_
.tablecontainer {_x000D_
  overflow-y: auto;_x000D_
  height: 200px;_x000D_
  background: #fff;_x000D_
}_x000D_
_x000D_
/* remove default cell borders and ensures table width 100% of its container*/_x000D_
.tablecontainer table {_x000D_
  border-spacing: 0;_x000D_
  width:100%;_x000D_
}_x000D_
_x000D_
/* add a thin border to the left of cells, but not the first */_x000D_
.tablecontainer td + td {_x000D_
  border-left:1px solid #eee; _x000D_
}_x000D_
_x000D_
/* cell padding and bottom border */_x000D_
.tablecontainer td, th {_x000D_
  border-bottom:1px solid #eee;_x000D_
  padding: 10px;_x000D_
}_x000D_
_x000D_
/* make the default header height 0 and make text invisible */_x000D_
.tablecontainer th {_x000D_
    height: 0px;_x000D_
    padding-top: 0;_x000D_
    padding-bottom: 0;_x000D_
    line-height: 0;_x000D_
    visibility: hidden;_x000D_
    white-space: nowrap;_x000D_
}_x000D_
_x000D_
/* reposition the divs in the header cells and place in the blank area of the headercontainer */_x000D_
.tablecontainer th div{_x000D_
  visibility: visible;_x000D_
  position: absolute;_x000D_
  background: #000;_x000D_
  color: #fff;_x000D_
  padding: 9px 10px;_x000D_
  top: 0;_x000D_
  margin-left: -10px;_x000D_
  line-height: normal;_x000D_
   border-left: 1px solid #222;_x000D_
}_x000D_
/* prevent the left border from above appearing in first div header */_x000D_
th:first-child div{_x000D_
  border: none;_x000D_
}_x000D_
_x000D_
/* alternate colors for rows */_x000D_
.tablecontainer tbody  tr:nth-child(even){_x000D_
     background-color: #ddd;_x000D_
}
_x000D_
<div class="headercontainer">_x000D_
  <div class="tablecontainer">_x000D_
    <table>_x000D_
      <thead>_x000D_
        <tr>_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_
</div>
_x000D_
_x000D_
_x000D_

Also as a JSFiddle


use this table into a DIV

<div class="tbl_container">
<table> .... </table>
</div>


.tbl_container{ overflow:auto; width: 500px;height: 200px; }

and beside this if you want to make it more beautiful and attractive use the jscollpane to customized your scrollbar..