Collapsing Margins
Let’s explore exactly what the consequences of collapsing margins are, and how they will affect elements on the page.
The W3C specification defines collapsing margins as follows:
"In this specification, the expression collapsing margins means that adjoining margins (no non-empty content, padding, or border areas, or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin."
In simple terms, this definition indicates that when the vertical margins of two elements are touching, only the margin of the element with the largest margin value will be honored, while the margin of the element with the smaller margin value will be collapsed to zero.1 In the case where one element has a negative margin, the margin values are added together to determine the final value. If both are negative, the greater negative value is used. This definition applies to adjacent elements and nested elements.
There are other situations where elements do not have their margins collapsed:
floated elements
absolutely positioned elements
inline-block elements
elements with overflow set to anything other than visible (They do not collapse margins with their children.)
cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
the root element
This is a difficult concept to grasp, so let’s dive into some examples.
Collapsing Margins Between Adjacent Elements
Margins collapse between adjacent elements. In simple terms, this means that for adjacent vertical block-level elements in the normal document flow, only the margin of the element with the largest margin value will be honored, while the margin of the element with the smaller margin value will be collapsed to zero. If, for example, one element has a 25px bottom margin and the element immediately underneath it has a 20px top margin, only the 25px bottom margin will be enforced, and the elements will remain at a distance of 25px from each other. They will not be 45px (25+20) apart, as might be expected.
This behavior is best demonstrated with a short example. Consider the following code:
h1 {
margin: 0 0 25px 0;
background: #cfc;
}
p {
margin: 20px 0 0 0;
background: #cf9;
}
Figure 1. Collapsing margins in actionAn illustration of collapsing margins between a h1 element and
a p element. There's a 25 pixel vertical gap between the two
elements.
As you’ll see from Figure 1, the gap between the elements is only 25px, and the smaller margin has collapsed to zero. If in the above example the elements had equal margins (say, 20 pixels each), the distance between them would be only 20px.2
There is one situation that will cause a slight deviation from the behavior of collapsing margins: should one of the elements have a negative top or bottom margin, the positive and negative margins will be added together to reach the final, true margin. Here’s an example style sheet that demonstrates the concept:
h1 {
margin: 0 0 25px 0;
background: #cfc;
}
p {
margin: -20px 0 0 0;
background: #cf9;
}
The bottom margin of the h1 element is a positive number (25px), and the top margin of the p element is a negative number (-20px). In this situation, the two numbers are added together to calculate the final margin: 25px + (-20px) = 5px.
If the result of this calculation is a negative number, this value will have the effect of one element overlapping the other. You could say that the negative margin pulls the element in the opposite direction to that of a positive margin. See margin for more details about negative margins.
Collapsing Margins Between Parent and Child Elements
So far, we’ve only addressed the collapsing effect on adjacent elements, but the same process holds true for parents and children whose margins touch. By “touch,” we mean the places at which no padding, borders, or content exist between the adjacent margins. In the following example, a parent element has a child element on which a top margin is set:
h1 {
margin: 0;
background: #cff;
}
div {
margin: 40px 0 25px 0;
background: #cfc;
}
p {
margin: 20px 0 0 0;
background: #cf9;
}
In the style sheet above, you can see that a top margin value is declared for the p element, and in the code excerpt below, you can see that the p element is a child of the div element:
<h1>Heading Content</h1>
<div>
<p>Paragraph content</p>
</div>
The result of this code is illustrated in Figure 2.
Figure 2. Collapsing margins on a child paragraphAn illustration of collapsing margins between a h1 element and
a div element with a child p element. There's a 40 pixel vertical
gap between the h1 element and the paragraph content.
You may have expected that the paragraph would be located 60px from the heading, since the div element has a margin-top of 40px and there is a further 20px margin-top on the p element. You may also have expected that 20px of the background color of the div element would show above the paragraph. This does not happen because, as you can see in Figure 2, the margins collapse together to form one margin. Only the largest margin applies (as in the case of adjoining blocks), as we’ve already seen.
In fact we would get the same result if our div element had no top margin and the p element had a 40px margin-top. The 40px margin-top on the p element effectively becomes the top margin of the div element, and pushes the div down the page by 40px, leaving the p element nesting snugly at the top. No background would be visible on the div element above the paragraph.
In order for the top margins of both elements to be displayed, and for the background of the div element to be revealed above the p element, there would need to be a border or padding that would stop the margins collapsing. If we simply add a top border to the div element, we can achieve the effect we were originally looking for:
h1 {
margin: 0;
background: #cff;
}
div {
margin: 40px 0 25px 0;
background: #cfc;
border-top: 1px solid #000;
}
p {
margin: 20px 0 0 0;
background: #cf9;
}
In Figure 3, we can see that the div element is still 40px away from the heading, but the paragraph has been pushed a further 20px down the page, thus revealing 20px of the background of the div element (through the presence of the border).
Figure 3. Adding a border to the parentAn illustration of collapsing margins between a h1 element and
a div element hat has a top border and a child p element. There's a
40 pixel vertical gap between the h1 element and the div element.
There's a further 20 pixel gap between the top of the div and the
paragraph content.
If we didn’t want a visible top border showing in the design, a 1px top padding on the div element would have achieved the same effect. Note that the border or padding should be applied to the parent div because a border on the paragraph would not stop the margins from collapsing, since the paragraph’s margin is outside of the border.
Important: Internet Explorer and Layout
As of this writing, Internet Explorer versions 7 and below will not collapse margins where the element has a layout. If the div in our example simply had a width set (one of the triggers that causes an element to gain a layout), we’d get the result shown in Figure 3, without the need to add padding or borders.
This is non-standard behavior for IE, and is perhaps one of the reasons why beginners are a little confused by the concept of collapsing margins when they first come across it. Most of the time, the elements will have a value (other than auto) for the width property (or one of the other properties that causes an element to gain a layout), and will not exhibit the collapsing margin behavior in IE.
The example above deals with a single parent and single child that have touching margins, but the same approach would apply if there were several children (that is, nested elements) that all had adjacent vertical margins: it would still mean that all the margins would collapse into one single margin. Although the examples above mentioned top margins, the same effect is true for bottom margins, as can be seen below.
In the following contrived example, we’ve nested four div elements, all of which have a 10px margin applied. Each div has a different background color, so the effects of the margin collapse will be clearly visible:
.box {
margin: 10px;
}
.a {
background: #777;
}
.b {
background: #999;
}
.c {
background: #bbb;
}
.d {
background: #ddd;
}
.e {
background: #fff;
}
<div class="box a">
<div class="box b">
<div class="box c">
<div class="box d">
<div class="box e">
The vertical margins collapse but the horizontal
margins don't. The vertical margins also collapse
in IE because the elements don't have a layout.
</div>
</div>
</div>
</div>
</div>
The result of the above CSS is shown in Figure 4.
Figure 4. Vertical margins after collapseAn illustration of collapsing margins on a group of four nested
div elements. There are no vertical margins visible as they have all
collapsed to zero, but the horizontal margins are clearly
visible.
As you can see in this example, the effect of our CSS is quite dramatic: all the vertical margins have collapsed to form a single, 10px margin. Unlike the horizontal margin example, where all the margins were visible, the vertical margins show no such colors at all, thanks to the background-color that has been applied to each element. The whole block will be positioned 10px from other in-flow elements on the page, but each nested block will collapse its margins into a single margin.
As discussed earlier, the simplest way to stop the margin collapse from occurring is to add padding or borders to each element. If we wanted 10px margins on each element we could simply use a 9px margin and 1px of padding to get the result we wanted:
.box {
margin: 9px;
padding: 1px;
}
The result of that small change will “un-collapse” the vertical margins, as you can see in Figure 5.
Figure 5. Margins haven’t collapsedAn illustration of collapsing margins on a group of four nested
div elements with padding set to 1 pixel. All the margins are
visible as they have not collapsed.
Again, it’s important to consider the effects that layout in Internet Explorer would have in the above demonstrations. Should the elements in the first example (Figure 4) have a layout in IE, the result would be exactly as shown in Figure 5. It’s also worth noting that in browsers other than IE, the same effect would occur if the overflow property was added with a value other than visible.
Wrapping It Up
Although the margin collapse behavior is at first a little unintuitive, it does make life easier in the case of multiple nested elements, where the behavior is often desirable. As shown above, easy methods are available to help you stop the collapse if required.
分享到:
相关推荐
2. **为父元素定义1像素的上内边距**:同样,增加内边距也可以阻止外边距合并,不过这也会增加元素的总高度,可能不是理想的解决方案。 3. **为父元素添加`overflow:hidden`**:这是一种常用的无副作用的解决方案。...
解决margin塌陷问题的关键在于阻止父元素和子元素之间的外边距合并。其中最常用的一种方法是通过创建块级格式化上下文(Block Formatting Context,简称BFC)来实现。 #### BFC的介绍与作用 **一、BFC的定义** ...
第一种:两个块级元素的上下边距折叠 第二种:父元素和子元素(或者最后一个元素)的...第一种、第三种:只有静态流的元素才会发生外边距合并故设置float position inline-block都可以 <style> .bother{ width:
- 使用`display: inline-block` 或 `float` 避免外边距合并。 #### 五、综合运用 为了更好地理解和掌握CSS盒子模型,可以通过以下步骤进行实践: 1. **初始化样式**:在项目的开头处添加全局样式重置,以确保...
- 只有在普通文档流中的块级元素才会发生外边距合并,行内元素、浮动元素或绝对定位的元素之间不会发生这种情况。 - CSS重置(CSS Reset)中常用`* { margin: 0; padding: 0; }`来消除默认的外边距和内边距,以...
在CSS布局中,"空白外边距互相叠加"是一个常见的问题,它涉及到元素之间的外边距合并规则。当两个或多个块级元素的外边距相邻时,它们的垂直外边距并不简单相加,而是取其中的最大值作为最终的外边距。这在某些情况...
例如,`color`属性改变文本颜色,`background-color`设置背景色,`padding`和`margin`调整元素的内边距和外边距,`display`属性可以改变元素的显示方式,如设置为`flex`或`grid`以实现更灵活的布局。 JavaScript是...
2. **盒模型与布局**:CSS盒模型包括内容(content)、内边距(padding)、边框(border)和外边距(margin),理解盒模型对于创建复杂的网页布局至关重要。这部分可能深入解析了不同浏览器之间的盒模型差异,并介绍了如何...
在网页设计的世界中,CSS扮演着至关重要的角色,其中外边距(margin)的管理是布局中不可忽视的一部分。外边距叠加(Margin ...在解决外边距叠加问题时,关键是要深入理解其机制并根据具体情况采用最合适的解决方案。
**1.2 相邻块元素垂直外边距合并问题** 当上下相邻的两个块元素(兄弟关系)相遇时,如果上面的元素有下外边距 `margin-bottom`,下面的元素有上外边距 `margin-top`,则它们之间的垂直间距不是两者的简单相加,...
1. **外边距折叠**:同一BFC内的块级元素,相邻的垂直外边距会合并。例如,两个div之间的距离不是它们外边距之和,而是两者中较大的那个。要避免这种情况,可以将它们放入不同的BFC,例如通过设置overflow为hidden...
**问题描述**:当一个元素设置了`float`属性后,其相邻的兄弟元素如果设置了`margin`可能会出现外边距合并现象。 **解决方案**: - **display: inline**:可以在浮动元素上添加`display: inline;`来避免此问题。 ...
边距重叠指的是两个或多个元素的外边距相遇合并为一个边距,导致最终的边距宽度小于预期的现象。这种情况通常发生在垂直边距上,比如元素的上边距和下边距相遇时。边距重叠问题有时会导致页面布局出现意外的结果,使...
综上所述,"core-layout-trbl"主要涉及HTML元素的盒子模型、外边距重叠问题及其解决方案。掌握这些知识点,将有助于提升HTML和CSS布局的技能,创建出更加精确和可控的网页设计。在实际工作中,不断学习和实践新的...
当两个相邻的浮动元素(通常为左浮动)之间有外边距(margin)时,在IE6中,它们之间的外边距会合并为较大值,即“外边距折叠”现象。 **解决方法:** - 在浮动元素后面添加一个空的`div`,并为其设置`clear: both;...
#### 上下外边距合并问题 在CSS中,当两个相邻的`margin-top`或`margin-bottom`相遇时,它们会合并成一个更大的外边距。 **解决办法:** - 尽量使用相同的外边距属性,要么都使用`margin-top`,要么都使用`margin-...
- 外边距合并(Margin Collapse):在同一个BFC中,两个垂直排列的块级盒子的上边距和下边距会发生合并。而不在同一个BFC中的盒子不会产生外边距合并现象。 - 清除浮动:通过将浮动元素包裹在一个BFC中,可以避免...
- 当两个垂直外边距相遇时,它们将会合并成为一个外边距。 - 结果是外边距较大的那个值被采用。 **24. RGBA与Opacity的差异** - **问题**: rgba()和opacity的透明效果有什么不同? - **答案**: - `rgba()`: 只...
- **盒模型**:理解CSS盒模型是布局的关键,包括内容、内边距、边框和外边距。 - **响应式设计**:CSS3引入媒体查询,实现不同设备屏幕尺寸下的适应性布局。 4. **JavaScript**: - **脚本语言**:JavaScript是...