Unspecified padding with border-box sizing - css

I noticed something odd with my CSS earlier. As you can see in my image below, I have a td element with padding set to 0. However, if you look to the left, you can see the green-tinted areas where there's about 10px of padding on the top and bottom, even thought Chrome says there is no padding. I didn't write the CSS, but I discovered that setting the box-sizing property to border-box is what seems to be causing this. But I can't really figure out how to get rid of it.
So where is this phantom padding coming from, and how can I get rid of it while still using border-box sizing?
EDIT: Here is a Fiddle that should demonstrate the behavior (at least in the latest version of Chrome). I can't figure out how to get rid of the padding unless I do something like table * { box-sizing: content-box; }, which I don't want to do.

Related

Do vertical margins collapse reliably and consistently across all browsers?

I'm trying to understand the effect that margin has on two elements. I have the following HTML, see the dabblet:
<p>some text</p>
<pre>some code</pre>
I have the following CSS:
body { color: white; }
p { background: red; margin-bottom: 50px; padding: 20px; }
pre { background: purple; margin-top: 40px; padding: 20px; }
So I've given the paragraph tag a bottom margin of 50px, and I've given the pre tag a top margin 40px. I was expecting therefore to find 90px vertical distance between them, but only have 50px.
I understand that the margins are collapsing, and that if I want to fix this then I need to add display: inline-block to the pre tag. But that causes the width of the pre tag to collapse.
Again, I know that I can fix the width problem by adding width: 100% to my pre tag, but I've got padding on the pre tag (20px), so this causes my elements to be too wide. I know that I can use box-sizing to deal with that, but what an almightly pain in the crotch it is to have to mess about with width, display and box-sizing just to have the desired amount of vertical space between two elements. So I simply refuse to do any of that.
Instead, I've decided that I'm just going to add margin-top: 90px to my pre tag, which will guarantee that I've got the 90px space that I want.
My question is: Are there any browsers out there that don't collapse margins in the way the others do? Will I inadvertently end up with 140px space (90px from the top-margin of the pre tag + 50px from the bottom margin of the paragraph tag)? In other words, are margins collapsed reliably and consistently across all browsers, or is there a browser out there that does it's own thing?
It's hard to give a definitive answer to this question because it's very broad. "All browsers" is a lot of browsers. There could always be some fringe browsers you never heard of that handle this differently. It all depends on how the browser's CSS rendering engine was written.
That said, any browser that wants to be taken seriously will try to adhere the W3C specs, which have the following to say about margin collapsing:
In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.
Adjoining vertical margins collapse, except:
Margins of the root element's box do not collapse.
If the top and bottom margins of an element with clearance are adjoining, its margins collapse with the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block.
Horizontal margins never collapse.
Source: Box Model (w3.org)
I figured it'd be a nice addition to just put your code to the test in as many browsers as possible. I made a test page page of your html (slightly modified), with an absolutely positioned 50px high block that should fit right in between the collapsed margin, to make it easier to spot a difference:
http://files.litso.com/playground/margin.html
Then I ran this through browsershots.org to get screenshots of how browsers would display this piece of HTML:
http://browsershots.org/http://files.litso.com/playground/margin.html#
(I have no idea how long this will stay cached, but I guess you could always just run it again)
Interestingly, the positioning of the blue block is a few pixels off in a bunch of the screenshots. You can still tell the margins are collapsed correctly, but I do wonder what exactly the problem is with the positioning.
The only browsers that don't seem to collapse the margin correctly are Dillo 3.0.2 and Links 2.7 on Debian 6.0, neither of which seem to listen to padding or margin properties at all (nor to the absolute positioning for that matter). They would mess up your layout no matter what, and you shouldn't worry about it. People use browsers like these for a specific reason, and seeing your page exactly as you intended it to be seen is not one of them.
TL;DR: Yes, it's safe to say that all browsers collapse these elements reliably and consistently.

CSS Challenge: INPUT going outside of DIV

