HTML Table that will change - javascript

I am having trouble with replicating this.
Im trying to make a table that changes based on the window size. When the window is large I want the table to look like the "large screen" graphic, and when the window is small I want the table to look like the "small screen" graphic.
[![enter image description here][1]][1]
What I have right now is this. When the window is large I have the desired layout.
[![enter image description here][2]][2]
When I make the preview window smaller, my table collapses into one column instead of looking like how I want it to look like. IT should loook like the "small screen" graphic on the screenshot above.
[![enter image description here][3]][3]

Make use of display: block for you media query display.
The default display value of table will be display: table; thead will be display: table-header-group;, tbody will be display: table-row-group;, tr will be display: table-row;, th and td will be display: table-cell;.
For the table header and body contents to fold in multiple lines, you have to make use of display: block, float: left, box-sizing: border-box;
To update the content of the header, you should do a tweek. Move the label COMPARISON to as span. On the smaller resolution, make the sapn hidden and add the content to after pseudo element.
.table-container {
display: block;
margin: 1em auto;
width: 100%;
max-width: 600px;
border-collapse: collapse;
}
.flag-icon {
margin-right: 0.1em;
}
.flex-row {
width: 20%;
border: 1px solid palevioletred;
}
.flex-row,
.flex-cell {
text-align: center;
}
#media only screen and (max-width: 600px) {
.table-container {
display: block;
}
th,
td {
width: auto;
display: block;
}
.flex-row {
width: 25%;
float: left;
box-sizing: border-box;
}
.flex-row.first {
width: 100%;
text-align: left;
}
thead,
thead tr,
tbody,
tbody tr {
display: block;
}
.header .flex-row.first span {
display: none;
}
.header .flex-row.first:after {
content: 'HOW THE PLAYERS COMPARE';
}
}
<table class="table-container" width="100%" role="table" aria-label="Destinations">
<thead>
<tr class="flex-table header" role="rowgroup">
<th class="flex-row first" role="columnheader">
<span>COMPARISON</span>
</th>
<th class="flex-row" role="columnheader">player 1</th>
<th class="flex-row" role="columnheader">player 2</th>
<th class="flex-row" role="columnheader">player 3</th>
<th class="flex-row" role="columnheader">player 4</th>
</tr>
</thead>
<tbody>
<tr class="flex-table row" role="rowgroup">
<td class="flex-row first" role="cell"><span class="flag-icon flag-icon-gb"></span>Speed</td>
<td class="flex-row" role="cell">11Sp </td>
<td class="flex-row" role="cell">22Sp</td>
<td class="flex-row" role="cell">33Sp</td>
<td class="flex-row" role="cell">44Sp</td>
</tr>
<tr class="flex-table row" role="rowgroup">
<td class="flex-row first" role="cell"><span class="flag-icon flag-icon-gb"></span>Endurance</td>
<td class="flex-row" role="cell">11E </td>
<td class="flex-row" role="cell">22E</td>
<td class="flex-row" role="cell">33E</td>
<td class="flex-row" role="cell">44E</td>
</tr>
<tr class="flex-table row" role="rowgroup">
<td class="flex-row first" role="cell"><span class="flag-icon flag-icon-gb"></span>Strength</td>
<td class="flex-row" role="cell">11St </td>
<td class="flex-row" role="cell">22S</td>
<td class="flex-row" role="cell">33S</td>
<td class="flex-row" role="cell">44S</td>
</tr>
</tbody>
</table>

Related

How to Fix the TD elements of first column of the table body while the rows are scrolling?

