How to add scrollbar only to tbody and not fixed thead - html

I am trying to create a table that has a scrollable <tbody> with a fixed <thead>. I have achieved that here https://jsfiddle.net/ghnfzwm6/16/.
However, this is not quite what I would like. I want the scroll bar to start where the <tbody> starts. I have attempted to do so by adding
height: 546px;
max-height: 546px;
overflow-y: scroll; /* only Y axis scroll */
to <tbody> and removing it from #tasks-table-wrapper. I also made <tbody> and <tr> display: block;
Here is the result https://jsfiddle.net/4gLwp697/3/. The problem now is that <thead> does not line up with <tbody>. I can fix that by specifying column widths, but I want them to be auto.
How can I fix this?

consider this code snippet, There is no direct solution to your problem, This is determined by the 'table' feature. The solutions for the current mainstream frameworks are as follows, You need to set the width of 'columns'.
* {
margin: 0;
padding: 0;
}
#content {
overflow: hidden;
height: 100%;
text-align: center;
}
#tasks-table-wrapper {
text-align: left;
display: inline-block;
width: auto;
}
.scrollbar-wrap {
overflow: auto;
height: 100px;
}
.black-table {
border-collapse: separate;
font-size: 0;
background-color: #121212;
text-transform: uppercase;
border-spacing: 0;
}
.black-table td {
color: #bbb;
font-size: 11px;
letter-spacing: 1px;
padding: 15px 30px;
}
.black-table th {
color: #fff;
font-size: 12px;
font-weight: 700;
letter-spacing: 2px;
padding: 15px 25px;
border-bottom: 1px solid #1c1c1c;
position: sticky; /* keep TH on top */
top: 0;
background-color: #121212;
white-space: nowrap;
}
<div id="content">
<div id="tasks-table-wrapper">
<table class="black-table">
<colgroup>
<col width="180">
<col width="180">
<col width="180">
<col width="180">
</colgroup>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
</table>
<div class="scrollbar-wrap">
<table class="black-table">
<colgroup>
<col width="180">
<col width="180">
<col width="180">
<col width="163">
</colgroup>
<tbody>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
You can see VUE Table with fixed header, Review the table elements.

Replace
#tasks tr {
display: block;
}
with
#tasks tr {
display: table;
width: 100%;
table-layout: fixed;
}
https://jsfiddle.net/5nt18cL0/

Related

Scrollable table with automatic column widths

