I'm trying to build a table in HTML where there is one row with some generic information, followed by multiple rows of related detail data, followed by again a generic row, a set of detailed rows, etc.
The way I'm approaching it is that the cells in the generic row have a rowspan equal to the number of detail rows plus one. That way the detail rows get "pushed" to the right by the generic row.
The problem I have is when the generic row is higher than the detail row, for example because of multi-line contents, on Firefox the detail row gets a minimal height aligned to the bottom while on Chromium-based browsers the detail row has the same height as the generic row.
An example with just one detail row:
<table border="1">
<tr>
<td rowspan="2">left<br><br>1</td>
<td rowspan="2">left<br><br>2</td>
</tr>
<tr>
<td>right1</td>
</tr>
</table>
In Firefox it looks like this:
Firefox preview
In Chromium it looks like this:
Chromium preview
Ironically, when I add style="height: 100%" to the rows, the situation is reversed and in Firefox the right cell grows to the other row's height, while in Chromium its size gets minimized.
<table border="1">
<tr style="height: 100%">
<td rowspan="2">left<br><br>1</td>
<td rowspan="2">left<br><br>1</td>
</tr>
<tr style="height: 100%">
<td>right1</td>
</tr>
</table>
I want to have the default Chromium behavior (the cell on the right using the same height as the rowspan cells) in both Firefox and Chromium.
Though in my specific case, I would also accept it if I kind of get the same behavior as in Firefox in both browsers but with the cell aligned to the top rather than the bottom.
This is the problem with every web browser. Try using normalize.css.
Under the hood, normalize.css does no magic. It just overrides some of the properties that the browser has set so as to make the HTML document the same throughout various browsers.
Be careful though, if you are also including another CSS document in your HTML document, the order of the positioning matters.
Normalize.css
Related
Here is some very simple HTML. On Chrome (v57) and Firefox (v55) the two cells to the right are the same height, and on Safari (v11) they are not. On Safari the top cell is only as big as needed for the content, and the bottom cell gets the rest of the space.
My question is - is one of these behaviours correct and one a bug? Is there something simple I can do to get Safari to produce the same results as Chrome (like is there a browser styling difference at play here)? I've inspected it and there are no user agent stylesheet differences that I can see.
img {
max-width: 100%;
display: block;
}
.image-cell {
width: 150px;
}
<table border=1 cellspacing=0 cellpadding=0 bgcolor="#3faaed">
<tr>
<td rowspan="2" class="image-cell">
<img src="http://www.rizwanashraf.com/wp-content/uploads/2009/04/gorgeous-chrysanthemum-3d-wallpaper.jpg" />
</td>
<td>Top Cell</td>
</tr>
<tr>
<td>Bottom Cell</td>
</tr>
</table>
I know there are a limitless number of ways that I can produce a image with two equal sized boxes next to it - that isn't the question. The question is, why the difference, and, can simple styling be added to homogenize them? (This is a learning question, as I say, there are a million ways to display two boxes beside a box. That's not what I'm asking.)
The spec leaves this explicitly undefined:
CSS 2.2 does not specify how cells that span more than one row affect row height calculations except that the sum of the row heights involved must be great enough to encompass the cell spanning the rows.
This means in particular that CSS does not define how the height of a cell spanning more than one row is distributed across the rows that it spans.
There is no good way to homogenize the table's appearance except by providing absolute heights to the table and/or the table rows. Given an arbitrary image whose height is not known in advance, this is pretty much impossible with CSS table layout.
Table cells are rendered arbitrarily depending on their content, so you can never be sure how they are going to be rendered. Specifying dimensions is the way to get specific results.
I have a table which is OK in web pages, but when printing my table (ctrl+p) it breaks not the way I want. The last row of the first page splits with the part of the row on the first page and the other part of the row on the second page. So, is there any way to overcome the problem, the rows can have different content and size. I also tried this properties
page-break-before/after: auto. page-break-inside:avoid;
but with no result. Is there any way to break the table and move the part of the table to the next page without splitting the last row into two parts for print media? Any help will be appreciated.
table,th,td
{
border:1px solid black;
border-collapse:collapse;
}
th,td
{
padding:5px;
}
</style>
</head>
<body>
<table style="width:100%;">
<tr>
<th><span>Firstname</span></th>
<th><span>Lastname</span></th>
<th><span>Points</span></th>
</tr>
<tr>
<td><span>Jill</span></td>
<td><span>Smith</span></td>
<td><span>50</span></td>
</tr>
<tr>
<td><span>Eve</span></td>
<td><span>Jackson</span></td>
<td><span>94</span></td>
</tr>
<tr>
<td><span>John</span></td>
<td><span>Doe</span></td>
<td><span>80</span></td>
</tr>
/*here I have many <tr> elements*/
</table>
</body>
</html>
If I understand correctly, you want your table to break only between rows and not within them. You can accomplish this in Firefox and Internet Explorer with the following css rule:
tr {page-break-inside: avoid;}
Unfortunately, that doesn't work in other popular browsers, such as Chrome.
As has been suggested, you can prevent page breaks within the content of an individual cell by wrapping it in a div that has "page-break-inside: avoid;" set on it, but if the content height varies within the row, you'll still end up with parts of the row on two different pages.
If you really want to solve this problem and are willing to throw some javascript at it, I have posted a solution here that should do the trick.
You can request a page break, which will be invisible on the screen, but will force the element to a new page when you print. But the rules are more subtle than you might expect.
The CSS property page-break-before:always can only by applied to a block element. Not an inline, or anything odd like a table-row or a list-item. So do not style the row or cell, nor even a <tbody> or a <br/>. And it cannot be an element that the browser is allowed to omit, so you cannot just throw in an empty <div> with the style on it. One has to add a <div> or <p> around the first cell contents, for instance, to give the style.
Likewise page-break-after:always can be applied to something similar at the end of the previous row. I find this totally annoying, as what I always want to protect is a row, or a grouping.
Some browsers may also want you to change the style of your table to page-break-inside:auto, as the default style for a table is often already page-break-before:avoid.
Since it is the default style, adding it does not help. The browser is already avoiding breaking your table as much as it is willing to. But failing to remove it easily makes the other options useless, especially in Chrome.
I have a table according to below. The second row has defined three columns, one with colspan=8 and the others with colspan=1. Still, the cells are not stretched according to the colspan, the "width" are a little bit more for second cell and widest for the third.
<table class="floating simpletable">
<tbody>
<tr><td colspan="10">1st row</td></tr>
<tr><td colspan="8">Column 1 -> Least wide</td><td colspan="1">2nd</td><td colspan="1">3rd</td></tr>
<tr><td colspan="10">3rd row</td></tr>
<tr><td colspan="1">1st cell</td><td colspan="9">4th row</td></tr>
</tbody>
</table>
What's the problem and how to fix it?
The widths of cells depend on cell contents, HTML and CSS settings for widths, browser, and possibly phase of the moon. The colspan attribute just specifies how many columns (hence, how many slots in the grid for the table) a cell occupies.
If you see the last cell of row 2 as the widest, then the reason is probably that it has most contents (or there is a width setting for it). Your demo code does not demonstrate such behavior.
If you don’t want the column widths adjust to the size requirements of cells, set the widths explicitly in CSS (or in HTML). Before this, it is best to remove all unnecessary complications from the table structure. If your demo code reflects the entire structure, then columns 2 through 8 are an unnecessary division, i.e. they could be turned to a single column. Demonstration (with poor-style pixel widths just for definiteness):
<table class="floating simpletable" border>
<col width=100><col width=100><col width=100>
<tbody>
<tr><td colspan="4">1st row</td></tr>
<tr><td colspan="2">span 1</td><td>span 2</td><td>span 3 </td></tr>
<tr><td colspan="4">3rd row</td></tr>
<tr><td>span</td><td colspan="3">other span</td></tr>
</tbody>
</table>
Without a rewrite like this, I’m afraid your table violates the table model of HTML, as currently there is no cell that starts in column 3 or column 4 or...
colspan determines how many columns a cell overlaps, not the size of those columns. Use the CSS width property to specify the width of things.
Only display: table-cell implements the behavior for colspan, so applying any other display value would cause the attribute to be ignored.
If you want to use some other display algorithm for the content of a cell you could use a wrapper:
<td colspan="2"> <!-- the cell is still `display: table-cell` -->
<div style="display: grid"> <!-- the wrapper can have any `display` rule you need -->
<!-- the cell content -->
</div>
</td>
What I am doing seems to work on firefox and IE but not safari.
I have something like this
<table>
<thead>
<tr>
<th style="display: none;">hi</th>
</tr>
</thead>
<tr class="someClass">
<td style="display: none;"><span>hi</span></td>
</tr>
Now imagine I have many columns and rows and many headers. Now in all browsers this coulmn would be hidden. In safari it makes some gap and then all the other columns are out of alignment.
http://gyazo.com/ef5ce5e994abb954aab7069b14699476.png
this is how my column headers look like. Am I missing something?
Setting display:none on an element takes it out of the document flow, but that doesn't always work well with table cells as they are not independent of the surrounding elements.
You would have to actually remove the elements from the table rather than hiding them to make the table realign itself with the remaining elements.
I think I figured it out. I just put that column last(and the header last as well). Now it seems to look proper.
I would like to ask what is the better way of specifying HTML column width? the width attribute or the style attribute? Assuming I am using IE 6. Does IE render the width attribute better than style?
By width attribute
<table width="900">
<tr>
<td width="450">A</td>
<td colspan="2" width="450">B&C</td>
</tr>
....
</table>
OR by style attribute
<table style="width:900px;">
<tr>
<td style="width: 450px;">A</td>
<td colspan="2" style="width: 450px;">B&C</td>
</tr>
....
</table>
Firstly before I answer your question, something you should know is how tables are rendered, experiment with the table-layout fixed style for the table element:
If the browser knows the width of the first table row columns upfront (if you provide the table layout fixed style on the table) the browser can begin rendering the top of the table even before its calculated the width of any resulting rows. What this means? Tables populated by Ajax calls with a fixed layout can begin displaying results to a user before the full ajax call is finished. Best way to think of this is like a progressive jpg. In the end your pages will appear to load faster.
table
{
table-layout:fixed;
}
Now to answer your question.
Actually neither example you provided is correct. you typically do not set width on a cell that is spanned across 2 or more cells. In any table its a good idea to create at least 1 row with all the cells, this can either be in the TH or (just the way I like to do it in a blank tr.
For example...
<table>
<tr>
<td width="450"></td>
<td width="225"></td>
<td width="225"></td>
</tr>
<tr>
<td>content here</td>
<td colspan="2">content here</td>
</tr>
</table>
What ever way you decide to use style or just standard html width, the choice is yours, but in the end you should have your first row (if table layout is fixed) or any row (if table layout is not fixed) to contain the width definition for each invidivual cell. This will also help you with planning the correct looking table, hope this helps.
Test the table layout fixed, by creating a huge like 10 000 row table, and test the rendering speed vs a non fixed table layout.
The whole debate about HTML 4 vs XHTML , style vs attributes I think is really a question of maintainability. I don't think there is anything wrong setting the width using Style or plain width with HTML 4 transitional, they both do the same thing. The reason why you can do both is because HTML has evolved a bit, yes it can get messy! Good luck
Just add <div> tag inside <td> or <th> define width inside <div>. This will help you. Nothing else works.
eg.
<td><div style="width: 50px" >...............</div></td>