GenweiWu / Blog

个人技术能力提升
MIT License
4 stars 0 forks source link

父div的高度被子div的padding影响 #64

Closed GenweiWu closed 5 years ago

GenweiWu commented 5 years ago

Tag: 外边距合并

GenweiWu commented 5 years ago
  <div class="outer" style="padding-top:0;padding-bottom:0;">
    <div class="inner"></div>
  </div>

  <div class="outer" style="padding-top:16px;padding-bottom:0;">
    <div class="inner"></div>
  </div>

  <div class="outer" style="padding-top:0;padding-bottom:16px;">
    <div class="inner"></div>
  </div>

  <div class="outer" style="padding-top:16px;padding-bottom:16px;">
    <div class="inner"></div>
  </div>
.outer{
  outline:1px solid blue;
  width:20%;
}

.inner{
  height:50px;
  background:orange;
  margin-top:10px;
  margin-bottom:-30px;
}

界面不太重要,大概是这样的: image

重点是,四个div的盒模型分别是: 1) image

2) image

3) image

4) image

GenweiWu commented 5 years ago

我的理解

子元素的margin实际上发生了外边距合并,但是padding会阻止对应位置的外边距合并, 即父元素的padding-top阻止了子元素的margin-top发生合并,反而看起来是子元素的margin-top生效了;类似的父元素的padding-bottom阻止了子元素的margin-bottom

所以有: 1) .inner的上下margin都发生外边距合并,看起来就是子元素的margin-top和margin-bottom都没生效,所以 高度=50

2) .outer设置padding-top使得.innermargin-top生效了, 所以 高度=50+10=60

3) .outer设置padding-bottom使得.innermargin-bottom生效了, 所以 高度=50-30=20

4) 参考得到 所以 高度=50+10-30=30

GenweiWu commented 5 years ago

发散问题1

  <div class="area">

    <div class="outer">
      <div class="inner"></div> 
    </div>

    <div class="outer">
      <div class="inner-holder"></div> 
    </div>

  </div>
.outer{
  outline:1px solid blue;
  width:20%;
  padding-top:16px;
  padding-bottom:16px;
}

.inner{
  height:50px;
  background:orange;
  margin-top:10px;
  margin-bottom:-30px;
}

.inner-holder{
  height:50px; 
  visibility:visible;
}

你会发现inner-holder没法模拟inner的位置(场景是我们需要实现一个滚动时,按钮看不见时浮动的效果,需要在按钮浮动时,模拟按钮的高度,否则会导致高度变化触发滚动事件死循环)

:)output

image

发现直接照抄height为50,会模拟的是82而之前是62 height_change

:)修复方法

方法1:在模拟时,照搬之前的margin的设置

.inner-holder{
  height:50px; 
  visibility:visible;
  margin-top:10px;
  margin-bottom:-30px;
}

方法2:模拟时重新计算高度

.inner-holder{
  height:30px; 
  visibility:visible;
}