I am trying to make a table with a scrollable <tbody> and a fixed <thead>.
I have attempted to do so here https://jsfiddle.net/ghnfzwm6/11/. However, as you can see the <thead> is not lined up with the <tbody>. Also, the scroll wheel is all the way to the right whereas I would like it right next to the table.
Does anyone know how I can fix this without setting fixed widths for the columns?
EDIT: Additionally, top: 0; moves the <thead> to the top of my page which is ok on the fiddle but not normally. However, without it there is a small gap...
EDIT2: I have found this solution https://jsfiddle.net/uo5v0cfw/11/. However, the problem gere is that the furthest right column is cut off by the scroll bar. This can be fixed by changing the overflow-x to auto, but I don't want to have to scroll horizontally...
Css for the #content div is not required. This css is enough for your scrollable table. I added some comments in the css below.
update: added minimum css for mobile support
#content {
}
#tasks-table-wrapper {
width: 800px; /* or use % for the width */
height: 546px;
max-height: 546px;
margin: 0 auto;
overflow-y: scroll; /* only Y axis scroll */
}
#tasks-table-wrapper * {
margin: 0;
padding: 0;
box-sizing: border-box; /* keep content in a TD cell */
}
#tasks {
border-collapse: collapse;
font-size: 0;
}
#tasks, #tasks thead, #tasks tbody, #tasks tr {
width: 100%; /* keep all elements full width */
}
#tasks th, #tasks td {
padding: 20px;
text-align: left;
background-color: #121212;
text-transform: uppercase;
}
#tasks th {
position: sticky; /* keep TH on top */
top: 0;
color: #fff;
font-size: 13px;
font-weight: 700;
letter-spacing: 2px;
}
#tasks td {
color: #bbb;
font-size: 11px;
letter-spacing: 1px;
}
/* minimum for mobile support */
#media (max-width: 767.9px) {
#tasks-table-wrapper {
max-width: 100%;
}
#tasks {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
}
You should try setting the thead to be position: sticky; instead of fixed. When an element is set to have a position of fixed or absolute the browser does not render it as part of its normal containing block. Because your thead is positioned as fixed it isn't being rendered as part of that containing block and thus your tbody is collapsing down to the size of its content. Using sticky will avoid this because it is designed to keep the element as part of the original containing block while allowing it to stick to the page in your determined location.
Just be sure to check browser support and polyfill if needed:
https://caniuse.com/#feat=css-sticky
Try this... add position:relative; to #tasks-table-wrapper.
CSS code
* {
margin: 0;
padding: 0;
}
#content {
overflow: hidden;
height: 100%;
}
#tasks-table-wrapper {
height: 546px;
max-height: 546px;
width: 35%;
overflow-y: scroll;
position: relative;
top: 0;
left: 50%;
transform: translate(-50%, 0px);
}
#tasks-table-wrapper table#tasks {
text-align: left;
text-transform: uppercase;
margin: 0 auto;
width: 100%;
background-color: #121212;
font-size: 0;
}
#tasks-table-wrapper table#tasks thead {
font-size: 13px;
color: #fff;
font-weight: 700;
letter-spacing: 2px;
border-collapse: collapse;
background-color: #121212;
text-align: left;
}
#tasks-table-wrapper table#tasks th {
padding: 20px;
}
#tasks-table-wrapper table#tasks tbody {
font-size: 11px;
color: #bbb;
letter-spacing: 1px;
margin-top: 57px;
}
#tasks-table-wrapper table#tasks tbody tr td {
padding: 20px;
}
HTML Code
<div id="content">
<div id="tasks-table-wrapper">
<table id="tasks">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tbody>
</table>
</div>
</div>
Edit: If you need to preserve the table display properties then you can do something like this:
Add position sticky to your th elements:
#tasks-table-wrapper table#tasks th {
padding: 20px;
position: sticky;
top: 0;
background-color: #121212;
}
And remove the fixed property from your thead element
#tasks-table-wrapper table#tasks thead {
font-size: 13px;
color: #fff;
font-weight: 700;
letter-spacing: 2px;
border-collapse: collapse;
background-color: #121212;
text-align: left;
/* position: fixed; */
/* top: 0; */
}
You may also change the table width to 100% and the wrapper to the desired size:
#tasks-table-wrapper {
height: 546px;
max-height: 546px;
overflow-y: scroll;
width: 90%;
margin: 0 auto;
}
#tasks-table-wrapper table#tasks {
text-align: left;
text-transform: uppercase;
margin: 0 auto;
background-color: #121212;
font-size: 0;
width: 100%;
}
If you don't care about table css properties, change the table elements display property to block or flex, I made a fiddle and a pen, hope it helps.
Try this.
Position sticky in TH (it's better for cross-browser)and border-collapse: collapse; in TABLE.
* {
margin: 0;
padding: 0;
}
#content {
overflow: hidden;
height: 100%;
}
#tasks-table-wrapper {
height: 546px;
max-height: 546px;
overflow-y: scroll;
}
#tasks-table-wrapper table#tasks {
text-align: left;
text-transform: uppercase;
margin: 0 auto;
background-color: #121212;
font-size: 0;
border-collapse: collapse;
}
#tasks-table-wrapper table#tasks thead {
font-size: 13px;
color: #fff;
font-weight: 700;
letter-spacing: 2px;
border-collapse: collapse;
background-color: #121212;
text-align: left;
}
#tasks-table-wrapper table#tasks thead tr {
}
#tasks-table-wrapper table#tasks th {
padding: 20px;
position: sticky;
top: 0;
border: 0;
background-color: #121212;
}
#tasks-table-wrapper table#tasks tbody {
font-size: 11px;
color: #bbb;
letter-spacing: 1px;
margin-top: 57px;
}
#tasks-table-wrapper table#tasks tbody tr {
}
#tasks-table-wrapper table#tasks tbody tr td {
padding: 20px;
}
<div id="content">
<div id="tasks-table-wrapper">
<table id="tasks">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tr>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<tr>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
</tbody>
</table>
</div>
</div>
Thanks to #bron for providing a jsfiddle with an almost complete solution. The last piece was to make the scrollbar go next to the table which I have done here https://jsfiddle.net/ghnfzwm6/16/.
#content {
...
text-align: center;
}
#tasks-table-wrapper {
width: auto;
...
display: inline-block;
}
And removed
#tasks, #tasks thead, #tasks tbody, #tasks tr {
width: 100%;
}

