Responsive First Column in a Responsive Table - html

The first column of six columns table filled with various length of content. I want to make it responsive with only one row, cutted by overflow hidden and ellipsis, while maintain the table still responsive in mobile viewport with 100% width.
My code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
table {
max-width: 100%;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #ddd;
}
th, td {
text-align: left;
padding: 8px;
}
td {
width: 50%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 10px;
}
tr:nth-child(even){background-color: #f2f2f2}
</style>
</head>
<body>
<h2>Responsive Table</h2>
<div style="width: 100%;">
<table>
<tr>
<th>Content</th>
<th>Name</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
</tr>
<tr>
<td>around the table, and it will display a horizontal scroll bar when needed</td>
<td>Smith</td>
<td>50</td>
<td>50</td>
<td>50</td>
<td>50</td>
<td>50</td>
</tr>
<tr>
<td>Eve Resize the browser window to see the effect. Try to remove the div element and see what happens to the table</td>
<td>Mike</td>
<td>94</td>
<td>94</td>
<td>94</td>
<td>94</td>
<td>94</td>
</tr>
<tr>
<td>Adam that is too wide, you can add a container element with overflow-x:auto around the table</td>
<td>Johnson</td>
<td>67</td>
<td>67</td>
<td>67</td>
<td>67</td>
<td>67</td>
</tr>
</table>
</div>
</body>
</html>
The code above makes the table become not responsive and failed to resize the first column as expected.
jsfiddle
Any help is highly appreciated.

The secret lies in display: block; ellipsis only applies to block-level elements. As such, you'll want to add the following rules to the relevant <td> elements:
display: block;
width: 100px; /* However wide you want the cell to be before ellipsis */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
This should only be applied to the first <td> element in each row, so you can use the selector td:first-of-type.
This can be seen in the following:
table {
max-width: 100%;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #ddd;
}
th,
td {
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #f2f2f2
}
td:first-of-type {
display: block;
width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<h2>Responsive Table</h2>
<div style="width: 100%;">
<table>
<tr>
<th>Content</th>
<th>Name</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
</tr>
<tr>
<td class="ellipsis">around the table, and it will display a horizontal scroll bar when needed</td>
<td>Smith</td>
<td>50</td>
<td>50</td>
<td>50</td>
<td>50</td>
<td>50</td>
</tr>
<tr>
<td>Eve Resize the browser window to see the effect. Try to remove the div element and see what happens to the table</td>
<td>Mike</td>
<td>94</td>
<td>94</td>
<td>94</td>
<td>94</td>
<td>94</td>
</tr>
<tr>
<td>Adam that is too wide, you can add a container element with overflow-x:auto around the table</td>
<td>Johnson</td>
<td>67</td>
<td>67</td>
<td>67</td>
<td>67</td>
<td>67</td>
</tr>
</table>
</div>
Note that you'll want to use pixel-based units rather than percentages, as with percentage the ellipsis will take effect, but the cell itself will still occupy 100% of the width.

Applying the style class below to your table cell individually should make the texts clip.
<style>
.clipText{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
.clipText:hover{
white-space: pre-wrap;
overflow: visible;
text-overflow: normal;
word-break: break-all;
}
</style>
and i would suggest if your trying to make a responsive table use css media query and display the table elements as blocks for small screens and arrange them as you see fit and a little js dom manipulation can also make it better using screen size as a condition.
<style type="text/css">
#media screen and (max-width: 520px){
table, th, tr, td{
display: block;
}
table tr:first-child{
display: none;
}
table tr:nth-child(even){
background-color: royalblue;
position: relative;
margin: 2% 0%;
}
table tr:nth-child(odd){
background-color: grey;
position: relative;
margin: 2% 0%;
}
table tr:nth-child(even) td{
color: white;
font-weight: bolder;
}
table tr:nth-child(odd) td{
color: black;
font-weight: bolder;
}
table td:nth-child(1)::before{
content: "Content: ";
}
table td:nth-child(2)::before{
content: "Name: ";
}
table td:nth-child(3)::before{
content: "Points: ";
}
table td:nth-child(4)::before{
content: "Points: ";
}
table td:nth-child(5)::before{
content: "Points: ";
}
table td:nth-child(6)::before{
content: "Points: ";
}
table td:nth-child(7)::before{
content: "Points: ";
}
}
</style>
to see the effects of the style above reduce/ minimize your browser size/width.

Finally I figured out how to solve this problem.
The secret is to make 2 different position within the TD that contain ellipsis text. This can be done by adding a new span element within the TD with position:absolute, while the TD itself use position:relative.
STEPS:
Style all TD with white-space:nowrap;
Style first TD with width:100% and position:relative
Style the span element within the TD with position:absolute; overflow: hidden; text-overflow: ellipsis; left: 0; right: 0;
Complete code on my working solution:
html, body {
margin: 0;
padding: 0;
font-family: sans-serif; */
}
table {
max-width: 100%;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #ddd;
display: table;
table-layout: auto;
}
th, td {
text-align: left;
padding: 8px;
}
td {
white-space: nowrap;
margin-bottom: 10px;
}
td:nth-child(1) {
width: 100%;
position: relative;
}
td:nth-child(1):not(:empty)::after {
/* Prevent row from collapsing vertically if the first column is empty */
content: '';
display: inline-block;
}
td:nth-child(1) > span {
position: absolute;
left: 0;
right: 0;
overflow: hidden;
text-overflow: ellipsis;
}
tr:nth-child(even){background-color: #f2f2f2}
<h2>Responsive Table</h2>
<div style="width: 100%;">
<table>
<tr>
<th>Content</th>
<th>Name</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
<th>Points</th>
</tr>
<tr><td><span>overflow-x:auto around the table, and it will display a horizontal scroll bar when needed</span></td> <td><span>Smith</span></td> <td><span>50</span></td> <td><span>50</span></td> <td><span>50</span></td> <td><span>50</span></td> <td><span>50</td>
</tr>
<tr><td><span>Eve Resize the browser window to see the effect. Try to remove the div element and see what happens to the table</span></td> <td><span>Mike</span></td> <td><span><span>94</span></span></td> <td><span><span>94</span></span></td> <td><span><span>94</span></span></td> <td><span><span>94</span></span></td> <td><span><span>94</span></td>
</tr>
<tr><td><span>Adamthat is too wide, you can add a container element with overflow-x:auto around the table</span></td> <td><span>Johnson</span></td> <td><span>67</span></td> <td><span>67</span></td> <td><span>67</span></td> <td><span>67</span></td> <td><span>67</td>
</tr>
</table>
</div>

Related

Make a div fill up the entire width and height of a table cell with unspecified dimensions

table, th, td, div {
font-family: Arial;
padding: 1em;
border-style: solid;
border-collapse: collapse;
text-align: center;
}
div {
writing-mode: vertical-rl;
background-color: #ddd;
border-color: #bbb;
}
<table>
<tr>
<td>one</td> <td>two</td> <td>three</td>
</tr>
<tr>
<td rowspan="2"> <div>four</div> </td>
<td>five</td> <td>six</td>
</tr>
<tr>
<td>seven</td> <td>eight</td>
</tr>
</table>
The desired result is for the div in the table cell to look more like
this:
Notice the "four" div fills the entire width and height of the table cell in the image but not in the code snippet.
There are questions similar to this that suggest using absolute positioning which doesn't work in this exact situation ( per my attempts ) on a table with unspecified width and height. Other answers say there is no way to do this without JavaScript. But those answers were from 2010. Any input would be much appreciated.
if you are okay with a few classes then you can achieve what you shown in the image.
table,
th,
td,
div {
font-family: Arial;
padding: 1em;
border-style: solid;
border-collapse: collapse;
text-align: center;
}
.spl {
writing-mode: vertical-rl;
border-style: none;
}
.inb {
background-color: #ddd;
}
<table>
<tr>
<td>one</td>
<td>two</td>
<td>three</td>
</tr>
<tr>
<td rowspan="2" class="inb">
<div class="spl">four</div>
</td>
<td>five</td>
<td>six</td>
</tr>
<tr>
<td>seven</td>
<td>eight</td>
</tr>
</table>
You could use jQuery as follows to get the (outer) width and height of that parent td and apply it to that div
$(document).ready(function() {
var cellwidth1 = $('.x1').outerWidth();
var cellheight1 = $('.x1').outerHeight();
$('.x2').css({
'height': cellheight1,
'width': cellwidth1
});
});
* {
box-sizing: border-box;
}
table, th, td, div {
font-family: Arial;
padding: 1em;
border-style: solid;
border-collapse: collapse;
text-align: center;
}
td.x1 {
padding: 0;
}
div.x2 {
writing-mode: vertical-rl;
background-color: #ddd;
border-color: #bbb;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>one</td> <td>two</td> <td>three</td>
</tr>
<tr>
<td class="x1" rowspan="2"> <div class="x2" >four</div> </td>
<td>five</td> <td>six</td>
</tr>
<tr>
<td>seven</td> <td>eight</td>
</tr>
</table>
After trying many things it seems that as of 2020 stretching a div to fill all the available space of a table cell without JavaScript is not possible unless you use absolute/relative positioning.
The downside with absolute positioning is that the cell does not expand with the content inside it and even not expanded the table cell seems to break on mobile ( tested with an iphoneXS on IOS14 )
dev-sbx.github.io/x
The only real solution here seems to be using a CSS Grid layout opposed to an HTML table.

What is the best way to style a vertical table with split background

How can I organize and style this data on a split background using css and html?
that layout of yours (if that's what you want right?), you need to collapse your table border for that, to avoid white gaps. add a special class for tr that represents the thead and style it accordingly. follow the pattern with <tr><th></th><td></td></tr>. use text-align to center them with right to th and left to td.
td, th {
padding: 8px;
font-size: 12px;
width: 250px;
}
th { background: #E9EADA; text-align: right; }
td { background: #FCFCFC; text-align: left; }
.table-header > * {
font-size: 16px;
color: #238E98;
}
table { border-collapse: collapse; }
<table>
<tr>
<th>First name</th>
<td>John</td>
</tr>
<tr>
<th>Last Name</th>
<td>Doe</td>
</tr>
<tr class="table-header">
<th>Details</th>
<td>---</td>
</tr>
<tr>
<th>Age</th>
<td>33</td>
</tr>
</table>

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.

Fixed first column table first column disappears after td resize in firefox

I have a table with fixed first column which will allow me to scroll the table columns left and right while keeping the first column in place.
(Entire table is in the wrapper that gives me the scrollbar as table is always wider than the wrapper.)
Table also has a toggle button on the header to show extra data in some td's.
When using Firefox, scrolling table to the right and then clicking the toggle button the entire first column disappears ...and this happens only in Firefox.
How to fix that?
Here is the fiddle
HTML
<div class="da-fixed-column-table-wrapper" data-ng-app="testModule" data-ng-controller="testController">
<table class="da-fixed-column-table" border=1>
<thead>
<tr>
<th>
<button ng-click="show=!show">show-hide</button>
</th>
<th>Header2</th>
<th>Header3</th>
<th>Header4</th>
<th>Header5</th>
</tr>
</thead>
<tbody>
<tr>
<td>first</td>
<td>second</td>
<td>third</td>
<td>fourth</td>
<td>fifth<span ng-show="show">more data</span></td>
</tr>
<tr>
<td>first</td>
<td>second</td>
<td>third<span ng-show="show">more data</span></td>
<td>fourth</td>
<td>fifth</td>
</tr>
</tbody>
</table>
</div>
CSS
.da-fixed-column-table-wrapper {
width: 100%;
overflow: auto;
box-sizing: border-box;
background: DarkKhaki;
}
.da-fixed-column-table {
width: 120%;
border-collapse: collapse;
box-sizing: border-box;
text-align: right;
}
.da-fixed-column-table tbody tr td:first-child,
.da-fixed-column-table thead tr th:first-child {
position: absolute;
border: none;
top: auto;
width: 8em;
text-align: left;
background: white;
}
.da-fixed-column-table thead tr th:nth-child(2),
.da-fixed-column-table tbody tr td:nth-child(2) {
padding-left: 9em;
}
You just need to add left: 0 to make sure the elements stick correctly. The change in width caused it move out of view.
.da-fixed-column-table tbody tr td:first-child,
.da-fixed-column-table thead tr th:first-child {
position: absolute;
border: none;
top: auto;
width: 8em;
text-align: left;
background: white;
left: 0;
}

HTML table with whitespace nowrap

Hey I was wondering if you can have a HTML table and make certain columns have whitespace: nowrap and the other columns that have whitespace: normal?
Example:
<table>
<thead>
<tr>
<th>No wrap</th>
<th>Wrap</th>
</tr>
</thead>
<tbody>
<tr>
<td>Small text</td>
<td>Wrap this longgggg text</td>
</tr>
</tbody>
</table>
CSS white-space is normal by default, so all you need is to set it to nowrap for some of the columns. One way is to add a class to them, as:
<td class="my_nowrap">this won't wrap</td>
<style>
.my_nowrap {
white-space: nowrap;
}
</style>
Other way would be to use CSS3 nth-child selector and (without setting classes) target some of the columns, as:
<style>
td:nth-child(2),
td:nth-child(3) {
.my_nowrap {
white-space: nowrap;
}
</style>
The above would set 2nd and 3rd column to nowrap.
Yes this is possible. Take a look at the example below.
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
tr.wrap {
width: 50px;
}
th.wrap, td.wrap {
background: red;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 10px;
}
<table style="width:100%">
<tr>
<th class='wrap'>Name</th>
<th colspan="2">Telephone</th>
</tr>
<tr>
<td class='wrap'>Bill Gates</td>
<td>555 77 854</td>
<td>555 77 855</td>
</tr>
</table>