How to freeze table columns - html

How to make the horizontal scroll bar only affects the gray columns in the following illustration.
html,
body {
background: #ccc;
font-family: Arial, sans-serif
}
#table {
background: white;
margin: 100px auto;
width: 400px;
overflow: auto;
text-align: center;
}
#inner-table {
border-collapse: collapse;
border-radius: 3px;
overflow: hidden
}
td,
th {
padding: 5px 10px;
}
th {
border-bottom: 1px solid #B8C2CC
}
.sticky {
background-color: #1C3D5A;
color: #dae1e7;
}
.scroll {
background-color: #B8C2CC;
color: #22292f
}
<div id="table">
<table id="inner-table">
<thead>
<tr>
<th class="sticky">sticky</th>
<th class="sticky">sticky</th>
<th class="scroll">scroll</th>
<th class="scroll">scroll</th>
<th class="scroll">scroll</th>
<th class="scroll">scroll</th>
<th class="scroll">scroll</th>
<th class="scroll">scroll</th>
<th class="sticky">sticky</th>
<th class="sticky">sticky</th>
</tr>
</thead>
<tbody>
<tr>
<td class="sticky">1</td>
<td class="sticky">2</td>
<td class="scroll">3</td>
<td class="scroll">4</td>
<td class="scroll">5</td>
<td class="scroll">6</td>
<td class="scroll">7</td>
<td class="scroll">8</td>
<td class="sticky">9</td>
<td class="sticky">10</td>
</tr>
<tr>
<td class="sticky">11</td>
<td class="sticky">12</td>
<td class="scroll">13</td>
<td class="scroll">14</td>
<td class="scroll">15</td>
<td class="scroll">16</td>
<td class="scroll">17</td>
<td class="scroll">18</td>
<td class="sticky">19</td>
<td class="sticky">20</td>
</tr>
</tbody>
</table>
</div>

This was rather more difficult to put together than I anticipated - and even now, I am wondering if there isn't a much simpler approach.
The approach below utilises:
an outer container which contains two position: absolute tables
a fixed-width inner container - using margins for positioning inside the outer container - with a scrollbar, which allows you to see the oversized table it contains
Working Example:
html,
body {
background: #ccc;
font-family: Arial, sans-serif
}
.outer-container {
position: relative;
background-color: white;
margin: 40px auto;
width: 400px;
overflow: hidden;
text-align: center;
}
.outer-container,
.inner-container {
height: 125px;
}
table {
height: 108px;
}
.inner-container table {
border-radius: 3px;
}
td, th {
padding: 5px 10px;
}
th {
border-bottom: 1px solid #B8C2CC
}
.fixed-table th,
.fixed-table td {
background-color: #1C3D5A;
color: #dae1e7;
}
.inner-container {
margin: 0 130px;
max-width: 612px;
overflow: auto;
}
.inner-container > table {
background-color: #B8C2CC;
color: #22292f
}
.outer-container > table {
position: absolute;
top: 0;
border-collapse: collapse;
}
.outer-container > table:nth-of-type(1) {
left: 0;
}
.outer-container > table:nth-of-type(2) {
right: 0;
}
<div class="outer-container">
<table class="fixed-table">
<thead>
<tr>
<th>sticky</th>
<th>sticky</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>11</td>
<td>12</td>
</tr>
</tbody>
</table>
<div class="inner-container">
<table>
<thead>
<tr>
<th>scroll</th>
<th>scroll</th>
<th>scroll</th>
<th>scroll</th>
<th>scroll</th>
<th>scroll</th>
</tr>
</thead>
<tbody>
<tr>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
</tr>
</tbody>
</table>
</div>
<table class="fixed-table">
<thead>
<tr>
<th>sticky</th>
<th>sticky</th>
</tr>
</thead>
<tbody>
<tr>
<td>9</td>
<td>10</td>
</tr>
<tr>
<td>19</td>
<td>20</td>
</tr>
</tbody>
</table>
</div>

CSS3 should do the job.
table {
position: relative;
padding-left: (width-of-your-td-elements);
}
table td:first-of-type {
position: absolute;
left: 0;
}
Sources

Related

How to make a dynamic table cell use overflow:hidden

