css 高度塌陷_web前端入门到实战:CSS 负边距的行为表现

96920bc474d198bf5759b392c4fa989b.png

CSS 中的负边距

margin 是可以设置为负值的,这会帮你实现靠近顶部/左边相邻元素的效果,或者实现靠近底部/右边相邻元素的效果。

先介绍下我们的测试元素:一个简单的包含三个段落的容器元素。注意,段落设置了固定宽度 250px

<div class="test-container"> <p>First paragraph with a bit of text in it to provide some content.</p> <p>Second paragraph with a bit of text in it to provide some content.</p> <p>Third paragraph with a bit of text in it to provide some content.</p>

</div>

<style>
* { box-sizing: border-box; }
.container {
  border: 5px double;
  width: 300px;
  padding: 0 10px;
}

.container p {
 border: 1px solid;
  width: 250px;
}
</style>

效果:

9b7c88445053b52358a355630e6369f0.png

负边距 margin-top/bottom

先给第一段文本 margin-bottom: -15px,结果第二段文本的经浏览器重新计算,向上提升了 15px

7332e7df067fa14e3d54180f61b5fb62.png

第二段文本作为邻居紧跟在第一段文本后面,第二段文本和第三段文本之间的间距没有变化,整体依旧是垂直布局。

这个技巧比较适合用来微调位置,如果一个元素想要轻微的盖住前面一个元素的话,可以使用它。

现在恢复布局,给第二段文本 margin-top: -15px 看看效果。

c437e18510a62ea548d37a1fefc2de56.png

可以看见,跟在第一段文本使用 margin-bottom: -15px 的效果一样。第二段文本在此被向上提升了 15px。通过在浏览器控制台查看,第一段文本的 margin-bottom 仍是默认的 1rem

边距合并(Margin collapsing)

边距塌陷行为在负边距上的行为是不同的。

针对负边距场景:如果相邻两元素中一个是正边距,一个负边距,则 相邻间距(adjoining margin)= 正边距 - 负边距绝对值(结果两元素相交和相离,取决于谁的绝对值更大);如果相邻两元素中没有正边距,则 相邻边距 = 0 - 边距 1 绝对值 - 边距 2 绝对值(结果两元素相交)。

对正边距来说,规则是这样的:浏览器会比较第一段文本的 margin-bottom 和第二段文本的 margin-top,谁的值大,最终间距就是谁,以 margin-bottom: 16pxmargin-top: 4px 为例,那么最终的间距为 16px;而对存在负边距的场景就不是这样了,像上面一个是 margin-bottom: 1em(假设是 16px),一个是 margin-bottom: -15px,那么按照规则,最终的间距是 16px - 15px,得 1px,因为是正值,所以表示两者相离 1px 的距离。

可以看见,我们可以使用负边距达到两元素相互靠近的布局,而不会受到边距合并的影响。

到这里,算是介绍完负边距 margin-top/bottom 的情况了。

负边距 margin-left/right

负边距 margin-left/right 的工作方式与 margin-top/left 一样,元素还是有一个固定宽度。下面分别给第一和第二个文本段落设置 margin-left: -10pxmargin-right: -10px

72e57888a78188022e706b73ff761a2d.png

可以看见,第一个段落向左偏移了 10px,宽度没有变化,同时右边缘也向左移动了 10px

第二个段落的负 margin-right 值没有起作用。因为 margin-right 负值影响的是第二个段落右面的元素,当前第二个段落右边是没有元素的,因此看不到效果。

为了展示 margin-right 负值效果,需要将段落元素设置成浮动的,这样就有右边的相邻元素了。

df3a9f2a60bcb4917885ad1b01332c21.png

现在在段落上设置负边距。

8b10ac4d870261eb58b50405e8dc2268.png

可以看见,因为第一个段落设置了 margin-right: -10px,导致第二个段落向左偏移 10px。这跟之前看到的 margin-bottom 负值的效果是一样的。

同时,第二个段落设置了 margin-top: -10px,于是向上偏移了 10px。第三个元素设置了 margin-bottom: -10px,但没有效果,是因为底部没有元素。

注: margin-bottom: -10px 产生了影响,效果没有出来不只是因为底部没有元素——我们将第一个元素删除,就能看到父元素高度塌陷了,塌陷的高度正好等于第三个段落元素的负边距绝对值,即 10px(如下图)。而之前没有塌陷的原因是因为第一个元素的高度撑开了父元素,导致父元素高度无法塌陷。

7d1a871f00c5d9ec1217ff5c3cd41c16.png
<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">GIF.gif</figcaption>

需要注意的是,边距合并只适用于 margin-topmargin-bottom 属性,不对 margin-leftmargin-right 起作用,所以不用担心这里的左右边距的合并问题。

如果,我们只是给第二个段落设置 margin-left: -10px,能看到同样的效果。

b7f029296d40470948c10c5a4133d247.png

可以看见,在元素固宽情况下,margin-leftmargin-right 负值的行为表现跟 margin-topmargin-bottom 负值的行为表现是一样的。

width: automargin-right 负值

现在不为段落设置固定宽度,而是让它们使用默认的 width: auto 设置观察 margin-right 的负值行为表现。默认情况下,width: auto 段落元素默认会充满在父元素宽度,同时受限于父元素的 padding

现在分别给第一和第二个段落设置 margin-left: -10pxmargin-right: -10px,第三个元素同时设置 margin-left: -10pxmargin-right: -10px 查看效果。注意,为了方便对照,这里加入了一个参考元素(Reference paragraph):

91932006211cd97e0b799e3a38d62418.png

观察发现:第一个段落向左偏移了 10px,宽度增加了,右边缘未受到影响,位置未变;第二个段落向右偏移了 10px,宽度增加了,左边缘未受到影响,位置未变。这种情况,只在 width: auto 下发生,这与固定宽度的元素表现是不一样的。

第三个段落的左右两端都使用负边距值,导致左右都向外延伸了 10px 的距离,正好抵消了容器元素左右 10pxpadding。这是负边距最常用的应用场景——为了让内容与容器间保持一定的留白间隙,容器设置了 padding,但是内容里的一个标题需要延伸到整个容器的宽度展示(不畏外部 padding 值),这就到使用负边距的时候了。

eb5d1f8dc48408dffa6c98dcce16529c.png

这里贴出了上面结构的样式(容器元素设置了 padding: 10px)。

h5 { margin-left: -10px; margin-right: -10px; padding-left: 10px; margin-top: 0; margin-bottom: 0; background-color: grey; color: white; /* no width, so defaults to width: auto */ }复制代码

再一次要说明的是,这只在标题元素 width: auto 的情况下才能生效,不过这已经覆盖 99% 的实际使用场景了。

以上即是对负边距在简单场景下行为表现的阐述,以此为基础,我们就可以进一步研究负边距在弹性布局和网格布局中的行为表现了。

从最零基础开始的的HTML+CSS+JavaScript。jQuery,Ajax,node,angular框架等到移动端HTML5的项目实战【视频+工具+系统路线图】都有整理,在线解析,学习指导,点:【WEB前端学习圈⑤】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值