I need to make a table responsive using CSS. When the screen size is small I must make the table headers and table cell data appear side by side. How can I do that using only CSS?
<table class="hobbies_table">
<tr>
<th>Name</th>
<th>Age</th>
<th class="hobbies">Hobby1</th>
<th class="hobbies">Hobby2</th>
<th>Contact</th>
</tr>
<tr>
<td>John</td>
<td>21</td>
<td class="hobbies_values">Football</td>
<td class="hobbies_values">Snooker</td>
<td>1234567890</td>
</tr>
<tr>
<td>Jack</td>
<td>30</td>
<td class="hobbies_values">Reading</td>
<td class="hobbies_values">Swimming</td>
<td>1234567890</td>
</tr>
<tr>
<td>Jenna</td>
<td>40</td>
<td class="hobbies_values">Travelling</td>
<td class="hobbies_values">Singing</td>
<td>1234567890</td>
</tr>
</table>
.hobbies {
width: 50%;
display: flex;
}
.hobbies_values {
width: 50%;
display: flex;
}
#hobbies_table td:nth-of-type(3):before { content: attr(hobbies) }
#hobbies_table td:nth-last-of-type(2):before { content: attr(hobbies) }
I know only basic CSS. So this is what I have tried. But I came to know this is the wrong way. So how can I correct the code?
Here in #media, I want the hobbies and hobbies_values to be displayed like this:
Hobby1: Football
Hobby2: Snooker
Hobby1: Reading
Hobby2: Swimming
Hobby1: Travelling
Hobby2: Singing
May it helps :)
.hobbies_table {
width: 100%;
}
th {
display: flex;
}
tr {
width: 20%;
display: inline-grid;
}
<table class="hobbies_table">
<tr>
<th>Name</th>
<th>Age</th>
<th class="hobbies">Hobby1</th>
<th class="hobbies">Hobby2</th>
<th>Contact</th>
</tr>
<tr>
<td>John</td>
<td>21</td>
<td class="hobbies_values">Football</td>
<td class="hobbies_values">Snooker</td>
<td>1234567890</td>
</tr>
<tr>
<td>Jack</td>
<td>30</td>
<td class="hobbies_values">Reading</td>
<td class="hobbies_values">Swimming</td>
<td>1234567890</td>
</tr>
<tr>
<td>Jenna</td>
<td>40</td>
<td class="hobbies_values">Travelling</td>
<td class="hobbies_values">Singing</td>
<td>1234567890</td>
</tr>
</table>
There are two popular approaches to your problem:
Solution A (Bootstrap's classic "table responsiveness")
Simply wrap the table inside a scrollable div and allow it to have its full width. Note this becomes confusing on mobile devices, especially when the user starts scrolling in both directions. A better mobile user experience is often times opening the table in a modal and allowing the user to scroll it in full screen).
Solution B (Separate markup for each case)
Have separate markup for each case, hiding the unwanted contents using #media queries. The base principle is that you duplicate content and hide the clone you don't want displayed on each responsiveness interval.
As with almost anything, no solution is clearly better than the other. It largely varies from case to case.
Here's a solution catered for your particular case (based on clarifications in comments):
.mobile_content {
display: none;
}
#media (max-width: 700px) {
.desktop_content {
display: none;
}
.mobile_content {
display: block;
}
.hobbies_values + .hobbies_values {
display: none;
}
}
<table class="hobbies_table">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th class="hobbies_values">
<div class="desktop_content">Hobby1</div>
<div class="mobile_content">Hobbies</div>
</th>
<th class="hobbies_values">Hobby2</th>
<th>Contact</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>21</td>
<td class="hobbies_values">Football<div class="mobile_content">Snooker</div></td>
<td class="hobbies_values">Snooker</td>
<td>1234567890</td>
</tr>
<tr>
<td>Jack</td>
<td>30</td>
<td class="hobbies_values">Reading<div class="mobile_content">Swimming</div></td>
<td class="hobbies_values">Swimming</td>
<td>1234567890</td>
</tr>
<tr>
<td>Jenna</td>
<td>40</td>
<td class="hobbies_values">Travelling<div class="mobile_content">Singing</div></td>
<td class="hobbies_values">Singing</td>
<td>1234567890</td>
</tr>
</table>
It's actually a separate case of solution B (where, rather than completely replace the table markup - you reuse part of it and only duplicate the part that is displayed under other column's content).
Related
I’ve built a web application and am in the process of making the pages mobile responsive. Specifically, I’m dealing with tables. I found a write up that explains how to make the table switch from horizontal to vertical for tablets and phones which have smaller screens. This works great, but the page has 3 tables and I’m not sure how to adapt the CSS for the 3 different tables.
The write up: https://www.liquidlight.co.uk/blog/article/tables-in-responsive-design/
Code Demo: https://codepen.io/team/css-tricks/pen/wXgJww?editors=1100
The portions I’m having trouble with is the labels of the cells. The CSS uses:
td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 0;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/*
Label the data
You could also use a data-* attribute and content for this. That way "bloats" the HTML, this way means you need to keep HTML and CSS in sync. */
td:nth-of-type(1):before { content: "No Longer with Parish"; }
td:nth-of-type(2):before { content: "Position"; }
td:nth-of-type(3):before { content: "Name, City"; }
td:nth-of-type(4):before { content: ""; }
td:nth-of-type(5):before { content: "Religious Affiliation"; }
td:nth-of-type(6):before { content: "Virtus"; }
td:nth-of-type(7):before { content: "Background Check"; }
td:nth-of-type(8):before { content: "Standard Code of Conduct"; }
td:nth-of-type(9):before { content: "Technology / Social Media"; }
td:nth-of-type(10):before { content: "Youth (under 18) Code of Conduct"; }
}
The CSS adds a cell before each cell in the row which contains a label for the item. This would be fine if all the tables showed the same data and could use the same labels. The problem is that they don’t. The 3 tables all have different numbers of columns as well.
How do I tweak the CSS to differentiate between the 3 tables? Should I use an ID in each of the td cells such as id=”One”; id=“Two”; id=”Three” and then target the td id?
I've tried adding id="one" to the first cell and using the following CSS to add the label, but can't get the label to show:
td#one:before { content: "label"; }
td#one:nth-of-type(1):before { content: "label"; }
#one:before { content: "label"; }
#one:nth-of-type(1):before { content: "label"; }
In the design window of visual studio, the cell is referenced as td#one so I thought that one of the first 2 lines of CSS would work. No label shows. Can someone explain how to reference the cell in order to get the label to show? Once I get that to work, table one will have cells one to nine, table two will have cells ten through nineteen and table three will have cells twenty through twenty-eight.
Maybe instead, I could add the label to the main td cell inside a div that displays none or inline using media queries.
Use nth-child instead of nth-of-type.
th:nth-child(1):before{content:'First Name'}
th:nth-child(2):before{content:'Last Name'}
th:nth-child(3):before{content:'Job Title'}
th:nth-child(4):before{content:'Favorite Color'}
th:nth-child(5):before{content:'Wars or Trek?'}
th:nth-child(6):before{content:'Secret Alias'}
th:nth-child(7):before{content:'Date of Birth'}
th:nth-child(8):before{content:'Dream Vacation City'}
th:nth-child(9):before{content:'GPA'}
th:nth-child(10):before{content:'Arbitrary Data'}
<table border="1">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody role="rowgroup">
<tr role="row">
<td role="cell">James</td>
<td role="cell">Matman</td>
<td role="cell">Chief Sandwich Eater</td>
<td role="cell">Lettuce Green</td>
<td role="cell">Trek</td>
<td role="cell">Digby Green</td>
<td role="cell">January 13, 1979</td>
<td role="cell">Gotham City</td>
<td role="cell">3.1</td>
<td role="cell">RBX-12</td>
</tr>
<tr role="row">
<td role="cell">The</td>
<td role="cell">Tick</td>
<td role="cell">Crimefighter Sorta</td>
<td role="cell">Blue</td>
<td role="cell">Wars</td>
<td role="cell">John Smith</td>
<td role="cell">July 19, 1968</td>
<td role="cell">Athens</td>
<td role="cell">N/A</td>
<td role="cell">Edlund, Ben (July 1996).</td>
</tr>
<tr role="row">
<td role="cell">Jokey</td>
<td role="cell">Smurf</td>
<td role="cell">Giving Exploding Presents</td>
<td role="cell">Smurflow</td>
<td role="cell">Smurf</td>
<td role="cell">Smurflane Smurfmutt</td>
<td role="cell">Smurfuary Smurfteenth, 1945</td>
<td role="cell">New Smurf City</td>
<td role="cell">4.Smurf</td>
<td role="cell">One</td>
</tr>
<tr role="row">
<td role="cell">Cindy</td>
<td role="cell">Beyler</td>
<td role="cell">Sales Representative</td>
<td role="cell">Red</td>
<td role="cell">Wars</td>
<td role="cell">Lori Quivey</td>
<td role="cell">July 5, 1956</td>
<td role="cell">Paris</td>
<td role="cell">3.4</td>
<td role="cell">3451</td>
</tr>
<tr role="row">
<td role="cell">Captain</td>
<td role="cell">Cool</td>
<td role="cell">Tree Crusher</td>
<td role="cell">Blue</td>
<td role="cell">Wars</td>
<td role="cell">Steve 42nd</td>
<td role="cell">December 13, 1982</td>
<td role="cell">Las Vegas</td>
<td role="cell">1.9</td>
<td role="cell">Under the couch</td>
</tr>
</tbody>
</table>
Sorry for the very specific title, couldn't think of how to say it in more general terms.
Assume you have a table and each row contains a cell that has an input, but some input fields have a class of 'DontRemoveMe'. How do you target every row except the 'DontRemoveMe' rows?
Manipulation of DOM Elements requires JavaScript. One way to achieve this is with jQuery:
function remove() {
$('tr:not(.dontRemoveMe)').remove();
}
.dontRemoveMe td {
background-color: green;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr class="dontRemoveMe">
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Jon</td>
<td>Jones</td>
<td>33</td>
</tr>
</table>
<button onclick="remove()">Remove rows</button>
CSS (Not Yet Implemented):
Using CSS level 4 selectors, I believe it would be
tr:has(td>input:not(>>.DontRemoveMe))
However, those aren't implemented in any browser. So you would want to use javascript.
Javascript:
// Select all rows that don't contain a input.DontRemoveMe
let rows = Array.from(document.querySelectorAll("tr")).filter(x => !(x.querySelector("input.DontRemoveMe")));
// Add a special class to these rows so we can target them with CSS
rows.forEach(x => x.classList.add("selected"));
td {
padding: 8px; /* Padding for all rows to make background visible */
}
.selected {
background: red;
}
<table>
<tr>
<td><input type="text" value="selected" />
</td>
</tr>
<tr>
<td><input class="DontRemoveMe" type="text" value="not selected" />
</td>
</tr>
<tr>
<td>
<input type="text" value="selected" />
</td>
</tr>
</table>
Here is an old school javascript way.
Find all the tr tags then find any children with class DontRemoveMe, if it doesn't find any add a .hide class to the current row.
But, honestly I'd question the reason you want to do it like this, chances are there is a more sensible way.
var tr = document.getElementsByTagName('tr');
var i = 0;
var length = tr.length
for (; i < length; i++) {
var dontRemove = tr[i].getElementsByClassName('DontRemoveMe')
if (!dontRemove.length) {
tr[i].classList.add('hide')
}
}
td {
color: #ededed;
}
.red {
background-color: #ff3030;
}
.blue {
background-color: #6495ED;
}
.hide {
display: none;
}
<table>
<tr class="red">
<td>Normal</td>
<td>Normal</td>
<td class="DontRemoveMe">Don't Remove Me</td>
</tr>
<tr class="blue">
<td>Can't see me</td>
<td>Can't see me</td>
<td>Can't see me</td>
</tr>
<tr class="red">
<td class="DontRemoveMe">Don't Remove Me</td>
<td>Normal</td>
<td class="DontRemoveMe">Don't Remove Me</td>
</tr>
</table>
In the above table to achieve equal width columns I have used <td class="col-md-1"></td>. But only the first few columns are equal width as shown in the image. As this is a long table I would like to scroll horizontally so that the table can maintain the required column width. but this table wouldn't grow. I even tried table{ width:auto !important }
.table {
width: 100%;
max-width: 100%;
margin-bottom: 20px;
}
The above styles get applied for my table from bootstrap
Classes I have used in the table element - <table class="table table-bordered"></table>
Framework: Bootstrap 3
You will want to use this markup:
<div class="table-responsive">
<table class="table">
...
</table>
</div>
Source: Responsive Table Bootstrap
Try to use <th> instead.
Example of table in bootstramp.
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>
<table summary="This table shows how to create responsive tables using Bootstrap's default functionality" class="table table-bordered table-hover">
<caption class="text-center">An example of a responsive table based on Bootstrap:</caption>
<thead>
<tr>
<th>Country</th>
<th>Languages</th>
<th>Population</th>
<th>Median Age</th>
<th>Area (Km²)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Argentina</td>
<td>Spanish (official), English, Italian, German, French</td>
<td>41,803,125</td>
<td>31.3</td>
<td>2,780,387</td>
</tr>
<tr>
<td>Australia</td>
<td>English 79%, native and other languages</td>
<td>23,630,169</td>
<td>37.3</td>
<td>7,739,983</td>
</tr>
<tr>
<td>Greece</td>
<td>Greek 99% (official), English, French</td>
<td>11,128,404</td>
<td>43.2</td>
<td>131,956</td>
</tr>
<tr>
<td>Luxembourg</td>
<td>Luxermbourgish (national) French, German (both administrative)</td>
<td>536,761</td>
<td>39.1</td>
<td>2,586</td>
</tr>
<tr>
<td>Russia</td>
<td>Russian, others</td>
<td>142,467,651</td>
<td>38.4</td>
<td>17,076,310</td>
</tr>
<tr>
<td>Sweden</td>
<td>Swedish, small Sami- and Finnish-speaking minorities</td>
<td>9,631,261</td>
<td>41.1</td>
<td>449,954</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">Data retrieved from infoplease and worldometers.</td>
</tr>
</tfoot>
</table>
ie10 is not showing fine border over colspan.
It is showing well on other browser, but not on IE 10.
I'll post my code below.
HTML CODE:
<table>
<thead>
<tr>
<td rowspan="2">1</td>
<td rowspan="2">2</td>
<td colspan="4">3</td>
<td rowspan="2">4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
<td colspan="2">7</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td colspan="3">4</td>
<td>5</td>
</tr>
</tbody>
</table>
CSS CODE:
table tr td {
border: 1px solid black;
width: 100px;
}
table {
border-collapse:collapse;
}
border under 7 is gone. How can I show it?
here is example on jsfiddle :
http://jsfiddle.net/H4z7Q/
ADD: If some event occurs in ie10, border come back to normal.
You can use table inline style stats. instead of border-collapse:collapse;
<table cellpadding=0 cellspacing=0>
will count as same effect.
but will return and will chrice ur problem
The markup violates the HTML table model, as you can see by checking it with http://validator.w3.org which says, referring to the first row: “Table column 6 established by element td has no cells beginning in it”.
So all bets are off. Modify the table structure so that it conforms, or try to achieve the desired layout using other tools than a layout table.
What's wrong with my CSS code? I want to hide the Timestamp column but it's not working? I do not have access to anything in the body, as it is automatically generated, hence i'm trying to use css.
http://snipt.org/Asge0
Code:
<html><head>
<meta http-EQUIV="refresh" content="5">
<style TYPE="text/css">
th, td {
padding-RIGHT: 50px;
text-ALIGN: CENTER;
}
.tb {
CLEAR: both;
}
.tsp {
display: none;
}
</style>
</head>
<body>
<div CLASS="tb"><!-- channeltable schedule="" --><table class="jdt" cellspacing="0">
<colgroup>
<col CLASS="sid"/>
<col CLASS="sun"/>
<col CLASS="chv"/>
<col CLASS="dfu"/>
<col CLASS="tsp"/>
</colgroup>
<thead>
<tr>
<th>Schedule</th>
<th>Name</th>
<th>Value</th>
<th>Units</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>Stream Level</td>
<td>---</td>
<td>metres</td>
<td>2013/06/18 18:10:01.948</td>
</tr>
<tr>
<td>A</td>
<td>Stream Flow</td>
<td>---</td>
<td>cumecs</td>
<td>2013/06/18 18:10:01.989</td>
</tr>
<tr>
<td>A</td>
<td>Tank Pressure</td>
<td>---</td>
<td>PSI</td>
<td>2013/06/18 18:10:02.029</td>
</tr>
<tr>
<td>A</td>
<td>Bubbler Voltage</td>
<td>---</td>
<td>V</td>
<td>2013/06/18 18:10:02.068</td>
</tr>
<tr>
<td>A</td>
<td>Water Temperature</td>
<td>---</td>
<td>Deg</td>
<td>2013/06/18 18:10:03.176</td>
</tr>
<tr>
<td>A</td>
<td>Conductivity</td>
<td>---</td>
<td>uS/cm</td>
<td>2013/06/18 18:10:03.244</td>
</tr>
<tr>
<td>A</td>
<td>Turbidity</td>
<td>---</td>
<td>NTU</td>
<td>2013/06/18 18:10:03.284</td>
</tr>
<tr>
<td>A</td>
<td>pH</td>
<td>OverRange</td>
<td>pH units</td>
<td>2013/06/18 18:10:03.322</td>
</tr>
<tr>
<td>A</td>
<td>Ext. Battery Voltage</td>
<td>18.996444</td>
<td>V</td>
<td>2013/06/18 18:10:03.323</td>
</tr>
</tbody>
EDIT:
Try this javascript hack:
(as it is it just reads first <tbody>, if you have more than one in each page you can add another for loop like in myrows)
var tbody = [];
var tbody = document.getElementsByTagName("tbody");
var myrows = [];
var myrows = tbody[0].getElementsByTagName("tr");
for (var i in myrows) {
var mycells = [];
var mycells = myrows[i].getElementsByTagName("td");
var lastcell = mycells[mycells.length - 1];
lastcell.style.color = "blue";
}
First answer:
Try with :last-child.
Something like
td:last-child {display:none;}
You have to set each <td> tag which you like to hide to <td class="tsp"> colgroup does not support the display attribute.
supported attributes are:
align, char, charoff, valign, width and span
some attributes are not supported in HTML5.
http://www.w3schools.com/tags/tag_colgroup.asp
Edit: as you mentioned you can not access table body try this to hide the 5th column in table:
tr td:nth-child(5), tr th:nth-child(5) {
display: none;
}
tr td + td + td + td + td {display:none } /*IE 8*/
As fallback for older browsers you also can try just to set width: 0px for colgroup
You need to apply the class to all corresponding td's and th's as well
<thead>
<tr>
<th>Schedule</th>
<th>Name</th>
<th>Value</th>
<th>Units</th>
<th CLASS="tsp">Timestamp</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>Stream Level</td>
<td>---</td>
<td>metres</td>
<td CLASS="tsp">2013/06/18 18:10:01.948</td>
</tr>
...etc
You can use the pseudo class :nth-child(n) on your table:
.jdt tr th:nth-child(5), .jdt tr td:nth-child(5) {
display: none;
}
This will hide the 5'th td, th elements in the table.
For more special selectors see this article:
http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/