Unwanted shifting using fixed column and rowspan in table

I have a table that uses rowspan for one of the table headers. This table also switches to a fixed column style on smaller sizes. The issue I'm running into is on smaller sizes, when the th with the rowspan becomes fixed, it messes up the structure of the remaning th.
A solution I thought of was to just have an empty th above Foods so I didn't have to use a rowspan, but due to ADA requirments, that's not an option.
Here's some code: CODEPEN
This is the large screen view - you can see there's a Foods column as well as two groups, each of which containing two columns.
Here's a view of when it goes to the fixed column layout. You can see that Group 1 - Col 1 now takes the place where Foods used to be, and the entire 2nd shifted.
HTML:
<div class="wrap">
<table>
<thead>
<tr>
<th rowspan="2" class="fixed">Foods</th>
<th colspan="2">Group 1</th>
<th colspan="2">Group 2</th>
</tr>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">Tacos</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
<tr>
<td class="fixed">Pizza</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
</tbody>
</table>
</div>
CSS:
table {
border: solid 1px black;
border-spacing: 0;
border-collapse: collapse;
width: 900px;
}
th {
vertical-align: bottom;
padding: 5px 10px;
border-left: solid 1px grey;
}
th[colspan="2"] {
border-bottom: solid 1px grey;
}
td {
border-top: solid 1px grey;
}
tbody tr:nth-child(odd) td {
background: grey;
}
.fixed {
border-left: none;
}
#media (max-width: 600px) {
.fixed {
position: absolute;
width: 50px;
left: 0;
}
.wrap {
overflow-x: scroll;
overflow-y: visible;
margin-left: 50px;
}
}
I am not really sure about the issue but it seems to be related to the use of position:fixed. You are removing the elements from the flow so it's like they no more belong to the table making the table algorithm behave strange.
An idea of fix is to consider a extra element that you make visible on small screen to avoid this issue. Basically this element will correct the table layout when you make some of the element position:fixed
* {
text-align: center;
font-weight: normal;
}
table {
border: solid 1px black;
border-spacing: 0;
border-collapse: collapse;
width: 900px;
}
th {
vertical-align: bottom;
padding: 5px 10px;
border-left: solid 1px grey;
}
th[colspan="2"] {
border-bottom: solid 1px grey;
}
td {
border-top: solid 1px grey;
}
tbody tr:nth-child(odd) td {
background: grey;
}
.fixed {
border-left: none;
}
.fix {
padding:0;
border:none;
}
#media (min-width:700px) {
.fix {
display:none;
}
}
#media (max-width: 700px) {
.fixed {
position: absolute;
width: 50px;
left: 0;
}
.wrap {
overflow-x: scroll;
overflow-y: visible;
margin-left: 50px;
}
}
<div class="wrap">
<table>
<thead>
<tr>
<th rowspan="2" class="fixed">Foods</th>
<th colspan="2">Group 1</th>
<th colspan="2">Group 2</th>
</tr>
<tr>
<th class="fix"></th>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">Tacos</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
<tr>
<td class="fixed">Pizza</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
</tbody>
</table>
</div>
To avoid extra element you can consider pseudo element:
* {
text-align: center;
font-weight: normal;
}
table {
border: solid 1px black;
border-spacing: 0;
border-collapse: collapse;
width: 900px;
}
th {
vertical-align: bottom;
padding: 5px 10px;
border-left: solid 1px grey;
}
th[colspan="2"] {
border-bottom: solid 1px grey;
}
td {
border-top: solid 1px grey;
}
tbody tr:nth-child(odd) td {
background: grey;
}
.fixed {
border-left: none;
}
thead > tr:last-child::before {
content:"";
display:table-cell;
padding:0;
border:none;
}
#media (min-width:700px) {
thead > tr:last-child::before {
display:none;
}
}
#media (max-width: 700px) {
.fixed {
position: absolute;
width: 50px;
left: 0;
}
.wrap {
overflow-x: scroll;
overflow-y: visible;
margin-left: 50px;
}
}
<div class="wrap">
<table>
<thead>
<tr>
<th rowspan="2" class="fixed">Foods</th>
<th colspan="2">Group 1</th>
<th colspan="2">Group 2</th>
</tr>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="fixed">Tacos</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
<tr>
<td class="fixed">Pizza</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
<td>blank</td>
</tr>
</tbody>
</table>
</div>

How to freeze table columns

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

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%;
}
}

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;
}