The title is not clear, I know. Let me explain what I mean:
First column has td elements which have varying rowspans. What I want is to keep the td text in first column 'fixed' at the top while scrolling down.
But only as long as the rest of the td elements in the remaining columns are in scope.
Once all the rows (which the first column cell is spanning) is out of table view, the td element should scroll out of the view and the next td should now start fixing.
After Scrolling a bit:
And after All the animal rows are scrolled out, the fixed 'Animal' td would also go up and then 'Cars' would be fixed and then Hats would be fixed like this:
I got it working by setting
vertical-align: top; for the element
and created a div under the td element which contains the actual value for the cell
then applied position: sticky; top:0; z-index: 1; to the div.
Working fiddle: https://jsfiddle.net/ankitkraken/yw0jhzpu/1/
HTML:
<td class="td-class-name" rowspan="3">
<div class="level-1">
"Cars"
</div>
</td>
CSS:
.td-class-names{
vertical-align: top;
}
.level-1{
position: sticky ;
top: 80px;
z-index: -1;
}
I had to use top: 80px;, top:0; was putting the td contents BEHIND the sticky table header.
You can acheive this result with the sticky positioning:
thead tr:first-of-type {
position: sticky;
top: 0px;
z-index: 10;
}
thead tr:first-of-type th {
background: yellow;
}
th {
border: 1px solid;
padding: 6px;
}
td {
border: 1px solid;
padding: 6px;
}
th[rowspan]>.box {
vertical-align: top;
position: sticky;
top: 34px;
}
th[rowspan][data-order='first'] {
background: orange;
}
th[rowspan][data-order='second'] {
background: green;
}
th[rowspan][data-order='third'] {
background: indianred;
}
th[rowspan][data-order='fourth'] {
background: lightblue;
}
.main-container {
position: relative;
}
.table-container {
position: static;
max-height: 180px;
max-width: 350px;
;
overflow-y: scroll;
}
.fake {
width: 100%;
height: 100px;
}
<div class="main-container">
<div class='table-container'>
<table>
<thead>
<tr>
<th>CATEGORY</th>
<th>TYPE</th>
<th>NAME</th>
</tr>
</thead>
<tbody>
<tr>
<th data-order='first' rowspan='5'>
<div class='box'>Animals</div>
</th>
<td>Dog</td>
<td>Bob</td>
</tr>
<tr>
<td>Dog</td>
<td>Flash</td>
</tr>
<tr>
<td>Cat</td>
<td>Mimi</td>
</tr>
<tr>
<td>Dog</td>
<td>Casper</td>
</tr>
<tr>
<td>Horse</td>
<td>Wind Lady</td>
</tr>
<tr>
<th data-order='second' rowspan='5'>
<div class='box'>Cars</div>
</th>
<td>Chrysler</td>
<td>Ann</td>
</tr>
<tr>
<td>Dodge</td>
<td>Christine</td>
</tr>
<tr>
<td>Ford</td>
<td>Foo</td>
</tr>
<tr>
<td>Ferrari</td>
<td>Dandy</td>
</tr>
<tr>
<td>Mercedes</td>
<td>A200</td>
</tr>
<tr>
<th data-order='third' rowspan='5'>
<div class='box'>Food</div>
</th>
<td>Apple</td>
<td>George</td>
</tr>
<tr>
<td>Banana</td>
<td>Rocco</td>
</tr>
<tr>
<td>Strawberry</td>
<td>Liza</td>
</tr>
<tr>
<td>Ananas</td>
<td>Ted</td>
</tr>
<tr>
<td>Avocado</td>
<td>Gary</td>
</tr>
<tr>
<th data-order='fourth' rowspan='5'>
<div class='box'>Phones</div>
</th>
<td>Iphone XXI</td>
<td>ObiWan</td>
</tr>
<tr>
<td>Nokia 8110</td>
<td>Neo</td>
</tr>
<tr>
<td>Ericsson</td>
<td>Dr. Who</td>
</tr>
<tr>
<td>Huawei Mate 40</td>
<td>Dead or Alive</td>
</tr>
<tr>
<td>Xiaomi</td>
<td>Ping</td>
</tr>
</tbody>
</table>
<div class='fake'>
</div>
</div>
</div>
Sticky positioning is not always straightforward, expecially when dealing with overflow properties and display: table. Here are some useful resources about these topics:
Position: stuck; — and a way to fix it
CSS Position Sticky - How It Really Works!
Creating sliding effects using sticky positioning
Position Sticky on <td> with colspan?

