Note:This article is my study note, without copyright,most of the content comes from others.css
推荐:殷荣桧——深度剖析Margin塌陷,BFC,Containing Block之间的关系html
举个例子,像下面这种状况,上下两个盒子的间距按说是20px和40px,但实际都是20px,这就是塌陷。git
<div style="background-color:tomato;width:100px;height:100px;margin-bottom:20px;"> hello world</div>
<div style="background-color:#bbb;width:100px;height:100px;margin-top:0px;"> hello world</div>
<hr>
<div style="background-color:tomato;width:100px;height:100px;margin-bottom:20px;"> hello world</div>
<div style="background-color:#bbb;width:100px;height:100px;margin-top:20px;"> hello world</div>
复制代码
其实这是CSS1.0故意设计的,由于这样符合平面设计师的要求。github
StackOverflow:为何塌陷时只出如今垂直方向?浏览器
在CSS出现以前使用的p标签,它要求每一个段落之间有相同的间隔,因此当你对p标签设置了margin-top
和margin-bottom
你发现就会出现塌陷的状况,并且会取两者之中的最大值。app
明白塌陷产生的条件也就明白了如何解决塌陷所带来的问题,那么塌陷产生的条件是什么?less
首先是一个大前提:元素之间没有被非空内容、padding、border 或 clear 分隔开。而后有符合下面几种毗邻状况:布局
top margin of a box and top margin of its first in-flow child
(一个元素的 margin-top 和它的第一个子元素的 margin-top)post
bottom margin of box and top margin of its next in-flow following sibling
(普通流中一个元素的 margtin-bottom 和它的紧邻的兄弟元素的的 margin-top)flex
bottom margin of a last in-flow child and bottom margin of its parent if the parent has ‘auto’ computed height
(一个元素( height 为 auto )的 margin-bottom 和它的最后一个子元素的margin-bottom)
top and bottom margins of a box that does not establish a new block formatting context and that has zero computed ‘min-height’, zero or ‘auto’ computed ‘height’, and no in-flow children
(一个没有建立 BFC、没有子元素、height 为0的元素自身的 margin-top 和 margin-bottom)
这段英文为摘抄:
原文连接:juejin.im/post/5aebd1…
W3C规范这样描述:
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
在BFC中,每一个盒子的左外边框紧挨着包含块的左边框(如果从右到左的格式,则为紧挨右边框)。即便存在浮动也是这样的(尽管一个盒子的边框会因为浮动而收缩),除非这个盒子的内部建立了一个新的BFC浮动,盒子自己将会变得更窄)。
这段英文为摘抄:
原文连接:www.w3cplus.com/css/underst… © w3cplus.com
方法已在代码中给出
<div class="wrapper">
<div class="content">
</div>
</div>
复制代码
* {
margin: 0;
padding: 0;
}
.wrapper {
background-color: #000;
margin-left: 100px;
margin-top: 100px;
width: 100px;
height: 100px;
/* float: left; */
/* position: absolute; */
/* display: inline-block; */
/* display: flex; */
/* 注意使用 overflow 溢出的部分会自动隐藏起来*/
/* overflow: hidden; */
/* 注意使用display: table虽然能够解决塌陷,可是cotainer的高度会失效 */
/* display: table; */
/* overflow: scroll; */
/* overflow: scroll 溢出的部分会变成滚动,效果奇葩,应该没什么用 */
}
.content {
/* 在子元素中使用如下这些也能够解决塌陷 */
/* float: left; */
/* position: absolute; */
/* display: inline-block; */
width: 50px;
height: 50px;
background-color: #0f0;
margin-left: 50px;
/* 设置 margin-top: 150px;咱们发现子级盒子会带着父级盒子一块儿往下移动,好像两者粘连到了一块儿或者说子级盒子好像没有了“顶“。这种现象叫作margin-left塌陷,是经典BUG。 */
margin-top: 150px;
}
复制代码
外边距折叠的例子以下
<div class="wrapper"></div>
<div class="content"></div>
复制代码
.wrapper{
height: 20px;
background-color: #000;
margin-top: 20px;
margin-bottom: 200px;
}
.content{
height: 20px;
margin-top: 100px;
background-color: #0f0;
}
复制代码
解决方法
overflow: hidden;
这一开始听起来可能有些困惑,由于咱们在前面讨论了BFC致使外边距折叠的问题。但咱们必须牢记在心的是毗邻块盒子的垂直外边距折叠只有他们是在同一BFC时才会发生。若是他们属于不一样的BFC,他们之间的外边距将不会折叠。因此经过建立一个新的BFC咱们能够防止外边距折叠。 以下,以后给父级元素添加
overflow: hidden;
便可解决margin合并
<div class="container">
<div class="content1"></div>
<div class="content2"></div>
</div>
<div class="container">
<div class="content3"></div>
</div>
复制代码
效果以下
上面一段话的原文连接: www.w3cplus.com/css/underst… © w3cplus.com
浮动元素带有float的元素,最先用来实现相似于报纸图片环绕的布局
<div class="wrapper">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>
<div class="content">6</div>
<div class="content">7</div>
<div class="content">8</div>
<div class="content">9</div>
</div>
<br>
<div class="context1">YAMA</div>
<div class="context2">YAMA</div>
复制代码
* {
margin: 0;
padding: 0;
}
.wrapper {
background-color: aqua;
/* width: 330px; */
border: 2px solid black;
/* 解决方法以下,在父级盒子添加overflow: hidden; */
overflow: hidden;
}
.content {
float: left;
/*使元素站队、浮动*/
color: #fff;
margin-left: 10px;
margin-bottom: 10px;
background-color: black;
width: 100px;
height: 100px;
}
.context1 {
float: left;
width: 100px;
height: 100px;
background-color: red;
color: white;
opacity: 0.7;
}
.context2 {
width: 150px;
height: 150px;
background-color: yellow;
color: blue;
/* 解决方法以下,在后面的元素变为行内块 */
/* display: inline-block; */
/* float: left; */
/* float: right; */
}
复制代码
效果如图
此处咱们注意到后面两个div好像具备层模型的特色,实际上不是,正确理解为:
浮动元素产生了浮动流,块级元素看不到全部产生了浮动流的元素 注: 产生了BFC的元素、文本类属性(带有inline属性)的元素以及浮动元素都能看到浮动元素 (这里所指的看不到指的是在进行定位时会无视它而进行覆盖,就像层模型同样绝对定位) (还需注意,若是设置position和float后由内容决定大小,打内部把元素转换成inline-block)
应用实例
<div class="wrapper">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<p>YAMA</p>
</div>
复制代码
* {
margin: 0;
padding: 0;
}
.wrapper {
border: 10px solid black;
overflow: hidden;
}
.content {
float: left;
color: #fff;
margin: 2px;
background-color: black;
width: 100px;
height: 100px;
}
p {
background-color: cadetblue;
/* clear: both; */
}
复制代码
下图中上面的图片设置了overflow: hidden;
,下面的没有
clear: both;
以后,意义是不容许该标签附近出现浮动对象,(相应的值还有左右),至关于清除了div标签的浮动特性。有时候一个浮动div周围的文字环绕着它(以下图中的左图所示)可是在某些案例中这并非可取的,咱们想要的是外观跟下图中的右图同样的。为了解决这个问题,咱们可能使用外边距,可是咱们也可使用一个BFC来解决。
<div class="container">
<div class="floated">
<img width="150px" src="https://user-gold-cdn.xitu.io/2020/4/18/1718da4f61a16e59?w=633&h=658&f=png&s=13693">
</div>
<p>YAMA YAMA YAMA YAMAYAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMAYAMA YAMA.
YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMAYAMA YAMA
YAMA YAMA
YAMA YAMA YAMA YAMAYAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMAYAMA YAMA.
YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMA YAMAYAMA YAMA
YAMA YAMA.</p>
</div>
复制代码
.floated {
float: left;
margin: 5px;
}
p {
color: rgb(14, 13, 13);
text-align: center;
/* 解决方法以下 */
/* overflow: hidden; */
}
复制代码
若是咱们正在建立的一个多列布局占满了整个容器的宽度,在某些浏览器中最后一列有时候将会被挤到下一行。会发生这样多是由于浏览器舍入(取整)了列的宽度使得总和的宽度超过了容器的宽度。然而,若是咱们在一个列的布局中创建了一个新的BFC,它将会在前一列填充完以后的后面占据所剩余的空间。
<div class="container">
<div class="column">column 1</div>
<div class="column">column 2</div>
<div class="column">column 3</div>
</div>
复制代码
.column {
/* 父元素或者说视窗宽度的31.33%,下面的百分号也是如此 */
width: 31.33%;
background-color: green;
float: left;
margin: 0 0%;
}
.column:last-child {
float: none;
overflow: hidden;
}
复制代码
如今即便容器的宽度会有轻微的变化,可是布局也不会中断。固然,这并非多列布局的最好选择,但它是防止最后一列下滑问题的一种方法。Flexbox在这种状况下多是一个更好的解决方案,可是这应该要说明一下在这些状况下元素是如何表现的。
请注意,BFC并非一个css属性,也不是一段代码,而是css中基于box的一个布局对象,它是页面中的一块渲染区域,而且有一套渲染规则,它决定了其子元素将如何定位,以及和其余元素的关系和相互做用。明确地,它是一个独立的盒子,而且这个独立的盒子内部布局不受外界影响,固然,BFC也不会影响到外面的元素