207

My css margins doesn't behave the way I want or expect them to. I seems like my header margin-top affect the div-tags surrounding it.

This is what I want and expect: What I want....

...but this is what I end up with: What I get...

Source:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Margin test</title>

<style type="text/css">
body {
    margin:0;
}
#page {
    margin:0;
    background:#FF9;
}
#page_container {
    margin:0 20px;
}
h1 {
    margin:50px 0 0 0;
}
</style>

</head>

<body>

<div id="page">
    <div id="page_container">
        <header id="branding" role="banner">
            <hgroup>
                <h1 id="site-title"><span><a href="#" title="Title" rel="home">Title</a></span></h1>
                <h2 id="site-description">Description</h2>
            </hgroup>
        </header>
    </div>
</div>

I have exaggerated the margin in this example. Default browser margin on h1-tag is somewhat smaller, and in my case I use Twitter Bootstrap, with Normalizer.css which sets default margin to 10px. Not that important, main point is; I can not, should not, want not change the margin on the h1-tag.

I guess it is similar to my other question; Why does this CSS margin-top style not work?. Question is how do I solve this specific issue?

I have read a few threads on similar problems, but haven't found any real answers and solutions. I know adding padding:1px; or border:1px; solves the problem. But that only adds new problems, since I do not want a padding nor a border on my div-tags.

There must be a better, best practice, solution? This must be pretty common.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
lejahmie
  • 17,938
  • 16
  • 54
  • 77

7 Answers7

270

Add overflow:auto to your #page div.

jsFiddle example

And check out collapsing margins while you're at it.

j08691
  • 204,283
  • 31
  • 260
  • 272
  • 4
    That works. Found loads of examples here ( http://www.seifi.org/css/understanding-taming-collapsing-margins-in-css.html ) aswell and some good explaining. No solution is really 100% satisfying. But I guess one just have to live with it, margin must work this way or text formatting would be impossible. 99% of time it works as needed. But every now and then comes the issue when designing a layout. :P – lejahmie Nov 26 '12 at 22:38
  • 8
    overflow:hidden; also worked for me and worked better for me in my scenario. – stuyam Dec 21 '14 at 15:24
  • 4
    Collapsing margins look incredibly complicated to define (many rules, many exceptions), what's it use? – estani Nov 26 '19 at 11:29
  • 3
    `display: flex` with `flex-direction: column` on parent container does the same trick. – Maksim Shamihulau Dec 06 '20 at 07:32
60

Add any one of the following rules:

float: left/right;
position: absolute;
display: inline-block;
overflow: auto/scroll/hidden;

This is caused by collapsing margins. See an article about this behavior here.

According to the article:

The W3C specification defines collapsing margins as follows:

“In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding, or border areas, or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.”

This is also true for parent-child elements.

All the answers include one of the possible solutions:

There are other situations where elements do not have their margins collapsed:

  • floated elements
  • absolutely positioned elements
  • inline-block elements
  • elements with overflow set to anything other than visible (They do not collapse margins with their children.)
  • cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
  • the root element
Mladen Janjetovic
  • 13,844
  • 8
  • 72
  • 82
Ziarno
  • 7,366
  • 5
  • 34
  • 40
22

Problem was the parent not taking into account children for height. Adding display:inline-block; did it for me.

Full CSS

#page {
    margin:0;
    background:#FF9;
    display:inline-block;
    width:100%;
}

See Fiddle

Dave Loepr
  • 946
  • 1
  • 7
  • 13
5

Just add border-top: 1px solid transparent; to your #page element.

From w3.org

Two margins are adjoining if and only if:
- no line boxes, no clearance, no padding and no border separate them

Reed
  • 14,703
  • 8
  • 66
  • 110
Amid
  • 185
  • 2
  • 8
  • It worked for me. While I like the `overflow:auto;` solution better, i thought this was cool. I thought the reference to w3 would be useful, so I added it to your answer. – Reed Feb 13 '20 at 21:28
3

Add the following rule:

overflow: hidden;

This is caused by collapsing margins. See an article about this behavior here.

According to the article:

If a parent element does not have any top padding or less top margin then its first child, then elements are rendered in a way that makes the parent element appear to have the child element's margin. So this can happen anywhere on a page where these conditions are met, but it tends to be most obvious at the top of a page.

nahid
  • 81
  • 10
0

The solutions in the other answers didn't work for me. Transparent borders, inline-block, etc., all caused other problems. Instead, I added the following css to my ancestor element:

parent::after{
  content: "";
  display: inline-block;
  clear: both;
}

Depending on your situation, this may cause its own problems because it adds extra space after the last child element.

Trevor
  • 13,085
  • 13
  • 76
  • 99
0

My approach when I was making styles for XenForo 2.1, but it should be useful for you: (Please replace those LESS variables to your actual values. Also, the absolute value of minor margins shall be as same as the height of before-after pseudo elements.)

// The following two lines are to avoid top & bottom fieldset borders run out of the block body.
// (Do not tweak the CSS overflow settings, otherwise the editor menu won't be float above the block border.)
&:before {content: "\a0"; display: block; width: auto; margin-bottom: floor(-1 * @xf-lineHeightDefault * @xf-fontSizeSmall - @xf-borderSizeMinorFeature);}
&:after {content: "\a0"; display: block; width: auto; margin-top: floor(-1 * @xf-lineHeightDefault * @xf-fontSizeSmall - @xf-borderSizeMinorFeature);}
Shiki Suen
  • 67
  • 1
  • 9