CSS中,margin的折叠(collapsing )问题
2016-02-03 16:26
686 查看
From:http://www.sitepoint.com/web-foundations/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. 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.
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
margin and the element immediately underneath it has a
margin, only the
margin will be enforced, and the elements will remain at a distance of
each other. They will not be
apart, as might be expected.
This behavior is best demonstrated with a short example. Consider the following code:
As you’ll see from Figure 1, the gap between the elements is only
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
There is one situation that will cause a slight deviation from the behavior of collapsing margins: shoul
4000
d 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:
The bottom margin of the h1 element is a positive number (
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:
(-
=
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.
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:
In the style sheet above, you can see that a top margin value is declared for the
and in the code excerpt below, you can see that the
is a child of the div element:
The result of this code is illustrated in Figure 2.
You may have expected that the paragraph would be located
the heading, since the div element has a
there is a further
the
You may also have expected that
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
The
the p element effectively becomes the top margin of the div element, and pushes the div down the page by
leaving the
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
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:
In Figure 3, we can see that the div element is still
from the heading, but the paragraph has been pushed a further
the page, thus revealing
the background of the div element (through the presence of the border).
If we didn’t want a visible top border showing in the design, a
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.
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
applied. Each div has a different background color, so the effects of the margin collapse will be clearly visible:
The result of the above CSS is shown in Figure 4.
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,
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
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
on each element we could simply use a
and
padding to get the result we wanted:
The result of that small change will “un-collapse” the vertical margins, as you can see in Figure 5.
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.
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.
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. 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 elementwith the smaller margin value will be collapsed to zero. If, for example, one element has a
25pxbottom
margin and the element immediately underneath it has a
20pxtop
margin, only the
25pxbottom
margin will be enforced, and the elements will remain at a distance of
25pxfrom
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; }
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.
There is one situation that will cause a slight deviation from the behavior of collapsing margins: shoul
4000
d 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
pelement,
and in the code excerpt below, you can see that the
pelement
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.
You may have expected that the paragraph would be located
60pxfrom
the heading, since the div element has a
margin-topof
40pxand
there is a further
20px
margin-topon
the
pelement.
You may also have expected that
20pxof
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-topon
the p element effectively becomes the top margin of the div element, and pushes the div down the page by
40px,
leaving the
pelement
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
pelement,
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
40pxaway
from the heading, but the paragraph has been pushed a further
20pxdown
the page, thus revealing
20pxof
the background of the div element (through the presence of the border).
If we didn’t want a visible top border showing in the design, a
1pxtop
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.
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
10pxmargin
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 { backgroun cf74 d: #ddd; } .e { background: #fff; }
The result of the above CSS is shown in Figure 4.
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,
10pxmargin.
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
10pxfrom
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
10pxmargins
on each element we could simply use a
9pxmargin
and
1pxof
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.
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.
相关文章推荐
- android 代码实现控件之间的间距
- Web布局连载——两栏固定布局(五)
- [div+css]晒晒最新制作专题推广页模板
- 设计更快的网页(三):字体和 CSS 调整
- 纯CSS制作的新闻网站中的文章列表
- 10条影响CSS渲染速度的写法与使用建议第1/3页
- BS项目中的CSS架构_仅加载自己需要的CSS
- 很不错的 CSS Hack 又学了一招
- 发一个css比较清爽的写法
- CSS expression控制图片自动缩放效果代码[兼容 IE,Firefox]
- css布局网页水平居中常用方法
- CSS经典技巧十则第1/2页
- css 兼容性问题this.style.cursor=''hand''
- IE6不能正常解析CSS文件问题的解决方法及原因分析
- 欲练CSS ,必先解决IE的一些细节分析
- CSS文字截取功能实现代码
- 支持IE6 IE7 Firefox 的纯CSS的下拉菜单
- 不同版本IE使用不同css(css条件注释语句用法)
- css类选择器的使用方法详解
- jQuery+css实现的切换图片功能代码