CSS messed up in mobile view

I have a simple nested table. Three columns - Name, Email,Contact. In the contact column, I have have two contact separated by a . This table gets stacked in the form of one row below the another in the mobile view.
Problem : Since the two contact numbers are separated by a break, in the mobile view it adds a huge space between the column headings. I just want to pick up "contact" heading in mobile(and not touch the numbers) and move it a little to reduce the space in between. Right now, whatever css I apply it moves the contact numbers along with it. Please suggest how can I do this ?
$(function() {
$(".fold-table tr.view").on("click", function() {
$(this).toggleClass("open").next(".fold").toggleClass("open");
});
});
$('.view, table.child').each(function() {
$('.view:even, table.child:even').addClass('odd');
$('.view:odd, table.child:odd').addClass('even');
});
.tableComponent table.parent {
font-family: 'Poppins';
font-size: 12px;
width: 60%;
border: none;
border-collapse: separate;
border-spacing: 0 2px;
}
.tableComponent table thead th {
border-bottom: 0;
border-top: 0;
}
.tableComponent table td,
th {
border-top: 0px;
}
table.fold-table>tbody>tr.view td,
table.fold-table>tbody>tr.view th {
cursor: pointer;
}
table.fold-table>tbody>tr.fold {
display: none;
}
table.fold-table>tbody>tr.fold.open {
display: table-row;
}
.odd {
background-color: #F2F2F2;
}
.even {
background-color: #F8F8F8
}
table.child {
font-family: 'Poppins';
font-size: 12px;
width: 100%;
margin-top: -0.1rem;
border-top: 2px solid #DBDBDB;
}
table.fold-table>tbody>tr.fold.open>td {
padding: 0;
}
#media all and (max-width: 500px) {
.tableComponent table.parent {
width: 90%;
margin-left: 5vw
}
.tableComponent thead {
display: none;
}
.tableComponent tr {
display: flex;
flex-direction: column;
margin-bottom: 5px;
}
.tableComponent td::before {
content: attr(col);
font-weight: bold;
padding-right: 20px;
width: 40vw;
display: inline-block;
}
table.child {
margin-top: -0.5rem;
}
.contactInfo {
display: inline-block;
margin-left: -0.2rem;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tableComponent">
<table class="table fold-table parent" id="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Contact</th>
</tr>
</thead>
<tbody>
<tr class="view">
<td col="Name">John</td>
<td col="Email">j#g.com</td>
<td col="Contact">
<span class="contactInfo">
35373726<br>
35373726
</span>
</td>
</tr>
<tr class="fold">
<td colspan="3">
<div class="fold-content">
<table class="child">
<tbody>
<tr>
<td col="Name">SUB Data 1</td>
<td col="Email">SUB Data 1</td>
<td col="Contact">SUB Data 1
</td>
</tr>
<tr>
<td col="Name">SUB Data 1</td>
<td col="Email">SUB Data 1</td>
<td col="Contact">SUB Data 1
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
In css, the inline elements doesn't take margins, so vertical alignment can be done like so
#media all and (max-width: 500px){
.tableComponent td::before {
vertical-align: top;
}
}
If you change the col="Contact" td into a flexbox, it will behave the way you want it at that screen size.
[col="Contact"] {
display: flex;
}

How to make table with fixed first column and vertical text to the left of fixed column

