HTML table leaving open gaps when hiding cells - html

The example below contains two tables, and each table includes two sections. Both tables and sections are structurally the same.
When the cells in the first table that are marked with class ".to-hide" are hidden by changing this class to ".hide" (shown in the second table), the resulting layout of the second table appears inconsistent; the cell "4" in the first section closes all gaps left by the hidden cells, but cell "4" in the second section leaves open gaps.
On Chrome 68.0.3440.106, the code snippet below shows how one cell "4" fill open gaps, but the other cell "4" does not. On Firefox 60.0.2, both cells "4" leave open gaps. The image below is taken on Chrome 68.
How can I ensure that visible cells in the table cover any gaps left by hidden cells, consistently, across browsers?
/* Styles to mark and hide marked cells. */
.to-hide { background-color: lightgray; }
.hide { display: none; }
/* Styles to make the tables in the code snippet look pretty. */
.left { display: inline-block; }
.right { display: inline-block; margin-left: 20px; }
table { background-color: yellow; }
td { padding: 0 1em; background-color: white; border: solid 1px gray; }
<div class="left">
Original table:
<table>
<tbody>
<tr>
<td rowspan="3">1</td>
<td rowspan="2">.<br/>2<br/>.</td>
<td class="to-hide">3</td>
<td>4</td>
</tr>
<tr>
<td class="to-hide">a</td>
<td class="to-hide">b</td>
</tr>
<tr>
<td colspan="3">A</td>
</tr>
<tr>
<td colspan="4">i</td>
</tr>
<tr>
<td rowspan="3">1</td>
<td rowspan="2">.<br/>2<br/>.</td>
<td class="to-hide">3</td>
<td>4</td>
</tr>
<tr>
<td class="to-hide">a</td>
<td class="to-hide">b</td>
<tr>
<td colspan="3">A</td>
</tr>
<tr>
<td colspan="4">i</td>
</tr>
</tbody>
</table>
</div>
<div class="right">
Shaded cells hidden (notice cells "4"):
<table>
<tbody>
<tr>
<td rowspan="3">1</td>
<td rowspan="2">.<br/>2<br/>.</td>
<td class="hide">3</td>
<td>4</td>
</tr>
<tr>
<td class="hide">a</td>
<td class="hide">b</td>
</tr>
<tr>
<td colspan="3">A</td>
</tr>
<tr>
<td colspan="4">i</td>
</tr>
<tr>
<td rowspan="3">1</td>
<td rowspan="2">.<br/>2<br/>.</td>
<td class="hide">3</td>
<td>4</td>
</tr>
<tr>
<td class="hide">a</td>
<td class="hide">b</td>
<tr>
<td colspan="3">A</td>
</tr>
<tr>
<td colspan="4">i</td>
</tr>
</tbody>
</table>
</div>

By hiding cells "a" and "b" rowspan="3" of cell "1" wants to occupy the same area like cell "i". Cell "i" can not span 3 rows since there are only 3 rows left and on the last row spans cell "i" all columns.
Forcing hidden cells to a size of 0 does not help.
.hide {
visibility: hidden;
width: 0;
height: 0;
padding: 0;
}
Taking hidden cells out of flow by position: absolute does not help either.
That the first section of the table still looks good (no gaps) must be some kind of error correction by browser.
Only by removing hidden cells from the table and changing the values for rowspan and colspan I was able to achieve the intended distribution of cells.
<tr>
<td rowspan="2">1</td>
<td>.<br/>2<br/>.</td>
<td>4</td>
</tr>
<tr>
<td colspan="2">A</td>
</tr>
<tr>
<td colspan="3">i</td>
</tr>

Related

How would I achieve a horizontal and vertical hover effect up to a hovered element in a table: How do I create an intersecting hover?

