How to make responsive table without using bootstrap - html

I would like to create a responsive table like this
Now, I have some large content of data(which is filled dynamically) for each cell, and if you notice this table overlaps the contents on least screen size(300 px and less). Though this can be managed, but I would like to have any optimal solution for this, if possible.
Any help would be appreciated.

It may be your answer please see result in full screen
table tr td,table tr td{
text-align: center;
}
#media only screen and (max-width: 500px) {
table,head,tbody,th,td,tr {
display: block;
}
thead tr {
display: none;
}
tr {
border: 1px solid #ccc;
}
td {
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
white-space: normal;
text-align:left;
min-height: 30px;
overflow: hidden;
word-break:break-all;
}
td:before {
position: absolute;
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
text-align:left;
font-weight: bold;
}
td:before { content: attr(data-title); }
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<table width="100%">
<thead>
<tr>
<th>Name</th>
<th>ID</th>
<th>designation</th>
</tr>
</thead>
<tbody>
<tr>
<td data-title="Name">John</td>
<td data-title="ID">100</td>
<td data-title="designation">Software Engineer</td>
</tr>
<tr>
<td data-title="Name">Shyam</td>
<td data-title="ID">101</td>
<td data-title="designation">Quality Analyst</td>
</tr>
<tr>
<td data-title="Name">Mark</td>
<td data-title="ID">102</td>
<td data-title="designation">Software Engineer</td>
</tr>
<tr>
<td data-title="Name">Bill</td>
<td data-title="ID">104</td>
<td data-title="designation">Quality Analyst</td>
</tr>
<tr>
<td data-title="Name">Arjun</td>
<td data-title="ID">105</td>
<td data-title="designation">Human Resources</td>
</tr>
<tr>
<td data-title="Name">Pratyush</td>
<td data-title="ID">106</td>
<td data-title="designation">Software Engineer</td>
</tr>
<tr>
<td data-title="Name">Anant</td>
<td data-title="ID">101</td>
<td data-title="designation">Administrative Dept</td>
</tr>
</tbody>
</table>
</body>
</html>
In above snippet you can use media query which screen size you want to stack td of table eg:300px

Kailash Chandra's answer gave me the clue for something I was trying to do. I wanted a 2 column table that was very compact in most cases, and Bootstrap always forces a minimum width on the first column. I just wanted a table that would act like a table until I got down to phone size, and then have it turn into a single row alternating a heading and the value below it. That turned out to be pretty trivial with this bit of css, which basically just uses the same trick to make it quit acting like a table. In this case I'm not changing anything else about it as it meets my need, but it would be easy enough to add some styling.
#media only screen and (max-width: 400px) {
.flyout-table table,
.flyout-table th,
.flyout-table td,
.flyout-table tr {
display: block;
}
}

Related

React: How to make <td> collapse as column in a <tr> in mobile view

I'm trying to make my websites look consistent across devices.
I have a table that looks like this:
How can I make the same table behave so that when viewed on mobile, the <td> in a <tr> will sort in a column order with the <th> next to every table data like this:
I am making the website in React so if there is a way of doing this in React that I am not aware of, the better
was able to do this with media queries:
/* set for mobile breakpoint */
#media (max-width: 1024px) {
/* display th for desktop only, hide on mobile */
.desktop {
display: none;
}
/* arranges td as column in the tr */
.mobile-flex {
display: flex;
width: 100%;
}
/* adds faux-headers on each td by reading "data-header" attribute of the td*/
td:before {
content: attr(data-header);
display: block;
font-weight: bold;
margin-right: 10px;
max-width: 110px;
min-width: 110px;
word-break: break-word;
}
}
<table>
<thead>
<tr>
<th class="desktop">Title</th>
<th class="desktop">Author</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mobile-flex" data-header="Title">Sample book title 1</td>
<td class="mobile-flex" data-header="Author">Sample author name 1</td>
</tr>
<tr>
<td class="mobile-flex" data-header="Title">Sample book title 2</td>
<td class="mobile-flex" data-header="Author">Sample author name 2</td>
</tr>
</tbody>
</table>
Media queries would probably not be effective here as you are looking to change the actual html. You'll probably want to use a package such as https://www.npmjs.com/package/react-breakpoints to render different content depending on whether it is a desktop or mobile device.
Use a single class and make your table responsive
#media (max-width: 576px) {
.tbl-responsive th {
display: none;
}
.tbl-responsive td {
display: flex;
}
.tbl-responsive td .btn{
position: relative;
left: -10px;
}
.tbl-responsive td:before {
content: attr(data-header);
font-weight: bold;
color: #000;
margin-right: 10px;
}
}
<table class="tbl-responsive">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
</tr>
</thead>
<tbody>
<tr>
<td data-header="Title: ">Sample book title 1</td>
<td data-header="Author">Sample author name 1</td>
</tr>
<tr>
<td data-header="Title: ">Sample book title 2</td>
<td data-header="Author: ">Sample author name 2</td>
</tr>
</tbody>
</table>

