浮动
本文最后更新于:1 年前
浮动
文本主要内容
- 标准文档流
- 标准文档流的特性
- 元素
- 行内元素和块级元素的相互转换
- 浮动的性质
- 浮动的清除
标准文档流
宏观地讲,我们的web页面和photoshop等设计软件有本质的区别:web页面的制作,是个“流”,必须从上而下,像“织毛衣”。而设计软件,想往哪里画个东西,都能画。
标准文档流的特性
空白折叠现象:
无论多少个空格、换行、tab,都会折叠为一个空格。
比如,如果我们想让img标签之间没有空隙,必须紧密连接:
1 |
|
高矮不齐,底边对齐:
自动换行,一行写不满,换行写。
元素
学习的初期,我们就要知道,标准文档流等级森严。
标签分为三种等级:
- 内联元素(行间/行内元素)、
- 块级元素、
- 内联块级元素(行内块元素)
我们可以举一个例子,看看块级元素和行内元素的区别:
上图中可以看到,h1
标签是块级元素,占据了整行,span
标签是行内元素,只占据内容这一部分。
现在我们尝试给两个标签设置宽高。效果如下:
上图中,我们尝试给两个标签设置宽高,但发现,宽高属性只对块级元素h1
生效。于是我们可以做出如下总结。
行内元素和块级元素的区别:(非常重要)
行内元素:
行内元素不独占一行、无法定义高宽,设置margin,padding,但只在水平方向有效
- 与其他行内元素并排;
- 不能设置宽、高。默认的宽度,就是文字的宽度。
块级元素:
块级元素独占一行,可以定义宽高,可以设置margin,padding
- 霸占一行,不能与其他任何元素并列;
- 能接受宽、高。如果不设置宽度,那么宽度将默认变为父亲的100%。
行内块元素(inline-block element)
内联块级元素,也叫行内块元素,它具有内联元素的部分特性之外,还具备了块级元素的部分特性。
不独占一行,可以定义宽高
行内块元素比较少,它们分别是:img、input、td、select、textarea、label、iframe
特点:
- 和相邻的内联块级元素在一行上,但是中间会有空白的间隙
- 默认的宽度就是本身内容的宽度
- 高度,行高,内边距和外边距都可以设置
行内元素和块级元素的分类:
从HTML的角度来讲,标签分为:
- 文本级标签:p、span、a、b、i、u、em。
- 容器级标签:div、h系列、li、dt、dd。
为甚么说p是文本级标签呢?因为p里面只能放文字&图片&表单元素,p里面不能放h和ul,p里面也不能放p。
现在,从CSS的角度讲,CSS的分类和上面的很像,就p不一样:
- 行内元素:除了p之外,所有的文本级标签,都是行内元素。p是个文本级,但是是个块级元素。
- 块级元素:所有的容器级标签都是块级元素,还有p标签。
元素的相互转换
块级元素可以转换为行内元素:
一旦给一个块级元素(比如div)设置:
1 |
|
那么,这个标签将立即变为行内元素,此时它和一个span无异。inline就是“行内”。也就是说:
- 此时这个div不能设置宽度、高度;
- 此时这个div可以和别人并排了。
行内元素转换为块级元素:
同样的道理,一旦给一个行内元素(比如span)设置:
1 |
|
那么,这个标签将立即变为块级元素,此时它和一个div无异。block”是“块”的意思。也就是说:
- 此时这个span能够设置宽度、高度
- 此时这个span必须霸占一行了,别人无法和他并排
- 如果不设置宽度,将撑满父亲
行内和块元素转换行内块元素
1 |
|
通过设置CSS样式属性display:inline-block
,可将内联元素,或块级元素转换成内联块级元素;
但如果是将元素转换成内联元素,则设置display:inline
;
如果是将元素转换成块级元素,则设置display:block
;inline-block
是css2.1新增的属性,对于IE7以下的版本不支持这个属性,所以需要一些兼容的办法。
脱离文档流
标准流里面的限制非常多,导致很多页面效果无法实现。如果我们现在就要并排、并且就要设置宽高,那该怎么办呢?办法是:移民!脱离标准流!
css中一共有三种手段,使一个元素脱离标准文档流:
- 浮动
- 绝对定位
- 固定定位
这便引出我们今天要讲的内容:浮动。
浮动的性质
现在有两个div,分别设置宽高。我们知道,它们的效果如下:
此时,如果给这两个div增加一个浮动属性,比如float: left;
,效果如下:
这就达到了浮动的效果。此时,两个元素并排了,并且两个元素都能够设置宽度、高度了(这在上一段的标准流中,不能实现)。
性质1:浮动的元素脱标
标准文档流特点:区分行块。
- 块级元素:可以设置宽高,必须独占一行。
- 行内元素:不能设置宽高,可以并排一行。
浮动的元素脱离了标准流的限制,具备行块二象性,浮动的元素可以设置宽高,还可以并排一行,而且不会有空白折叠现象,如果元素不设置宽高,可以被元素内容自动撑开。
脱标即脱离标准流。我们来看几个例子。
证明1:
上图中,在默认情况下,两个div标签是上下进行排列的。现在由于float属性让上图中的第一个<div>
标签出现了浮动,于是这个标签在另外一个层面上进行排列。而第二个<div>
还在自己的层面上遵从标准流进行排列。
证明2:
上图中,span标签在标准流中,是不能设置宽高的(因为是行内元素)。但是,一旦设置为浮动之后,即使不转成块级元素,也能够设置宽高了。
所以能够证明一件事:一旦一个元素浮动了,那么,将能够并排了,并且能够设置宽高了。无论它原来是个div还是个span。所有标签,浮动之后,已经不区分行内、块级了。
浮动元素没有margin塌陷
margin塌陷出现在标准流中,浮动元素以及脱离了标准流,不再具有margin塌陷现象
浮动的元素让出标准流位置
元素浮动之后,脱离了标准流,会将原来占有的标准流位置让给后面的一个同一级元素
1 |
|
由于浏览器中有兼容性,不会使用这种属性制作压盖效果,压盖一般用定位
如果没有特殊需求,不允许一个父元素中的子元素有的浮动有的不浮动,同级元素中有一个浮动其他的也要浮动。
性质2:浮动的元素依次贴边
我们来看一个例子就明白了。
我们给三个div均设置了float: left;
属性之后,然后设置宽高。当改变浏览器窗口大小时,可以看到div的贴靠效果:
上图显示,3号如果有足够空间,那么就会靠着2号。如果没有足够的空间,那么会靠着1号大哥。
如果没有足够的空间靠着1号大哥,3号自己去贴左墙。
不过3号自己去贴墙的时候,注意:
上图显示,3号贴左墙的时候,并不会往1号里面挤。
同样,float还有一个属性值是right
,这个和属性值left
是对称的。
贴边性质常见应用:
- 表格
- 导航栏
- 电商或者企业网站布局
性质3:浮动的元素有“字围”效果
来看一张图就明白了。我们让div浮动,p不浮动。
上图中,我们发现:div挡住了p,但不会挡住p中的文字,形成“字围”效果。
总结:标准流中的文字不会被浮动的盒子遮挡住。(文字就像水一样)
关于浮动我们要强调一点,浮动这个东西,为避免混乱,我们在初期一定要遵循一个原则:永远不是一个东西单独浮动,浮动都是一起浮动,要浮动,大家都浮动。
性质4:收缩
收缩:一个浮动的元素,如果没有设置width,那么将自动收缩为内容的宽度(这点非常像行内元素)。
举例如下:
上图中,div本身是块级元素,如果不设置width,它会单独霸占整行;但是,设置div浮动后,它会收缩
浮动的补充(做网站时注意)
上图所示,将para1和para2设置为浮动,它们是div的儿子。此时para1+para2的宽度小于div的宽度。效果如上图所示。可如果设置para1+para2的宽度大于div的宽度,我们会发现,para2掉下来了:
布置一个作业,要求实现下面的效果:
为实现上方效果,代码如下:
1 |
|
浮动的问题
浮动的子元素是不会撑高父元素
标准流中的元素,不设置高度的情况下,都能被内部的标准流元素自动撑高。
如果内部的子元素进行了浮动,浮动的子元素是撑不高标准流父亲的。
1 |
|
父元素无高度,浮动元素可能会影响后面的浮动贴边
父元素没有高度,会影响后面元素的标准流位置,如果浮动的子元素足够高时,有可能影响到后面浮动元素的贴边
1 |
|
浮动的清除
这里所说的清除浮动,指的是清除浮动与浮动之间的影响。
方法1:给浮动元素的祖先元素加高度
li的父亲div没有设置高度,导致这两个div的高度均为0px(我们可以通过网页的审查元素进行查看)。div的高度为零,导致不能给自己浮动的孩子,撑起一个容器。
撑不起一个容器,导致自己的孩子没办法在自己的内部进行正确的浮动。
好,现在就算给这个div设置高度,可如果div自己的高度小于孩子的高度,也会出现不正常的现象:
给div设置一个正确的合适的高度(至少保证高度大于儿子的高度),就可以看到正确的现象:
1 |
|
解决:父元素有了高度,前面的浮动不能影响后面元素的标准流位置和贴边。
问题:父元素高度不是自适应,一旦子元素高度变化,问题可能再次出现。
总结:
如果一个元素要浮动,那么它的祖先元素一定要有高度。
有高度的盒子,才能关住浮动。(记住这句过来人的经验之语)
方法2:父元素使用clear:both;
网页制作中,高度height其实很少出现。为什么?因为能被内容撑高!也就是说,刚刚我们讲解的方法1,工作中用得很少。
那么,能不能不写height,也把浮动清除了呢?也让浮动之间,互不影响呢?
这个时候,我们可以使用clear:both;
这个属性。如下:
1 |
|
clear就是清除,both指的是左浮动、右浮动都要清除。clear:both
的意思就是:不允许左侧和右侧有浮动对象。
这种方法有一个非常大的、致命的问题,它所在的标签,margin属性失效了。
margin失效的本质原因是:上图中的box1和box2,高度为零。
方法3:隔墙法
上面这个例子中,为了防止第二个div贴靠到第二个div,我们可以在这两个div中间用一个新的div隔开,然后给这个新的div设置clear: both;
属性;同时,既然这个新的div无法设置margin属性,我们可以给它设置height,以达到margin的效果(曲线救国)。这便是隔墙法。
隔墙法有外墙法和内墙法
外墙法:
在两个大的父盒子之间添加一个空的div标签,标签上带有clear:both
属性
解决:浮动影响后面元素标准流位置和贴边,模拟父元素间的距离。
问题:父元素没有高度自适应。
1 |
|
内墙法:(推荐使用)
在元素内部,所有的浮动子元素后面添加一个空的div元素,标签高度为0,添加clear属性
解决:父元素高度自适应,浮动影响后面的元素位置和贴边。
缺点:浮动是 css 样式属性带来的问题,内墙法使用 HTML 结构去辅助解决问题,如果页面中浮动元素很多,需要添加多个没有语义的空标签,造成HTML结构的冗余
1 |
|
方法4:伪类 :after
(推荐使用)
本质是使用伪类方法利用css代码书写一堵内墙。
伪类选择器:通过选中的标签添加伪类,去选中标签的某个状态或位置。:after
:这个伪类表示选中的是某个标签内部的最后的位置。
书写方法:前面必须加普通的选择器,后面连续书写伪类名称。
1 |
|
将伪类添加给一个选中父盒子的选择器后面,一般给需要清除浮动的父盒子设置一个clearfix的类名。
解决:父元素高度自适应,浮动影响后面元素位置和贴边
1 |
|
方法5:溢出隐藏 overflow:hidden;
(推荐使用)
这种方案让父容器形成了BFC(块级格式上下文),而BFC可以包含浮动,通常用来解决浮动父元素高度坍塌的问题。
BFC的触发方式
我们可以给父元素添加以下属性来触发BFC:
● float 为 left | right
● overflow 为 hidden | auto | scorll
● display 为 table-cell | table-caption | inline-block
● position 为 absolute | fixed
这里可以给父元素设置overflow:auto,但是为了兼容IE最好使用overflow:hidden。
但这种办法有个缺陷:如果有内容出了盒子,用这种方法就会把多的部分裁切掉,所以这时候不能使用。
BFC的主要特征:
● BFC容器是一个隔离的容器,和其他元素互不干扰;所以我们可以用触发两个元素的BFC来解决垂直边距折叠问题。
● BFC不会重叠浮动元素
● BFC可以包含浮动,这可以清除浮动。
给内部有浮动子元素的父元素添加溢出隐藏 overflow:hidden 属性,可以解决浮动所有问题
元素没有高度时,如果同时设置了overflow:hidden,元素会自适应内容的高度
我们可以使用如下属性:
1 |
|
overflow即“溢出”, hidden即“隐藏”。这个属性的意思是“溢出隐藏”。顾名思义:所有溢出边框的内容,都要隐藏掉。如下:
上图显示,overflow:hidden;
的本意是清除溢出到盒子外面的文字。但是,前端开发工程师发现了,它能做偏方。如下:
一个父亲不能被自己浮动的儿子,撑出高度。但是,只要给父亲加上overflow:hidden
; 那么,父亲就能被儿子撑出高了。这是一个偏方。
1 |
|
高度自适应原因:
一个元素没有设置高度,同时设置了溢出隐藏,浏览器在加载盒子尺寸时,遇到溢出隐藏浏览器会强制性去检索内部的子元素的高度,不论子元素是标准流还是浮动,都会将最高的高度作为父盒子高度加载。
浮动影响后面的元素:
父元素有了高度后,可以管理住内部所有的浮动元素,不会延伸到后面标签中影响贴边。
浮动清除的总结
浮动的元素,只能被有高度的盒子关住。 也就是说,如果盒子内部有浮动,这个盒子有高,那么妥妥的,浮动不会互相影响。
1、加高法
工作上,我们绝对不会给所有的盒子加高度,这是因为麻烦,并且不能适应页面的快速变化。
1 |
|
2、clear:both;
法
最简单的清除浮动的方法,就是给盒子增加clear:both;
表示自己的内部元素,不受其他盒子的影响。
1 |
|
浮动确实被清除了,不会互相影响了。但是有一个问题,就是margin失效。两个div之间,没有任何的间隙了。
3、隔墙法
外墙法:
在两部分浮动元素中间,建一个墙。隔开两部分浮动,让后面的浮动元素,不去追前面的浮动元素。
墙用自己的身体当做了间隙。
优点:浮动影响后面元素标准流位置和贴边,模拟父元素间的距离。
缺点:父元素没有高度自适应。
1 |
|
内墙法:
1 |
|
内墙法的优点就是,父元素高度自适应,浮动影响后面的元素位置和贴边。。这样,这个div的背景、边框就能够根据p的高度来撑开了。
缺点:浮动是 css 样式属性带来的问题,内墙法使用 HTML 结构去辅助解决问题,如果页面中浮动元素很多,需要添加多个没有语义的空标签,造成HTML结构的冗余
4、伪类 :after
本质是使用伪类方法利用css代码书写一堵内墙。:after
:这个伪类表示选中的是某个标签内部的最后的位置。
将伪类添加给一个选中父盒子的选择器后面,一般给需要清除浮动的父盒子设置一个clearfix的类名。
在.clearfix:after
内添加内容转成块元素,高度为零, 使用clear: both;
清除浮动,最后将创建的元素占位并隐藏
解决:父元素高度自适应,浮动影响后面元素位置和贴边
1 |
|
5、overflow:hidden;
这个属性的本意,就是将所有溢出盒子的内容,隐藏掉。但是,我们发现这个东西能够用于浮动的清除。
我们知道,一个父亲,不能被自己浮动的儿子撑出高度,但是,如果这个父亲加上了overflow:hidden;
那么这个父亲就能够被浮动的儿子撑出高度了。并且,overflow:hidden;
能够让margin生效。
父元素添加溢出隐藏 overflow:hidden
属性,可以解决浮动所有问题
元素没有高度时,如果同时设置了overflow:hidden
,元素会自适应内容的高度
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!