I have a table which has a vertical and horizontal title ("Initial Gravity" and "Final Gravity" respectively), I have a hover effect on my elements, but what I would really like is for my hover to intersect in a manner similar to that shown in the image.
I've used red rectangles in the image purely for representation purposes, I'm hoping to use the same hover as is seen on the hovered element, so the result I'm looking to achieve is a purple bar across the row and a purple bar down the column intersecting on the element the user is hovering over.
If code is needed to help get help, please let me know what code you need to see. The table is a monster at 56 rows and 28 cols so not sure if I should add the entire code or just a snippet.
.card-body table{
width:100%;
}
.blank-cell, th{
background: #000;
color: #fff;
}
td {
text-align: center;
}
th{
background: #000;
color: #fff;
}
td:hover {
background: #530288;
color:white;
}
<table>
<thead>
<tr>
<th></th>
<th></th>
<th>
<div><strong>Final Gravity</strong></div>
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="row-2">
<td class="blank-cell"></td>
<td class="tooltip"></td>
<td class="tooltip">0.990</td>
<td class="tooltip">0.992</td>
<td class="tooltip">0.994</td>
</tr>
<tr class="row-3">
<td class="blank-cell"><strong>Initial Gravity</strong></td>
<td class="tooltip">1.020</td>
<td class="tooltip">3.9</td>
<td class="tooltip">3.7</td>
<td class="tooltip">3.4</td>
</tr>
<tr class="row-4">
<td class="blank-cell"></td>
<td class="tooltip">1.022</td>
<td class="tooltip">4.2</td>
<td class="tooltip">3.9</td>
<td class="tooltip">3.7</td>
</tr>
<tr class="row-5">
<td class="blank-cell"></td>
<td class="tooltip">1.024</td>
<td class="tooltip">4.5</td>
<td class="tooltip">4.2</td>
<td class="tooltip">3.9</td>
</tr>
</tbody>
</table>

Aligning both rows and columns in a nested table

I am trying to process an XML file via XSLT to produce an HTML report. The report contains a table with 3 columns: Description, Date and Note. One row of this table may contain one description, but multiple dates and notes. The dates and notes for a single description form pairs, but sometimes either a date or a note is missing. I could have the following problems:
A note does not have a corresponding date, so the date-note pair representation is skewed (See Date 1.2 and Note 1.2 in the example). A desired representation would have an empty line followed by Date 1.2 on a different line.
A note spans multiple lines, but its corresponding date does not, so the following notes are not aligned with their dates.
Here is an example. I used <br/> elements for demonstration purposes.
<table>
<tr>
<td class="firstcolumn">Description</td>
<td>Date</td>
<td class="lastcolumn">Note</td>
</tr>
<tr>
<td class="firstcolumn">Description 1. Could span multiple lines.</td>
<td valign="top" align="right">Date 1.2</td>
<td valign="top" align="right" class="lastcolumn">Note without date 1.1<br/> Note 1.2</td>
</tr>
<tr>
<td class="firstcolumn">Description 2.</td>
<td valign="top" align="right">Date 2.1<br/> Date 2.2</td>
<td valign="top" align="right" class="lastcolumn">Some really long note<br/>spanning multiple lines 2.1<br/> Note 2.2</td>
</tr>
</table>
Here is a link to a fiddle: JSFiddle.
I tried to solve this with nested tables: for each row of the outer table, I created a nested table with 2 columns, each row of which contained a date-note pair (or an empty cell and a note). The dates and notes now align. However, the nested table column widths do not align across the rows of the outer table. I tried to solve this by setting all nested table widths using the styles
table { width:100%;table-layout:fixed;} /* for each nested table */
td {width:90px;} /* for the columns of nested tables */
The columns now align. However, sometimes the notes are cut off and not visible (using the overflow style I can make them appear outside the table border, but it looks ugly). Ideally, I would want to have column widths that adjust to the notes' lengths.
I think I made it!
What I did is:
I broke the 2nd and 3rd rows in two
to the first one I gave rowspan="2"
I created two classes: bt and bb
table {
border-collapse: collapse;
width: 75%;
}
td {
border-collapse: collapse;
border: 1px solid black;
padding: 0px;
margin: 0px;
font-family: Calibri;
}
td.firstcolumn {
width: 60%;
}
td.lastcolumn {
width: 25%;
}
.bt {
border-top: 0;
}
.bb {
border-bottom: 0;
}
<table>
<tr>
<td class="firstcolumn">Description</td>
<td>Date</td>
<td class="lastcolumn">Note</td>
</tr>
<tr>
<td rowspan="2" class="firstcolumn">Description 1. Could span multiple lines.</td>
<td class="bb" valign="top" align="right"></td>
<td class="bb" valign="top" align="right">Note without date 1.1</td>
</tr>
<tr>
<td class="bt" valign="top" align="right">Date 1.2</td>
<td class="bt" valign="top" align="right" class="lastcolumn"> Note 1.2</td>
</tr>
<tr>
<td rowspan="2" class="firstcolumn">Description 2.</td>
<td class="bb" valign="top" align="right">Date 2.1</td>
<td class="bb" valign="top" align="right" class="lastcolumn">Some really long note<br/>spanning multiple lines 2.1</td>
</tr>
<tr>
<td class="bt" valign="top" align="right"> Date 2.2</td>
<td class="bt" valign="top" align="right" class="lastcolumn">Note 2.2</td>
</tr>
</table>
Here's a fiddle
Assuming that you need to adjust width automatically based on contents try changing in example provided here
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_td_width
<!DOCTYPE html>
<html>
<head>
<style>
table,th,td
{
border:1px solid black;
}
</style>
</head>
<body>
<table style="width:100%">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td width="70%">January</td>
<td width="30%">$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</table>
<p>The width attribute is not supported in HTML5. Use CSS instead.</p>
</body>
</html>

