leaking margin: unexpected offset due to nested DIVs - html

I have some unexplained weirdness with a nested DIV's margin "leaking" out of the parent container .
The following test case* probably explains it best:
http://jsbin.com/ibaze
The outer wrapper (red) doesn't start at the very top - unless there's a text node or overflow: auto; on that element.
(Tested on Firefox and Safari.)
While overflow allows me to work around the issue, I'd quite like to know why it is happening in the first place.
Any insights would be appreciated!
* it's a minimal test case except for the script at the bottom, which merely illustrates the workarounds

The reason why it is not working is that your vertical margin in CSS is collapsing, which is expected behavior.
Remove the margin from #inner, and instead specify a padding: 50px; to your #outer to get the desired result:
* {
margin: 0;
padding: 0;
}
body {
color: white;
background-color: blue;
}
#outer {
padding: 50px;
background-color: red;
}
#inner {
background-color: green;
}
For more information on Vertical Margin Collapsing, I recommend you read the following article:
CSS - Auto-height and margin-collapsing

Related

Why some html and body properties have this behaviour?

I'm trying to understand a few things.
First question:
Why there is a margin-top on the body?
html {
height: 100%;
background-color: red;
}
body {
height: 100%;
margin: 0;
background-color: yellow;
}
<h1>Hello Plunker!</h1>
If I look with dev tool inspector in Chrome, it shows me that the h1 top margin starts outside the body top margin (picture shows the h1 highlighted):
Second question:
In the next example, why does the yellow color is drawn outside the body?
I expected to see yellow color only within the body element, given that I set overflow property:
body {
height: 100px;
background-color: yellow;
margin: 0;
overflow: hidden;
}
Third question
If I add a background-color on the html element, it works, the yellow color fills only the body element, why?
html {
background-color: red;
}
body {
height: 100px;
background-color: yellow;
margin: 0;
overflow: hidden;
}
Your First Question
Why there is a margin-top on the body?
Answer Is
It is because of h1 tag, h1 takes margin from top and bottom. Your point is appriciatable that html (red color) is showing.
Its the default behavior. it will work fine when you add float to h1
h1{float: left;}
Your Second Question
I expected to see yellow color only within the body element, given
that I set overflow property
Answer Is
overflow only works when you apply fix width/height to any tag/class.
if you apply overflow hidden to html/body it doesn't works, i think its the default behavior of the browser like firefox as well as others may be. Because same thing happened to me as well.
Third Questions answer also summarized in Answer of Second Question
i hope it would be helpful. Thanks
Set margin: 0 to h1 and add padding instead, will solve your issue.

Why content won't take a different background color?

I have the whole page set to gray as the background color, but would like only the content area to be set to a different color. According to my CSS, this should be happening but it isn't. Why not?
html,
body {
background-color: #FAFAFA;
}
#page-wrapper {
margin: 0 auto;
padding: 0;
width: 1024px;
}
#content {
background-color: blue;
}
OK, well, I thought there might be an obvious answer, because this is a severly slimmed-down version of my code. Yes it has content and there are things in the page-wrapper.
The jsfiddle link is here: http://jsfiddle.net/2pzo80Lu/
Also, if anyone has critiques of the code otherwise, it would be much appreciated.
You need to add overflow:auto to your rules for #content because the children are floated. Floating them essentailly removes them from the normal flow and collapses the parent since it behaves as if there's no content. Adding the overflow rule restores the behavior you seek.
#content {
background-color: blue;
overflow:auto;
}
jsFiddle example
your elements inside #content div is floated right and left so the div has no height ( 0px ) , you can solve this in css by adding the following code
#content {
background-color: blue;
overflow:auto;
}
or in html by adding the following code before the close of the element of #content
<div style="clear:both;"></div>
this will clear any floating and you code should work very will. good luck

What would a negative margin on all four sides do in CSS?

