margin 重叠与负值
一、margin 纵向重叠
与横向不同,margin 纵向重叠取重叠区最大值,不进行叠加。
如下:
<style>
.container {
width: 400px;
height: 200px;
background-color: blanchedalmond;
}
.container > div:first-child {
background-color: blueviolet;
width: 100%;
height: 100px;
margin-bottom: 100px;
}
.container > div:nth-child(2) {
background-color: aquamarine;
width: 100%;
height: 50px;
margin-top: 50px;
}
</style>
<body>
<div class="container">
<div></div>
<div></div>
</div>
</body>
效果图如下:
当然父子元素直接也如此。
二、margin 负值问题
- margin-top和margin-left 是负值,元素会向上或者向左移动
- margin-right 负值,右侧元素左移,自身不受影响
- margin-bottom负值,下侧元素上移,自身不受影响
BFC
一、是什么
BFC,即块格式化上下文(Block Formatting Context),是一块独立的渲染区域,决定了其子元素将如何定位,以及和其他元素的关系、相互作用。BFC内部元素的渲染不会影响边界以外的元素,并且有一套渲染规则:
- 内部的盒子会在垂直方向上一个接一个的放置;
- 对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关;
- 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,但是注意position为absolute的元素是可以超出他的包含块边界);
- BFC的区域不会与float的元素区域重叠;
- 计算BFC的高度时,浮动子元素也参与计算;
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
Block fomatting context
=block-level box
+Formatting Context
box即盒子模型,block-level box即块级元素。
Formatting context是W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系、相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context(简称IFC)。
也就是说,BFC,只有
block-level box
参与,它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
二、触发条件
触发 BFC
的条件有:
- 根元素(
<html>)
- 浮动元素(元素的
float
不是none
) - 绝对定位元素(元素的
position
为absolute
或fixed
) - 行内块元素(元素的
display
为inline-block
) - 表格单元格(元素的
display
为table-cell
,HTML表格单元格默认为该值) - 表格标题(元素的
display
为table-caption
,HTML表格标题默认为该值) - 匿名表格单元格元素(元素的
display
为table、``table-row
、table-row-group、``table-header-group、``table-footer-group
(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或inline-table
) overflow
计算值(Computed)不为visible
的块元素display
值为flow-root
的元素contain
值为layout
、content
或 paint 的元素- 弹性元素(
display
为flex
或inline-flex
元素的直接子元素) - 网格元素(
display
为grid
或inline-grid
元素的直接子元素) - 多列容器(元素的
column-count
或column-width
(en-US) 不为auto,包括 ``column-count
为1
) column-span
为all
的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中。
备注:加粗为较常用的。
三、应用场景
1. 清除内部浮动
BFC
在计算高度时,浮动元素也会参与。
清除浮动前:
清除浮动后:
<style>
.container {
width: 200px;
border: 2px solid brown;
/* display: flow-root; 清除内部浮动 */
}
.container > div {
background-color: blueviolet;
opacity: 0.3;
float: left;
width: 100px;
height: 100px;
}
</style>
<body>
<div class="container">
<div></div>
</div>
</body>
2. 防止 margin 重叠(坍塌)
margin
坍塌:
使用 BFC
防止 margin
坍塌后:
father
父元素的设置了 margin-bottom: 50px
,child
子元素设置了 margin-bottom
,理想情况下下方的蓝色块应该距离 child
元素(绿块)100px,然而显然不是,因为发生了 margin
重叠/坍塌。 此时,通过给 father
设置一个 BFC
就可以解决这个问题了。
<style>
body {
background-color: blanchedalmond;
}
.father {
margin-bottom: 50px;
/* display: flow-root; 防止 margin 坍塌*/
}
.child {
height: 100px;
width: 200px;
margin-bottom: 50px;
background-color: lightgreen;
}
.blue {
height: 100px;
width: 200px;
background-color: lightblue;
}
</style>
<body>
<div class="father">
<div class="child">child</div>
</div>
<div class="blue"></div>
</body>
以上演示了 child
元素和 father
元素的 margin
塌陷问题,通过设置 display: flow-root
来解决。display: flow-root
是一个新的 display
属性的值,它可以创建无副作用的 BFC。
3. 自适应多栏布局
这里列举一个两栏布局,三栏布局待后面文章详细列举说明。
<style>
.aside {
width: 100px;
height: 200px;
float: left;
background-color: black;
opacity: 0.2; /* 为了方便演示效果 */
}
.main {
height: 200px;
background-color: plum;
display: flow-root; /* 设置BFC,使main可以自适应 */
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
因为为 aside
元素设置了浮动,所以 main
的左边会与包含块的左边相接触,如下图:
为了达到两栏布局 aside
和 main
互不影响的效果,为 main
设置 BFC
,实现自适应布局效果,如下图: