CSS - 你遇到过子元素设置margin-top,影响父元素的情况吗

文章探讨了如何在HTML中避免子元素间的边距折叠问题,提供了添加元素、创建块级格式上下文、设置边框、padding、absolute定位和转换为行内块元素等七种解决方案,并指出为父元素创建块级格式上下文是最佳实践。
摘要由CSDN通过智能技术生成

难度级别:初级及以上                                 提问概率:60% 


例如在一个div盒子元素内,需要设置一个标题,我们用一个p标签做为这个标题元素。根据UI设计要求,标题元素需要距离父div元素20px,理所当然想到的就是为标题元素设置margin-top为20px,希望可以撑开距离顶部的距离。但根据经验可知,这样做是存在问题的,父div元素会紧跟着p元素向下20px,并没有达到撑开20px的效果。先来看一下最初的代码和下图的效果

HTML代码:
<div class="box">
    <div class="inner">
       <p class="title">标题内容</p>
    </div>
</div>

CSS代码:
<style>
* {
margin: 0;
padding: 0;
}
.box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
margin-left: 30px;
width: 300px;
height: 200px;
}
.title {
margin-top: 20px;
width: 100%;
text-align: center;
background: yellow;
}
</style>

 

目录

产生问题的原因 

1 添加一个元素

2 创建块级格式上下文

3 为父元素设置边框

4 为父div元素设置padding-top样式

5 为子标题元素添加padding-top样式

6 对标题元素使用absolute定位的方式

7 使标题元素变为行内块元素


 

产生问题的原因 

通过上图发现,原本很正常的代码,希望class为title的p标签和class为inner的div标签之间产生20px的间距,但却不经意间使class为inner的div标签与class为box的div标签之间产生了20px的间距,这并不是我们预期的效果。

这种效果也就是所谓的边距折叠,结合本场景的案例,意思就是相邻的class为inner和title两个元素,margin-top进行了折叠,浏览器会解析两个元素margin-top的最大值,并使用这个最大值。但需要注意的是,只有上下边距会产生折叠,左右边距不会产生折叠。

既然知道产生问题的原因,我们接下来尝试一些解决方案,使标题元素顶部,可以正常与父div元素产生20px的间距。

 

1 添加一个元素

产生问题的原因中有一个重要点,在于相邻的两个元素产生了边距折叠,那么使标题元素与父div元素不相邻,便可得到解决。我们在标题元素的上面添加一个div兄弟元素,设置其高度为20px。

HTML代码:
<div class="box">
<div class="inner">
<div class="blank-element"></div>
<p class="title">标题内容</p>
</div>
</div>
CSS代码:
<style>
.blank-element {
height: 20px;
}
</style>

 

通过上图可知,添加一个空白元素的方式,使得标题元素和父div元素产生了20px的间距。这样做虽然解决了问题,但多添加一个DOM元素的选择并不是明智的。 

 

2 创建块级格式上下文

我们知道创建块级上下文可以清除浮动,而这种办法也可以解决父子元素边距重叠的问题

HTML代码:
<div class="box">
<div class="inner">
<p class="title">标题内容</p>
</div>
</div>
CSS代码:
<style>
* {
   margin: 0;
   padding: 0;
}
.box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
overflow: hidden;
margin-left: 30px;
width: 300px;
height: 200px;
}
.title {
margin-top: 20px;
width: 100%;
text-align: center;
background: yellow;
}
</style>

 

通过为 .inner 类添加overflow:hidden 的方式,使父div元素和子标题元素规定于块级上下文中。这样做不用添加多余的DOM元素,是个不错的选择。 

3 为父元素设置边框

通过为父元素设置边框的方法也可以解决边距重叠的问题

CSS代码:
<style>
* {
margin: 0;
padding: 0;
}
.box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
margin-left: 30px;
border-top: 1px solid #000;
width: 300px;
height: 200px;
}
.title {
margin-top: 20px;
width: 100%;
text-align: center;
background: yellow;
}
</style>

 

虽然为 .inner 类设置上边框解决了问题,但很显然如上图中,使父div又增加了一个带有色值的边框,即便是设置上边框的色值为transparent的透明色,也会使父div的高度加一,这无疑是破坏了原有的代码环境。 

 

