【问题标题】:How to disable margin collapse between sibling elements如何禁用兄弟元素之间的边距折叠
【发布时间】:2016-05-17 08:53:20
【问题描述】:

可能这是非常愚蠢且众所周知的技巧,但我还没有找到任何解决方法。我试过“overflow”、“content: ' '; display: table;”、padding1pxborder。没有成功。所以我为这个问题做了一个小例子。

有 2 个块元素:带有下边距的页眉和带有上边距的页脚。任务是让边距相加:50 + 49 = 99 px!

.main-header {
  margin-bottom: 50px;
}
.main-footer {
  margin-top: 49px;
}
<h1>if distance btw H.&amp;F. is 99 px then margins don't collapse! Unfortunatelly, is is</h1>

<header class="main-header">
  HEADER Lorem ipsum dolor.
</header>

<footer class="main-footer">
  FOOTER <span>&copy;2015 Lorem ipsum dolor.</span>
</footer>

【问题讨论】:

    标签: css margin


    【解决方案1】:

    您可以浮动它们以禁用折叠边距,使用width:100% 使它们占据整个宽度,而不是由内容决定。

    .main-header,
    .main-footer {
      float: left;
      width: 100%;
    }
    .main-header {
      margin-bottom: 50px;
    }
    .main-footer {
      margin-top: 49px;
    }
    <h1>if distance btw H.&amp;F. is 99 px then margins don't collapse! Unfortunatelly, is is</h1>
    
    <header class="main-header">
      HEADER Lorem ipsum dolor.
    </header>
    
    <footer class="main-footer">
      FOOTER <span>&copy;2015 Lorem ipsum dolor.</span>
    </footer>

    【讨论】:

      【解决方案2】:

      您可以添加一个简单的floatclear:both,使用::before::after 伪元素。

      根据 MDN:

      保证金崩溃发生在三种基本情况:

      相邻的兄弟姐妹 相邻兄弟的边距被折叠(除非后面的兄弟需要清除浮动)。

      .main-header::after, .main-footer::before {
        content:'';
        float:left;
        width:100%;
        clear:both;
      }
      
      .main-header::after {
        margin-bottom: 50px;
      }
      
      .main-footer::before {
        margin-top: 49px;
      }
      <header class="main-header">
        HEADER Lorem ipsum dolor.
      </header>
      
      <footer class="main-footer">
        FOOTER <span>&copy;2015 Lorem ipsum dolor.</span>
      </footer>

      【讨论】:

        【解决方案3】:

        由于有adjacent siblings 并且由于边距折叠占用了更高的边距,我们使用了 + CSS 运算符,以便当 headerfooter 之间没有其他元素时,我们将footermargin-top增加到99px

        JS Fiddle

        .main-header {
          margin-bottom: 50px;
          background-color: orange;
        }
        .main-footer {
          background-color: skyblue;
          margin-top: 49px;
        }
        .main-header + .main-footer {
          /* only when there's no other elements between header and footer this will be applied */
          margin-top: 99px;
        }
        <header class="main-header">HEADER Lorem ipsum dolor.</header>
        
        <footer class="main-footer">FOOTER <span>&copy;2015 Lorem ipsum dolor.</span></footer>

        【讨论】:

          【解决方案4】:

          首先,发布的flexbox solution that @Nenad Vracar 是最有效的。


          几种选择
          假设问题是您不知道两个标签之间是否有某些东西,您可以在这种情况下使用额外的选择器(虽然如果两个标签之间只有文本,它会失败,因为它仍然会应用 99 边距)

          .main-header + .main-footer{margin-top:99px;}
          <h1>if distance btw H.&amp;F. is 99 px then margins don't collapse! Unfortunatelly, is is</h1>
          
          <header class="main-header">
              HEADER Lorem ipsum dolor.
          </header>
          
          <footer class="main-footer">
              FOOTER <span>&copy;2015 Lorem ipsum dolor.</span>
          </footer>

          现在,根据您的情况,您可以使用您提到的技巧并将边距传递给伪元素。

          .main-header:after {
              content: '';
              margin-bottom: 50px;
              display: table;
          }
          
          .main-footer:before {
              content: '';
              display: table;
              margin-top: 49px;
          }
          
          .main-header,
          .main-footer {
              overflow: auto;
          }
          <h1>if distance btw H.&amp;F. is 99 px then margins don't collapse! Unfortunatelly, is is</h1>
          
          <header class="main-header">
              HEADER Lorem ipsum dolor.
          </header>
          
          <footer class="main-footer">
              FOOTER <span>&copy;2015 Lorem ipsum dolor.</span>
          </footer>

          【讨论】:

            【解决方案5】:

            您可以使用 Flexbox,因为它没有 collapsing margins

            .content {
              display: flex;
              flex-direction: column;
            }
            
            .main-header {
              margin-bottom: 50px;
            }
            .main-footer {
              margin-top: 49px;
            }
            <div class="content">
              <header class="main-header">
                HEADER Lorem ipsum dolor.
              </header>
            
              <footer class="main-footer">
                FOOTER <span>&copy;2015 Lorem ipsum dolor.</span>
              </footer>
            </div>

            【讨论】:

            • +1 因为我正在使用 flexbox 期望折叠边距并开始拉我的头发,因为它们不会折叠。你能在规范中引用它们不会崩溃的地方吗?
            • 要添加此内容,请将align-items: flex-start 放在.content 上,这样您的元素就不会拉伸。他们的默认设置是不拉伸。