I am on a project with Angular 5 and I am trying to have a table within and a vertical and horizontal scroll (with fixed left column and header), the vertical scroll works but not the horizontal one, even worse my inside is displayed in two lines.
My number of columns is also a variable and I wish that table takes 100% width. How do I achieve 100% table width?
My code :
css:
.table-tendency thead, .table-tendency tbody,.table-tendency tr,.table-tendency td, .table-tendency th { display: block; }
.table-tendency tr:after {
content: ' ';
display: block;
visibility: hidden;
clear: both;
}
.table-tendency thead td {
height: 50px;
font-weight: normal;
}
.table-tendency tbody {
max-height: 400px;
overflow-y: scroll;
}
.table-tendency {
overflow-x: scroll;
}
.table-tendency thead td {
width: 16.4% ;
float: left;
text-align: center;
}
.table-tendency tbody td {
width: 16.6% ;
float: left;
text-align: center;
}
HTML
<div class=" table-responsive marge" *ngIf="selectedForecastSection.name !== '' && showTendencies">
<table class="table table-striped table-tendency">
<thead>
<tr>
<td> {{'Year' | translate}}</td>
<td *ngFor="let tendencyPeriod of tendencyPeriods"> {{tendencyPeriod.name}}</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let year of years" >
<td class="yearColumn"> {{year}}</td>
<td *ngFor="let tendencyPeriod of tendencyPeriods">
<span [ngStyle]="setFont(dataFilter(year, tendencyPeriod.id))"> {{dataFilter(year, tendencyPeriod.id).anyVehicleFlow | number:'1.2-2'}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
I need a table just like describred in Fixed right column table scales to responsive design But when I define a background color using css the rule doesn't apply to the fixed column
Jsfiddle: https://jsfiddle.net/3ckvkr1f/2/
Thanks!
HTML
<div class="table-responsive">
<table class="table-striped" cellpadding="9">
<thead>
<tr>
<th>
col1
</th>
<th>
col2
</th>
<th class="crud-links"> Options</th>
</tr>
</thead>
<tr>
<td>
R1col1 alçkfjalçkfjalkjflaksjflaksj
</td>
<td>
R1col2 aslkfjasklçfjaklçfjasklfjasçklfjas
</td>
<td class="crud-links">
x
</td>
</tr>
<tr>
<td style="white-space: nowrap;">
R2col1 alçkfjalçkfjalkjflaksjflaksj slkfjsçklafjaslfkjsldk
</td>
<td style="white-space: nowrap;">
R2col2 aslkfjasklçfjaklçfjasklfjasçklfjas
</td>
<td class="crud-links">
x
</td>
</tr>
<tr>
<td style="white-space: nowrap;">
R3col1 alçkfjalçkfjalkjflaksjflaksj slkfjsçklafjaslfkjsldk
</td>
<td style="white-space: nowrap;">
R3col2 aslkfjasklçfjaklçfjasklfjasçklfjas
</td>
<td class="crud-links">
x
</td>
</tr>
</table>
</div>
CSS:
.table-striped > tbody > tr:nth-of-type(2n+1) {
background-color: blue;
}
.page-header {
padding-bottom: 9px;
margin: 40px 0 20px;
border-bottom: 1px solid #eeeeee;
}
.table-hover th, .table-hover td {
padding: 9px;
}
.table-responsive {
width: inherit;
max-width: 80%;
margin-bottom: 15px;
overflow-x: scroll;
overflow-y: hidden;
border: 0;
}
.crud-links{
position: absolute;
overflow:hidden;
width: 91px;
right: 0;
}
.table-striped > tbody > tr:nth-of-type(2n+1) {
background-color: blue;
}
Are you talking about the ones with the class .crud-links?
If so, just do
tr .crud-links { background: something; }
If you're talking about them not getting the same color as every other in the main part, just do the same, but using tr .crud-links:nth-of-type(odd)
Your css code refers to tbody tag, but You are missing it.
.table-striped > tbody > tr:nth-of-type(2n+1)
Correct yout html code, or change css like this:
.table-striped tr:nth-of-type(2n+1)
/*first three column class name as follow, */
/*tbody used for only tr td work otherwise table header also work with bgcolor*/
/*fixed column first three column hover color change*/
tbody > tr:hover > .freez,
tbody >tr:hover > .freez2,
tbody> tr:hover > .freez3{
background-color:#f5f5f5 !important;
}
I have a table with fixed first column which will allow me to scroll the table columns left and right while keeping the first column in place.
(Entire table is in the wrapper that gives me the scrollbar as table is always wider than the wrapper.)
Table also has a toggle button on the header to show extra data in some td's.
When using Firefox, scrolling table to the right and then clicking the toggle button the entire first column disappears ...and this happens only in Firefox.
How to fix that?
Here is the fiddle
HTML
<div class="da-fixed-column-table-wrapper" data-ng-app="testModule" data-ng-controller="testController">
<table class="da-fixed-column-table" border=1>
<thead>
<tr>
<th>
<button ng-click="show=!show">show-hide</button>
</th>
<th>Header2</th>
<th>Header3</th>
<th>Header4</th>
<th>Header5</th>
</tr>
</thead>
<tbody>
<tr>
<td>first</td>
<td>second</td>
<td>third</td>
<td>fourth</td>
<td>fifth<span ng-show="show">more data</span></td>
</tr>
<tr>
<td>first</td>
<td>second</td>
<td>third<span ng-show="show">more data</span></td>
<td>fourth</td>
<td>fifth</td>
</tr>
</tbody>
</table>
</div>
CSS
.da-fixed-column-table-wrapper {
width: 100%;
overflow: auto;
box-sizing: border-box;
background: DarkKhaki;
}
.da-fixed-column-table {
width: 120%;
border-collapse: collapse;
box-sizing: border-box;
text-align: right;
}
.da-fixed-column-table tbody tr td:first-child,
.da-fixed-column-table thead tr th:first-child {
position: absolute;
border: none;
top: auto;
width: 8em;
text-align: left;
background: white;
}
.da-fixed-column-table thead tr th:nth-child(2),
.da-fixed-column-table tbody tr td:nth-child(2) {
padding-left: 9em;
}
You just need to add left: 0 to make sure the elements stick correctly. The change in width caused it move out of view.
.da-fixed-column-table tbody tr td:first-child,
.da-fixed-column-table thead tr th:first-child {
position: absolute;
border: none;
top: auto;
width: 8em;
text-align: left;
background: white;
left: 0;
}
EDIT 2: I'm talking about the layout of the table, not the colours.
I need to style my table so that it appears as such:
The idea is to have the first th td pair on top and the rest should be in line under it.
Is that feasible through CSS?
I don't have control over the HTML here so CSS is my only option.
Edit:
Here's the HTML
<div class="content">
<table>
<thead>
<tr>
<th class="thtitle" >
Title </th>
<th class="thvalue" >
Value </th>
<th class="thquantity" >
Quantity </th>
<th class="thsum" >
Sum </th>
</tr>
</thead>
<tbody>
<tr class="first">
<td class="tdtitle" >…</td>
<td class="tdvalue" >…</td>
<td class="tdquantity" >…</td>
<td class="tdsum" >…</td>
</tr>
<tr class="last">
<td class="tdtitle" >…</td>
<td class="tdvalue" >…</td>
<td class="tdquantity" >…</td>
<td class="tdsum" >…</td>
</tr>
</tbody>
</table>
</div>
Edit 2:
I've added a fiddle that does exactly what you want, but be warned that nth-child doesnt play nice in IE8. It also assumes that the HTML you gave us is ALWAYS that way [ie always has the same amount of th/td's].
http://jsfiddle.net/8awAj/
Edit:
Is the html you posted ALWAYS like that? Ie never any more or less headings etc?
This isn't 100% what you want, but its kind of close. To get exactly what you want you would have to do a LOT of manual absolute positioning using :nth-child which would be horrible.
http://jsfiddle.net/9JWpA/
table {
width: 100%;
padding-top: 40px;
position: relative;
}
th {
background: yellow;
}
td {
background: green;
}
th,
td {
top: 40px;
width: 16.666%;
position: absolute;
}
th:first-child,
td:first-child {
width: 100%;
top: 0;
left: 0;
}
td:first-child {
top: 20px;
}
th:nth-child(2) {
left: 0;
}
td:nth-child(2) {
left: 16.666%;
}
th:nth-child(3) {
left: 33.333%;
}
td:nth-child(3) {
left: 49.998%;
}
th:nth-child(4) {
left: 66.666%;
}
td:nth-child(4) {
left: 83.33%;
}
try this..
http://jsfiddle.net/9JWpA/
html:
<table cellspacing=0;>
<tr><th colspan="6">th</th></tr>
<tr><td colspan="6">td</td></tr>
<tr><th>th</th><td>td</td><th>th</th><td>td</td><th>th</th><td>td</td></tr>
</table>
css:
table
{
width:200px;
border:1px solid black;
text-align:left;
}
th
{
background:yellow;
}
td
{
background:green;
}
I am writing a page where I need an html table to maintain a set size. I need the headers at the top of the table to stay there at all times but I also need the body of the table to scroll no matter how many rows are added to the table.
I want it to look like method 2 in this url: http://www.cssplay.co.uk/menu/tablescroll.html
I have tried doing this but no scrollbar appears:
tbody {
height: 80em;
overflow: scroll;
}
<table border=1 id="qandatbl" align="center">
<tr>
<th class="col1">Question No</th>
<th class="col2">Option Type</th>
<th class="col1">Duration</th>
</tr>
<tbody>
<tr>
<td class='qid'></td>
<td class="options"></td>
<td class="duration"></td>
</tr>
</tbody>
</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>
You have to insert your <table> into a <div> that it has fixed size, and in <div> style you have to set overflow: scroll.
Update:
The original answer was written 10 years ago. These days there are lots of good UI components for table views and showing in proper ways. So my suggestion is to go for one of these free or paid components to make sure you already support lots of edge cases which is already implemented in these components.
The accepted answer provided a good starting point, but if you resize the frame, change the column widths, or even change the table data, the headers will get messed up in various ways. Every other example I've seen has similar issues, or imposes some serious restrictions on the table's layout.
I think I've finally got all these problems solved, though. It took a lot of CSS, but the final product is about as reliable and easy to use as a normal table.
Here's an example that has all the required features to replicate the table referenced by the OP: jsFiddle
The colors and borders would have to be changed to make it identical to the reference. Information on how to make those kinds of changes is provided in the CSS comments.
Here's the code:
/*the following html and body rule sets are required only if using a % width or height*/
/*html {
width: 100%;
height: 100%;
}*/
body {
box-sizing: border-box;
width: 100%;
height: 100%;
margin: 0;
padding: 0 20px 0 20px;
text-align: center;
background: white;
}
.scrollingtable {
box-sizing: border-box;
display: inline-block;
vertical-align: middle;
overflow: hidden;
width: auto; /*if you want a fixed width, set it here, else set to auto*/
min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
font-family: Verdana, Tahoma, sans-serif;
font-size: 15px;
line-height: 20px;
padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
position: relative;
border-top: 1px solid black;
height: 100%;
padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
top: 0;
background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
content: "";
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
left: 0;
}
.scrollingtable > div > div {
min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
max-height: 100%;
overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
overflow-x: hidden;
border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
width: 100%;
border-spacing: 0;
margin-top: -20px; /*inverse of column header height*/
/*margin-right: 17px;*/ /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
position: absolute;
top: -20px; /*inverse of caption height*/
margin-top: -1px; /*inverse of border-width*/
width: 100%;
font-weight: bold;
text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
vertical-align: bottom;
white-space: nowrap;
text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
display: inline-block;
padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 20px; /*match column header height*/
border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
position: absolute;
top: 0;
white-space: pre-wrap;
color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
content: "";
display: block;
min-height: 20px; /*match column header height*/
padding-top: 1px;
border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
position: absolute;
width: 100px;
top: -1px; /*inverse border-width*/
background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
content: "";
display: table-cell;
position: relative;
padding: 0;
border-top: 1px solid black;
top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
border-bottom: 1px solid black;
padding: 0 6px 0 6px;
height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
<div class="scrollingtable">
<div>
<div>
<table>
<caption>Top Caption</caption>
<thead>
<tr>
<th><div label="Column 1"></div></th>
<th><div label="Column 2"></div></th>
<th><div label="Column 3"></div></th>
<th>
<!--more versatile way of doing column label; requires 2 identical copies of label-->
<div><div>Column 4</div><div>Column 4</div></div>
</th>
<th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
</tr>
</thead>
<tbody>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
</tbody>
</table>
</div>
Faux bottom caption
</div>
</div>
<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->
Not sure why no one mentioned to just use the built-in sticky header style for elements. Worked great for me.
.tableContainerDiv {
overflow: auto;
max-height: 80em;
}
th {
position: sticky;
top: 0;
background: white;
}
Put a min-width on the in #media if you need to make responsive (or similar).
see Table headers position:sticky or Position Sticky and Table Headers
I resolved this problem by separating my content into two tables.
One table is the header row.
The seconds is also <table> tag, but wrapped by <div> with static height and overflow scroll.
Worth noting, that depending on your purpose (mine was the autofill results of a searchbar) you may want the height to be changeable, and for the scrollbar to only exist if the height exceeds that.
If you want that, replace height: x; with max-height: x;, and overflow:scroll with overflow:auto.
Additionally, you can use overflow-x and overflow-y if you want, and obviously the same thing works horizontally with width : x;
If you get to the point where all the mentioned solutions don't work (as it got for me), do this:
Create two tables. One for the header and another for the body
Give the two tables different parent containers/divs
Style the second table's div to allow vertical scroll of its contents.
Like this, in your HTML
<div class="table-header-class">
<table>
<thead>
<tr>
<th>Ava</th>
<th>Alexis</th>
<th>Mcclure</th>
</tr>
</thead>
</table>
</div>
<div class="table-content-class">
<table>
<tbody>
<tr>
<td>I am the boss</td>
<td>No, da-da is not the boss!</td>
<td>Alexis, I am the boss, right?</td>
</tr>
</tbody>
</table>
</div>
Then style the second table's parent to allow vertical scroll, in your CSS
.table-content-class {
overflow-y: scroll; // use auto; or scroll; to allow vertical scrolling;
overflow-x: hidden; // disable horizontal scroll
}
Very easy, just wrap the table in a div that has overflow-y:scroll; and overflow-x:scroll properties, and make the div have a width and length smaller than the table.
IT WILL WORK!!!
The CSS:
div{ overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; } table{ width:50px; height:50px; }
You can make the table and the DIV around the table be any size you want, just make sure that the DIV is smaller than the table.
You MUST contain the table inside of the DIV.
just add on table
style="overflow-x:auto;"
<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
<tr>
<th class="col1">Question No</th>
<th class="col2">Option Type</th>
<th class="col1">Duration</th>
</tr>
<tbody>
<tr>
<td class='qid'></td>
<td class="options"></td>
<td class="duration"></td>
</tr>
</tbody>
</table>
style="overflow-x:auto;"`