浮动的元素会影响其兄弟元素的位置,并可能导致父元素的高度塌陷(假如父元素没设置高度),因此需要清除浮动(带来的影响)。
常用方法有:
div
兄弟元素,设置 clear:both
<br>
兄弟元素,设置 clear 属性为 alldiv{
zoom:1;
}
div:after{
content:"";
display:block;
clear:both;
}
display: table
(触发BFC)overflow: hidden
(触发 BFC)这里主要说下 clear:both
。clear:both
意思是说,设置了该属性的元素,其左边和右边不允许存在浮动元素。
clear:both
的元素为了满足其左右两边没有浮动元素的这个条件,只能自身下移,从而带动了父元素高度的撑开。那么为什么除了 clear:both
之外,其他方法也能清除浮动呢?因为那些方法大都触发了 BFC,而 BFC 是可以清除浮动的,这个后面再介绍。
文档流内,块级元素与块级元素在垂直方向上的 margin 有时会合并(塌陷)为单个 margin,这样的现象称之为 margin 塌陷(margin collapse)。具体包括三种情况:
border-bottom
设置
父元素没有 padding-bottom
值
父元素和第一个子元素之间没有inline元素分隔
父元素没有 height,min-height,max-height
计算规则:
子元素和父元素上边界重叠,并且以子元素的 margin-top
作为父元素的 margin-top
整体移动。对于 margin-bottom
同理。
那么怎么解决 margin 塌陷问题呢?同样是利用接下来要讲到的 BFC。
BFC 即 Block formatting context,译为块级格式化上下文。简单来说,它是一种属性,这种属性影响着元素的定位以及与其兄弟元素之间的相互作用。因为是属性,所以我们通常说“元素具有 BFC”、“元素触发了 BFC”,而不说“元素是 BFC”。
从样式上看,具有 BFC 的元素与普通的容器没有什么区别;但是从功能上,具有 BFC 的元素可以看作是隔离了的独立容器,容器里面的子元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器没有的一些特性。
CSS 规定满足下列 CSS 声明之一的元素便会生成 BFC:
从整体上看,BFC 是隔离了的容器,这个具体可以表现为三个特性:
前面我们说过 BFC 可以用于解决 margin 塌陷问题。
前面说过,父元素没有设置高度时,子元素的浮动会导致父元素表现为 0 高度,也就是说正常情况下父元素无法包含浮动的子元素。如图:
.Fa{
border: 2px solid red;
width: 300px;
}
.son{
width:180px;
height:180px;
background-color:yellow;
float:left;
}
但是触发了父元素的 BFC 后,父元素将可以包含浮动的子元素。如图:
.Fa{
border: 2px solid red;
width: 300px;
overflow:hidden; /* 随便一个 BFC 的触发条件 */
}
.son{
width:180px;
height:180px;
background-color:yellow;
float:left;
}
前面说过浮动元素会影响兄弟元素的位置,具体地说就是浮动之后脱离了文档流,使得兄弟元素上移填补空缺,而这会使得它被浮动元素覆盖。如图:
但是触发了兄弟元素的 BFC 后,兄元素将不会被浮动的元素覆盖 ———— 不会被覆盖,意味着兄弟元素出现在浮动元素的旁边或者下面,具体取决于父元素的宽度。 如果父元素的宽度足以包含这两个子元素的宽度之和,则子兄弟元素和子浮动元素并排。如图:
如果父元素的宽度不足以包含这两个子元素的宽度之和,则子兄弟元素会出现在子浮动元素的下面。如图:
让我们进一步拓展一下可视化格式模型的一些概念,由于比较复杂,所以只做了解即可。
可视化格式模型规定了客户端(浏览器)如何在媒介(显示器)中渲染文档树(document tree)。如下图,每个节点、元素都有属于自己的可见或不可见、有名或匿名的盒模型,可视化格式模型即规定了这些盒、框框如何整齐地排列在页面中,还有盒子之间的相互作用。
可视化格式模型的体系包括: 1.包含块 CB(Containing block) 2.控制框:块框、行框 3.FC(Formatting Context, 格式化上下文)
这里只说 FC 和定位体系。
FC 即 Formatting context,译为格式化上下文。这是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系、相互作用。除了最常见的 CSS2.1 中的 BFC 和 IFC 之外,CSS3 中还增加了 GFC 和 FFC。
前面已经说过了。
p
中插入 div
)会产生两个匿名块与 div
分隔开,即产生两个 IFC,每个 IFC 对外表现为块级元素,与 div
垂直排列。vertical-align:middle
,其他行内元素则可以在此父元素下垂直居中。display:grid
的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。display:flex
或者 display:inline-flex
的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少 safari 和 chrome 还是 OK 的,毕竟这俩在移动端才是王道。
Flex box 由伸缩容器和伸缩项目组成。通过设置元素display:flex
或者 display:inline-flex
可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。
伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flex box 定义了伸缩容器内伸缩项目该如何布局。
在定位的时候,浏览器会根据元素的盒类型和上下文对这些元素进行定位,可以说盒就是定位的基本单位。在 CSS2.1 中,有三种定位方案 ———— 普通流、浮动和绝对定位,下面分别对这三种布局简略说明一下:
普通流(Normal flow)
浮动 (Floats)
绝对定位 (Absolute positioning)
position:absolute
或 position:fixed
,它是绝对定位元素;position: absolute
,元素将相对最近的一个非 static 定位的父元素进行定位,如果没有则相对于 body;