Responsive table is hiding columns with no values - html

On one of my pages, I have a responsive table that changes layout when the browser gets small. When the columns in my table have values, everything works correctly, as shown in this fiddle.
When the columns do not have values, however, some of them don't show up in the small-version of the table's layout, as shown in this fiddle.
What am I missing?
I have also copied the requisite code from the non-working version below:
#media only screen and (max-width: 760px),
(min-device-width: 768px) and (max-device-width: 1024px) {
/* Force table to not be like tables anymore */
table, thead, tbody, th, td, tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr { border: 1px solid #ccc; }
td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
}
td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/* Label the data */
td:nth-of-type(1):before { content: "MFG P/N"; }
td:nth-of-type(2):before { content: "MFG Name"; }
td:nth-of-type(3):before { content: "Part ID"; }
td:nth-of-type(4):before { content: "Description"; }
td:nth-of-type(5):before { content: "Cost"; }
td:nth-of-type(6):before { content: "Price"; }
td:nth-of-type(7):before { content: "On Hand"; }
td:nth-of-type(8):before { content: "On Order"; }
td:nth-of-type(9):before { content: "Allocated"; }
td:nth-of-type(10):before { content: "Shipped"; }
td:nth-of-type(11):before { content: "Report"; }
td:nth-of-type(12):before { content: "RMA"; }
td:nth-of-type(10):before { content: "File"; }
td:nth-of-type(10):before { content: "Add Part"; }
}

Your problem isn't exactly what you're describing. In looking at your table in the "non-working example" fiddle, the result does not show a series of empty table cells - it shows no table cells.
Instead, you are outputting:
<td valign="top" colspan="10" class="dataTables_empty">No data available in table</td>
You're using a fairly clever CSS trick to display the column text before each one of your cells - which I applaud you for - but my impression is that you don't really understand how the CSS trick works, which is why you're having the error. Let me break it down for you, so it makes sense.
Your CSS is based around using the selector :nth-of-type(N) to prepend some content in front of a <td>. You have 9 columns in your grid: Company, Cust.No, Contact, Address, Phone, Email, File, Created Date and Notes.
When your page gets below a certain width, based on your media query, the following things happen:
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
This block moves the <thead> tag, containing your table's column headers, off of the screen's visible space (10,000px above and to the left of the viewable area).
table, thead, tbody, th, td, tr {
display: block;
}
td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
}
As the comment says, these blocks disable the default display: table CSS rendering of the table, and instead start forcing all of the elements contained therein to have block display - meaning that each new element will start on a new line by default. This is what causes your cells to appear on top of each other within a single row.
The padding-left: 50% on the <td> tags is what forces your data to display starting in the center of the table.
Now for the magic:
td:nth-of-type(1):before { content: "MFG P/N"; }
This line says... "for any <td> tag, if it is the (1)th <td> within its parent element, inject the text 'MFG P/N' into its :before pseudo-element."
The :before pseudo-element is a CSS construct which appears outside the DOM (you can't see it in the mark-up or by inspecting the page's elements) - but still renders on the screen. It renders inside the element it applies to (the <td>). The following CSS tells it how to display:
td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
In other words, within the position: relative <td> parent, position the :before pseudo-element 6px from the top edge, and 6px from the left edge, make it 45% as wide as the <td>, etc.
This is what injects the "header" in front of your rows.
Now for the problem:
Your HTML/JS is currently rendering the following HTML in your non-working example (simplified to show the important parts):
<table>
<thead><!-- omitted because it is off-screen --></thead>
<tbody>
<tr class="odd">
<td valign="top" colspan="10" class="dataTables_empty">
No data available in table
</td>
</tr>
</tbody>
</table>
Note that there is only one <td> inside your <tbody>. This is why you aren't displaying multiple rows with multiple prepended headers - there is only one <td> cell which your CSS is acting on.
If you want, instead, to display a series of empty boxes with the requisite header values, you will need to change the HTML output to the following:
<table>
<thead><!-- still omitted, because it still doesn't matter --></thead>
<tbody>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td><!-- 9 columns, to match your 9 headers -->
</tbody>
</table>
This will allow your CSS rules for the :nth-of-type(1) through :nth-of-type(9) to render the requisite headers properly, with the (non-breaking space) forcing the table to display the <td> tags in all browsers, by providing "invisible" content.
I hope this helps.
An additional note:
Your current CSS contains a bunch of junk that you don't need. Specifically:
td:nth-of-type(10):before { content: "Shipped"; }
td:nth-of-type(11):before { content: "Report"; }
td:nth-of-type(12):before { content: "RMA"; }
td:nth-of-type(10):before { content: "File"; }
td:nth-of-type(10):before { content: "Add Part"; }
The last 5 of your :nth-of-type rules. These will never be applied, using your current HTML layout - because you only have 9 columns in your table.
In addition - you have 3 separate rules that target :nth-of-type(10)... this means that even if you did have a 10th column, only the last of these rules ("Add Part") is going to be applied, as it will override both of the previous.

