浮动float
float的意思是浮动, 主要用于实现文字环绕图片
浮动
浮动元素会向左/右移动, 直到它的外边缘碰到包含框或另一个浮动框的边框为止.
float有四种值
- none : 默认值, 不浮动
- right: 向右浮动
- left : 向左浮动
- inherit: 继承父元素的float值, IE不支持
根据常规流和格式化上下文的特性, 浮动框脱离常规流(normal flow), 它会影响到内联框的排列, 但不会影响到块级框.
这是因为, 在布局浮动元素时, 一旦普通流中出现了浮动元素, 一个框盒首先根据常规流来布局, 然后脱离常规流, 向左/右移动.
这导致沿着它边上的文本content
都将"浮动". 即, 其它盒子看不到被float的盒子, 但其它盒子中的文本却能看到它.
# 高度塌陷
浮动有一个很大的副作用, 就是当浮动框高度超出容器框的时候, 容器不会自动升高来闭合浮动元素, 这被称为容器的高度塌陷现象.
# 浮动卡住
其它元素在预期外, 受到浮动的影响, 被浮动元素卡住. 或一行内浮动元素放不下, 换行后, 被高度不一致的元素卡住.
清除浮动 / 闭合浮动
很多人都已经习惯称之为清除浮动, 但是确切地来说是不准确的.
- 清除浮动: 对应的单词是 clear, 对应CSS中的属性是 clear: left | right | both | none
- 闭合浮动:更确切的含义是使浮动元素闭合, 从而减少浮动带来的影响. 这一概念与BFC有关.
闭合浮动正是为了解决高度塌陷问题的, 单单清除浮动还不足够.
# 最佳实践 | after法
.clearfix:after {
content:" ";
display:block;
visibility:hidden;
height:0;
clear:both;
}
.clearfix { *zoom:1; }
::after
是伪元素, 它只对块级元素有效.display:block
, 使生成的元素以块级元素显示, 占满剩余空间visibility:hidden
, 隐藏contentheight:0
, 避免生成内容破坏原有布局的高度zoom:1
, 触发IE的hasLayout, 后者相当于是IE中的BFC机制
这本质上是一个空div法的变形, 但更符合语义和结构.
以下是可选的改进
## 避免margin重叠
即再添加一个:before, 其样式设置与:after一致.
当该容器中的内部元素float创建了BFC, 内部元素的margin-top就会和上一个盒子的margin-bottom叠加
## 零宽度空格
.clearfix:before, .clearfix:after {
content:"/200B";
display:block;
height:0;
clear:both;
}
.clearfix { *zoom:1; }
content:"/200B"
, Unicode字符里中的零宽度空格, 也就是U+200B, 这个字符本身是不可见的, 相当于设置了visibility:hidden
这个改进只是少写几行代码而已. 但也许可能在某些页面下, 并不支持内嵌的CSS使用Unicode字符,所以并不总是安全的.
## Bootstrap
Bootstrap采用了Nicolas Gallagher
的方案.
.cf:before, .cf:after {
content:" ";
display:table;
}
.cf:after { clear:both; }
.cf { *zoom:1; }
bs中的less源码为
.clearfix() {
&:before,
&:after {
content: " ";
display: table;
}
&:after {
clear: both;
}
}
# 空div法
在浮动元素末尾添加一个空div, 设置其为clear: both
- 优点: 通俗易懂, 容易掌握
- 缺点: 添加了太多无意义的空标签, 有违结构与表现的分离的原则, 在后期维护中将是噩梦.
# br法
在浮动元素末尾添加一个br, 设置br的clear:all
- 优点: 比空标签方式语义稍强, 代码量较少
- 缺点: 同样有违结构与表现的分离, 不推荐使用
以下几个办法都是在试图触发BFC
# 父元素也设置浮动
- 优点: 不存在结构和语义化问题, 代码量极少
- 缺点: 使得与父元素相邻的元素的布局会受到影响, 不可能一直浮动到body, 不推荐使用
# 父元素设置display:table
- 优点: 结构语义化完全正确, 代码量极少
- 缺点: 盒模型属性已经改变, 由此造成的一系列问题, 得不偿失, 不推荐使用
# overflow法
通过设置父元素overflow值设置为hidden; 在IE6中还需要触发 hasLayout , 例如 zoom:1
- 优点: 不存在结构和语义化问题, 代码量极少
- 缺点: 内容增多时候容易造成不会自动换行导致内容被隐藏掉, 无法显示需要溢出的元素; 04年POPO就发现overflow:hidden会导致中键失效
或者设置为overflow:auto
- 缺点: 多个嵌套后, firefox某些情况会造成内容全选; IE中 mouseover 造成宽度改变时会出现最外层模块有滚动条等, firefox早期版本会无故产生focus等
References
Todo
- 补齐代码
- 演示一下margin重叠问题