Chrome 50 Change in implicit table-cell height behaviour - html

See jsFiddle.
<table>
<tr>
<td>
<div>
Hello World
</div>
</td>
</tr>
</table>
html, body {
height:100%;
background-color:steelblue;
margin:0;
}
table {
height:100%;
border:1px;
}
td {
border:1px;
}
tr {
background-color: green;
}
div {
background-color:salmon;
height:100%;
}
Prior to Chrome 50, a table with height 100% would also implicitly apply height 100% to it's table cells.
This has been a longstanding bug in Firefox and IE versions < 11. Chrome and Safari have always passed the implicit percentage height onto the cells.
What is the correct behaviour according to the specifications? Has this been introduced by design?
Edit:
Chromium Bug Report

This appears to be the same question as this Chromium issue, which was closed over 2 months ago.
According to the comments there, the new behavior in Chrome 50 is "more spec compliant".
So, to answer your question, it would appear this is intentional, and is considered (at least by the Chromium developers) to be the correct behavior according to the specifications.
The solution, naturally, is to just explicitly set the cell's height to 100%.

The above answer works (to explicity set the cells height to 100%)
If you want all cells to follow that patterns, you can simply use
<style>
td{
height:100%;
}
</style>
Alternatively, you could try:
<style>
td{
height:inherit;
}
</style>
I believe either should work.

Related

How to make a link (anchor) tags 100% height of containing th/td tags?