4 为父div元素设置padding-top样式

可以避开为子标题元素设置margin-top这一环节,换个思路,将子标题元素的margin-top样式属性去掉,为父div元素设置padding-top属性,也可以解决父子元素边距重叠的问题。

CSS代码:
<style>
* {
margin: 0;
padding: 0;
}
.box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
margin-left: 30px;
width: 300px;
height: 200px;
padding-top: 20px;
}
.title {
width: 100%;
text-align: center;
background: yellow;
}
</style>

为父div元素设置padding-top属性的方法虽然也解决了边距重叠的问题,但通过上图发现,父div元素的高度变为了220px,这种办法很显然和添加边框的方法类型,都会改变原有代码环境,也不推荐使用。 

5 为子标题元素添加padding-top样式

可以再换一种思路,父div元素不做处理,去掉子标题元素的margin-top样式,为其设置padding-top样式,这样标题元素就会增高,增加空白间距。

CSS代码:
<style>
* {
margin: 0;
padding: 0;
}
.box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
margin-left: 30px;
width: 300px;
height: 200px;
}
.title {
width: 100%;
padding-top: 20px;
text-align: center;
background: yellow;
}
</style>

 

如上图,这种方法并没有改变父div元素在上下文的代码环境,但标题元素的空白高度增加了,本例中我们为子标题元素的背景色设置为yellow,使得这种方法并不合适。但如果标题元素与父div元素的背景色值相同,这种方法也是可行的。 

6 对标题元素使用absolute定位的方式

既然我们一直在想办法对子标题元素,那么也绝对不会少了position定位的一席之地。可以通过为父div元素设置相对定位,子标题元素再进行absolute绝对定位的方式进行解决。

CSS代码:
<style>
* {
   margin: 0;
padding: 0;
}
    .box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
position: relative;
margin-left: 30px;
width: 300px;
height: 200px;
}
.title {
position: absolute;
margin-top: 20px;
width: 100%;
text-align: center;
background: yellow;
}
</style>

 这种方法也解决了父子元素边距重叠的问题,但需要注意的是,子标题元素设置了absolute绝对定位,这就使得当前的DOM文档流与之前产生了差异,当父div元素内部再添加其他元素的时候,就需要更多的考虑元素定位问题,虽然解决了当前的问题,但很显然还会产生更多的问题。

 

7 使标题元素变为行内块元素

既然我们所说的边距重叠,说的是块级元素上下文的边距重叠,那么将子标题元素原本的块元素,改变为inline-block行内块元素,同样也是可以解决的。

CSS代码:
<style>
* {
margin: 0;
padding: 0;
}
.box {
margin: 100px;
width: 360px;
height: 260px;
border: 1px solid blue;
}
.inner {
margin-left: 30px;
width: 300px;
height: 200px;
}
.title {
display: inline-block;
margin-top: 20px;
width: 100%;
text-align: center;
background: yellow;
}
</style>

这种将块元素更改为行内块元素的方法虽然解决了问题,但他具有行内元素的特性,也就是说在标题元素后面再添加行内元素,便会出现横向排列的情况,所以这种解决方案也是有缺陷的。

综合以上7种解决方案发现,为父元素创建块级格式上下文的方式,不会多添加DOM元素,不会改变原有代码环境,不需要做多余的定位处理,也不需要改变元素原有的属性,而且代码量小,在本案例中是最合适的。


刷题思考

    很多初学者其实并不能很好的回答这道题,原因就在于子元素设置margin-top,由于影响因素较多,并不会百分百出现影响父元素的情况。所以想要回答好这类题目,除了日常工作中细心总结外,能够利用业务时间多学习并把所学知识实践到项目中是很重要的。


类似考点

    这类题目属于不经意类型的考点,意思就是日常工作中并不会百分百的出现,而想要完美的回答面试题,就需要说出其原理与多个解决方案。面试官还可能会问,例如你遇到过z-index失效的情况吗?例如你是否用CSS选择器查找过父元素?你知道两个相邻的行内元素之间为什么会有空隙吗等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

经海路大白狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值