优秀文章:/iyangyuan/archive//03/27/2983813.html
浮动细节原理
所有元素设置float浮动之后,会脱离文档流,脱离文档流的元素都会变成行内块
脱离文档流之后,不再区分行内元素和块元素,都是行内块
不再独占页面一行
可以设置宽高,宽高默认由内容撑开
所有元素设置浮动之后,会脱离文档流,不再占用文档流位置,可以认为变为行内块
块元素设置浮动之后,水平布局的等式不需要强制成立,因此,块元素浮动之后可以在一行显示
浮动元素向左或向右时,不会超过它前面的其他浮动元素(水平方向)
浮动元素会尽可能的向左/右移动,直到碰到边框或别的浮动元素(水平方向)
浮动元素所在位置高度不会超过在它上一个浮动的元素,最多和它一样高(垂直方向)
上一个浮动元素,看的是html而不是css
解释了box3上方有足够的空位却没有上移的原因
浮动元素布局 link
浮动元素默认不会从父元素中移出
每个盒子都自成一界,有自己的文档流,内部如何布局与外部元素无关
可以想象父元素就是一堵墙,子元素不管怎么浮动也无法逾越
父元素如果没有设置高度,所有子元素浮动,脱离文档流,会导致父元素高度塌陷
浮动会使元素脱离文档流,但不会脱离文本流,文字环绕效果
浮动卡的现象(上面的水平垂直原理)
当浮动的元素高度不一致时,会出现卡的现象,直到调整到合适的高度值,才恢复正常的左浮动
浮动的元素会尽可能的向左/右移动,直到碰到边框或别的浮动元素(浮动卡的现象)
浮动元素之间没有垂直margin的合并
垂直margin合并仅是文档流的特性
高度塌陷问题(脱离文档流导致的问题)
对于父元素来说(父元素没有设置高度),脱离了文档流的子元素不能再撑开父元素了,所以会出现高度塌陷的问题
高度塌陷是因为子元素脱离文档流,相对定位不脱离文档流,因此不会塌陷
没有宽度塌陷? 如果不设置宽高,宽度默认为父元素宽度,高度默认为 0
行内元素不会占据浮动元素空间
浮动的元素,脱离文档流,不再占用原本空间,其他未浮动块和行内块元素就会占据它原来的位置
行内元素没有宽高,宽高由文字内容撑开,但是浮动未脱离文本流,呈现文字环绕效果
解决方案,开启BFC
BFC的概念(块级格式化环境)link
简单介绍
BFC是css中的一个隐含属性,可以为一个元素开启BFC
BFC不能直接开启,只能间接开启,以下开启BFC的方式都会存在副作用
利用开启BFC可以解决父元素高度塌陷问题
元素开启BFC后的特点
开启BFC的元素不会被浮动元素所覆盖
开启BFC的元素不会和其中的子元素发生上外边距重叠(合并)
开启BFC的元素可以包含浮动的子元素(因此不会塌陷)
以下方式可以开启BFC
开启元素的浮动
将元素设置为行内块元素
将元素的overflow设置为一个非visible的值,如 overflow: auto(推荐)
利用after伪类配合 clear 清除浮动解决高度塌陷,是目前最好的解决方案,这个方式不会开启BFC
代码示例
不会被浮动元素所覆盖,可以包含浮动的子元素
不会和其中的子元素发生上外边距重叠
clear 清除浮动
如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear属性来清除浮动元素对当前元素所产生的影响
清除浮动原理
清除浮动的原理是,设置clear之后,浏览器会对该元素添加一个上外边距,以使其位置不受其他元素的影响
清除浮动细节
块元素浮动之前,也就是在标准流中,是竖向排列的,而浮动之后可以理解为横向排列
清除浮动可以理解为打破横向排列
清除浮动只能影响使用清除的元素本身,不能影响其他元素
清除浮动并不是让浮动的元素不浮动了,该浮动还浮动
清除浮动的关键字是clear,定义如下:
一句话总结:clear清除浮动元素对当前元素所产生的影响
clear : none | left | right | both
none : 默认值。允许两边都可以有浮动对象
left : 不允许左边有浮动对象(添加一个除了它自己左浮动中高度最高的上外边距)
right : 不允许右边有浮动对象(添加一个除了它自己右侧浮动中高度最高的上外边距)
both : 不是两侧都不能右浮动(添加一个除了它自己左右浮动元素中高度最大的上外边距)
clear 详细讨论
怕我以后忘了,所以这里各种情况详细讨论一遍
1. 假如box1、box2、box3三个盒子,它们分别是左浮动,左浮动,右浮动,现在给box2添加clear:left
① 给box2添加clear:left,相当于给box2添加除了它自己左浮动盒子中高度较大的上外边距
② 虽然1,2,3盒子都脱离文档流,但在空中行内块依然是从左到右,从上到下排列,box2位置确定
③ 为何box3也跟着下来呢?html中box3在box2后面,css中box2中执行clear:left时,html中box3还未生成
④ 轮到box3执行浮动时,它自然跟在box2后面
2. 假如box1、box2、box3三个盒子,它们分别是左浮动,左浮动,右浮动,现在给box2添加clear:right
① html中box3在box2后面,css中box2中执行clear:right时,html中box3还未生成
② 故css中box2中执行clear:right时,右边并没有浮动元素
3. 假如box1、box2、box3三个盒子,它们分别是左浮动,不浮动,右浮动,现在给box2添加clear:left
① 给box2添加clear:left,相当于给box2添加除了它自己左浮动盒子中高度较大的上外边距
② box2并没有浮动,独占一行,box3只能下移了
4. 假如box1、box2、box3三个盒子,它们分别是左浮动,右浮动,右浮动,现在给box3添加clear:right
① 给box3添加clear:right,相当于给box3添加除了它自己右浮动盒子中高度较大的上外边距
② 给box3添加clear:both,相当于给box3添加除了它自己左右浮动盒子中高度较大的上外边距
after伪类解决高度塌陷 link
前面介绍了通过开启BFC解决高度塌陷问题,以下介绍非开启BFC的方案
方案1
直接设置父元素的高度
优势:极其简单
弊端:可能违背初衷,不设置高度本身就是为了盒子高度随内容变化
方案2 (非BFC)
在父元素中,追加空子元素,并设置其clear属性为both
clear是css中专用于清除浮动的属性
原理:追加空盒子,然后clear:both,相当于给新增空盒子添加除了它自己左右浮动盒子中高度较大的上外边距,以撑开父元素
作用:清除当前元素前面的元素浮动所带来的影响
优势:代码量少 容易掌握 简单易懂
弊端:该方式是以html去修改样式,会添加无意义的空标签,有违结构与表现的分离,不便于后期的维护
改进:通过css去修改样式显然更合理
方案2.1(非BFC)(比较完美)
使用after伪元素添加box, 配合clear清除浮动
相对于空标签闭合浮动的方法
优势:不破坏文档结构,没有副作用
弊端:代码量多
.clearfix:after{
content: "";
display: block;
clear: both;
}
after 选择器向选定的元素之后插入内容
content:""; 生成内容为空
display: block; 生成的元素以块级元素显示,
clear:both; 清除前面元素浮动带来的影响
方案2.2(非BFC)(同时解决高度塌陷和父子元素外边距合并)
使用after伪元素添加box, 配合clear清除浮动,解决高度塌陷
使用before伪元素添加box, 配合clear清除浮动,解决父子元素外边距合并
方案3
设置父元素浮动 (开启BFC)
优势:简单,代码量少,没有结构和语义化问题
弊端:对后续元素会有影响
方案4
为父元素设置overflow属性 (开启BFC)
取值:hidden 或 auto
优势:简单,代码量少
弊端:如果有内容要溢出显示(弹出菜单),也会被一同隐藏
方案5
父元素设置display:table (开启BFC)
优势:不影响结构与表现的分离,语义化正确,代码量少
弊端:盒模型属性已经改变,会造成其他问题
方案7
同时解决高度塌陷 和 margin边距重叠
margin边距重叠机制是否要消除看情况
.clearfix:before, .clearfix:after{
content: "";
display: table;
}
.clearfix:after{
clear: both;
}
/*ie是非标准浏览器 用来兼容ie*/
.clearfix{
zoom: 1;
}