Related

How to have equal spacing between cell elements in table in mobile view?

I am working on a website in which I want to have equal spacing between cell elements in mobile view.
The HTML code for that particular section of code where I want equal spacing is:
HTML code:
<td id="gv-field-6-25" class="gv-field-6-25"></td>
<td id="gv-field-6-29" class="gv-field-6-29">2016</td>
CSS code:
The complete CSS code which I am using is in order to make cell elements is:
#media (max-width: 767px) {
.gv-container-2777 th {
display: none;
}
.gv-container-2777 tr + tr {
display: block;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
.gv-container-2777 td {
display: block;
margin-bottom: 5%;
margin-top: 7.9%;
}
.gv-container-2777 td::before {
display: block;
font-weight: bold;
margin-bottom: 1.6%;
}
.gv-container-2777 td:first-child::before {
content: 'Year Submitted';
}
.gv-container-2777 td:nth-child(2)::before {
content: 'Descriptive Title of Proposal:';
}
.gv-container-2777 td:nth-child(3)::before {
content: 'Name of Institution';
}
.gv-container-2777 td:nth-child(4)::before {
content: 'Awarded';
}
}
Problem Statement:
I am wondering what changes I should make in the CSS code (can't change the HTML code as its all coming from wordpress) so that there is equal spacing between elements before and after the border.
Attached are the screenshots where I want equal spacing before and after the border:
1st Image:
2nd Image:
3rd Image:
4th Image:
In the above screenshot the spacing is off before and after the border. I am wondering what changes I should make in the fiddle so that I can find equal spacing before and after the border.
Give margin-bottom and margin-top for .gv-container-2777 td same value.
.gv-container-2777 td {
margin-top: 5%;
margin-bottom: 5%;
}
Remove margin-bottom for .gv-container-2777 td::before

CSS mobile table display conflicts with empty table cells

I'm using the CSS below on a table in a site written in PHP (Drupal, but have also tried on another straight html table). This is used to make tables look a little more presentable on mobile devices. This is a modified version of the code at this link: https://css-tricks.com/responsive-data-tables/. When I render this table in any browser, the last row is getting messed up if there are empty values in it. Basically if there are empty values it will display all of the labels from the empty cells in the last row on top of one another right below the table. All of the prior rows hide the empty fields just fine. This table must be able to have empty values in it. Does anyone know how to hide those last row cells if they contain empty values?
#media
only screen and (max-width: 800px) {
table, thead, 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%;
}
td:before {
position: absolute;
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/*
Label the data
*/
td:nth-of-type(1):before { content: "Date"; }
td:nth-of-type(2):before { content: "Reg. Deadline"; }
td:nth-of-type(3):before { content: "Event Name"; }
td:nth-of-type(4):before { content: "File 1"; }
td:nth-of-type(5):before { content: "File 2"; }
td:nth-of-type(6):before { content: "File 3"; }
td:nth-of-type(7):before { content: "File 4"; }
}
If you need to hide it you can use :empty MDN link.
This stops the before pseudo element to be visible if the td is empty. You can use content:""too.
td:nth-of-type(1):empty:before,
td:nth-of-type(2):empty:before,
td:nth-of-type(3):empty:before,
td:nth-of-type(4):empty:before,
td:nth-of-type(5):empty:before,
td:nth-of-type(6):empty:before,
td:nth-of-type(7):empty:before{display:none}
UPDATE
with less css td:empty:before{display:none;}jsfiddle. You should add a class to your table and use it to make this css more specific so that you wont get into trouble in other td:before in your site. e.g. table.myvalues td:empty:before{display:none;}
If you find yourself out of time to find a more progressive solution..
Try popping a few of these in the empty table cells. (Non-breaking space)
More info:
http://www.sightspecific.com/~mosh/www_faq/nbsp.html

Bootstrap Layout Too Wide on Smart Phone

I'm trying to come up with an HTML/CSS layout for mobile devices. (It will likely be a separate website just for mobile devices, but I may be able to get away using a responsive site for both.)
I'm using Bootstrap, and found a layout that I'm implementing. You can see it at http://softcircuits.com/MediCorp/Menus.htm.
The problem is, when I load this page on my Android device (LG G2), the page is slightly wider than my display. So I can view the right side of the page only by scrolling horizontally.
I tried changing all of the container references to instead use container-fluid but it made no difference.
Does anyone know how I can make this page fit my device?
UPDATE:
Steven Wave has been helpful. He suggested some CSS to allow word wrapping. But A) the table still doesn't fit on my LG G2 (1080 x 1920 display), and B) why on Earth is word wrapping prevented by Bootstrap in the first place? Isn't Bootstrap responsive designed to work on cell phones?
Ok so here my last suggetion :)
Overrule again the default bootstrap attributes like:
#media screen and (max-width: 767px){
.table-responsive>.table>thead>tr>th, .table-responsive>.table>tbody>tr>th,
.table-responsive>.table>tfoot>tr>th, .table-responsive>.table>thead>tr>td,
.table-responsive>.table>tbody>tr>td, .table-responsive>.table>tfoot>tr>td {
word-break: break-word;
}
}
and you will be able to achieve your goal.
But i think this is a confusing table and it is not very readable. Because of this bootstrap decided to use the horizontal scrolling behavior. Just for readability.
Update Scaling:
There a several ways you can "scale".
CSS 3 transform: scale(x,y)
With several plugins to manipulate fontsizes eg.
Media Queries
In your case i would decide to use Media Queries so i manipulated your updated site with the Developer Tools
First i added ÌD's to the tables so i can easely overrule bootstrap and dont care about specificity.
<div class="container table-responsive">
<p>....</p>
<table class="table" id="tableA">....</table>
<table class="table table-striped table-condensed" id="tableB">....</table>
</div>
Then i created specific media queries for the points where the table widths become bigger then the viewport.
#media (max-width: "500px") {
#tableB td, #tableB th {
padding: 5px 2px;
font-size: 12px;
}
}
#media (max-width: "400px") {
.container {
padding-right: 5px;
padding-left: 5px;
}
#tableB td, #tableB th {
padding: 5px 2px;
font-size: 12px;
}
}
#media (max-width: "450px") {
#tableA td {
padding: 5px 2px;
font-size: 12px;
}
}
#media (max-width: "350px") {
#tableA td {
padding: 5px 1px;
font-size: 10px;
}
}
In this scenario it's all about space so i reduced the .container attributes as well go get more space.
Now you can resize your site down to 290px (whitch is absolutely ok - most mobile devices are now coverd) and the tables fit to the with.
275px!!
The tabel headers of the second table are very close together but it's also ok i think.
290px!!
Ok know the font-size is smal but there is also the posibility the scale the content trough the smartphone.
Hope that will help!
The problem comes up with your table! You can resolve this with adding the table-responsive attribute to your 'container' div which includes both tables!!
UPDATE:
<div class="container table-responsive">
<p>....</p>
<table class="table">....</table>
<table class="table table-striped table-condensed">....</table>
</div>
A better way is to wrapp only the tables and not the hole content!
Have a look at the bootsrap DOCUMENTATION
UPDATE:
Here the final bootstrap specific solution:
<div class="container">
<p>....</p>
<div class="table-responsive">
<table class="table">....</table>
</div>
<div class="table-responsive">
<table class="table table-striped table-condensed">....</table>
</div>
</div>
This will avoid the empty space at the second table. In general the bootstrap responsive table is fluid as long as the td content does not fill the space. When the content is longer then the horicontal scrolling for the table appears. This is the typical behavior!
If you realy DON'T want that you should go a nother way! Thera are plenty of diffrent solutions for responsive tables out there like THIS
Maybe you find one that fitts your needs!
Overrule the bootsrap attributes from white-space: nowrap; to normal:
#media screen and (max-width: 767px)
.table-responsive>.table>thead>tr>th,
.table-responsive>.table>tbody>tr>th,
.table-responsive>.table>tfoot>tr>th,
.table-responsive>.table>thead>tr>td,
.table-responsive>.table>tbody>tr>td,
.table-responsive>.table>tfoot>tr>td {
white-space: normal;
}
So the tables fit down to 430px. For all smaler devices the scrolling appears.
for positioning example :
<div class="col-sm-12">
<div class="col-sm-6">
column 1
</div>
<div class="col-sm-6">
column 2
</div>
</div>
can use this for tr and td also
Here is solution that change N-columns table to list of properties for screen that width is less than 1000px:
<style>
#media only screen and (max-width: 1000px) {
#userManageTable {
margin-top: 16px;
}
#userManageTable, #userManageTable thead, #userManageTable tbody,
#userManageTable th, #userManageTable td, #userManageTable tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
#userManageTable thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
#userManageTable tbody tr {
border: 1px solid #ccc;
}
#userManageTable tbody td {
/* Behave like a "row" */
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
height: 49px;
width: 100%;
}
#userManageTable tfoot {
width: 100%;
}
#userManageTable tfoot td {
/* Behave like a "row" */
border: none;
position: relative;
height: 49px;
width: 100%;
}
#userManageTable tbody td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/*
Label the data
*/
#userManageTable tbody td:nth-of-type(1):before {
content: "Imię";
}
#userManageTable tbody td:nth-of-type(2):before {
content: "Nazwisko";
}
#userManageTable tbody td:nth-of-type(3):before {
content: "Login";
}
#userManageTable tbody td:nth-of-type(4):before {
content: "Aktywność";
}
#userManageTable tbody td:nth-of-type(5):before {
content: "";
}
#userManageTable tbody td:nth-of-type(6):before {
content: "";
}
#userManageTable tbody td:nth-of-type(7):before {
content: "";
}
#userManageTable tbody td:nth-of-type(8):before {
content: "";
}
#userManageTable tbody td:nth-of-type(9):before {
content: "";
}
#userManageTable tbody td:nth-of-type(10):before {
content: "";
}
}
</style>
It works with default Bootstrap v.3 CSS.
Just give it id = "userManageTable".

