How to display scroll bar onto a html table
Something like this?
http://jsfiddle.net/TweNm/
The idea is to wrap the <table>
in a non-statically positioned <div>
which has an overflow:auto
CSS property. Then position the elements in the <thead>
absolutely.
#table-wrapper { position:relative;}#table-scroll { height:150px; overflow:auto; margin-top:20px;}#table-wrapper table { width:100%;
}#table-wrapper table * { background:yellow; color:black;}#table-wrapper table thead th .text { position:absolute; top:-20px; z-index:2; height:20px; width:35%; border:1px solid red;}
<div id="table-wrapper"> <div id="table-scroll"> <table> <thead> <tr> <th><span class="text">A</span></th> <th><span class="text">B</span></th> <th><span class="text">C</span></th> </tr> </thead> <tbody> <tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr> <tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr> <tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr> <tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr> <tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr> <tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr> <tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr> <tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr> <tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr> <tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr> <tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr> <!-- etc... --> <tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr> </tbody> </table> </div></div>
HTML table with 100% width, with vertical scroll inside tbody
In order to make <tbody>
element scrollable, we need to change the way it's displayed on the page i.e. using display: block;
to display that as a block level element.
Since we change the display
property of tbody
, we should change that property for thead
element as well to prevent from breaking the table layout.
So we have:
thead, tbody { display: block; }
tbody {
height: 100px; /* Just for the demo */
overflow-y: auto; /* Trigger vertical scroll */
overflow-x: hidden; /* Hide the horizontal scroll */
}
Web browsers display the thead
and tbody
elements as row-group (table-header-group
and table-row-group
) by default.
Once we change that, the inside tr
elements doesn't fill the entire space of their container.
In order to fix that, we have to calculate the width of tbody
columns and apply the corresponding value to the thead
columns via JavaScript.
Auto Width Columns
Here is the jQuery version of above logic:
// Change the selector if needed
var $table = $('table'),
$bodyCells = $table.find('tbody tr:first').children(),
colWidth;
// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
return $(this).width();
}).get();
// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
$(v).width(colWidth[i]);
});
And here is the output (on Windows 7 Chrome 32):
WORKING DEMO.
Full Width Table, Relative Width Columns
As the Original Poster needed, we could expand the table
to 100% of width
of its container, and then using a relative (Percentage) width
for each columns of the table.
table {
width: 100%; /* Optional */
}
tbody td, thead th {
width: 20%; /* Optional */
}
Since the table has a (sort of) fluid layout, we should adjust the width of thead
columns when the container resizes.
Hence we should set the columns' widths once the window is resized:
// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
/* Same as before */
}).resize(); // Trigger the resize handler once the script runs
The output would be:
WORKING DEMO.
Browser Support and Alternatives
I've tested the two above methods on Windows 7 via the new versions of major Web Browsers (including IE10+) and it worked.
However, it doesn't work properly on IE9 and below.
That's because in a table layout, all elements should follow the same structural properties.
By using display: block;
for the <thead>
and <tbody>
elements, we've broken the table structure.
Redesign layout via JavaScript
One approach is to redesign the (entire) table layout. Using JavaScript to create a new layout on the fly and handle and/or adjust the widths/heights of the cells dynamically.
For instance, take a look at the following examples:
- jQuery .floatThead() plugin (a floating/locked/sticky table header plugin)
- jQuery Scrollable Table plugin. (source code on github)
- jQuery .FixedHeaderTable() plugin (source code on github)
- DataTables vertical scrolling example.
Nesting tables
This approach uses two nested tables with a containing div. The first table
has only one cell which has a div
, and the second table is placed inside that div
element.
Check the Vertical scrolling tables at CSS Play.
This works on most of web browsers. We can also do the above logic dynamically via JavaScript.
Table with fixed header on scroll
Since the purpose of adding vertical scroll bar to the <tbody>
is displaying the table header at the top of each row, we could position the thead
element to stay fixed
at the top of the screen instead.
Here is a Working Demo of this approach performed by Julien.
It has a promising web browser support.
And here a pure CSS implementation by Willem Van Bockstal.
The Pure CSS Solution
Here is the old answer. Of course I've added a new method and refined the CSS declarations.
Table with Fixed Width
In this case, the table
should have a fixed width
(including the sum of columns' widths and the width of vertical scroll-bar).
Each column should have a specific width and the last column of thead
element needs a greater width which equals to the others' width + the width of vertical scroll-bar.
Therefore, the CSS would be:
table {
width: 716px; /* 140px * 5 column + 16px scrollbar width */
border-spacing: 0;
}
tbody, thead tr { display: block; }
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 140px;
}
thead th:last-child {
width: 156px; /* 140px + 16px scrollbar width */
}
Here is the output:
WORKING DEMO.
Table with 100% Width
In this approach, the table
has a width of 100%
and for each th
and td
, the value of width
property should be less than 100% / number of cols
.
Also, we need to reduce the width of thead
as value of the width of vertical scroll-bar.
In order to do that, we need to use CSS3 calc()
function, as follows:
table {
width: 100%;
border-spacing: 0;
}
thead, tbody, tr, th, td { display: block; }
thead tr {
/* fallback */
width: 97%;
/* minus scroll bar width */
width: -webkit-calc(100% - 16px);
width: -moz-calc(100% - 16px);
width: calc(100% - 16px);
}
tr:after { /* clearing float */
content: ' ';
display: block;
visibility: hidden;
clear: both;
}
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 19%; /* 19% is less than (100% / 5 cols) = 20% */
float: left;
}
Here is the Online Demo.
Note: This approach will fail if the content of each column breaks the line, i.e. the content of each cell should be short enough.
In the following, there are two simple example of pure CSS solution which I created at the time I answered this question.
Here is the jsFiddle Demo v2.
Old version: jsFiddle Demo v1
How to add a scrollbar to an HTML5 table?
If you have heading to your table columns and you don't want to scroll those headings then this solution could help you:
This solution needs thead
and tbody
tags inside table
element.
table.tableSection {
display: table;
width: 100%;
}
table.tableSection thead, table.tableSection tbody {
float: left;
width: 100%;
}
table.tableSection tbody {
overflow: auto;
height: 150px;
}
table.tableSection tr {
width: 100%;
display: table;
text-align: left;
}
table.tableSection th, table.tableSection td {
width: 33%;
}
Working fiddle
With comments
Note: If you are sure that the vertical scrollbar is always present, then you can use css3 calc property to make the thead cells align with the tbody cells.
table.tableSection thead {
padding-right:18px; /* 18px is approx. value of width of scroll bar */
width: calc(100% - 18px);
}
You can do the same by detecting presence of scrollbar using javascript and applying the above styles.
Scroll bar not appearing in html table
You have to set a height for either the div or the table and only one overflow is required:
<div style="overflow-y:auto; height: 400px;">
<table class="events-table">
A table can't be made scrollable. But check out this answer: How to display scroll bar onto a html table
How to add vertical scroll bar to a table that has the first column always fixed
Is it possible to make it vertically scroll-able with CSS only?
Short answer: it is, but let's analyze the problem first:
To show this I have made a minimal example of yours (I used a real table
and not divs
and chose a layout that differs just a bit, but the problems will still be the same and are applying to your code snippets as well).
.wrapper {
display: flex;
overflow: auto;
}
.sticky-left {
text-align: left;
left: 0;
position: absolute;
}
.sticky-left td {
max-width: 200px;
min-width: 200px;
background: lightgrey;
}
thead th {
padding: 15px 5px;
background: #f4f3f8;
font-size: 14px;
border: none;
color: #575962;
max-width: 200px;
min-width: 200px;
}
.content-table {
margin-left: 200px;
}
<div class="wrapper">
<table class="sticky-left">
<thead>
<tr>
<th>#</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>February</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
<tr>
<td>January</td>
</tr>
</tbody>
</table>
<table class="content-table">
<thead>
<tr>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
<th>#</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
<tr>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
<td>January</td>
</tr>
</tbody>
</table>
</div>
HTML table overflow not working
Your code is incorrect as you added an extra space between th
and .t-Report-colHead
in .t-Report-tableWrap table thead th .t-Report-colHead {
However, here is a working code.
tr{
display: table;
width: 100%;
table-layout: fixed;
}
thead{
display: block;
}
tbody{
display: block;
height: 180px;
overflow: auto;
}
CODEPEN
Hope this helps.
Adding a scroll bar vertically to a table
You have some syntax error in your HTML code, Check updated snippet below
.scrollit { width:100%; overflow:scroll; height:300px; display: block;}
<div class="scrollit"> <table width="100%"> <thead> <tr> <th><span>ID</span></th> <th><span>Name</span></th> <th><span>Location</span></th> <th><span>Date</span></th> <th><span>Catagory</span></th> </tr> </thead> <tbody> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> <td>lorem ipsum</td> </tr> <tr> <td>lorem ipsum</td> <td>lorem ipsum</td>
Related Topics
Problems With CSS Sticky Footer
Placing Border Inside of Div and Not on Its Edge
Why Does the HTML Input With Type "Number" Allow the Letter 'E' to Be Entered in the Field
What's the Difference If I Put CSS File Inside ≪Head≫ or ≪Body≫
Why Is Form Enctype=Multipart/Form-Data Required When Uploading a File
Why the Content Is Not Covered by the Background of an Overlapping Element
How to Encode/Decode HTML Entities in Ruby
Getting the Source HTML of the Current Page from Chrome Extension
Display Pdf Within Web Browser
Add a Background Image (.Png) to a Svg Circle Shape
Svgs Not Scaling Properly in Ie - Has Extra Space
Why Doesn't Table ≫ Tr ≫ Td Work When Using the Child Selector
How to Make a Vertical Line in Html
What Are All the Valid Self-Closing Elements in Xhtml (As Implemented by the Major Browsers)
Change Color of Png Image Via Css
Nesting Block Level Elements Inside the ≪P≫ Tag... Right or Wrong