Made a table with first column fixed using this fiddle link http://jsfiddle.net/Yw679/6/ need a vertical text to left of fixed column(the text also vertical text also remains fixed like first column).
Difference between fiddle link and my expected output
1. the text 'co1' and 'co2' is vertically aligned
2. the vertical text should be fixed like the first column is.
fiddle code
1.HTML:
<div style="width:400px">
<table class="table1">
<tr>
<thead>
<th> make me fixed</th>
</thead>
</tr>
<tr>
<td>value number 1</td>
</tr>
</table>
<div class="table2">
<table>
<tr>
<thead>
<th>make me scrollable eeeeeeeeeeee eeeeeeeeee eeeeeeeeee eeeeeeeeee eeeeeeeee eeeeeeeeeeeeeeeeee eeeeeeee eeeeeeeeeee eeeeeeeeeeeeee eeeeeeeeee eeeeeeee</th>
</thead>
</tr>
<tr>
<td> value number 2 </td>
</tr>
</table>
</div>
</div>
2.CSS
th,td {
padding: 5px;
border: 1px solid #000;
white-space: nowrap;
}
.table1 {
float: left;
}
.table2 {
width: 200px;
overflow: auto;
}
Here's the expected output
Something like this?
th,td {
padding: 5px;
border: 1px solid #000;
white-space: nowrap;
}
.table1 {
float: left;
}
.table2 {
width: 200px;
overflow: auto;
}
.text-container {
display: inline;
float: left;
width: 1rem;
}
.text {
text-align: center;
width: 0;
font-size: 10px;
word-wrap: break-word;
line-height: .5rem;
padding: 2px;
}
<div class="text-container">
<div class="text">CO1</div>
<div class="text">CO2</div>
</div>
<div style="width:400px">
<table class="table1">
<tr>
<thead>
<th> make me fixed</th>
</thead>
</tr>
<tr>
<td>value number 1</td>
</tr>
</table>
<div class="table2">
<table>
<tr>
<thead>
<th>make me scrollable eeeeeeeeeeee eeeeeeeeee eeeeeeeeee eeeeeeeeee eeeeeeeee eeeeeeeeeeeeeeeeee eeeeeeee eeeeeeeeeee eeeeeeeeeeeeee eeeeeeeeee eeeeeeee</th>
</thead>
</tr>
<tr>
<td> value number 2 </td>
</tr>
</table>
</div>
</div>

How to set html table height and column widths?