I want to use overflow:hidden on a dynamic table that should only be as wide as necessary:
<table>
<tr>
<td>Should_not_overflow</td>
</tr>
<tr>
<td style="overflow: hidden;">This text should overflow please</td>
</tr>
</table>
I know that it works with a fixed table layout, but I need a dynamic table.
I also know that it would work with a fixed width and a nested <div>, but again, I need a dynamic table layout.
.table-wrapper {
font-size:12px;
position: relative;
width: 50%;
height: 275px;
border: 1px solid #333;
padding: 50px 0 0;
margin: 10px auto;
}
.header-bg {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 50px;
background-color: #03A9F4;
}
.table-container {
overflow-x: hidden;
overflow-y: auto;
height: 100%;
}
table {
width: 100%;
background-color: #FFF;
overflow-x: hidden;
overflow-y: auto;
}
tr {
&:nth-child(even) {
background-color: #F2F2F2;
}
th {
text-align: left;
padding: 0 5px;
.th-extra {
width: 100%;
.th-extra__inner {
position: absolute;
top: 0;
color: #000;
line-height: 50px;
text-align: left;
border-left: 1px solid #333;
padding: 0 0 0 5px;
margin: 0 0 0 -5px;
}
}
&:first-child {
.th-extra__inner {
border: none;
}
}
}
}
td {
line-height: 42px;
text-align: left;
padding: 0 5px;
& + td {
border-left: 1px solid #333;
}
}
<div class="table-wrapper">
<div class="header-bg"></div>
<div class="table-container">
<table cellspacing="0">
<thead>
<tr>
<th>
<div class="th-extra">
<div class="th-extra__inner">First</div>
</div>
</th>
<th>
<div class="th-extra">
<div class="th-extra__inner">Second</div>
</div>
</th>
<th>
<div class="th-extra">
<div class="th-extra__inner">Third</div>
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column with longer content</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
<tr>
<td>Column</td>
<td>Column</td>
<td>Column</td>
</tr>
</tbody>
</table>
</div>
</div>

Remove border spacing from every 2n element in table

