在CSS中跳出标准文档流的方式有三种:浮动、绝对定位和固定定位,其中绝对定位和固定定位在我的另一篇博客CSS中的定位中有了比较详细的介绍,这篇博客希望能跟大家一起讨论CSS中的浮动。
浮动属性最早提出是在CSS1中,其最初的主要目的就是为了允许其他内容(如文本)“围绕”图像,因此浮动属性也只允许作用于图像(有些浏览器还支持表格),后来随着不断发展,浮动属性也允许作用于任何元素,但是文本环绕这一页面样式目前仍然只有利用float属性可以实现,具有唯一性,以下面代码为例:
文本环绕
A
B:我们发现元素A和元素B有一部分重叠,但是文本并没有被元素A所覆盖,而是环绕在
元素A的周围,这恰是浮动特性提出最初的目的;同时我们从这个图中不难看出,首先浮动脱离了标准文档
流,所以元素A和元素B有一部分重叠,但是浮动依然会影响标准文档流的布局,具体表现为虽然元素A和
元素B有一部分重叠但是元素B的文本完全绕开了元素A
页面效果:
如图中所述:我们发现浮动虽然脱离了标准文档流,但是仍然会对标准文档流中的内存空间产生影响,这也是浮动与绝对定位之间的一个重要区别,我们下面尝试用绝对定位来实现文本环绕效果,你将会清晰看到两者之间的区别。
示例:
页面结果:
从两图对比中我们可以发现虽然浮动和绝对定位都可以脱离标准文档流,但是绝对定位是将元素彻底从标准文档流中删除,元素在标准文档流中不占据内存空间,因此更不会对其他元素产生影响,而浮动也是脱离标准文档流,元素向左或向右浮动,但是这些已经被从标准文档流中删除的元素依然会对页面布局产生影响,下面让我们一起去探讨浮动的特性及影响。
首先我们来看CSS中对于浮动的定义:
使元素脱离文档流,按照指定的方向(左或右发生移动),直到它的外边缘碰到包含框或另一个浮动框的边框为止。
更为通俗来说也就是CSS浮动的两大原则:
在CSS中,我们float属性实现元素框的浮动,可选值有如下三种
那么float属性又有什么特性呢?
1、文字环绕
这一功能也是float最初的设计目的,CSS在不断地发展过程中对于float属性一直“不忘初心”,甚至还更加完善,使其能够支持除图像以外的其他元素,关于文字环绕在本文前半部分已经有了详细介绍,此处不再赘述。
2、行级元素横排显示( 感觉这一点在实际项目中应该是运用最多的)
示例:
左浮动:
first
second
third
页面效果:
至此,我们展示了如何利用左浮动和右浮动将块级元素在行内横排显示,但是我们一起看一下下面几种特殊情况:
(1)如果我们只给第二个元素添加左浮动会怎么样?
示例:
first
second
third
页面效果:
这儿增加了third元素的宽度是希望能够更清楚得看到左浮动的second元素对third元素的覆盖,发生这种覆盖的原因是second元素脱离了标准文档流,不再占据标准文档流的空间,所以third元素向上移动,second元素覆盖了部分third元素。
大家可以自己尝试一下分别给first元素和third元素添加左浮动试试
(2)如果父组件宽度不足会怎么样?
示例:
first
second
third
(3)接下来是见证奇迹的时刻
示例:
first
second
third
forth
页面效果:
从上图我们神奇的发现:原本应该换行的forth元素竟然被卡住了,后来我查了一下相关资料发现,以换行的那个元素为基准,如果有浮动元素的高度大于换行的那个元素,那么当换行元素换行时会被高的那个元素“卡住”。这一点容易被大家忽略。
3、行内元素可以设置宽度和高度
示例:
first
second
页面效果:
4、支持margin
浮动脱离了标准文档流,但是浮动元素依然支持margin属性
示例:
first
second
third
那我们如何解决高度坍塌和浮动塌陷,清除元素浮动带给我们的影响呢?
1、给定高度
发生高度坍塌的本质原因还是子元素由于浮动无法支撑起父元素的高度,所以我们可以通过给浮动元素的祖先元素指定高度,只要浮动元素在一个有高度的盒子里,那么这个浮动就不会影响后面的元素了,也就是清除了浮动带来的影响;
我们对上面例子进行修改:
#container {
border: 2px solid red;
width: 400px;
height: 150px;
}
页面效果:
我们可以看到高度坍塌问题解决了,并且第二个div元素也不会再受到浮动元素的影响。
2、利用clear属性清除浮动
实际上在我们日常的开发中很少给元素指定高度,往往都是内容把元素的高度撑高,所以第一种方法我们在日常开发中使用其实并不广泛,下面我们来介绍利用clear: both来清除浮动,首先clear就是清除的意思,both,代表左浮动和右浮动都清除掉。通俗一点来讲,就是说清除别人对我的影响。
我们尝试对上面例子进行如下修改:
示例:
页面效果:
我们可以看到第二个div元素不再受浮动元素的影响,解决了我们前文提到的浮动塌陷的影响,看到这儿可能有人会问:那我们能不能通过给第一个div元素添加clear属性解决高度坍塌的问题?
我们看示例:
#container {
clear: both;
width: 400px;
border: 2px solid red;
}
#anotherBox {
clear: both;
width: 400px;
height: 200px;
background-color: yellow;
}
页面效果:
我们发现答案竟然是“完全没有变化”,这是因为即使给第一个div添加clear属性清除所有浮动元素带给它的影响,但是由于浮动子元素已经脱离了标准文档流,文档流中第一个div中没有任何子元素占据文档流空间,依然无法撑起第一个div的高度,同时这种方法还有一个巨大的缺陷:那就是两个div之间margin属性失效了,我们以下面代码为例:
#anotherBox {
margin-top: 10px;
clear: both;
width: 400px;
height: 200px;
background-color: yellow;
}
页面效果:
后面有人又开始脑洞大开:在中间一个空盒子,然后给那个空盒子clear:both;这样加了一堵墙之后,第二个div就能掉下来并且不干扰了上面的元素。而且第二个div还是能通过magin-top调节两个div(“墙体”div不要算进去)之间的间距,把这种方法也叫做"隔墙法"。
示例:
first
second
third
页面效果:
至此隔墙法较为完美的解决了浮动塌陷的问题,但是高度坍塌问题并没有得到解决,后来有程序员基于隔墙法的思路提出了“内墙法”,即将充作墙体的div添加进第一个div元素的底部,我们看代码示例:
first
second
third
页面示例:
至此,我们惊喜地发现内墙法完美的解决了高度坍塌和浮动塌陷两个问题,之所以能够解决高度坍塌是因为第一个div中底部的div元素由于clear属性清除了浮动元素对于自己的影响,在标准文档流中占据原本应该占据的内存空间,撑起了第一个div元素的高度,同时第二个div元素依然可以通过margin调节两个div元素之间的距离。因此内墙法在许多项目工程中得到了较为普遍的使用。
总结:
clear属性如何清除浮动:clear属性不允许被清除浮动的元素的左边/右边挨着浮动元素,底层原理是在被清除浮动的元素上边或者下边添加足够的清除空间。不要在浮动元素上清除浮动,以之前的情况示例:
first
second
third
页面效果: