I am trying to implement a table with fixed headers using the concepts from this page:
http://www.imaputz.com/cssStuff/bigFourVersion.html#
When I implemented the CSS from that page, my table columns are not aligned with the table headers.
HTML:
<div id="tableContainer" class="tableContainer">
<table class="sortable" border=1 frame=void cellspacing=0 cellpadding=4>
<thead class="fixedHeader">
<tr>
<th id="Column1" align=center valign=bottom>Column 1</th>
<th id="Column2" align=center valign=bottom>Column 2</th>
<th id="Column " align=center valign=bottom>Column 3</th>
</tr>
</thead>
<tbody class="scrollContent">
<tr>
<td align=right>ABCD</td>
<td aligh=right>XY</td>
<td aligh=right>12345678</td>
</tr>
<tr>
<td align=right>BAR</td>
<td aligh=right>BAZ</td>
<td aligh=right>12345678</td>
</tr>
<tr>
<td align=right>BAR</td>
<td aligh=right>BAZ</td>
<td aligh=right>12345678</td>
</tr>
<tr>
<td align=right>CD</td>
<td aligh=right>FOO</td>
<td aligh=right>12345678</td>
</tr>
<tr>
<td align=right>BAR</td>
<td aligh=right>BAZ</td>
<td aligh=right>12345678</td>
</tr>
</tbody>
</table>
CSS:
html>body tbody.scrollContent {
display: block;
height: 100px;
overflow: auto;
}
thead.fixedHeader tr {
position: relative
}
html>body thead.fixedHeader tr {
display: block
}
div.tableContainer {
clear: both;
border: 1px solid #963;
height: 150px;
overflow: auto;
width: 300px
}
html>body div.tableContainer {
overflow: hidden;
}
div.tableContainer table {
float: left;
}
Here is that on jsfiddle:
http://jsfiddle.net/softvar/yL84C/
I was able to 'fix' this by explicitly setting the cell size:
CSS:
* {
box-sizing: border-box;
}
th, td {
width: 100px;
}
html>body tbody.scrollContent {
display: block;
height: 100px;
overflow: auto;
}
thead.fixedHeader tr {
position: relative
}
html>body thead.fixedHeader tr {
display: block
}
div.tableContainer {
clear: both;
border: 1px solid #963;
height: 150px;
overflow: auto;
width: 300px
}
html>body div.tableContainer {
overflow: hidden;
}
div.tableContainer table {
}
Here is that one jsfiddle:
http://jsfiddle.net/cFr38/
But what I really want is the cells to be automagically sized based on the data (which is what my table does now without the new CSS)? How can I do that?
Related
I am having the following table with fixed header and scrollable body.The problem here is that i can't find a way to set my two table rows to be 50% width of the table.
#wrapper {
width: 100%;
}
table {
border: 1px solid black;
width: 100%;
table-layout: fixed;
}
th,
td {
width: 50%;
border: 1px solid black;
}
thead > tr {
position: relative;
display: block;
}
tbody {
display: block;
height: 80px;
overflow: auto;
}
<div id="wrapper">
<table>
<thead>
<tr>
<th>column1</th>
<th>column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>row1</td>
<td>row1</td>
</tr>
<tr>
<td>row2</td>
<td>row2</td>
</tr>
<tr>
<td>row3</td>
<td>row3</td>
</tr>
<tr>
<td>row4</td>
<td>row4</td>
</tr>
</tbody>
</table>
</div>
why setting 50% of th,td does not work ?
How can i do this automatically - so if i have in future three table cells they will expand the table width and will have equal width at the end ?
According to this answer, you should remove the display: block both in tr and tbody and the columns will align
#wrapper {
width: 100%;
}
table {
border: 1px solid black;
width: 100%;
table-layout: fixed;
}
th,
td {
width: 50%;
border: 1px solid black;
}
thead>tr {
position: relative;
}
tbody {
height: 80px;
overflow: auto;
}
<div id="wrapper">
<table>
<thead>
<tr>
<th>column1</th>
<th>column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>row1</td>
<td>row1</td>
</tr>
<tr>
<td>row2</td>
<td>row2</td>
</tr>
<tr>
<td>row3</td>
<td>row3</td>
</tr>
<tr>
<td>row4</td>
<td>row4</td>
</tr>
</tbody>
</table>
</div>
I want to make one width of column in table to be less, than content with. Here's my code:
html:
<table class="table">
<thead>
<tr>
<th class="col1">col1</th>
<th class="col2">col2</th>
<th class="col3">col3</th>
<th class="col4">col4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col1">aaaaaa</td>
<td class="col2">aaaaaa</td>
<td class="col3">aaaaaa</td>
<td class="col4">aaaaaa</td>
</tr>
</tbody>
</table>
scss:
.table {
margin: 0;
padding: 0;
border-collapse: collapse;
table-layout: fixed;
}
td, th {
border: 1px solid black;
padding: 5px 8px;
}
td:first-child, th:first-child {
width: 10px;
overflow: hidden;
white-space: nowrap;
}
As I understand setting table-layout: fixed should helped, but nothing is really changed. The first column's with still is not 10px.
How can I set width to a column then?
You may give it a try with max-width instead.
disclaimer: unsure if all browsers will take it
.table {
margin: 0;
padding: 0;
border-collapse: collapse;
table-layout: fixed;
}
td, th {
border: 1px solid black;
padding: 5px 8px;
}
td:first-child, th:first-child {
max-width: 10px;
overflow: hidden;
white-space: nowrap;
}
<table class="table">
<thead>
<tr>
<th class="col1">col1</th>
<th class="col2">col2</th>
<th class="col3">col3</th>
<th class="col4">col4</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col1">aaaaaa</td>
<td class="col2">aaaaaa</td>
<td class="col3">aaaaaa</td>
<td class="col4">aaaaaa</td>
</tr>
</tbody>
</table>
Also when I added width: 100% to the table, code started to work
I have a problem with my fixed header and fixed column table. The header is fixed but the column isn't. So how do I fix this problem? I have tried to give the first column position: fixed but it doesn't work right. If possible without Javascript. (I have tried to find solutions from earlier questions of the same topic but none of those helped me). Here is my Codepen.
body {
background-image: url(http://absfreepic.com/absolutely_free_photos/small_photos/green-grass-football-lawn-4020x2261_98957.jpg);
}
h3 {
margin: auto;
text-align: center;
padding: 10px;
color: white;
}
.table {
background-color: white;
margin: auto;
width: 600px;
border-collapse: separate;
display: block;
overflow-x: scroll;
}
thead,
tbody {
display: inline-block;
}
tbody {
overflow-y: scroll;
overflow-x: hidden;
max-height: 70px;
position: relative;
}
th {
background-color: lightgrey;
}
td,
th {
min-width: 100px;
max-width: 100px;
word-wrap: break-word;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<h3>World Cup 2018</h3>
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th colspan="6">Europe</th>
<th colspan="3">South-America</th>
<th colspan="2">Asia</th>
</tr>
<tr>
<th>Countries</th>
<th>Germany</th>
<th>Spain</th>
<th>Portugal</th>
<th>France</th>
<th>England</th>
<th>Croatia</th>
<th>Argentina</th>
<th>Brazil</th>
<th>Colombia</th>
<th>Japan</th>
<th>Russia</th>
</tr>
</thead>
<tbody>
<tr>
<th>Goalkeeper</th>
<td>Neuer</td>
<td>De Gea</td>
<td>Beto</td>
<td>Lloris</td>
<td>Butland</td>
<td>Subasic</td>
<td>Caballero</td>
<td>Alisson</td>
<td>Ospina</td>
<td>Kawashima</td>
<td>Lunev</td>
</tr>
<tr>
<th>Defender</th>
<td>Boateng</td>
<td>Ramos</td>
<td>Pepe</td>
<td>Varane</td>
<td>Walker</td>
<td>Lovren</td>
<td>Otamendi</td>
<td>Marcelo</td>
<td>Sanchez</td>
<td>Makino</td>
<td>Granat</td>
</tr>
<tr>
<th>Midfielder</th>
<td>Kroos</td>
<td>Iniesta</td>
<td>Ronaldo</td>
<td>Tolisso</td>
<td>Lingard</td>
<td>Modric</td>
<td>Messi</td>
<td>Paulinho</td>
<td>Rodriguez</td>
<td>Honda</td>
<td>Golovin</td>
</tr>
<tr>
<th>Forward</th>
<td>Gomez</td>
<td>Asensio</td>
<td>Quaresma</td>
<td>Griezmann</td>
<td>Welbeck</td>
<td>Perisic</td>
<td>Dybala</td>
<td>Neymar</td>
<td>Bacca</td>
<td>Osako</td>
<td>Smolov</td>
</tr>
</tbody>
</table>
body {
background-image: url(http://absfreepic.com/absolutely_free_photos/small_photos/green-grass-football-lawn-4020x2261_98957.jpg);
}
h3 {
margin: auto;
text-align: center;
padding: 10px;
color: white;
}
.table {
background-color: white;
margin: auto;
width: 600px;
border-collapse: separate;
display: block;
overflow-x: scroll;
}
thead,
tbody {
display: inline-block;
}
thead {
position: sticky;
top: 1px;
z-index: 9999;
}
tbody {
height: 80px;
}
th {
background-color: lightgrey;
}
td,
th {
min-width: 100px;
max-width: 100px;
word-wrap: break-word;
}
.fixed {
position: sticky;
width: 5em;
left: 0;
top: auto;
z-index: 999;
}
td:not(.fixed) {
z-index: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="conatiner">
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th colspan="6">Europe</th>
<th colspan="3">South-America</th>
<th colspan="2">Asia</th>
</tr>
<tr>
<th class="fixed">Countries</th>
<th>Germany</th>
<th>Spain</th>
<th>Portugal</th>
<th>France</th>
<th>England</th>
<th>Croatia</th>
<th>Argentina</th>
<th>Brazil</th>
<th>Colombia</th>
<th>Japan</th>
<th>Russia</th>
</tr>
</thead>
<tbody>
<tr>
<th class="fixed">Goalkeeper</th>
<td>Neuer</td>
<td>De Gea</td>
<td>Beto</td>
<td>Lloris</td>
<td>Butland</td>
<td>Subasic</td>
<td>Caballero</td>
<td>Alisson</td>
<td>Ospina</td>
<td>Kawashima</td>
<td>Lunev</td>
</tr>
<tr>
<th class="fixed">Defender</th>
<td>Boateng</td>
<td>Ramos</td>
<td>Pepe</td>
<td>Varane</td>
<td>Walker</td>
<td>Lovren</td>
<td>Otamendi</td>
<td>Marcelo</td>
<td>Sanchez</td>
<td>Makino</td>
<td>Granat</td>
</tr>
<tr>
<th class="fixed">Midfielder</th>
<td>Kroos</td>
<td>Iniesta</td>
<td>Ronaldo</td>
<td>Tolisso</td>
<td>Lingard</td>
<td>Modric</td>
<td>Messi</td>
<td>Paulinho</td>
<td>Rodriguez</td>
<td>Honda</td>
<td>Golovin</td>
</tr>
<tr>
<th class="fixed">Forward</th>
<td>Gomez</td>
<td>Asensio</td>
<td>Quaresma</td>
<td>Griezmann</td>
<td>Welbeck</td>
<td>Perisic</td>
<td>Dybala</td>
<td>Neymar</td>
<td>Bacca</td>
<td>Osako</td>
<td>Smolov</td>
</tr>
</tbody>
</table>
</div>
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%;
}
}
I've assigned '25px' to 'tr' in this photo, but 29 on the actual page.
I found out that 'border' goes right and left in css, and 2px is added.
I am wondering why 2px is applied when it becomes '27px' even if it does so.
The code below shows the code shown in the picture.
.div_result {
overflow-y: hidden;
width: 766px;
height: 250px;
overflow-x: auto;
border: 1px solid #dbdbdb;
}
table.scroll {
width: 150%;
border-spacing: 0;
}
table.scroll tbody,
table.scroll thead {
display: block;
}
thead tr th {
height: 30px;
}
table.scroll tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td,
thead th {
border: 1px solid black;
}
tbody td:last-child,
thead th:last-child {}
thead tr {
display: inline-table;
width: 100%;
}
th {
background-color: red;
}
<div class="div_result " style="position:relative;">
<table id="" class="scroll">
<thead class="sorted_head">
<tr>
<th id="" class="result_title " width="25">
<span class="some-handle">a</span>
</th>
<th id="" class="result_title " width="120">
<span class="some-handle">a</span>
</th>
<th id="" class="result_title " width="250">
<span class="some-handle">a</span>
</th>
<th class="result_title ">
<span class="some-handle">a</span>
</th>
</tr>
</thead>
<tbody class="sort_body">
<tr>
<td style="padding: 0;width: 25px;">asd</td>
<td style="width: 120px;">asd</td>
<td style="width: 250px;">asd</td>
<td style="width: 738px;">asd</td>
</tr>
<tr>
<td>asd</td>
<td>asd</td>
<td>asd</td>
<td>asd</td>
</tr>
<tr>
<td>asd</td>
<td>asd</td>
<td>asd</td>
<td>asd</td>
</tr>
<tr>
<td>asd</td>
<td>asd</td>
<td>asd</td>
<td>asd</td>
</tr>
</tbody>
</table>
</div>
CSS table will auto-space it's columns based on first row. Also you need table {table-layout: fixed} for it to work:
$(document).ready(function () {
console.log($('table td:first').outerWidth());
})
table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
}
td {
box-sizing: border-box;
height: 25px;
border: 1px solid white;
background-color: blue;
}
td:first-child {
width: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
<tr><td></td><td></td></tr>
</table>