Absolute positioning element 100% width inside relative positioned container bug in webkit - css

I've used this positioning trick a bit to achieve complex outcomes. I think I've come across a bug in webkit browsers which I'm struggling to understand.
Here is the simple markup:
<table>
<tbody>
<tr>
<td>
<div>
<span class="cols-6"></span>
</div></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
and CSS:
*, *:after, *:before {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
table {
table-layout: fixed;
border-collapse: collapse;
width: 100%;
}
tr {
border: 1px solid #ddd;
}
td {
vertical-align: top;
padding: 0;
height: 100px;
border: solid #ddd;
border-width: 1px 0 0 0;
box-shadow: -1px 0px #ddd;
}
td div {
position: relative;
}
td div span.cols-6 {
position: absolute;
width: 600%;
height: 20px;
background: #ccc;
}
To see this in action, open up this http://jsfiddle.net/JFxqt/14/ in chrome.
The displayed span is absolutely positioned inside a relative container. As the table uses fixed layout, its cells are all fixed width, hence a child should be able to make use of a percentage width. The table has 7 columns while the span's width is set to 600% (i.e. 6 columns * 100%). It fails to cover all 6 columns in webkit browsers. Firefox and IE renders fully across all specified columns.
Ideally setting the span's width to 100% should render across 1 column, 200% across 2 columns and so on.
Anyone have any ideas or workarounds?

Try this: http://jsfiddle.net/JFxqt/3/
I changed this around in your CSS:
body{margin:0px}
td div {
}
span.cols-6 {
position: absolute;
width: 85.6%;
height: 20px;
background: #ccc;
z-index:10;
top:0;
left:0;
}

You are seeing a cross-browser issue related to how the widths of table cells are computed and inherited. This may be either a bug or something that is not specified explicitly by the CSS specifications and left to the browser to decide.
In Firefox, the width of <td> is inherited by the <div> whereas in the webkit (Chrome) browser, the width inherited by the child <div> is 1px smaller.
When you multiply by 100% and 200%, you won't see an effect, but by the time you get to the last cell at 700%, you see about a 7px gap.
If you are building a CSS framework, you will need to create a style for Firefox browsers and another for webkit browsers.
For the case of 6 columns, I found the following would work:
td div span.cols-6 {
position: absolute;
left:-1px;
width: 600%;
border-right: 6px solid #ccc;
height: 20px;
background: #ccc;
}
I add a right border that is 600% x 1px = 6px and then position the span to the left by -1px. For another number of columns, for example, .cols-3, you would need width: 300% and border-right: 3px solid #ccc and so on.
You may need to use some type of a CSS filter or selector hack. I did find the following reference: http://browserhacks.com
No clean or elegant solution for this problem unfortunately.

Well after a day or two searching for workarounds it would seem a conditional JS enhancement for Webkit browsers is the only viable solution.
The problem stems from Webkits (and Opera's old rendering engine) calculation of percentage widths, which are always rounded down to the nearest pixel as opposed to being stored as a double. Therefore in Webkit a 1px descrepancy may be added for every factor of 100% (eg 2300% - 100% * 23 - will have a maximum of 23px discrepancy), while Firefox and later versions of IE can only have an overall maximum of 1px discrepancy.
John Resig touched on this issue a while ago, http://ejohn.org/blog/sub-pixel-problems-in-css/

Related

Div tag inside td does not showing background color on mozilla [duplicate]

This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 5 years ago.
My goal is to draw bar chart and everything looks fine on Google Chrome but on Mozilla Firefox(v 46.0.1) div's tag inside td element do not display background color at all.
Here's live example: https://jsfiddle.net/zck5mw7m/
Green bar does not show up in Mozilla Firefox but it does in Google Chrome
table {
width: 100%;
height: 100%;
border-collapse: collapse;
border-bottom: 1px solid #aaa;
position: absolute;
z-index: 2;
}
td {
vertical-align: bottom;
position: relative;
margin: 0;
padding: 0;
width: initial;
z-index: 3;
> div {
background: #72a822;
margin: 0 20%;
}
}
<table>
<tbody>
<tr>
<td>
<p>Label</p>
<div ng-style="{'height': order.value/maxValue * 100 + '%'}"></div>
</td>
</tr>
</tbody>
</table>
EDIT
Originally I calculated and set height property of div element using angularjs dynamically. I remind that this code works for Google chrome but IT DOEST NOT work for Mozilla Firefox so the problem lays somewhere in compatibility of browsers.
EDIT vol 2
Here's live example: https://jsfiddle.net/zck5mw7m/
Green bar does not show up in Mozilla Firefox but it does in Google Chrome
use what is called inline css.
<td style="background-color: #E30000;">this is a Test </td>
This should work for you.

Styling inconsistency on Chrome and Firefox

I have a table, that for one of its cells I am using the rule
border-right: 3px solid #000 !important;
It works fine on Chrome but in Firefox the border is invisible. I say invisible because if I deactivate the rule I can see the cells' contents move slightly.
-moz-box-sizing: border-box;
Did not help in any way as far as I can see.
So if you were to run this small example in Chrome, it would look fine. In Firefox you can spot some errors though (be sure to view at a wider width to see the error)
I have tried various other suggested option with no good results. The one closer to solving the issue was removing border-collapse altogether, but that makes all borders visible as can be seen from the image below:
Is this common for Firefox, and how can I overcome the issue.
One thing to try would be to add another block element inside of the table cell and apply your border style to that element. For example, you might try to do something like this:
<table>
<tr>
<td>
<div style="border-right: 3px solid #000;">My Content</div>
</td>
</tr>
</table>
Table cells like <td> and <th> are sized differently than regular block, inline block, or inline elements and so the borders might also get computed slightly differently depending on available space.
By using a <div> inside of your table cell, you can set it's width to 100% and it's height to 100% so that it covers the entire available table cell, then you can apply any border you like to the div and with box-sizing:border-box set on the div element, it should look the way you want. For example:
<div style="border-right: 3px solid #000; width: 100%; height: 100%; box-sizing: border-box;">My Content</div>
Here is more info on table sizing / box model quirks
I have updated your original jsfiddle https://jsfiddle.net/sfodcjkz/4/ with some of the minor tweaks
https://jsfiddle.net/sfodcjkz/18/.
The changes I carried over your fiddle are:
Removed empty <tbody> elements. Best practice is to group the body rows inside a <tbody>. Some modern browsers may auto correct the errors, but not all browsers are smart enough. So for consistency, we can avoid being dependent on smarter browsers.
Next I had problems with these css:
Line:349
.responsive-table thead {
clip: auto;
height: auto;
overflow: auto;
position: relative;
width: auto;
}
Line:258
.responsive-table thead {
border: 0 none;
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
Simply removed those css styles and you can see a cleaner look.
It's a known 'bug' in Firefox. It's being caused by setting the border-collapse to collapse. One solution is to set the border-collapse to separate.

CSS - 100%px fixes my issue?

I have a question on something weird that is rendering on the latest IE and Chrome browsers. I have a div that is supposed to span 100% of a parent. So clumsily, I gave it - width: 100%px; as a CSS property. Here is my entire item:
.loc_vendiv{
position: relative;
margin-top: 5px;
left: 0px;
width: 100%px;
height: 120px;
border: 1px solid #333;
background-color: #fff;
}
The weird thing - that worked perfectly. So much so, that I just noticed today that this was wrong. Not wanting an ugly style sheet, I removed the px from the end. And... the div was two pixels too wide. Any explanation as to why this is happening? Here is the parent div:
#loc_catlist{
position: absolute;
width: 612px;
height: 720px;
top: 50px;
left: 0px;
background-color: #eee;
overflow-y: auto;
overflow-x: hidden;
}
I'm mildly annoyed, as the bad code works, yet the correct code doesn't do what I want. I don't think I can leave it, though. I don't like little hiccups like this...
It's because of your border.
Try adding :
box-sizing: border-box;
to your .loc_vendiv class, it will take the border in account.
Browsers usually ignore invalid css rules like width: 100%px; which means that to get the style you had with the mistake. you only have to remove the width rule.
2px too wide is likely caused because you have a width of 100% in addition to a border of 1px (all around adds up to 2px width).
A fix can be found here from "Paul Irish" about
box-sizing
what happens is that when the width value is wrong (100%px;) this part of the CSS is simply ignored by the browser. If this part of the css was deleted, the result would be the same.
About the 2 extra pixels, this happens because of the border set to the div.loc_vendiv.
The width of div.loc_vendiv is equal to the width of div#loc_catlist and to this is added the border value (1px for the left border and 1px for the right border = 2px).
Remember that the border width is added to the size of the object while the padding creates an internal space.

Why is the padding calculated differently between <a> and <button> elements?

Why exactly is the padding calculated differently between a and button elements?
HTML
<button type="button">CLICK</button>
LINK
CSS
button {
padding: 10px;
height: 30px;
border: 0;
background: #ccc;
line-height: 30px;
}
a {
display: inline-block;
padding: 10px;
height: 30px;
background: #ccc;
line-height: 30px;
}
The default box-sizing value for buttons in Chrome (and Firefox) is border-box:
DEMO
I.e. the total height, including padding (and border and margin), of the element is 30px, not 50px like for the link. You can fix this by setting
box-sizing: content-box;
explicitly.
DEMO
More info about the box model.
Why the border-box is the default value I cannot say. I haven't found a specification for it. Chrome, Firefox and Safari seem to do this (didn't test other browsers).
<a href...>
Links never have a set-height, if you inspect the html, you can see that; what is really done is giving it a line-height and padding. when you write height: 30px, it is useless.
With respect to that, you are defining a height for the <button>, which is why it does not look the same as how you styled your link
Here is a fiddle to show how to make them the same, by removing the set-height of the <button>

Pixel and percentage width divs side-by-side

I've found a lot of similar questions, and tried out several solutions (including some of the so-called "holy grail" CSS layouts), but they don't quite do what I need.
I have a containing div (a CSS containing block) with id right. Inside it on the left side, I want a fixed-width div (a splitter bar, but it doesn't matter what it's being used for; id splitpane); on the right, filling the rest of the space, another div (id right-box below).
I've tried making the two inner divs display: inline-block (with vertical-align: top), setting the left one to width: 3px, but then there's no way to set the right to have width 100% - 3px. I've also tried using the float: left/margin-left: -100%/margin-left: 3px trick, but it has the same problem: the 100% plus the 3px overflows the parent containing block and causes a scroll bar to pop up. (Of course, it's not the scroll bar per se that's the problem; I could use overflow: hidden to remove it, but then content on the right would be truncated.)
Currently I'm using width: 99.5% for the right div, but that's a terrible hack (and is subject to overflow depending on screen width). It looks a bit like this:
<div id="right"><div id="splitpane"></div><div id="right-box">
...
</div></div>
With CSS as follows (float version, but the inline-block version is similar):
#right {
display: inline-block;
vertical-align: top;
height: 100%;
width: 85%; /* this is part of a larger div */
}
#right-box {
width: 99.5%; /* stupid hack; actually want 100% - 3px for splitter */
height: 100%;
}
#splitpane {
float: left;
width: 3px;
height: 100%;
background: white;
border-left: solid gray 1px;
border-right: solid gray 1px;
cursor: e-resize;
}
Is it even possible to do this? This is for an internal app., so solutions only need to work in Firefox 3 (if they are specific to FF3, though, preferably it's because the solution is standards-compliant but other browsers aren't, not because it's using Firefox-only code).
DIVs are the wrong element type for this since they don't "talk" to each other. You can achieve this easily with a table:
<table style="width:200px">
<tr>
<td id="splitpane" style="width: 3px">...</td>
<td id="rightBox" style="width: 100%">...</td>
<tr>
</table>
The 100% will make the rightBox as wide as possible but within the limits of the table.
This is possible. Because block level elements automatically expand to take up any remaining horizontal space, you can utilise a block level element next to an uncleared floated element with your desired width.
<style type="text/css">
div {
height: 100px;
}
#container {
width: 100%;
}
#left {
background: #FF0;
}
#splitpane {
position: relative;
float: right;
background: #000;
width: 3px;
}
</style>
<div id="container">
<div id="splitpane"></div>
<div id="left"></div>
</div>
See http://jsfiddle.net/georeith/W4YMD/1/
why you didn't use margin-left (since it was float layout) on right box?
so no need to create a splitter div...
#right{
width:200px; /*specify some width*/
}
#rightbox{
float:left;
margin-left: 3px; /*replace the splitter*/
/*margin: 0 3px; /*use this to give left & right splitter*/ */
}
yeah something like that, i hate empty div, it's not semantic and it's like putting a splitter on the "old" table way
If the div #right-box is only going to contain non-floated content it might be an idea to just put the content inside #right instead and let it wrap around the floated #splitpane.

Resources