I have a table with the following basic structure:
<table>
<thead>
<tr>
<th>
Header Text
</th>
...
</tr>
</thead>
<tbody>
<tr>
<td>Random text</td>
...
</tr>
...
</tbody>
</table>
Where the a link tags can be clicked to re-sort the table.
I want to define some CSS so that regardless of how many lines the text within the a tags span across, all of the a link tags will take up 100% the height of their containing th tags so that you can click anywhere within the table header to sort on a particular column.
I tried using the following CSS, but it only worked in Chrome:
th {
height: 1px;
}
th a {
height: 100%;
}
I also know that you could use JavaScript to solve this problem, but I'd really like to avoid that if possible. In other words, an HTML/CSS only solution would be ideal.
I have to support IE back to IE8 and pretty much all versions of Chrome, FF, etc. Does anyone have any advice on how to do this?
Thank you.
EDIT: Old version relied on duplicating the link and hiding a copy while sizing the other outside of document flow, but we can do better... here's better.
You can get it to work in relatively modern Chrome (39.0+) and Firefox (31.2+) and in the last version of Safari for Windows (5.1.7) via ::before.
In IE, it won't quite size it right on its own (same problem as with the doubling), but by tossing in an overflow:hidden, making the height larger than 100%, and adding ::after with clever positioning, you can mitigate this problem fairly easily.
If you set the heights back to 100% you can force the banding IE has to be visible.
Obviously, the background-shading on hover is purely for demonstrative purposes.
In addition, I figured out how to make elder fox (FF 3.5.2, welcome to CSS3) degrade cleanly. That's what .safety is for, and it was actually easier to do than I had expected.
body{
background: #f06;
background: linear-gradient(45deg, #f06, yellow);
min-height: 100%;
}
.safety{
position:relative;
}
th{
position:relative;
background-color:rgba(255,255,255,0.5);
overflow:hidden;
}
a{
display:block;
}
a:hover{
text-decoration:none;
background-color:rgba(255,0,0,0.3);
}
a::before{
content:"";
position:absolute;
top:0;
left:0;
height:900%;
width:100%;
}
a::after{
content:"";
position:absolute;
bottom:0;
right:0;
height:900%;
width:100%;
}
a:hover::before{
background-color:rgba(0,0,255,0.3);
}
a:hover::after{
background-color:rgba(0,255,0,0.3);
}
<span class="safety">
<table>
<tr>
<th>The Link</th>
<th><br /><br />next cell<br /><br /></th>
<th>The Link 2<br />Naturally Taller</th>
<th>next cell</th>
</tr>
<tr>
<th>streeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeetch</th>
<th>next cell</th>
<th>next cell</th>
<th>next cell</th>
</tr>
</table>
</span>
Why pseudoelements?
Because we didn't remove the link itself from document flow, the link is still able to greedily grab the screen real-estate it itself needs.
And since we can position and size them separately, we can mitigate any bugs with how the browser picks what 100%; means without removing the link.
Why you can't simply say height:100%;
Firstly, a is an inline element, meaning it is only as big as its content. Ergo, sizing on it itself fails without making it a block or inline-block.
However, that only makes width:100%; work in this case.
If you want to have a height:100%; you must declare what 100% is in a non-internally-relative manor that can be propagated down to the percentage-based element. That means no percentages (outside of the screen units vh, vw, vmin, vmax), as otherwise you'd get "correct" behavior when something scales its size upwards, creates more scroll bar, then scales its size upwards more in an infinite loop.
You CAN bypass this, however, via position:absolute, since that removes the element from the normal flow- as in it is not allowed to increase the size of its parent, so it cannot produce an infinite loop.
Since the parent has a knowable finite size if it doesn't scale to its relative-height child, height:100%; on the absolute element will be used (in the expected manner) so long as the absolute element is also a block or inline-block element (as inline is force-sized by its contents).
It also will require a width, even if block, because it has been removed from document flow and thus no longer knows for certain how wide it should be (parent or anchoring ancestor?)
Aside
The change of implementation was thanks to Lea Verou's book, and I felt like a total dunce when I read her suggestion of using ::before- especially since I've actually used it for expanding the clickable area before.
Also, what the hell is an element to its pseudo-elements? Parent from an affair with the CSS?
As long as there's no cell padding on the TH, this should work:
th {
height: 2em;
}
th a {
display: block;
height: 2em;
}

Alternative to IE 10 Conditional Comments to center positioned div

I use this code to center absolutely positioned div
.class{
width: 10px;
height:10px;
position:absolute;
left:0;
right:0;
top:0;
bottom:0;
margin:auto
}
This is not working in IE 10 and lower versions, but I dont want to change this code as it's comfortable for all other browsers and devices.
I know that Conditional comments are not working in IE 10 too, so how can I solve this issue there?
You have besides those options mentioned above:
Calculated Padding + Width:
.container {
padding:5%;
}
.container .center{
width:90%;
height:90%;
display:block;
}
Or if you only need it to be horizontally centered:
.centered {
width:80%;
margin:0 auto;
}
But if you still aren't getting any results to work, then you may have malformed HTML. When internet explorer finds bad HTML or a meta tag expressing a specific version to emulate, it will and then newer features don't work. I recreated your style on JSFIDDLE and it worked for me even on internet explorer 8 (Although 7 did fail). Otherwise you may not be putting a position value on the CSS of the parent element if it is apearing out of place.
You should detect by JavaScript if the browser is IE10. If it is you can add a special class in the page body or in any html element you want.
JS
if (navigator.userAgent.indexOf("MSIE 10") > -1) {
document.body.classList.add("ie10");
}
CSS
.ie10 {
...
}

How to work around Firefox's miscalculation of widths

Under some situations, Firefox grossly miscalculates the widths of some DOM elements, which in turn causes layouts to break.
This jsFiddle gives an example of the problem. The numbers displayed below the table are the widths (in pixels) of the div that is shaded dark-gray, and of its parent (as reported by jQuery). Compare the results produced by the latest versions of Firefox (or IE 11) and Chrome (or Safari). Chrome always reports 250 for both widths (as expected), but Firefox always reports a larger number (though the exact number may depend on the OS and/or version of FF and/or phase of the moon). As a result, there's not enough room to render the svg elements in the next td at 3/row.
(More bewildering still: the numbers displayed below the table will vary according to the number of svg elements included in the second td element.)
This erratic/unpredictable behavior makes it practically impossible to design a layout.
How can I ensure that FF will compute such widths correctly, or alternatively, how can I work around this bug?
EDIT: updated jsFiddle (including the link to it).
Now, to keep the gods of SO happy:
body > div,table,table *{outline:1px solid red;}
html,body{height:100%;}
*{
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
*{margin:0;padding:0;border:0;}
table{
border-spacing:0;
border-collapse:collapse;
}
body{
font-family:courier;
font-size:13px;
background-color:palegoldenrod;
}
body > div{
width:312px;
margin:0 auto;
padding:40px 0 0;
background-color:white;
min-height:100%;
}
label{
display:block;
padding:0 1ex;
}
.button-container{
color:white;
background-color:#555;
}
.button-container > div{
display:inline-block;
}
.button-container > div:first-child{
font-weight:bold;
}
.ul-container > div{
width:100%;
border:1px solid black;
-webkit-border-radius:4px;
border-radius:4px;
}
ul{list-style:none;}
li{
width: 72px;
float:left;
margin: 0px 5px 1px;
padding: 0px 5px;
border-width: 1px;
line-height: 14px;
}
br{
clear:left;
}
body > div > div:last-child{margin:40px;}
<body>
<div>
<table><tbody><tr>
<td>
<div class="button-container">
<div>xxxx xxxxx</div>
<div>
<label> <input type="radio"> xxxx xxxx xxx xxxx xxxx </label>
</div>
</div>
<div class="ul-container" style="width: 250px;">
<div style="width: 248px;">
<ul style="width: 246px;">
<li>A</li><li>B</li><li>C</li><li>D</li><li>E</li><li>F</li><li>G</li><li>H</li><li>I</li>
</ul>
<br>
</div>
</div>
</td>
<td>
<div>
<svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg><svg width="20" height="20"></svg>
</div>
</td>
</tr></tbody></table>
<div></div>
</div>
(function ($) {
var $msg = $('body > div > div:last-child');
function showw (sel) {
var w = $(sel).width();
$('<span>', {text: '' + w})
.css('margin-left', 5)
.appendTo($msg);
console.log(w);
}
showw('.button-container');
showw('table td:first-child');
}(jQuery));
If you remove the inline-block rule for .button-container > div, it forces the two divs to sit on separate lines, allowing the table to take on a consistent width.
What is happening there is the browser is trying to put the elements on the same line. A cell in a table with no explicit width or overflow instructions will grow wider to accommodate the content lines inside it. Because the two elements are inline, they are considered a single line. The text wraps as you would expect (the browser does a good job protecting the integrity of your content), but this is arbitrary as far as the width calculation goes; it affects the calculated width of the line that the elements form, and therefore pushes the table cell open wider. The browser is trying to take what you gave it and make sense of it while it also tries to preserve the integrity and legibility of your data, because it is a table and that's what tables do.
This is another good example of why tables are not the right tool for layout. They are designed to accommodate and present data, so they do a good job flowing and sizing around text. Different user agents have different strategies when it comes to how this is accomplished -- that is all within the specification. When you abuse the element, you wind up having to contend with design properties that do not suit your use case.
Fiddle: http://jsfiddle.net/Cy7dA/
It isn't "miscalculating the width" at all.
Your problem is simply that your label and input are different widths in both browsers. The extra width is then pushing the button-container and td out further.
Try to get your input/label combo consistent between the browsers (you probably need explicit margins on the input) and your problem is solved.

CSS background issue with table row in Google Chrome

I have a table in which I have this
</tr>
<tr class="table-top-background" >
<td class="thread-pic" ></td>
<td class="thread-top-middle" colspan="2" >Threads</td>
<td class="thread-information">Last Post</td>
</tr>
So I want to give background image to my tr, so I put this
.table-top-background
{
background:url('/img/design/extra-large-back.png') no-repeat;
position:relative;
color:White;
height:31px;
}
.thread-pic
{
width:30px;
}
.thread-information
{
width:280px;
}
.thread-top-middle
{
width:418px;
}
The problem is that in all browser's it is fine expect Google Chrome.
In Google Chrome it seems that I give background not to tr, but to all td's... It repeat same background for each td.
It is the same in IE7, but in one of stackoverflow questions I read about solving that with position:relative and it helped.
But I didn't find any solutuin for Chrome.
I try to give tr css like this also
.table-top-background
{
background:url('/img/design/extra-large-back.png') no-repeat 0% 100%;
display:block;
position:relative;
color:White;
height:31px;
width:728px;
}
But it change all my table design... At that time text's in td's of this header row aren't in that places and also all other first td's of my table are in the same size as my header tr . It seems really hillarious.
I tried also to give display:inline-table instead of display:block and it didn't help me too...
What is the solution of that problem?
EDIT: Same problem is in Safari, so it is webkit problem.
Although it worked for me, take a look at:
Can we solve the table row background image problem, in chrome, in multi celled tables?
Which mentions this fiddle:
http://jsfiddle.net/pzjUt/
Using display:table-cell on the <tr> seems to do the trick, but it may have side effects in Chrome or other browsers.

html - div, minimal size

how can i set minimal height for div? But it have to resize with new data.
min-height works fine... except in IE.
The way to fix it and therefore use it everywhere is importing ie7.js
div#name
{
height: 60px;
height: auto !important;
min-height: 60px;
}
This should work across browsers including IE
You want the CSS property min-height. You'll need to be careful of not great browser support (particularly older versions of IE, shockingly enough).
div#foo {
min-height:10em;
}
in ie6.css or prepend with * html selector ( hack warning )
div#foo { height:10em; }
Since MSIE6 doesn't support min-height.