主要内容: 浮动的介绍、清除浮动、各种定位、BFC以及外边距合并的介绍。
浮动
什么是浮动元素
浮动元素是float 的值不是none的元素。
浮动元素的特征
- 任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素
- 浮动元素会尽可能远地向左或者向右浮动, 直到它的外边缘碰到包含框或者另外一个浮动元素的框的边缘
- 浮动元素从网页的正常流动中移除,但是仍然保持部分的流动性(与绝对定位相反)
- 由于浮动元素从网页的正常流中删除, 所以会造成父容器塌陷
- 文本和内联元素会环绕浮动元素。浮动元素脱离普通流,如果浮动元素后面有一个文档流中元素, 那么这个元素的框会表现的像浮动元素不存在, 但是框的文本内容会受浮动元素影响,会移动以留出空间
浮动元素对其他元素的影响
- 对父容器的影响:对于其父元素来说,元素浮动之后,它脱离当前正常的文档流,所以它也无法撑开其父元素,造成父容器的塌陷
- 对其他浮动元素的影响:
同一个方向的浮动元素:当一个浮动元素在浮动过程中碰到同一个方向的浮动元素时,它会紧跟在它们后面;
反方向的浮动元素:互不影响,位于同一条水平线上,当空间不够时会被挤下 - 普通元素的影响:
如果浮动元素后面兄弟元素为块级元素,该元素会忽视浮动元素的而占据它的位置,但它的内部文字和其他行内元素都会环绕浮动元素。
但是如果后面的块元素设置了clear属性时, 会对块元素产生影响, 具体情况取决于clear的值 - 对文字的影响:文字会环绕浮动元素排列
清除浮动
清除浮动指什么
清除浮动指元素的侧边不允许出现浮动元素,从而使得浮动元素的不占据普通文档流空间的造成的父元素的高度塌陷问题得到解决,主要通过clear属性实现。
clear:指定一个元素是否可以在它之前的浮动元素旁边,或者必须向下移动(清除浮动) 在它的下面。clear 属性适用于浮动和非浮动元素。
当应用于非浮动块时,它将非浮动块的边框边界移动到所有相关浮动元素外边界的下方。这个行为作用时会导致margin collapsing不起作用。
当应用于浮动元素时,它将元素的外边界移动到所有相关的浮动元素外边界的下方。这会影响后面浮动元素的布局,后面的浮动元素的位置无法高于它之前的元素。
方法:
- 设置浮动包含块的父元素height值。
- 使得含块的父元素变成BFC。
- 通过添加:after伪元素,然后在伪元素上设置clear属性来实现。
如何清除浮动
清除浮动之前,可以看到由于浮动元素脱离了文档流, 父元素塌陷了:
- 添加空的div,利用clear属性清除浮动
如果我们想让父元素在视觉上包围浮动元素可以像下面这样处理,在最后添加一个空div,利用clear属性对它清理。缺点是增加了一个无意义的标签
- 利用BFC可以包含浮动的特性让父容器形成BFC,从而达到清除浮动的目的 (具体怎么形成BFC后面会介绍)
使用BFC清除浮动也有它的局限性:
使用float的时候会使父容器长度缩短,而且有个重要缺陷:父容器float解决了其塌陷问题, 那么父容器的父容器怎么办;
overflow 属性会影响滚动条和绝对定位的元素;
position 会改变元素的定位方式;
display这几种方式没有解决低版本IE的问题……
- 最标准,无副作用的清除浮动的方法: 给需要清除浮动的父元素加上以下代码(IE6.7不支持 )
.clearfix:after{
content:' ';
display: block;
clear: both;
}
或者:
.clearfix:after{
content:' ';
display: table;
clear: both;
}
定位
CSS有三种基本的定位机制:普通流,浮动,绝对定位(absolute,fixed)
普通流
普通流是默认定位方式,在普通流中元素框的位置由元素在html中的位置决定,这也是我们最常见的方式,其中position: static与position:relative属于普通流的定位方式。
相对定位可以看作特殊的普通流定位,元素位置是相对于它在普通流中位置发生变化(即相对于元素本身正常位置进行定位)。在使用相对定位时,无论元素是否移动,元素在文档流中占据原来空间 ,只是表现出来的位置会改变。
浮动
设置了浮动的元素会脱离普通流,它可以向左或者向右移动直到它碰到了包含框或者另外一个浮动的边框。浮动元素会对其他浮动元素以及它后面的普通流中的文本产生影响。
绝对定位
绝对定位的元素的位置是相对于距离最近的非static祖先元素位置决定的。如果元素没有已定位的祖先元素,那么他的位置就相对于初始包含块html来定位。
绝对定位使元素的位置与文档流无关,也不占据文档流空间,普通流中的元素布局就像绝对定位元素不存在一样。
由于绝对定位与文档流无关,所以绝对定位的元素可以覆盖页面上的其他元素,可以通过z-index属性控制叠放顺序,z-index越高,元素位置越靠上。
绝对定位的宽度是收缩的。
绝对定位包括 absolute和 fixed。fixed固定定位,固定定位是绝对定位的一种,固定定位的元素也不包含在普通文档流中,差异是固定元素的包含块儿是视窗(viewport)
CSS position属性
CSS属性 position用于指定一个元素在文档中的定位方式,position的值有以下种:
值 | 描述 |
---|---|
inherit | 从父元素继承position属性的值 |
static | 默认值, 没有定位, 元素出现在正常的流中(此时 top, right, bottom, left 和 z-index 属性无效) |
relative | 生成相对定位的元素, 相对于元素本身正常位置进行定位,因此left: 20px; 会向元素的left位置添加 20px |
absolute | 生成绝对定位的元素,相对于static定位以外的第一个祖先元素(offset parent)进行定位,元素位置通过left,top,right以及bottom属性进行规定 |
fixed | 生成绝对定位的元素, 相对于浏览器窗口进行定位。元素的位置通过left,top,right以及bottom属性进行规定 |
sticky | CSS 3 新属性,兼容性差,一般用JS实现。表现类似position: relative和 position: absolute 的合体。在目标区域在屏幕中可见时,它的行为就像position: relative; 而当页面滚动超出目标区域时,它的表现就像position: fixed,它会固定在目标位置 |
TIPS :只有relative,absolute,fixed可以设置left,top,right,bottom 的值
position:relative 和 负margin 区别
position:relative和负margin都可以使元素位置发生偏移,二者有什么区别呢?
- 使用position: relative对元素进行偏移时,由于元素在文档流中占据原来空间,相对自己原本的位置偏移,不影响其它普通流中元素的位置
- 使用负margin 的话, 除了让元素自身发生偏移还影响其它普通流中的元素
BFC
BFC是什么
BFC的全称是block formatting context (块级格式化上下文),是Web页面的可视化CSS渲染出的一部分。它是块级盒布局出现的区域,也是浮动层元素进行交互的区域。
BFC是一个名词,是一个独立的布局环境,我们可以理解为一个箱子(实际上是看不见摸不着的),箱子里面物品的摆放是不受外界的影响的。
如何生成 BFC
W3C标准中这样描述:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
非块级盒子的浮动元素、绝对定位元素及块级容器(比如inline-blocks,table-cells和table-captions),以及overflow属性是visible之外任意值的块级盒子,都会创建了一个BFC。即当元素CSS属性设置了下列之一时,即可创建一个BFC:
float:left|right
position:absolute|fixed
display: table-cell|table-caption|inline-block
overflow: hidden|scroll|auto
注意:浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只能清除同一块格式化上下文中在它前面的元素的浮动。
BFC 作用
- BFC会阻止垂直外边距(margin-top, margin-bottom)折叠
创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠(垂直方向的)
- BFC不会重叠浮动元素
由于浮动元素的层级比不浮动的元素层级高, 所以浮动元素会重叠后面的非浮动元素,我们只要让后面的元素形成BFC,就可以解决遮挡问题了
利用BFC使文字不再围绕浮动元素, 形成两栏布局
- BFC清除浮动(实质是让父元素形成BFC包含浮动)
块格式化上下文对于定位与清除浮动很重要。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只能清除同一块格式化上下文中在它前面的元素的浮动。
外边距合并
块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,这种行为称为外边距塌陷(margin collapsing),有的地方翻译为外边距合并。
外边距合并的场景
-
相邻的兄弟姐妹元素外边距合并
毗邻的两个兄弟元素之间的外边距会塌陷(除非后者兄弟姐妹需要清除过去的浮动)
例如下面box1和box2合并后的外边距是两个外边距中的较大值 40px
-
块级父元素与其第一个/最后一个子元素外边距合并
如果块级父元素中,不存在上边框、上内边距、内联元素、清除浮动这四条属性(也可以说,当上边框宽度及上内边距距离为0时),那么这个块级元素和其第一个子元素的上边距就可以说”挨到了一起“。
此时这个块级父元素和其第一个子元素就会发生上外边距合并现象,换句话说,此时这个父元素对外展现出来的外边距将直接变成这个父元素和其第一个子元素的margin-top的较大者。
类似的,块级父元素的 margin-bottom与它的最后一个子元素的margin-bottom之间会发生下外边距合并现象。
下例中父元素ct 与它第一个子元素box1的外边距合并, 对外展现外边距30px
空块元素外边距合并
如果存在一个空的块级元素,其 border、padding、inline content、height、min-height 都不存在。那么此时它的上下边距中间将没有任何阻隔,此时它的上下外边距将会合并
我们先来看空元素box1没有外边距的时候,box2是紧挨body的
然后我们来给空元素box1添加外边距,这里我们为了更直观的看空元素的外边距到底会发生什么变化, 给box2也设置一个左外边距
可以看到空元素box1 的上下外边距也发生了合并
关于外边距合并,可以看下MDN 上的介绍https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
合并后外边距大小
- 两个合并的margin都是正值的时候,其大小是其中的最大外边距;
- 在负外边距的情况下,合并后的外边距为最大正外边距与最小负外边距(即负边距中绝对值最大的一个)之和
- 当 margin 都是负值的时候,合并后的外边距是比较小的外边距
- 所有毗邻的margin要一起参与运算,不能分步进行
阻止相邻元素外边距合并
不让相邻元素外边距合并的方法
- 被非空内容、padding、border 或 clear 分隔开
- 不在一个普通流中或一个BFC中
- margin在垂直方向上不毗邻
实例
-
对于父子外边距合并
(1)可以通过给父元素加border/ padding来阻止外边距合并
(2)创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠
- 对于相邻块元素
(1)浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠。所以我们只要根据需要给两个块元素添加相关属性就好了,太多了,就不截图了......
(2)利用BFC防止margin折叠(与阻止父子外边距折叠用法有区别),见下图:
例外的情况
- 根元素的外边距不会参与折叠
- 不设置任何属性的空span和空div不影响任何布局,可以无视之。