zoukankan      html  css  js  c++  java
  • CSS外边距合并&块格式上下文

    前言

    之前在前端开发的过程中,都没有遇到外边距合并的问题(其实是因为大多时候都直接用前端样式库(〃'▽'〃)),这一次需要动手排一个页面,也挺简单,但是遇到了一个奇怪的问题,所以学习记录一下。

    问题

    测试代码如下:

    <!doctype html>
    <html class="no-js" lang="">
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>test</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <style>
    * {
        margin: 0;
        padding: 0;
    }
    
    body {
        max- 750px;
        margin: 0 auto;
    }
    
    .div1 {
        background: yellow;
        height: 200px;
    }
    
    .div2 {
        background: blue;
        height: 200px;
    }
    
    .div2Child {
        background: red;
        height: 100px;
    }
    </style>
    
    <body>
        <div class="div1">我是吃瓜群众</div>
        <div class="div2">
            <div class="div2Child" style="margin-top: 50px">我是子div</div>
            <p style="color: white">我是父div</p>
        </div>
    </body>
    
    </html>


    子div设置了margin-top之后,父div也跟着一起margin-top了。

    原因如下:

    Margin Collapsing 外边距合并

    块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,其大小是组合到其中的最大外边距,这种行为称为外边距塌陷(margin collapsing),或外边距合并。

    外边距合并的3中基本原因:
    1、相邻的元素
    毗邻的两个兄弟元素之间的外边距会合并

    2、块级父元素与其第一个/最后一个子元素

    • 如果块级父元素中,不存在border, padding, inline part, block formatting context created, or clearance 来隔离第一个子元素的上边距,就会发送外边距合并现象。
    • 如果块级父元素,不存在border, padding, inline content, height, min-height, max-height来隔离下边距,则会和最后一个子元素合并。

    3、空块元素
    如果存在一个空的块级元素,不存在 border、padding、inline content、height、min-height来隔离上下外边距,那么它的上下外边距将会合并。

    • 当都为正数时,取两者中较大者。
    • 当都为负数时,取绝对值较大者。
    • 当一正一负时,取相加之和。
    • 外边距设为0时,这些规则也仍旧生效。

    BFC(Block Formatting Context 块格式化上下文)与元素外边距合并 :

    • 当两个元素属于不同的BFC时,这两个元素的外边距不会合并
    • 但在同一个BFC内,两个相邻元素的外边距仍会合并。

    Block Formatting Context 块格式化上下文

    一个块格式化上下文(block formatting context) 是Web页面的可视化CSS渲染出的一部分。它是块级盒模型出现的区域,也是浮动元素与其他元素进行交互的区域。

    一个块格式化上下文由以下之一创建:

    • 根元素或一些包含它的元素
    • 浮动元素 (元素的 float 不是 none)
    • 绝对定位元素 (元素的 position 为 absolute 或 fixed)
    • 内联块 (元素具有 display: inline-block)
    • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
    • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
    • display隐式创建的匿名表格列,包括table, table-row, table-row-group, table-header-group, table-footer-group (这些都是html的默认样式), or inline-table
    • 具有overflow 且值不是 visible 的块元素,
    • display: flow-root
    • flex 项目
    • grid 项目
    • 多列容器(column-count 和 column-width 不是 auto, 包括 column-count: 1的元素)
    • column-span: all 应当总是会创建一个新的格式化上下文,即便具有 column-span: all 的元素并不被包裹在一个多列容器中。

    解决方案

    知道了问题原因所在,以及了解了相关原理,就很好办了。
    1、给div2设置border
    为了不改变div2的大小,还需将设置 box-sizing为border-box将padding和border包含在定义的width和height之内

    .div2 {
        background: blue;
        height: 200px;
        border-top: 1px solid transparent;
        box-sizing: border-box;
    }

    2、去掉div2Child的margin,改为设置div2的padding

    .div2 {
        background: blue;
        height: 200px;
        padding-top:50px;
        box-sizing: border-box;
    }

    3、div2设置为内联元素

    .div2 {
        background: blue;
        height: 200px;
        display: inline-block;
         100%;
    }

    4、清除浮动
    所有浮动元素包含在div2内,增加样式clearfix

    .clearfix::before, .clearfix::after{
        overflow: hidden;
        display: table;
        visibility: hidden;
        content: '';
        clear: both;
    }

    或者创建一个新的BFC,使其在不同的上下文中,不合并外边距。
    5、给div2设置Position

    .div2 {
        background: blue;
        height: 200px;
        position: absolute;
         100%;
        max- 750px;
    }

    6、给div2设置float,注意后面的元素需要clear浮动

    .div2 {
        background: blue;
        height: 200px;
        float: left;
         100%;
    }

    7、给div2设置display

    .div2 {
        background: blue;
        height: 200px;
        display: inline-block;
        /*display: table;*/
         100%;
    }

    8、给div2设置flex

    .div2 {
        background: blue;
        height: 200px;
        display: flex;
        flex-direction: column;
    }

    9、给div2设置overflow

    .div2 {
        background: blue;
        height: 200px;
        overflow: hidden;
    }

    万变不离其宗

    参考

    https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
    https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context

  • 相关阅读:
    AES算法加解密Java工具类AESUtil
    并发与高并发(二十二)高并发の服务降级与服务熔断思路
    并发与高并发(二十一) 高并发の应用限流思路
    并发与高并发(二十)高并发の应用拆分思路
    da5_模块
    day5_集合
    day5_递归调用
    day5_判断价格输入是否是正整数或正小数
    day5_函数_判断小数
    day5_函数_文件读写_用一个函数来满足文件的读或者写_应用默认参数
  • 原文地址:https://www.cnblogs.com/leestar54/p/8087679.html
Copyright © 2011-2022 走看看