I have a table that looks like this:
And every row has a hidden details field:
So I want to remove border spacing from row and its details row.. How can I do that?
this is my HTML:
<table class="table message-table">
<thead>
<tr>
<th>Title</th>
<th>Date</th>
<th>Action</th>
<th></th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let message of messages | paginate: config">
<tr>
<td>{{message.title}}</td>
<td>{{message.created | date:'longDate'}}</td>
<td (click)="message.collapsed = !message.collapsed; makeMessageSeen(message);" [attr.aria-expanded]="!message.collapsed" aria-controls="collapseExample">{{message.collapsed ? 'More' : 'Less'}}</td>
<td></td>
</tr>
<tr id="collapseExample" [ngbCollapse]="message.collapsed">
<td>{{message.text}}</td>
<td colspan="3"></td>
</tr>
</ng-container>
</tbody>
</table>
and this is my SCSS:
.messages {
background-color: $color-background-main;
min-height: 17rem;
overflow-x: auto;
padding-top: 2rem;
.message-table {
border-collapse: separate;
border-spacing: 0 0.4rem;
thead {
th {
border: none;
font-size: 0.6rem;
color: #9b9b9b;
text-transform: uppercase;
padding-top: 0;
padding-bottom: 0;
&:first-child {
width: 70%;
padding-left: 1rem;
}
}
}
}
tbody {
tr {
box-shadow: $main-shadow;
background-color: white;
&.selected {
box-shadow: $shadow-selected;
}
td:first-child {
padding-left: 1rem;
}
}
td {
background-color: white;
border: none;
padding-top: 0;
padding-bottom: 0;
padding-right: 0;
height: 2.5rem;
vertical-align: middle;
table-layout: fixed;
&:first-child {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
&:last-child {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
padding-right: 0;
width: 2rem;
}
}
}
}
How can I fix this? I've tried making tr a top border but nothing happened... What are other solutions for my problem?
UPDATE 1
Adding codepen of a simple example : https://codepen.io/anon/pen/prxgOe
UPDATE 2
I want to remove spacing between title and details tr elements ONLY!
Here is a quick fix using borders.
table {
border-collapse: collapse;
border-spacing: 0 0.4rem;
}
tr {
background-color: #ccc;
}
.title {
border-top: 5px solid #fff;
}
.details {
/* display: none; */
}
<table>
<thead>
<tr>
<th>Title</th>
<th>Created</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="title">
<td>title1</td>
<td>2017-01-01</td>
<td>More</td>
</tr>
<tr class="details">
<td>this is text1</td>
<td colspan="2"></td>
</tr>
<tr class="title">
<td>title2</td>
<td>2017-01-01</td>
<td>More</td>
</tr>
<tr class="details">
<td>this is text2</td>
<td colspan="2"></td>
</tr>
<tr class="title">
<td>title3</td>
<td>2017-01-01</td>
<td>More</td>
</tr>
<tr class="details">
<td>this is text3</td>
<td colspan="2"></td>
</tr>
</tbody>
</table>
I think you want like this
table {
border-collapse: collapse;
border-spacing: 0 0.4rem;
}
tr {
background-color: #ccc;
display: table-row;
}
table {
border-collapse: collapse;
border-spacing: 0 0.4rem;
}
tr {
background-color: #ccc;
display: table-row;
}
.title:first-child {
border-top: 7px solid #fff;
}
.title {
border-top: 12px solid #fff;
}
tbody tr:nth-child(2n) {
position: relative;
}
tbody tr:nth-child(2n)::after {
bottom: 0;
box-shadow: 0 2px 2px 0 #ebebeb;
content: "";
height: 100%;
left: 0;
position: absolute;
right: 0;
width: 100%;
}
<table>
<thead>
<tr>
<th>Title</th>
<th>Created</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="title">
<td>title1</td>
<td>2017-01-01</td>
<td>More</td>
</tr>
<tr class="details">
<td>this is text1</td>
<td colspan="2"></td>
</tr>
<tr class="title">
<td>title2</td>
<td>2017-01-01</td>
<td>More</td>
</tr>
<tr class="details">
<td>this is text2</td>
<td colspan="2"></td>
</tr>
<tr class="title">
<td>title3</td>
<td>2017-01-01</td>
<td>More</td>
</tr>
<tr class="details">
<td>this is text3</td>
<td colspan="2"></td>
</tr>
</tbody>
</table>
*ngFor has an option to detect odd and even rows:
<div *ngFor="let message of messages; let odd=odd; let even=even>..</div>
then you can use odd or even values to set style/class as so:
<div [class.evenClass]="event" [class.oddClass]="odd">...</div>
and in the stylesheet, define .evenClass and .oddClass style as needed.
P.S.You have a table layout, you need to adapt above to your case
#hunzaboy and #ankitapatel answers were kind of good for me, but eventually I came with different solution which is probably not the best one, but it works like a charm... It does not break the ui scalability or anything else...
So I just added div elements in each of td elements so my HTML now looks like this:
<tbody>
<ng-container *ngFor="let message of messages | paginate: config">
<tr>
<td [class.unseen]="!message.seen" [class.seen]="message.seen">{{message.title}}</td>
<td [class.unseen]="!message.seen" [class.seen]="message.seen">{{message.created | date:'longDate'}}</td>
<td class="details-button" (click)="message.collapsed = !message.collapsed; makeMessageSeen(message);" [attr.aria-expanded]="!message.collapsed" aria-controls="collapseExample">{{message.collapsed ? 'More' : 'Less'}}</td>
<td></td>
</tr>
<tr id="collapseExample" [ngbCollapse]="message.collapsed">
<td>
<div class="text-container">{{message.text}}</div>
</td>
<td colspan="3">
<div class="empty-container"></div>
</td>
</tr>
</ng-container>
</tbody>
and then I added this SCSS to my file:
#collapseExample {
td {
padding: 0;
}
.text-container {
background-color: #fff;
margin-top: -23px;
padding-left: 1rem;
border-radius: 0.2rem;
height: 100%;
padding-bottom: 1rem;
}
.empty-container {
background-color: #fff;
height: 100%;
margin-top: -20px;
width: 100%;
}
}

How to hide borders between rows in a html table and display only borders between columns using css