CSS responsive tables

I'm going out of my mind becouse of this. I'm trying to make tables responsive on mobile using only CSS and HTML. Searched google and stackoverflow for hours and still no idea how to grab this problem. Tried different methods and still nothing. Tried div tables and normal.
ok here it goes, i'm trying to make this table > http://postimg.org/image/62upgmozv/ transform via media query 480px into this > http://postimg.org/image/5brtspn5x/
colors and names are important. I need just a suggestion or idea how to solve this. main problem for me is to make div table with separate div for DATE(orange) and then sort it for mobile(see second pic) and then repeat with next date.
You can look at an example I have made of this: http://www.f1time.com/mobile/
I dont have a code from your table, so I thought I'd share the one I did for that functionality.
#media only screen and (max-width: 500px) {
/* Force table to not be like tables anymore */
table, thead, tbody, th, td, tr {
display: block;
}
/* Hide table headers (but not display: none;, for accessibility) */
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr { border: 1px solid #ccc; }
td {
/* Behave like a "row" */
border: none;
position: relative;
padding-left: 50%;
}
td:before {
/* Now like a table header */
position: absolute;
/* Top/left values mimic padding */
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
}
/*
Label the data
*/
td:nth-of-type(1):before { content: "Current Position"; }
td:nth-of-type(2):before { content: "Position Change"; }
td:nth-of-type(3):before { content: "Manager"; }
td:nth-of-type(4):before { content: "Lap"; }
td:nth-of-type(5):before { content: "Gap"; }
td:nth-of-type(6):before { content: "Gap to Front"; }
td:nth-of-type(7):before { content: "Lap Time"; }
td:nth-of-type(8):before { content: "Fastest"; }
td:nth-of-type(9):before { content: "Pits"; }
td:nth-of-type(10):before { content: "Status"; }
}

