CSS深入理解之float浮动
1、什么是 CSS Float(浮动)?
CSS 的 Float(浮动),会使元素向左或向右移动,其周围的元素也会重新排列。Float(浮动),往往是用于图像,但它在布局时一样非常有用。CSS float 属性定义元素在哪个方向浮动,浮动元素会生成一个块级框,直到该块级框的外边缘碰到包含框或者其他的浮动框为止。
2、浮动的原始意义?
我们使用float
浮动做了很多其本职工作以外的事情,于是我们会混淆,我们会回看不清float
真正的面目。浮动真正的意义在哪里呢?要知道这个问题的答案很简单,假设现在CSS中没有浮动(float)属性,那么会变成一个什么样子。我们会发现,目前流行采用浮动方法实现的无论是分栏布局,还是列表排列我们都可以用其他一些CSS属性(不考虑table
)代替实现,唯一一个实现不了的就是“文字环绕图片”,我是想不出来能有什么方法可以让文字环绕图片显示。好,这个替代不了的作用才是float
真正的意义所在。所以,请记住,浮动出现的意义其实只是用来让文字环绕图片而已,仅此而已
3、元素怎样浮动?
元素的水平方向浮动,意味着元素只能左右移动而不能上下移动。一个浮动元素会尽量向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。浮动元素之后的元素将围绕它。浮动元素之前的元素将不会受到影响。
float
的可能值为:left或right或none。
- left - 使左边缘接触包含块的左边缘或另一浮动块的右边缘。
- right - 使右边缘接触包含块的右边缘或另一浮动块的左边缘。
- none - 元素不浮动。
默认情况下,浮动元素将堆叠在一起。
clear属性清除堆叠。
它指定浮动元素的一个或两个边缘必须不与另一个浮动元素的边缘邻接。
其可能的值为:
- left - 元素的左边缘可能不与另一个浮动元素邻接。
- right - 元素的右边缘可能不与另一个浮动元素邻接。
- both - 两边都不能与另一个浮动元素邻接。
- none - 元素不被清除,并且任一边缘可以邻接另一个浮动元素
4、浮动的“破坏性”?
文字之所以会环绕含有float
属性的图片是因为浮动破坏了正常的line boxes。由于line boxes的高度是由其内部最高的inline boxes的高度决定的,所以这里line boxes的高度就是图片的高度。此时图片与文字是同一box类型的元素(都是inline boxes),是在同一行上的,所以,默认状态下,一张图片只能与一行文字对齐。而要想让一张图片要与多行文字对齐,唯一能做的就是破坏正常的line boxes模型。正常情况下,图片自身就是个inline boxes,与两侧的文字inline boxes共同组成了line boxes,但是,一旦图片加入了浮动,情况就完全变了。我认为是浮动彻底破坏了img
图片的inline boxes特性,至少有一点我可以肯定,图片的inline boxes不存在了,一旦图片失去了inline boxes特性就无法与inline boxes的文字排在一行了,其会从line boxes上脱离出来,跟随自身的方位属性,靠边排列。这种状态跟限制性内切酶起作用几乎一致,一条基因链上(line boxes)有很多的基因(inline boxes),然后限制性内切酶(float
)会切除特定的DNA序列,此序列(float
元素)就会从基因链上脱离出来。
浮动破坏了图片的inline box,产生了两个结果:一是图片无法与文字同行显示,脱离了其原来所在的line box链;二是没有了高度(无inline box -> 无line box -> 无高度)。而这些结果恰恰是文字环绕图片显示所必须的。
5、解决高度塌陷的问题 – 清除浮动
高度塌陷:高度塌陷是指当容器内包含浮动元素,容器并未像如同这些元素不浮动般的自动扩展延伸。在文档流中,父元素的高度默认是被子元素撑开的, 也就是子元素多高,父元素就多高。但是当为子元素设置浮动以后,子元素会完全脱离文档流,此时将会导致子元素无法撑起父元素的高度,导致父元素的高度塌陷。由于父元素的高度塌陷了,则父元素下的所有元素都会向上移动,这样将会导致页面布局混乱。 所以在开发中一定要避免出现高度塌陷的问题, 我们可以将父元素的高度写死,以避免塌陷的问题出现, 但是一旦高度写死,父元素的高度将不能自动适应子元素的高度,所以这种方案是不推荐使用的。
解决方案一:根据W3C的标准,在页面中元素都有一个隐含的属性叫做Block Formatting Context , 简称BFC,该属性可以设置打开或者关闭,默认是关闭的。当开启元素的BFC以后,元素将会具有如下的特性:
i.父元素的垂直外边距不会和子元素重叠
ii.开启BFC的元素不会被浮动元素所覆盖
iii.开启BFC的元素可以包含浮动的子元素
如何开启元素的BFC ?
i.设置元素浮动 ,使用这种方式开启,虽然可以撑开父元素,但是会导致父元素的宽度丢失 而且使用这种方式也会导致下边的元素上移,不能解决问题 。
ii.设置元素绝对定位。
iii.设置元素为inline-block ,可以解决问题,但是会导致宽度丢失,不推荐使用这种方式 。
iv.将元素的overflow设置为一个非visible的值。
推荐方式:将overflow设置为hidden是副作用最小的开启BFC的方式。 但是在IE6及以下的浏览器中并不支持BFC,所以使用这种方式不能兼容IE6。在IE6中虽然没有BFC,但是具有另一个隐含的属性叫做hasLayout,该属性的作用和BFC类似,所在IE6浏览器可以通过开hasLayout来解决该问题 。开启方式很多,我们直接使用一种副作用最小的: 直接将元素的zoom设置为1即可 。zoom表示放大的意思,后边跟着一个数值,写几就将元素放大几倍。zoom:1表示不放大元素,但是通过该样式可以开启hasLayout。zoom这个样式,只在IE中支持,其他浏览器都不支持。
<body>
<div class="box1">
<div class="box2"></div>
</div>
<div class="box3"></div>
</body>
.box1{
border: 10px red solid;
zoom:1;
overflow: hidden;
}
.box2{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
.box3{
height: 100px;
background-color: yellow;
}
解决方案二:可以直接在高度塌陷的父元素的最后,添加一个空白的div,由于这个div并没有浮动,所以他是可以撑开父元素的高度的,然后在对其进行清除浮动,这样可以通过这个空白的div来撑开父元素的高度, 基本没有副作用 。使用这种方式虽然可以解决问题,但是会在页面中添加多余的结构。
<body>
<div class="box1">
<div class="box2"></div>
<div class="clear"></div>
</div>
</body>
.box1{
border: 1px solid red;
}
.box2{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
.clear{
clear:both;
}
解决方案三:可以通过after伪类向元素的最后添加一个空白的块元素,然后对其清除浮动,这样做和添加一个div的原理一样,可以达到一个相同的效果,而且不会在页面中添加多余的div,这是我们最推荐使用的方式,几乎没有副作用。 在IE6中不支持after伪类, 所以在IE6中还需要使用hasLayout来处理。
<body>
<div class="box1">
<div class="box2"></div>
</div>
</body>
.box1{
border: 1px solid red;
}
.box2{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
.clearfix:after{
/*添加一个内容*/
content: "";
/*转换为一个块元素*/
display: block;
/*清除两侧的浮动*/
clear: both;
/*设为不可见*/
visibility: hidden;
height:0;
}
.clearfix{
zoom:1;
}
6、float与JavaScript
JavaScript可以改变CSS的属性,其他些属性还好,但是这个float
值得一说,为何呢,因为float貌似是JavaScript中的一个关键字,不能使用obj.style.float="left";
这样的句子。得使用其他写法。
IE浏览器:obj.style.styleFloat = "left";
其他浏览器:obj.style.cssFloat = "left";