关于元素设置margin-top能够改变body位置的原因及解决(子元素设置margin-top改变父元素定位)
关于元素设置margin-top能够改变body位置的原因及解决(子元素设置margin-top改变父元素定位)
起因:在进行bootstrap的.navbar-brand内文字设置垂直居中时采用line-height=高度,无法居中,发现源码.navbar-brand 设置了 padding: 15px 15px;(默认导航高度为50),于是居中应该是等于高度-30,解决过程中写了几个div用于检测问题,结果遇到了以下问题,经过数小时的研究(时间大多花费在百度与谷歌上,以及研究原因上),于是写下这篇文章做个总结,加深个人记忆。
我写了两个div,从上往下分别标记为div1和div2,设置了相同的margin与高宽,然后给div1设置左浮动。那么根据我薄弱的基础判断,这时候刷新页面应该出现的是两个div重叠在一起,只显示一个div,但是结果出现了偏差,两个div并没有叠加显示,并且div1出现在了div2下方。
(F5后的显示)
预期的结果并没有出现,然后开始排查写的代码,发现问题出现在margin上,清除div的maring后元素显示正常,不会出现错位。
(清除了margin之后的正常状态)
由于margin-left是正常的,所以显然是margin-top的设置出现了些问题,于是推理查找问题,n分钟后得出如下结论
正常文档流状态下,div1浮动,脱离了文档流,然后div2这时候依旧处在文档流状态,于是向上移动至div1浮动前的位置,这时候body的位置发生改变,向下移动了div2设置的margin-top的距离,(又一个问题出现了,为什么div2设置的margin能够改变body的位置,或者说是父元素的位置!好吧,这个问题经过百度与测试后发现是个固有问题,在文章末尾做详细说明)。
(蓝色部分是body)
而div1这时候处于浮动状态,由于同样设置了margin,所以浮动后同样会改变位置,div1浮动后根据body的位置重新进行定位,所以div1浮动后,两个div的位置不会重合。(解决方法-给body添加padding-top,或者border——详情见结尾。)
(可以很明显看出div2根据body进行了margin定位)
两个div的css如下:
1 div:nth-child(1){ 2 float: left; 3 margin: 50px; 4 width: 200px; 5 height: 200px; 6 border: 10px solid #000; 7 }
8 div:nth-child(2){ 9 margin:50px; 10 width: 200px; 11 height: 200px; 12 border: 10px solid #000; 13 }
关于子元素的margin-top会改变父级元素的位置,(也就是div2的margin-top改变了body位置),以下。
这个问题发生的原因是根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠。再说了白点就是:父元素的第一个子元素的上边距margin-top如果碰不到有效的border或者padding.就会不断一层一层的找自己 “领导”(父元素,祖先元素)的麻烦。只要给领导设置个有效的 border或者padding就可以有效的管制这个目无领导的margin防止它越级,假传圣旨,把自己的margin当领导的margin执行。 对于垂直外边距合并的解决方案上面已经解释了,为父元素例子中的middle元素增加一个border-top或者padding-top即可解决这个问题。