Strange behaviour with border-collapse and colspan

I am trying to make an organisational chart in HTML. The code is fairly simple, but I have some problems with the rendering in Chrome/Safari and Opera.
Here is what the result should look like, as it works in Firefox and IE:
Here is in Chrome and Safari
And here is in Opera:
The problem comes from the border-collapse: collapse property in CSS. If I use the old coding style cellspacing="0" cellpadding="0"it works more or less, but is not valid in HTML5.
I created a jsFiddle to show the problem: http://jsfiddle.net/aGVp4/7/
My HTML:
<table cellspacing="0" cellpadding="0">
<tr>
<td colspan="3"></td>
<td colspan="2" class="case"></td>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="3"></td>
<td colspan="2" class="case"></td>
<td colspan="3"></td>
</tr>
<tr>
<td></td>
<td colspan="3" class="right bottom"></td>
<td colspan="3" class="bottom"></td>
<td></td>
</tr>
<tr> <!-- No colspan here, to make the layout symmetrical -->
<td class="right"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="right"></td>
<td></td>
</tr>
<tr>
<td colspan="2" class="case"></td>
<td colspan="4"></td>
<td colspan="2" class="case"></td>
</tr>
</table>
And my CSS:
.orgchart {
border-spacing: 0;
border-collapse: collapse;
}
td {
width: 3em;
height: 1em;
}
td.case {
border: 1px solid black;
}
td.right {
border-right: 1px solid black;
}
td.bottom {
border-bottom: 1px solid black;
}
td.top {
border-top: 1px solid black;
}
The problems seems to be caused by different interpretations of the collapsing border model in browsers. The border conflict resolution is defined in terms of cells, not slots, and when you use colspan=3, one cell spans 3 slots.
The 2nd cell of the 2nd row has a solid bottom border, and the 2nd cell of the 3rd row has no top border. When borders collapse, solid wins none. But the cells are only partially adjacent, as they span different columns. Browsers hand this differently. Chrome makes the border span all the columns of the upper cell, whereas Firefox makes the border span only one column, the one that the cells share – which is more reasonable, but CSS 2.1 seems to leave the issue open.
I tried playing with border: hidden, which helps on Chrome but causes new problems on Opera.
It seems that there are two options. You could use the HTML attributes, if they do the job. Though declared obsolete and forbidden in HTML5 CR, the same document also requires continued support to them in browsers.
But a cleaner, and perhaps more robust, approach is to avoid the problem by adding more empty cells. This means dividing two 3rd row cells into two cells so that only one of them shares a border with the cell of the 2nd row. This makes the table even more grid-like, but not essentially more complex:
<table class="orgchart">
<tr>
<td colspan="3"></td>
<td colspan="2" class="case"></td>
<td colspan="3"></td>
</tr>
<tr>
<td colspan="3"></td>
<td colspan="2" class="case" ></td>
<td colspan="3"></td>
</tr>
<tr>
<td></td>
<td colspan="2" class="bottom"></td>
<td class="right bottom"></td>
<td class="bottom" ></td>
<td colspan="2" class="bottom" ></td>
<td></td>
</tr>
<tr> <!-- No colspan here, to make the layout symmetrical -->
<td class="right"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="right"></td>
<td></td>
</tr>
<tr>
<td colspan="2" class="case"></td>
<td colspan="4"></td>
<td colspan="2" class="case"></td>
</tr>
</table>
Add a new empty row <tr></tr> under the colspan will fix this problem (not a beautiful solution but works).
I played with your jsfiddle, and found a hack to fix the issue in Chrome and Safari.
Also works on FF and IE, but didn't test on Opera.
Try this (jsfiddle):
td.bottom {
border-top: 1px solid white; // this is the hack
border-bottom: 1px solid black;
}
td.right.bottom {
border-top: none; // fix for IE
}
As this is a hack, it may not work as your chart grows complex, but hope this helps in short-term.