CSS: Labels in table columns

BACKGROUND:
I would like to have small labels in columns of a table.
I'm using some implemented parts of HTML5/CSS3 in my project, and this section specifically is for mobile devices. While both facts are not necessarily relevant, the bottom line is that I don't have to support Internet Explorer or even Firefox for that matter (just WebKit).
THE PROBLEM
With my current CSS approach, the vertical padding of the cell comes from the <span> element (set to display: block with top/bottom margins), which contains the "value" of the column. As a result there's no padding when the <span> is empty or missing (no value) and the label is not in place.
The "full" coulmns should give you the idea of where I want the labels to be, even if there's no value, and the <span> is not there.
I realize that I could use "non-breaking-space", but I would really like to avoid it.
I wonder if any of you have a fix / better way to do this? current code is below.
<!DOCTYPE html>
<html lang="en">
<head>
<title>ah</title>
<style>
body {
width: 320px;
}
/* TABLE */
table { width: 100%; border-collapse: collapse; font-family: arial; }
th, td { border: 1px solid #ccc; border-width: 0px 0px 1px 1px; }
th:last-child, td:last-child { border-right-width: 1px; }
tr:first-child th { border-top-width: 1px; background: #efefef; }
/* RELEVANT STUFF */
td {
padding: 3px;
}
td sup {
display: block;
}
td span {
display: block;
margin: 3px 0px;
text-align: center;
}
</style>
</head>
<body>
<table>
<tr>
<th colspan="3">something</th>
</tr>
<tr>
<td><sup>some label</sup><span>any content</span></td>
<td><sup>some label</sup><span>any content</span></td>
<td><sup>some label</sup><span></span></td><!-- No content, just a label -->
</tr>
</table>
</body>
</html>
As above, you can use:
td {
padding: 3px;
vertical-align:top;
}
If you wanted to retain the padding exactly, even on the invisible elements, you can force the hasLayout attribute on the empty span using:
td {
padding: 3px;
vertical-align:top;
}
td sup {
display: block;
}
td span {
display: inline-block;
margin: 3px 0px;
text-align: center;
width:100%;
}
The inline-block technique is discussed extensively at Drawing empty inline boxes in CSS?