I would like to have a table with a scrollbar to the right.
I want to accomplish this without any plugins(jQuery) just with css.
The table header is supposed to stay fixed.
What do I need to do to get this working?
You have taken on a task that, if you succeed, will make you a hero. I tried this and the straightforward thing -- to position:fixed; the <thead> -- is impossible. I had to copy all of the <thead> into a new object. But when you do that, the horizontal spacing of the <th> elements all goes away so the headings don't line up with the <td>s anymore. I ended up doing something like this:
First of all, abandon ie6 and ie7. There's no hope for those guys.
Make two copies of the table, one where the body is invisible and the <thead> is visible, and the other where it's vice-versa.
Give z-index:1; to the table with the visible <thead>.
Give z-index:0; to the table with the visible <tbody>.
Deal with horizontal scrolling, but not until after you find that onScroll isn't an ie8 event (not to mention ie6), so that you have to take a setInterval break every tenth of a second or so just to handle scrolling the <thead> left and right in ie8.
This will give you a table body of infinite scroll in both axes, with a table head that scrolls in the x axis only. Pretty much works in FF, Chrome, and Safari. But is shaky in ie8. A real pita.
Good luck, and please write if you get this to work!
Only the Firefox and IE6-7 browsers support the built-in <tbody> scrolling:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Scrolling</title>
<style type="text/css">
div.content
{
border: #000000 1px solid;
height: 400px;
overflow-y: auto;
width: 800px;
}
.fixedHeader
{
white-space: nowrap;
}
.fixedHeader tr
{
height: auto;
position: relative;
}
.fixedHeader tr td
{
background-color: #778899;
border: #000000 1px solid;
text-align: center;
}
tbody.scrollContent
{
overflow-x: hidden;
overflow-y: auto;
height: 370px;
}
.scrollContent tr td
{
background-color: #C0C0C0;
border: #000000 1px solid;
padding-right: 22px;
vertical-align: top;
}
</style>
<!--[if IE]>
<style type=text/css>
div.content
{
overflow-x: hidden;
overflow-y: auto;
}
</style>
<![endif]-->
</head>
<body>
<div>
<div class="content">
<table cellspacing="0">
<thead class="fixedHeader">
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</thead>
<tbody class="scrollContent">
<tr>
<td>Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented.</td>
<td>Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. </td>
<td>Pages can be displayed either with or without tabs. </td>
<td>Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented.</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Here is the solution,
Table fixed header and the content inside the table can be scrollable.
HTML Part
<div class="table_wrapper">
<div class="header">
<div class="head1">Left</div>
<div class="head2">Center</div>
<div class="head3">Right Column</div>
</div>
<div class="tbody">
<table>
<tbody><tr><td class="td1">1</td><td class="td2">2</td><td class="td3">3</td></tr>
<tr><td class="td1">1</td><td>2</td><td class="td3">3</td></tr>
<tr><td class="td1">2</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">3</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
</tbody></table>
</div>
</div>
CSS Part
.table_wrapper {background:tomato;border:1px double olive;float:left;}
.tbody{height:80px;overflow-y:auto;width:400px;background:yellow;}
table{border-collapse:collapse; width:100%;}
td{border-right:1px solid red;border-bottom:1px solid red;padding:1px 5px;}
.td3{border-right-width:0;}
.header{ width:400px;background:DodgerBlue;border-bottom:1px solid red;}
.header div{padding:1px 5px;float:left;border-right:1px solid orange;}
.header .head3{float:none;border-right-width:0;}
.head3 span{padding-left:5px;}
.td1{width:100px;}
.td2{width:140px;}
.header .head1{width:100px;}
.header .head2{width:140px;}
This simple CSS should do the trick:
table.table-scroll-body {
position: relative;
height: 200px; }
table.table-scroll-body tbody {
position: absolute;
width: 100%;
max-height: 150px;
overflow: auto; }
And the HTML if you need it..
<table class="table-scroll-body">
<thead>
<th>Header 1</th>
<th>Header 2</th>
</thead>
<tbody>
<tr>
<td>Some content..</td>
<td>Some content..</td>
</tr>
<tr>
<td>Some content..</td>
<td>Some content..</td>
</tr>
<tr>
<td>Some content..</td>
<td>Some content..</td>
</tr>
</tbody>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
table
{
width: 320px;
display: block;
border:solid black 1px;
}
thead
{
display: inline-block;
width: 100%;
height: 20px;
}
tbody
{
height: 200px;
display: inline-block;
width: 100%;
overflow: auto;
}
th, td
{
width: 100px;
text-align:center;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
</body>
</html>
branching off of astrandr's answer.. here is how I did it, using their example:
css:
.transactHistory table
{
width: 320px;
display: block;
}
.transactHistory thead
{
display: inline-block;
}
.transactHistory tbody
{
height: 133px;
display: inline-block;
width: 100%;
overflow: auto;
}
.transactHistory th
{
width: 100px;
text-align:center;
}
.transactHistory tr
{
width: 100px;
text-align:center;
}
.transactHistory td
{
width: 100px;
text-align:center;
}
Table:
<div class="transactHistory">
(..table code)
</div>
This works, took it right off my website:
#news_box {
overflow: scroll;
overflow-x: hidden;
}
EDIT:
I also just found this with a nice example:
http://www.imaputz.com/cssStuff/bigFourVersion.html
Here's another good article on it:
http://www.scientificpsychic.com/blogentries/html-and-css-scrolling-table-with-fixed-heading.html
Related
I have an html table that I set the width and height to a given size. I'd like all cells in the table to be the same height and width filling up the table regardless of what's in them(even if empty) and how many cells there are.
I'd like a purely CSS solution(no JS) to this problem if possible.
In case anyone is wondering, I'm using JS to change how many cells there are in the table and I'd like the table to be same size no matter the cell count.
It's possible but you'd have to worry about content being clipped because it overflows to the next cell.
The important pieces are:
table-layout: fixed
Table and column widths are set by the widths of table and col
elements or by the width of the first row of cells. Cells in
subsequent rows do not affect column widths.
However
If no widths are present on the first row, the column widths are
divided equally across the table, regardless of content inside the
cells.
white-space: nowrap
Collapses white space as for normal, but suppresses line breaks (text
wrapping) within the source.
overflow: hidden
Content is clipped if necessary to fit the padding box. No scrollbars
are provided, and no support for allowing the user to scroll (such as
by dragging or using a scroll wheel) is allowed. The content can be
scrolled programmatically (for example, by setting the value of a
property such as offsetLeft), so the element is still a scroll
container.
Example:
table{
/* Set the table width, can be a percentage or size */
width: 100%;
/* If no widths are present on the first row, the column widths are divided equally across the table */
table-layout: fixed;
/* Table border */
border: 1px solid black;
/* A margin to separate the tables */
margin-bottom: 20px;
/* Set the fixed table height */
height: 200px;
}
tr{
/* Keep the cells from wrapping content to a new line. */
white-space: nowrap;
}
td{
/* Cell border */
border: 1px solid black;
/* Hide anything in the row that overflows the cell otherwise content could cross cell borders */
overflow: hidden;
}
<table>
<thead>
<tr>
<td>Column 1 ddddddddddddddddddd</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 5</td>
<td>Column 6</td>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1 ooooooooooooooooooooooooooooooooooooooo</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4 bbbbbbbbbbbbbbbbbbb</td>
<td>Cell 5</td>
<td>Cell 6 ggggggggggg</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4 asdasdasdadsadsdasadsadsadsdas</td>
<td>Cell 5</td>
<td>Cell 6 jkasddsakjakjlasdjkladslkjalkjadsklajds</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
<table>
</table>
<html>
<body style="background: white;">
<table style="height: 100%;width: 100%;">
<tbody>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
</body>
</html>
results in:
(this is pasted in a new tab so there is no extra Css styling or anything going on)
How can I stop the rows from growing to their max height but rather to the content height? (preferably without setting a fixed 20px height to the row)
Edit: I want to the table to still fill the whole page
You could try using flexboxes to achieve that:
table,
tr {
display: flex;
width: 100%;
}
tbody {
width: 100%;
}
th,
td {
display: inline-flex;
flex-grow: 1;
}
<body style="background: white;">
<table style="height: 100%; width: 100%">
<tbody>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</tbody>
</table>
</body>
Just be mindful that you'll be loosing some of the table features.
Height 100% is not required
Remove it to take the minimum size table requires
Quite simple really. I've probably missed something obvious but here goes.
I have a <table> inside a multi-column view. The idea being, it's a fairly tall table so having it on multiple columns makes it less obnoxiously vertical and fits better on-screen.
The problem is that the rows in columns 2 and beyond have no header.
If I go to Print Preview, however, each column has a "copy" of the <thead> - as it should, IMO, since that's what the <thead> is for.
Is it possible to get this behaviour, apparently only available by default in #media print, to work on the webpage itself?
(Note that the table's contents are dynamic and the whole thing should be responsive, so manually inserting / breaking up the table is a no-go.)
#container {
column-count: 3;
}
<div id="container">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
</tbody>
</table>
</div>
Here is a simple table. I want table column to rotate. That's why I have added a class text-flip. It will rotate the column data. But I want to change Cell 1, Cell 2 width based on column data width (after rotate). Like thebelow picture-
Here column data size may be change.
body{
padding-top: 50px;
}
.text-flip{
transform: rotate(-90deg);
}
<table border="1">
<tbody>
<tr>
<td class="text-flip">Column Data 1</td>
<td class="text-flip">Column Data 2</td>
<td class="text-flip">Column Data 3</td>
<td class="text-flip">Column Data 4</td>
<td class="text-flip">Column Data 5</td> </tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
</tr>
</tbody>
</table>
You can do it by combining writing-mode with a rotation to achieve vertical text. You'll also need to add the class to a div instead of the td.
Edge will treat the height of the div as though it was 100% width, making it take up the full height of the table, so we can add display: inline-block to make it only take up as much space as needed.
body{
padding-top: 50px;
}
.text-flip{
display: inline-block;
writing-mode: tb-rl;
transform: rotate(-180deg);
white-space: nowrap;
padding: 10px
}
<table border="1">
<tbody>
<tr>
<td ><div class="text-flip">Column Data 1</div></td>
<td><div class="text-flip">Column Data 2</div></td>
<td><div class="text-flip">Column Data 3</div></td>
<td><div class="text-flip">Column Data 4</div></td>
<td><div class="text-flip">Column Data 5</div></td> </tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
</tr>
</tbody>
</table>
You could use writing-mode if you can spare IE/Edge and Safari
https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode
body{
padding-top: 50px;
}
.text-flip{
writing-mode: vertical-lr;
}
<table border="1">
<tbody>
<tr>
<td class="text-flip">Column Data 1</td>
<td class="text-flip">Column Data 2</td>
<td class="text-flip">Column Data 3</td>
<td class="text-flip">Column Data 4</td>
<td class="text-flip">Column Data 5</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
</tr>
</tbody>
</table>
You can do like this :-
body{
padding-top: 50px;
}
.text-flip {
white-space: nowrap;
height: 120px;
vertical-align: bottom;
}
.text-flip > div {
transform: rotate(-90deg);
width: 30px;
}
.text-flip > div > span {
border-bottom: 1px solid #ccc;
padding: 5px 10px;
}
<table border="1">
<tbody>
<tr>
<td class="text-flip"><div><span>Column Data 1</span></div></td>
<td class="text-flip"><div><span>Column Data 2</span></div></td>
<td class="text-flip"><div><span>Column Data 3</span></div></td>
<td class="text-flip"><div><span>Column Data 4</span></div></td>
<td class="text-flip"><div><span>Column Data 5</span></div></td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
</tr>
</tbody>
</table>
I have 8 td in my table and my problem is I would like to wrap the td every 4th column. So in short, I want the 5th td will display in new line. Please help me. Thanks.
<div id="schedule">
<table>
<tbody>
<tr>
<td>terdg</td>
<td>yhr6t</td>
<td>yhr6t</td>
<td>yhr6t</td>
<td>hgf</td>
<td>gdrg</td>
<td>tyht</td>
<td>drf</td>
</tr>
</tbody>
</table>
</div>
If you must retain the same HTML structure you can manage this with floats but it's likely that you will lose the "tableness" of the cells and you may have to adjust accordingly.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
table {}
td {
float: left;
width: 25%;
padding: 1em;
border: 1px solid grey;
white-space: nowrap;
}
td:nth-child(4n + 1) {
clear: both;
}
<div id="schedule">
<table>
<tbody>
<tr>
<td>cell 1</td>
<td>cell 2</td>
<td>cell 3</td>
<td>cell 4</td>
<td>cell 5</td>
<td>cell 6</td>
<td>cell 7</td>
<td>cell 8</td>
<td>cell 9</td>
<td>cell 10</td>
<td>cell 11</td>
<td>cell 12</td>
</tr>
</tbody>
</table>
</div>
<div id="schedule">
<table>
<tbody>
<tr>
<td>terdg</td>
<td>yhr6t</td>
<td>yhr6t</td>
<td>yhr6t</td>
</tr>
<tr>
<td>hgf</td>
</tr>
<tr>
<td>gdrg</td>
<td>tyht</td>
<td>drf</td>
</tr>
</tbody>
</table>
</div>