HTML Table Styling

I'm encountering a problem when styling an dynamic generated table. The user can choose how many columns there have to be, some of them have got a fixed length. How can I let the other give a percentage of the space left, without having to specify the exact width of the columns every time AND without ending up with different column widths with different data/different browsers?
Example:
<style type="text/css">
table{
width:800px;
border:1px solid #CCCCCC;
/* table-layout: fixed; */
}
table td {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
border:1px solid #EEEEEE;
}
table tbody td.active{
text-align:center;
width:100px; /* fixed */
}
table tbody td.option{
width:100px; /* fixed */
}
table tbody td.nonfixed{
width:auto;
}
</style>
<table>
<thead>
<tr>
<td>Name</td>
<td>Description</td>
<td>Active</td>
<td colspan="2">Options</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="5">+ Add new row<td>
</tr>
</tfoot>
<tbody>
<tr>
<td class="nonfixed">[Name 1]</td>
<td class="nonfixed">[Description 1]</td>
<td class="active">[X]</td>
<td class="option">Edit</td>
<td class="option">Delete</td>
</tr>
<tr>
<td class="nonfixed">[Name 2]</td>
<td class="nonfixed">[Description 2]</td>
<td class="active">[0]</td>
<td class="option">Edit</td>
<td class="option">Delete</td>
</tr>
</tbody>
</table>
In the example both "nonfixed" columns should have the exact same width. This should also work when the user adds a nonfixed column or switches the first column with the last etc.
Who's able to help me out?
I see two possible approaches... either use a script to calculate the flexible-width columns' widths and average them, or use nested tables to split the two flex cols at 50%:
<table>
<tr>
<td class="fixed"></td>
<td class="fixed"></td>
<td class="fixed"></td>
<td class="flex-wrapper">
<table width="100%">
<tr>
<td width="50%"></td>
<td width="50%"></td>
</tr>
</table>
</td>
</tr>
</table>

A way to group table cells together in html?

So it is pretty straight forward. I need a way to group cells together. Like a <div> or a <span> but none of them worked. <tbody> seemed like a good solution but it only works for table rows. Help!
If you're looking for a way to merge 2 o more cells in a row into one single cell, along with other "regular" cells (as you would do in a google|excel spreadsheet) in a way similar to this:
then you can use the colspan attribute for td elements, indicating how many cells are you merging:
<tr>
<td colspan=2> Merged Cell occupying 2 columns </td>
</tr>
<tr>
<td> Regular cell </td>
<td> Another cell in same row </td>
</tr>
Additionally, you can use the td[colspan] selector in css (combined with any parent selector of your choice) to refer to these merged cells.
Here's a working example:
/* Style for cells with any colspan attribute */
td[colspan] {
text-align: center;
}
/* No extra space between cells */
table {
border-collapse: collapse;
}
th, td {
border: 1px solid gray;
margin: 0;
padding: 3px 10px;
text-align: right;
}
<table>
<tr>
<th>Day</th>
<th>Invoice</th>
<th>Total</th>
</tr>
<tr>
<!-- this cell will occupy 3 columns -->
<td colspan=3>January</td>
</tr>
<tr>
<td>2</td>
<td>0348</td>
<td>248.35</td>
</tr>
<tr>
<td>7</td>
<td>0349</td>
<td>126.14</td>
</tr>
<tr>
<td>18</td>
<td>0350</td>
<td>821.99</td>
</tr>
<tr>
<td colspan=3>February</td>
</tr>
<tr>
<td>27</td>
<td>0351</td>
<td>643.50</td>
</tr>
</table>
You can add the html col tag to group the columns td.
.col-group-1 {
background-color: yellow;
}
.col-group-2 {
background-color: silver;
}
<table>
<colgroup>
<col class="col-group-1">
<col span="2" class="col-group-2">
</colgroup>
<tr>
<th>Name</th>
<th>City</th>
<th>Phone</th>
</tr>
<tr>
<td>Mary</td>
<td>New york</td>
<td>987654321</td>
</tr>
<tr>
<td>Magdalena</td>
<td>Los Angeles</td>
<td>123456789</td>
</tr>
</table>
</body>
</html>
Please check out the html col tag
and how to use them with css styling