Child element margins leaking to the parent element

4

I did not find in the community anything that clarified my doubt, so let's go!

In the example below, I do not know why water loads, the margin property of the elements p and h1 exceed the limit of the parent element.

.div1 {
  background-color: cyan;
}
.div2 {
  background-color: lightblue;
}
<div class="div1">
  <p>paragrafo</p>
</div>
<div class="div2">
  <h1>titulo</h1>
</div>

Looking at the inspector view is this situation:

For what reason / reason is this happening?

Why is the margin not only limited within the parent element, thus increasing its height?

    
asked by anonymous 06.10.2016 / 16:04

2 answers

3

As this answer link

As W3 Collapsing Margins :

  

Adjacent margins of two or more boxes (which may or may not be siblings) can combine to form a single margin. It refers to this type of margins that combine in this way like "collapse" and the resulting combined margin is called "margin of collapse".

This is also explained link :

  For example, elements with float, absolute and elements with inline-block, table-cell, and table-captions are not actually block boxes, and block boxes with overflow other than overflow: visibile generate a new block for formatting the content .

     

In the context of a content format block, the "boxes" are placed vertically out one after the other, starting from the top of the contents of a block. The vertical distance between the boxes is determined by the margin property, the vertical margins between the level of the blocks are adjacent in the context of the context causing the collapse.

When collapse does not occur (merging of margins):

  • Horizontal margins.
  • Overflow elements that are different from visible, such as hidden and auto
  • Elements with float: left; or float: right;
  • Elements with position other than static
  

Note: I still want to improve the answer, because my English is a bit weak and sometimes I get lost in the direction of the sentence, other than the links quoted are outdate, p>

How to avoid collapse

  • In order for the margin to not affect the parent element you can apply a padding-top (if you use margin-top on the child element) and padding-bottom (if you use margin-bottom on the child element) on the parent element so it is fixed automatically:

    .pai1 {
        background: #f00;
        color: #fff;
    }
    
    .pai2 {
        padding: 1px 0; /* adiciona um px no topo e em baixo */
        margin: -1px 0; /* ajusta negativamente para que o padding aparente sumir */
        background: #00f;
        color: #fff;
    }
    
    .pai1 .filho, .pai2 .filho {
        margin: 20px 0;
    }
    <p>Teste</p>
    <!-- com o problema -->
    <div class="pai1">
        <div class="filho">teste</div>
    </div>
    
    <hr>
    
    <!-- sem o problema -->
    <div class="pai2">
        <div class="filho">teste</div>
    </div>
  • Using the pseudo element :before and :after :

    .pai {
        background: #f00;
        color: #fff;
    }
    
    .pai:before, .pai:after {
         content: " ";
         height: 0;
         display: block;
         overflow: hidden;
    }
    
    .pai .filho {
        margin: 20px 0;
    }
    <p>Teste</p>
    <div class="pai">
        <div class="filho">teste</div>
    </div>
  • Using overflow: hidden; (this may not have fixed height), this is perhaps the simplest way to resolve:

    .pai {
        background: #f00;
        color: #fff;
        overflow: hidden;
    }
    
    .pai .filho {
        margin: 20px 0;
    }
    <p>Teste</p>
    <div class="pai">
        <div class="filho">teste</div>
    </div>
  • 06.10.2016 / 16:45
    1

    Each browser has a default style sheet, see in your inspector that the style is referencing to user agent stylesheet .

    For example, for the element <h1></h1> , in the case of chrome you will have the following rule:

    h1 {
        display: block;
        font-size: 2em;
        -webkit-margin-before: 0.67em;
        -webkit-margin-after: 0.67em;
        -webkit-margin-start: 0px;
        -webkit-margin-end: 0px;
        font-weight: bold;
    }
    

    When an element does not have a css definition, it will always use the browser default, to ignore, just set a rule, see:

    h1 {
      margin: 0;
    }
    p {
      margin: 0;
    }
    .div1 {
      background-color: cyan;
    }
    .div2 {
      background-color: lightblue;
    }
    <div class="div1">
      <p>paragrafo</p>
    </div>
    <div class="div2">
      <h1>titulo</h1>
    </div>
        
    06.10.2016 / 16:20