If I wrote this:
#element {
margin-top: -50px;
}
By general rule, it would move the element upwards by 50 pixels.
Recently, I accidentally used this bit of code instead:
.elements {
margin: -50px;
}
So I had these <div> tags, one beneath the other, and by writing margin: -50px; they all somehow got closer together.
But thinking in retrospect, I don't really see how this worked. The size of the elements didn't change (as far as I know, as they contained child elements, and the child elements were closer together as well), and they didn't seem to zoom in size or anything.
I did some research online, but all I could find was for negative margins on one or two sides at most.
Is there an explanation to this? What actually happens? Maybe it's because I'm using Google Chrome, and maybe nothing happens in other browsers?
Tha margin is not added to the appearance of the element but rather to its bounds, so basically your element looks e.g. 200x200 but its bounds are equal to that of an element of 100x100 since you substract 50px from every side. Try it for yourself:
Fiddle here.
HTML:
<div class="e1"><div></div></div>
<div class="e2"><div></div></div>
CSS:
body {
padding: 100px;
}
div {
width: 200px;
height: 200px;
float: left;
margin: -50px;
}
.e1 {
background: red;
}
.e2 {
background: yellow;
}
.e1>div, .e2>div {
width: 100px;
height: 100px;
outline: 1px solid blue;
margin: 50px;
}
I've added a padding to the body to make the elements be pushed down so you can see the overlap they cause. Updated so you can see the bounds of the squares that result.

How can I fix this strange box model behaviour of Webkit browsers?

I came across a very strange behaviour of Webkit browsers today: It concerns the way a margin is calculated next to other (floated) blocks.
Though I think this must be a common problem, I couldn't find anything about it so far.
Here's my situation: I have two <aside>s followed by a <div>. They are all displayed next to each other, the <div> on the left then .#aside-1 and #aside-2. I achieve this throught the following CSS code:
aside {
margin-bottom: 30px;
padding: 0px 10px 10px;
width: 180px;
}
#aside-1 {
float: right;
margin-left: -400px;
margin-right: 200px;
}
#aside-2 {
float: right;
}
div {
overflow: auto; /* Block formatting context */
margin-right: 400px;
padding: 0px 10px 0px 20px;
}
This works fine in Firefox and IE>6.
However, what happens in Chrome and Safari is that the margin-right of the div isn't calculated from the right boundary, but is instead only calculated from the left of aside-2. This causes the div to be 200 pixels (width + padding of sidebar-2) too small.
What causes this Webkit behaviour and how can I fix it?
Anyway, thanks a lot for your help in advance!
OK, so I tested a bit more and came up with a simple solution):
Just give the div a fixed width. This of course only works if your layout is based on fixed widths, which is the case for me.
Try with CSS RESET, that should work.
Here's one : http://html5doctor.com/html-5-reset-stylesheet/

CSS fluid layout without tables

Everything online points me to stop using tables, which I've tried my best to do, but I've come across a problem which tables seems to be the only solution for. I have 5 inline-block elements that I want spaced evenly across 100% of the width of the page. I put a width of 20% on the style and set the margin and padding to zero. When I view the page, everything looks pretty good except for the horizontal scrollbar added to the page. If I put these elements in a 100% width table with 5 columns this isn't a problem. In this case do I need to use a table or is there a better solution?
BTW, I've tried this in both Chrome and IE8.
Update: Something I've discovered is that a ~5px gap is being inserted between my elements (found by putting a background-color on them). I have no clue why, as nothing in my styles denotes this:
<div class="links">
Previous
Current
Next
01/01/2011
01/08/2011
</div>
.links
{
white-space: nowrap;
width: 100%;
}
.links a
{
display: inline-block;
width: 20%;
padding: 0;
margin: 0;
color: White;
background-color: #4C8331;
}
Another update:
After JMC Creative pointed out my dumb mistake of putting spaces between the anchors that almost fixed the issue, but now there is one pixel of scrollbar. I see no inherited style that should cause this.
Try putting them in a container. Like so:
#container {
margin: 0;
padding: 0;
width: 100%;
}
#boxes {
float: left;
width: 20%;
}
Your html markup has a space in between the a tags. So therefore it's being rendered as 5 blocks which are 20% wide and 4 spaces of roughly 4px each. So you end up with 100% + 16px.
Edit
In order to solve the scrollbar that is plaguing you in IE, you could set up a conditional comment like so:
<!--[if IE]>
<style type="text/css"> .links { overflow: hidden; } </style>
<![endif]-->
Be sure your body and html set to margin: 0; padding: 0;.
Have you tried using overflow: hidden? Or more specifically overflow-y: hidden?
You want to float your anchors. Doing it this way works for me.
CSS:
.links {
width: 100%;
}
.links>a {
float: left;
display: inline-block;
width: 20%;
padding: 0;
margin: 0;
color: #fff;
background-color: #4C8331;
}
HTML:
<div class="links">
Previous
Current
Next
01/01/2011
01/08/2011
</div>
You may get a scrollbar or see some of the anchors wrapped to another line if there isn't room to fit them all on the page (ie, content overflows the width). I will note that I have seen IE get this wrong and incorrectly wrap when it shouldn't. It seems like a rounding issue and could be worked around.