I'm trying to accomplish something specific around platform constraints I'm under.
I created a somewhat self-explanatory jsfiddle of the problem at http://jsfiddle.net/MrV5M/4/
The specific problem:
On Chrome, the right border of the input box is cut off.
On Safari, the width of the content class cell exceeds the container so it spills over the border.
On IE9, the label doesn't float to the left of the content div
The main reason I care about Safari is because I'm working on a JQuery Mobile/PhoneGap app which is also a web app. I'm only supporting modern browsers, but this is driving me nuts. Normally I'd just use a table for the container, but the text-overflow: ellipsis styles on the content div don't work when inside a table. (Basically, I'm trying to keep the content to a single line and have ellipsis without enforcing a fixed width or calculating a width with Javascript)
Anyone have the l33t CSS skills to make this work? I sure don't... :)
Just add this CSS to your Stylesheet, and get peace of mind on your issue :D
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
You may not like this answer. I made some adjustments in the css which fixes Chrome and IE9 issues. Take a look,
http://jsfiddle.net/MrV5M/11/
There are many ways to do what you are trying to do, but if you insist on using 'flex' stuff which is largely un-supported (even in the majors see here), you'll need to add the vendor prefixes to flex.
e.g... -webkit-flex, -moz-flex
Also, I don't think you need to be setting widths on elements that have the flex property.. not positive though.
So your browser issues:
-IE doesn't support flex at all so you're label won't float unless you use a float.
-The reason your input/content is spilling over the container and getting cut off is not really anything to do with flex.. but the way css works.. setting an element to 100% width means setting it to the width of its parent. But by default, css doesn't count the padding/border-width as part of that width. So you end up getting 100% width plus the L/R padding and border. But, since you are only supporting modern browsers.. box-sizing:border-box; to the rescue. Google it for details, but putting it on your input element should do the trick.

Underlining Hyperlinks - Text-decoration vs. Border-bottom and Browser Inconsistencies

I'm not a big fan of the default text-decoration. I ususally set it to "none" then do a "border-bottom: 1px dotted somecolor" on 'a' and a "border-bottom: 1px solid someothercolor" on 'a:hover'
I've noticed something recently that I don't think was happening before. Even with padding-bottom on the text's container set to 0, there's too much vertical space between the bottom of the letters and my border-bottom.
What's odder is that Chrome still seems to behave nicely and respect my 0 padding, but Firefox and IE appear to be adding about 4 or 5 pixels of vertical space.
When I temporarily revert to "text-decoration: underline" I still see too much space.
Any idea what's going on here?
I'm going to bet the culprit is inline-block as a display setting. See the difference (in Firefox) at http://jsfiddle.net/s8FYS/6/.
EDIT: Some further investigation reveals that inline Firefox (looking in Firebug) sets the height to auto which ends up less than the actual line-height, whereas inline-block calculates the height (since it is now acting like a block) equal to line-height * font-size, which pushes the border down.
You can "compensate" for it by setting the height (in this fiddle, a 1.35em worked with my default font-size of 16px), but I'm not sure that doing such would necessarily compensate correctly at all times.
Change line-height, for example:
a{ line-height:1em; }

Firefox & IE agree with each other (but not Chrome) on rendering padding for element with display: table-cell

I'm trying to create a site which uses laterally-stacked "blades" of content. The element containing them is moved laterally inside a div with overflow-x: hidden to create the desired sidescrolling effect. This seems to be working fine: The element containing the "blades" is set to display: table; width: 100%; table-layout: fixed and each blade is styled as follows: display: table-cell; width: 601px; border-right: 1px solid white; padding: 10px. Finally, the nav element has width 621px, with no horizontal padding or margins.
It all seems simple enough, but I'm getting a very odd cross-browser bug: Firefox and IE9 agree on how the page looks, but Chrome has a different opinion. I've figured out what Chrome is doing, but I haven't been able to figure out why it's doing it.
The doctype's set and everything else seems to be working fine. Except for background-colors, the rules above are all I've defined in the stylesheet, and there are no inline styles. Here are some screenshots which illustrate the problem behavior.
Here's the page in Firefox - as desired, the right edge of the navigation bar aligns with the right edge of the content box.
Same in IE9.
In Chrome, the padding is subtracted from the width, creating the overhang shown above. I never set border-box anywhere in the stylesheet, nor do I see it in the computed rules in Chrome - it just says that the width is 581px, whereas it's 601px in the other two browsers.
[Note: I saw that there were other posts on padding issues, but none where Firefox and IE9 agreed and Chrome did something different.]
Edit Here's a JSFiddle link: http://jsfiddle.net/aCeAw/
This is just a bug in Chrome. When it computes column widths for table-layout: fixed, it incorrectly ignores cell padding. See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=652941 complete with spec quotes, and the almost-5-year-old WebKit bug report at https://bugs.webkit.org/show_bug.cgi?id=13339.
You may be able to work around this by using width styles on display: table-column elements, as discussed in the Mozilla bug report above. Alternately, you could add a first row with 0 height and no paddings, but the cell widths you want... I realize both of those mess with the actual site markup, which may not be an option in your case, of course.

Different Interpretation of TH Box Model Between Browsers

I'm noticing discrepancies between browsers in how the width of a TH tag is interpreted, specifically whether or not padding is included in the width calculation.
I am building a reusable library for quickly generating and styling tables (for tabular data, of course). This means that I have full control over the code I generate, but that I need to actually solve the problem versus finding a hack for a particular instance.
Simplest Description of the Problem
A TH in IE9 and FF is sized based on its padding + width (as expected). Chrome and Safari include the padding in the width, leading to undesirable results.
For example, if the cell is set to 16px wide + 4px of padding, IE9 correctly displays the cell as 20px wide. Chrome displays it as 16px wide.
Here is a JS Fiddle showing the differences: http://jsfiddle.net/CZnau/
You can see how the last cell is sized differently between browsers.
Notes
I am aware of box-sizing and even though the default is to not include the padding in width calculation of a cell, setting box-sizing: content-box explicitly does not fix the problem.
The fiddle shows a fixed layout table. I wish to use table-layout: fixed to handle display correctly in other scenarios. Specifically, my actual implementation uses text-overflow, wrapping management, and variable width layouts. In my testing using a fixed layout is the only reliable way to make all my requirements play together nicely. Plus, fixed layout tables potentially render more quickly.
I have tried setting the width explicitly on each TD, but this does not fix the issue (perhaps it conflicts with the fixed layout table?)
In case you want more details around why I need a fixed layout table, try this fiddle with and without table-layout: fixed and note the differences. With a fixed layout, the table is correctly sized to 100% and truncates text elegantly, even with a variable width cell.
http://jsfiddle.net/6GPmY/
Firefox doesn't support box-sizing: content-box; yet, not even in their Aurora Version.
Until then you can use -moz-box-sizing:
th, td {
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 8px;
}
jsFiddle Demo

Resources