I have an simple html table where I want to only display the borders between columns and hide the borders between rows. I tried the code below but it did not achieve what I was after.
I have also used border-collapse : collapse in css, but it didn't seem to work.
table td, table th { border: 1px solid black; padding: 5px; }
#items { clear: both; margin: 30px 0 0 0; border: 1px solid black; }
#items th { background: #eee; }
#items textarea { width: 300px; height: 50px; }
#items,td {
border-collapse: collapse;
border-spacing: 0;
margin: 0;
padding: 0;
}
<table id="items">
<thead>
<tr>
<th style="width:100px;">Slno</th>
<th style="width:300px;">Description of Goods</th>
<th style="width:120px;">Quantity</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td>1</td>
<td>S1</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>S2</td>
<td>5</td>
</tr>
<tr>
<td>3</td>
<td>S3</td>
<td>5</td>
</tr>
</tbody>
</table>
Is this what you looking for
table th { border: 1px solid black; padding: 5px; }
table td{ padding: 5px; }
#items { clear: both; margin: 30px 0 0 0; border: 1px solid black; }
#items th { background: #eee; }
#items textarea { width: 300px; height: 50px; }
#items,td {
border-collapse: collapse;
border-spacing: 0;
margin: 0;
padding: 0;
}
<table id="items">
<thead>
<tr>
<th style="width:100px;">Slno</th>
<th style="width:300px;">Description of Goods</th>
<th style="width:120px;">Quantity</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td>1</td>
<td>S1</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>S2</td>
<td>5</td>
</tr>
<tr>
<td>3</td>
<td>S3</td>
<td>5</td>
</tr>
</tbody>
</table>
you made the th/td to have "border:1px solid black" but you only need border-right
table td, table th {border-right: 1px solid black; padding: 5px; }
#items { clear: both; margin: 30px 0 0 0; }
#items th { background: #eee; }
#items textarea { width: 300px; height: 50px; }
#items,td {
border-collapse: collapse;
border-spacing: 0;
margin: 0;
padding: 0;
}
<table id="items">
<thead>
<tr>
<th style="width:100px;">Slno</th>
<th style="width:300px;">Description of Goods</th>
<th style="width:120px;">Quantity</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td>1</td>
<td>S1</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>S2</td>
<td>5</td>
</tr>
<tr>
<td>3</td>
<td>S3</td>
<td>5</td>
</tr>
</tbody>
</table>
Add border right only
table td, table th { border-right: 1px solid black; padding: 5px; }
#items { clear: both; margin: 30px 0 0 0; border: 1px solid black; }
#items th { background: #eee; }
#items textarea { width: 300px; height: 50px; }
#items,td {
border-collapse: collapse;
border-spacing: 0;
margin: 0;
padding: 0;
}
<table id="items">
<thead>
<tr>
<th style="width:100px;">Slno</th>
<th style="width:300px;">Description of Goods</th>
<th style="width:120px;">Quantity</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td>1</td>
<td>S1</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>S2</td>
<td>5</td>
</tr>
<tr>
<td>3</td>
<td>S3</td>
<td>5</td>
</tr>
</tbody>
</table>

Scrollable table contents html/css

