如何解释下面这个css现象

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="renderer" content="webkit">
  <title>Document</title>
  <style>
    div {
      /* border: 1px solid #000; */
      width: 50%;
      margin: 0 auto;
      font-size: 16px;
      text-align: center;
    }

    #dot {
      margin-bottom: 50px;
    }
    h1 {
      margin: 0 auto;
      width: 20px;
    }
  </style>
</head>

<body>
  <div>
    <p id="height"></p>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>
    <p>6</p>
    <p>7</p>
    <p>8</p>
    <p>9</p>
    <p id="dot">.</p>
  </div>
  <h1>hello</h1>
  <script>
    window.onload = function () {
      function animate() {
        document.getElementById('height').innerHTML = window.getComputedStyle(document.body.firstElementChild).height;
        var dot = document.getElementById('dot');
        var m = window.getComputedStyle(dot).marginBottom;
        console.log(m);
        m = parseInt(m);
        m -= 1;
        document.getElementById('dot').style['margin-bottom'] = m + 'px';
        requestAnimationFrame(animate);
      }
      animate();
    }
  </script>
</body>

</html>

脚本的内容是把div元素的最后一个子元素的marginBottom值不断减少,并把div的元素的高度输出到div的第一个子元素中
其中当div元素设置了边框的时候,减少最后一个元素的marginBottom值会发现div这个父元素的高度在不断减少
当div元素不设置边框的时候,减少最后一个元素的marginBottom值会发现div这个父元素的高度不再变化
而且下面定义的h1的hello在以上的两种情况下都可以穿透div里面的文本
请问一下如何解释这种现象

阅读 1.7k
2 个回答

个人认为这是外边距合并的问题。

如果在父元素与其最后一个子元素之间不存在边框、内边距、行内内容、height、min-height、max-height将两者的 margin-bottom 分开,那么这两对外边距之间会产生折叠。此时子元素的外边距会“溢出”到父元素的外面。

问题一

div元素不设置边框的时候,减少最后一个元素的marginBottom值会发现div这个父元素的高度不再变化。

这是因为设置在dot元素上的外边距相当于转移到父元素上,所以通过window.getComputedStyle(document.body.firstElementChild).height取到的div的content-box高度是不会发生变化的。

问题二

当div元素设置了边框的时候,减少最后一个元素的marginBottom值会发现div这个父元素的高度在不断减少。

设置边框后外边距不再合并,所以div父元素content-box为子元素的border-box高度总和,会随着dot元素的marigin-bottom减少而减少。

问题三

下面定义的h1的hello在以上的两种情况下都可以穿透div里面的文本。
  1. 有边框时因为div高度减少所以h1的布局位置上移;
  2. 没有边框时,因为div有负的margin-bottom所以布局位置上移。

你应该是理解上出现了偏差,设置元素的margin-bottom,并不会改变元素的height的应用值,height属性只是其内容区的高度。
对于现象解释,首先要知道:块级元素正常布局时,盒子间的距离是由margin边决定的。
第一个情况:因为外边距合并,两个盒子的距离就是负数了,效果就是hello上移(为什么负margin会上移,我也没找到相关介绍,可能因为是各大浏览器厂商的共识吧),所以会穿透文本
第二个情况:因为第一个盒子高度是auto,根据布局规则#dot设置负margin会导致它的高度变矮,然后hello和它距离不会变化,但它的overflowvisible所以内容会溢出,看起来也是hello穿透文本

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题