I am attempting to control the height of a table body so that a scrollbar appears when more data than fits in a view is displayed, thead must stay visible. At the same time I'm trying to control the width of the table columns.
The table height can be controlled by setting 'display: block' in the table body css. The table body will now be limited by the container height or any height the table body is set to. This messes up the column widths though.
The column widths can be assured by setting as desired. As long as the tbody isn't set to 'display: block' the columns display properly but the tbody is out of control and ignores any height you may have set.
I'm trying to do this to make it possible for the result to be easily chapter 508 compliant for screen reader technology for those with disabilities. AT this point, I'm planning to convert to jquery.dataTables which puts a view port over top of a table so I can keep the 508 compliance and get the functionality I need. This seems way over the top for what I'm wanting to accomplish but I can't find a simple way to do it with a native table and basic css.
Test code is as follows:
<div id="div1">
<table>
<colgroup>
<col id='col-1'>
<col id='col-2'>
</colgroup>
<thead>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February is a long month that seems like it could go on forever!</td>
<td>$80</td>
</tr>
<tr>
<td>March</td>
<td>$180</td>
</tr>
<tr>
<td>April</td>
<td>$86</td>
</tr>
<tr>
<td>May</td>
<td>$98</td>
</tr>
<tr>
<td>June</td>
<td>$29</td>
</tr>
<tr>
<td>July</td>
<td>$44</td>
</tr>
<tr>
<td>August</td>
<td>$244</td>
</tr>
</tbody>
</table>
#div1 {
height: 100px;
width: 400px;
padding: .5px;
border: 1px solid red;
}
colgroup {
width: 100%;
}
#col-1 {
width:70%;
}
#col-2 {
width:30%;
}
table {
width: 100%;
table-layout: auto;
}
thead {
background-color: #B2DFFF;
}
tbody {
height: 72px;
overflow-y: scroll;
background-color: #F0F0F0;
/* display:block; This will set column width correctly but it messes up tbody height */
display:block; /* This will allow height to be set but it messes up columns width */
}
Does anyone have any ideas?
Add overflow: auto to your container div's css.
Link to JSFiddle: http://jsfiddle.net/bmarple/NK378/10/
It is possible, just have some considerations:
thead {display: table; width: 100%;}
tbody {display: block; overflow: auto;}
tbody tr {display: table; width: 100%;}
td, th {/* should set a width for each td, th*/}
This is the example: http://jsfiddle.net/NK378/14/
Add overflow:scroll; to #div1 to add scroll beyond a height of 100px.
http://jsfiddle.net/NK378/13/
EDIT:
I could not see from your question that you wanted the header in view at all times. To do this, aply the style to the tbody so it doesn't apply to the header.. So the tbody tag has an id of "scroll", and the css for #scroll is:
#scroll {
display:block;
overflow-y: scroll;
display: block;
height: 20px;
width:400px;
}
http://jsfiddle.net/NK378/17/
Try to change the "display" property to "inline-block" and "max-width", "min-width", "overflow-x", "white-space" like that:
CSS
tbody td {
display: inline-block;
max-width: 100px;
min-width: 100px;
overflow-x: scroll;
white-space: nowrap;
}
JSFIDDLE
Watch the second line in the table.
In the case you want to limit the height of your td:
CSS
tbody td {
display: inline-block;
max-width: 100px;
min-width: 100px;
overflow-y: scroll;
max-height: 30px;
min-height: 30px;
overflow-x: hidden;
}
JSFIDDLE
You shouldn't use display: block on tables. They need their default display: table in order to function correctly.
You can just set the containing div to scroll when it overflows:
#div1 {
height: 100px;
width: 400px;
padding: .5px;
border: 1px solid red;
overflow-y: scroll; /* Added */
}
Demo
UPDATE
I completely missed the requirement for the thead to not scroll. One way to achieve this is to nest another table inside the first to separate it from the thead. You are allowed to place a <div> inside a <td> so that's how you create the scroll.
<div id="div1">
<table>
<thead>
<tr>
<th>Month</th>
<th class="savings">Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2">
<div class="table-body">
<table>
<tbody>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February is a long month that seems like it could go on forever!</td>
<td>$80</td>
</tr>
<tr>
<td>March</td>
<td>$180</td>
</tr>
<tr>
<td>April</td>
<td>$86</td>
</tr>
<tr>
<td>May</td>
<td>$98</td>
</tr>
<tr>
<td>June</td>
<td>$29</td>
</tr>
<tr>
<td>July</td>
<td>$44</td>
</tr>
<tr>
<td>August</td>
<td>$244</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Some additional styles
th:first-child, td:first-child {
width: 80%;
}
table table td {
padding: 4px 5px;
}
.table-body {
height: 100px;
overflow: auto;
}
UPDATED DEMO

how to avoid table-layout avoid for certain elements of the table?

So i've been trying to use table-layout fixed so that the content get's it's width by the largest one but i don't want that to happen to all of the data's. Some of them need to have a width by the content itself not by a sibling they have in the same row. Here's the code
<table>
<tbody>
<tr>
<td> </td>
<td> </td>
<th>2012</th>
<th>2011</th>
<th>Var</th>
</tr>
<tr>
<td class="day">M</td>
<td class="date">3</td>
<td>300,500</td>
<td>300,500</td>
<td>0%</td>
</tr>
<tr>
<td class="day">T</td>
<td class="date">4</td>
<td>300,500</td>
<td>300,500</td>
<td>0%</td>
</tr>
</tbody>
And here's the CSS
table {
float: left;
width: 100%;
height: auto;
margin-top: 20px;
table-layout: fixed;
display: table;
}
table tr{
border-bottom: 1px solid #ccc;
width: 100%;
}
table tr th{
text-align: center;
}
table tr td{
display: table-cell;
text-align: center;
}
So the question is that i want the td's with class date and day to have width by their own width like width = auto to avoid the table cell function. What do you guy's suggest i should do. Can i do this in CSS or shall i do a script for that.

Categories

Resources