Hover effect on hyperlink not working properly after switching table into mobile view

I have a table with several columns that can be switched into mobile view by clicking a button. Some fields contain hyperlinks.
<style>
.show-thin {
width: 930px; /* complete width of alternative table view */
}
/* Force table to not be like tables anymore */
.show-thin table, .show-thin thead, .show-thin tbody, .show-thin th, .show-thin td, .show-thin tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
.show-thin thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
.show-thin tr { border: 1px solid #ccc; }
.show-thin td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eef;
position: relative;
padding-left: 30%; /* distance of table-values from left margin 30px */
}
.show-thin td:before {
/* Now like a table header */
position: absolute; /* puts field-names at left margin */
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/*
Label the data
*/
.show-thin td:before { content: attr(data-label); }
</style>
<script>
function toggle() {
var table = document.querySelector('.myTable');
table.classList.toggle('show-thin');
}
</script>
<button onclick="toggle()">Toggle</button>
<hr/>
<table class="myTable">
<thead>
<tr class="tr thin-hide">
<th data-label='Nr'>Nr</th>
<th>Estimated arrival date</th>
<th>Amount</th>
<th>Period</th>
<th>Period2</th>
<th>Period3</th>
<th>Period4</th>
<th>Period5</th>
<th>Period6</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Nr">1234</td>
<td data-label="Estimated Arrival Date">03/15/2001</td>
<td data-label="Amount">$1.00</td>
<td data-label="Period"><a href='https://www.startpage.com' target='_blank'>Startpage</a></td>
<td data-label="Period2"><a href='https://www.wikipedia.com' target='_blank'>Wikipedia</a></td>
<td data-label="Period3"><a href='https://www.google.com' target='_blank'>Google</a></td>
<td data-label="Period4">3rd</td>
<td data-label="Period5">3rd</td>
<td data-label="Period6">3rd</td>
</tr>
<tr class="tr">
<td data-label="Account">1235</td>
<td data-label="Estimated Arrival Date">04/21/2002</td>
<td data-label="Amount">$12.00</td>
<td data-label="Period">4th</td>
<td data-label="Period2">4th</td>
<td data-label="Period3">4th</td>
<td data-label="Period4">4th</td>
<td data-label="Period5">4th</td>
<td data-label="Period6">4th</td>
</tr>
<tr>
<td data-label="Account">4594</td>
<td data-label="Estimated Arrival Date">11/11/2011</td>
<td data-label="Amount">$45.50</td>
<td data-label="Period">2nd</td>
<td data-label="Period2">2nd</td>
<td data-label="Period3">2nd</td>
<td data-label="Period4">2nd</td>
<td data-label="Period5">2nd</td>
<td data-label="Period6">2nd</td>
</tr>
<tr>
<td data-label="Account">4594</td>
<td data-label="Estimated Arrival Date">11/11/2011</td>
<td data-label="Amount">$45.50</td>
<td data-label="Period">2nd</td>
<td data-label="Period2">2nd</td>
<td data-label="Period3">2nd</td>
<td data-label="Period4">2nd</td>
<td data-label="Period5">2nd</td>
<td data-label="Period6">2nd</td>
</tr>
</tbody>
</table>
In desktop mode the hover effect of the hyperlinks works as it should.
After switching into mobile view the hover effect of the hyperlinks works only in the very upper margin of the respective words.
I think the problem is in the CSS, however, I didn´t get it to work properly.
In mobile mode the the first column overlaps the second column. Add background-color: green to .show-thin td:before {...} and you will see it happen. Ergo, the first column is too wide.
Change width in .show-thin td:before {...} to 28% or less and your problem is solved....

Completely rearrange Table element with media query

I'm trying to rearrange a relatively large table (using CSS media query) after the width of a screen reaches a certain point and have it look like this (see image below) when the browser window is squished all the way through:
I've already succeed at deleting the unwanted rows, and getting the basic layout of it.
The Problem is:
the inline block elements below each day of the week need to fit the width of the table, and nothing has worked so far, not flex (maybe I'm not using it correctly) or overflow, or border-box.
HTML (just a table)
<table>
<thead>
<tr>
<th>DAY</th>
<th style="width:300px;">CLASS</th>
<th>TIME</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Monday</td>
<td>Endurance biking</td>
<td>9am-1pm</td>
<td>Register</td>
</tr>
<tr>
<td>Tuesday</td>
<td>Speed biking</td>
<td>2pm-4pm</td>
<td>Register</td>
</tr>
<tr class="toBeDeleted">
<td>Wednesday</td>
<td colspan="3" class="noClasses">No classes</td>
</tr>
<tr>
<td>Thursday</td>
<td>Speed biking</td>
<td>3pm-5pm</td>
<td>Register</td>
</tr>
<tr class="toBeDeleted">
<td>Friday</td>
<td colspan="3" class="noClasses">No classes</td>
</tr>
<tr>
<td>Saturday</td>
<td>Endurance biking</td>
<td>9am-1pm</td>
<td>Register</td>
</tr>
<tr>
<td>Sunday</td>
<td>Endurance biking</td>
<td>10am-4pm</td>
<td>Register</td>
</tr>
</tbody>
</table>
CSS (deletes 2 rows and the "thead", colors every first cell of each row and place that cell above the rest of it's respective row)
#media only screen and (max-width: 530px){
thead, .pasDeClasses{
display: none;
}
td:first-child{
background-color: #4080bc;
color: white;
font-family: Arial;
display: block;
}
tr > td{
border-left: 1px solid white;
max-width: 100%;
display: inline-block;
padding-top: 10px;
padding-bottom: 10px;
}
table{
min-width: 90%;
margin-left: auto;
margin-right: auto;
font-family: Arial;
}
}
thead{
background-color: #4080bc;
color: white;
}
td{
background-color: #d6d6d6;
padding-top: 10px; padding-bottom: 10px; padding-left: 30px; padding-right:
30px;
text-align: center;
}
You could try absolute-positioning only the last tr elements at the bottom of their parents. notice the position:relative, and display:block on the parent tr
tr{
display:block;position:relative;padding-bottom:20px
}
tr td:last-child{
position:absolute;bottom:0;
width:100%;height:20px
}
This works using the rule that an absolutely positioned element inside of a relatively positioned element will "dock" to the relatively positioned parent-element, rather than the viewport.

HTML table with mixed rowspan

I'm trying to use HTML to construct a table with three rows (1-3) and three columns (A-C) forming nine "virtual cells" (A1, B1, C1, A2, B2, C2, A3, B3, C3) and apply row spanning so that:
cell A1 span all three rows (covering A2 and A3)
cell C1 span two rows (covering C2)
cell B2 span two rows (covering B3)
This is what I want to see:
This is the HTML I thought would give me that:
<html>
<head>
<style>
table { border-collapse: collapse; }
td { border: 1px solid black; padding: 1em; vertical-align: top; }
</style>
</head>
<body>
<table>
<tr><td rowspan="3">A1</td><td>B1</td><td rowspan="2">C1</td></tr>
<tr><td rowspan="2">B2</td></tr>
<tr><td>C3</td></tr>
</table>
</body>
</html>
But that gives me:
What is the correct way to get what I want? Or is it not possible?
This is for use in technical documentation. It is not a layout issue, the content is semantically a table.
In order to prevent the rows collapsing without the need for additional markup, you can attach a phantom cell to each row with tr::after set to display: table-cell with your cell padding on top and bottom and a unicode blank space:
tr::after {
content: '\00a0';
display: table-cell;
padding: 1em 0;
}
Gives you the correct result:
It's worth noting that the phantom cell will create a slight gap to the right like this:
Full snippet
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 1em;
vertical-align: top;
}
tr:after {
content: '\00a0';
display: table-cell;
padding: 1em 0;
}
<table>
<tr>
<td rowspan="3">A1</td>
<td>B1</td>
<td rowspan="2">C1</td>
</tr>
<tr>
<td rowspan="2">B2</td>
</tr>
<tr>
<td>C3</td>
</tr>
</table>
Here's a solution without having to know the table height up front, using hidden table cells, like in Align table using rowspan and colspan (as I said, it's basically a duplicate, just another layout):
<html>
<head>
<style>
table { border-collapse: collapse; }
td { border: 1px solid black; padding: 1em; vertical-align: top; }
td.hidden { visibility: hidden; padding: 1em 0; border: 0 none; }
</style>
</head>
<body>
<table>
<tr><td rowspan="3">A1</td><td>B1</td><td rowspan="2">C1</td><td class="hidden">‌</td></tr>
<tr><td rowspan="2">B2</td><td class="hidden">‌</td></tr>
<tr><td>C3</td><td class="hidden">‌</td></tr>
</table>
</body>
</html>
Why not just setting a height to the tr cause it is a table the height will adjust anyways if there is more content inside the row.
something like so:
table {
border-collapse: collapse;
}
tr {
height: 30px;
}
td {
border: 1px solid black;
padding: 1em;
vertical-align: top;
}
<table>
<tr>
<td rowspan="3">A1</td>
<td>B1</td>
<td rowspan="2">C1</td>
</tr>
<tr>
<td rowspan="2">B2</td>
</tr>
<tr>
<td>C3</td>
</tr>
</table>
Otherwise,
<!DOCTYPE html>
<html>
<head>
<style>
table { border-collapse: collapse; }
td{border: 1px solid black; padding: 1em; vertical-align: top; }
</style>
</head>
<body>
<table>
<tr>
<td rowspan="3">A1</td>
<td>B1</td>
<td rowspan="2">C1</td>
</tr>
<tr>
<td rowspan="2">B2</td>
</tr>
<tr>
<td rowspan="2">C3</td>
</tr>
</table>
</body>
</html>
You could hack it like this:
<html>
<head>
<style>
table { border-collapse: collapse; }
td { border: 1px solid black; padding: 1em; vertical-align: top; }
</style>
</head>
<body>
<table>
<tr>
<td style="width:0px;padding:0;border:0"></td>
<td rowspan="3">A1</td>
<td>B1</td>
<td rowspan="2">C1</td>
</tr>
<tr>
<td style="width:0px;padding:0;border:0;height:50px"></td>
<td rowspan="2">B2</td>
</tr>
<tr>
<td style="width:0px;padding:0;border:0"></td>
<td>C3</td>
</tr>
</table>
</body>
</html>
... but I would recommend to use another structure instead of tables, since it doesn't have a lot in common with table, besides the columns.
It's depend the height of your table.
http://codepen.io/anon/pen/jBOgpx
<table>
<tr>
<td rowspan="3">A1</td>
<td>B1</td>
<td rowspan="2">C1</td>
</tr>
<tr>
<td rowspan="2" style="height:65px">B2</td>
</tr>
<tr>
<td>C3</td>
</tr>
</table>