I'm trying to make my table contents scrollable, I've had to create a table inside one of the table rows which means if the table has more than one row the contents isn't aligned with the correct heading as showing in the fiddle;
https://jsfiddle.net/f5ax5w2r/
thead.panel-heading {
background-color: #242a30;
border-color: #242a30;
border-bottom: 1px solid #242a30;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
cursor: move;
width: 100%;
}
thead.panel-heading tr th {
color: #ffffff;
font-weight: 500;
padding: 10px 40px !important;
text-align: left;
}
tbody.panel-content {
background-color: #f0f3f4;
}
tbody.panel-content tr td {
padding: 10px 20px !important;
text-align: left;
}
tbody div {
overflow-x: hidden;
overflow-y: scroll;
height: 300px;
}
<table>
<thead class="panel-heading">
<tr>
<th>Client</th>
<th>Client</th>
</tr>
</thead>
<tbody class="panel-content">
<tr>
<td>
<div class="scrollit">
<table>
<tr>
<td>Alex Best</td>
<td>Yahoo Answers</td>
</tr>
<tr>
<td>Andrew Smith</td>
<td>Monkey Tube</td>
</tr>
<tr>
<td>James Harris</td>
<td>Limewire</td>
</tr>
<tr>
<td>Mike Anderson</td>
<td>Twitter</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
The number of table cells do not match in each table row in your code. Adding the correct colspan value should do it.
thead.panel-heading {
background-color: #242a30;
border-color: #242a30;
border-bottom: 1px solid #242a30;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
cursor: move;
width: 100%;
}
thead.panel-heading tr th {
color: #ffffff;
font-weight: 500;
padding: 10px 40px !important;
text-align: left;
}
tbody.panel-content {
background-color: #f0f3f4;
}
tbody.panel-content tr td {
padding: 10px 20px !important;
text-align: left;
}
tbody div {
overflow-x: hidden;
overflow-y: scroll;
height: 300px;
}
<table>
<thead class="panel-heading">
<tr>
<th>Client</th>
<th>Client</th>
</tr>
</thead>
<tbody class="panel-content">
<tr>
<td colspan="2">
<div class="scrollit">
<table>
<tr>
<td>Alex Best</td>
<td>Yahoo Answers</td>
</tr>
<tr>
<td>Andrew Smith</td>
<td>Monkey Tube</td>
</tr>
<tr>
<td>James Harris</td>
<td>Limewire</td>
</tr>
<tr>
<td>Mike Anderson</td>
<td>Twitter</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
Try adding colspan="2" to the td which has table inside.
https://jsfiddle.net/f5ax5w2r/
<table>
<thead class="panel-heading">
<tr>
<th>Client</th>
<th>Client</th>
</tr>
</thead>
<tbody class="panel-content">
<tr>
<td colspan="2">
<div class="scrollit">
<table>
<tr>
<td>Alex Best</td>
<td>Yahoo Answers</td>
</tr>
<tr>
<td>Andrew Smith</td>
<td>Monkey Tube</td>
</tr>
<tr>
<td>James Harris</td>
<td>Limewire</td>
</tr>
<tr>
<td>Mike Anderson</td>
<td>Twitter</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>

Table with sticky column - Issue with cell size

I have a table that can slide left or right when the screen is narrow enough. The first column is positioned absolute so that it is always visible.
Is it possible to make the cells in the first column maintain the size of the cells in the other columns? I am not sure how to achieve this while keeping the first column frozen.
Here is a fiddle to my code: http://jsfiddle.net/ta945/
Here's the HTML and CSS
HTML:
<div>
<table>
<thead>
<tr>
<th class="sticky">Name</th>
<th>Helpful Services</th>
<th>State</th>
<th>City</th>
<th>Phone</th>
<th>URL</th>
</tr>
</thead>
<tbody>
<tr>
<td class="sticky">First Name</td>
<td>Math</td>
<td>CO</td>
<td>San Francisco</td>
<td>123-456-7890</td>
<td>http://somewhere.com</td>
</tr>
<tr>
<td class="sticky">Second Name</td>
<td>Reading</td>
<td>NY</td>
<td>New York City</td>
<td>123-456-7890</td>
<td>http://somewhere.com</td>
</tr>
<tr>
<td class="sticky">Third Name</td>
<td>Art</td>
<td>IL</td>
<td>Chicago</td>
<td>123-456-7890</td>
<td>http://somewhere.com</td>
</tr>
<tr>
<td class="sticky">Four Name</td>
<td>Programming</td>
<td>IL</td>
<td>Chicago</td>
<td>123-456-7890</td>
<td>http://somewhere.com</td>
</tr>
</tbody>
</table>
</div>
CSS:
div {
width: 100%;
border: 1px solid #000000;
overflow-y: hidden;
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
}
table {
border-collapse: seperate;
border-spacing: 0;
margin-left: 5em;
}
thead, tbody, tr {
vertical-align: middle;
}
th {
font-weight: bold;
padding: 2px 4px;
background-color: #676767;
color: #FFFFFF
}
td {
padding: 2px 4px;
}
tbody tr:nth-child(even) td {
background-color: #cccccc;
}
.sticky {
position: absolute;
left: 0;
top: auto;
margin-left: 9px;
}