Changing layout in table row using CSS only

I have a table using jQuery datatables with some rows in it.
Per this example, the table could look something like this:
https://jsfiddle.net/ef42942g/
I want to use CSS to change the way the table rows are shown so the final result will look something like this: https://jsfiddle.net/hamx5tas/ (please ignore the actual code)
It's very important to keep the basic table structure. I want that the change will be made entirely using CSS (if at all possible).
I have tried various changes to the tr's and td's css but with not much luck.
<table cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<th>Thumbnail</th>
<th>Title</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<img src="http://www.cmacgm-marcopolo.com/wp-content/uploads/2013/01/vignette-cargo-carnet-pratique-zeebrugge.jpg" width="100">
</td>
<td>Title 1</td>
<td>100$</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
<tr>
<td>
<img src="http://www.cmacgm-marcopolo.com/wp-content/uploads/2013/01/vignette-cargo-carnet-pratique-zeebrugge.jpg" width="100">
</td>
<td>Title 1</td>
<td>100$</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
<tr>
<td>
<img src="http://www.cmacgm-marcopolo.com/wp-content/uploads/2013/01/vignette-cargo-carnet-pratique-zeebrugge.jpg" width="100">
</td>
<td>Title 1</td>
<td>100$</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
</tbody>
</table>
I will appreciate any help that can be handed.
Thanks in advance.
You can adjust the layout using CSS flexbox. No changes necessary to the HTML.
CSS
thead > tr { display: none; }
tbody { display: flex; }
tbody > tr {
display: flex;
flex-direction: column;
align-items: center;
margin: 5px;
border: 1px solid black;
}
tbody > tr > td {
display: flex;
justify-content: center;
align-items: flex-start;
padding: 5px;
}
tbody > tr > td img {
width: 100px;
height: 65px;
}
tbody > tr > td:last-child {
flex-direction: row;
}
tbody > tr > td:last-child button {
margin: 5px;
}
Revised Demo
Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, use Autoprefixer. More browser compatibility details in this answer.
You can achieve what you want with pure CSS, changing the display property.
In this way, let's say that the table will not behave like a table anymore.
After that, you just have to adjust minor details to achieve your goal.
CSS:
tr {
width: 120px;
display: inline-block;
padding: 5px;
border: 1px solid black;
margin-right: 20px;
}
td {
padding: 5px;
display: block;
text-align: center;
}
Check it here: JSFiddle.
Hope it helps!
Setting the display on the td elements to block, and the display on the tr elements to inline-block gets you most of the way there.
td { padding: 5px;
border-bottom: none;
border-right:1px solid black;
display:block;}
tr{
display:inline-block;
}
thead{
display: none;
}
It sounds like you have some specific requirements for the format, so I won't go into further detail on assumptions, but from here you should be able to get what you want by turning borders on and off where needed.
https://jsfiddle.net/ef42942g/3/
I saw that Op wanted the structure unaltered so I had to go back to the drawing board. The following are the CSS changes:
Assigned display: none; to <thead>
Made the 3 tr into display: inline-table
Made all of the td to tr
Made the .main table 90vw which...
...made it easy for me to get the 3 tables symmetrical...
...some margins and padding...
...compared to the model we were provided, my table are 2px further apart, 10px wider, and 20px taller.
Fiddle
Snippet
thead {
display: none;
}
table {
width: 90vw;
}
tr {
display: inline-table;
outline: 1px solid black;
margin: 10px 5px;
}
td {
padding: 10px 15px;
display: table-row;
height: 30px;
text-align: center;
}
img {
width: 120px;
margin: 10px 15px;
}
<table cellspacing="0" cellpadding="0" border="0">
<thead>
<tr>
<th>Thumbnail</th>
<th>Title</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<img src="http://www.cmacgm-marcopolo.com/wp-content/uploads/2013/01/vignette-cargo-carnet-pratique-zeebrugge.jpg" width="100">
</td>
<td>Title 1</td>
<td>100$</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
<tr>
<td>
<img src="http://www.cmacgm-marcopolo.com/wp-content/uploads/2013/01/vignette-cargo-carnet-pratique-zeebrugge.jpg" width="100">
</td>
<td>Title 1</td>
<td>100$</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
<tr>
<td>
<img src="http://www.cmacgm-marcopolo.com/wp-content/uploads/2013/01/vignette-cargo-carnet-pratique-zeebrugge.jpg" width="100">
</td>
<td>Title 1</td>
<td>100$</td>
<td>
<button>Edit</button>
<button>Delete</button>
</td>
</tr>
</tbody>
</table>