浮动流
文章目录
- 浮动流
- 一、标准流
- 二、浮动流
一、标准流
所谓网页布局就是网页排版的方式,css中有三种网页布局的方式:标准流、浮动流和定位流。
标准流也称文档流,这是浏览器默认的排版方式。标准流中网页的元素会按从左往右、从上往下的顺序依次排列。
标准流中,块级元素会按从上往下的顺序以此排列,而行内元素和行内块级元素则是按从左往右的顺序排列,当一行排满一行会排入下一行中。
另外在网页布局时经常会出现一个问题,当我们固定了盒子的大小,然后缩小网页的尺寸时,盒子不会跟着网页缩小而缩小,因而页面的布局会发送扭曲。为了解决这个问题,我们可以使用百分比来设置盒子的大小,但是百分比设置大小时,盒子父元素的高度必须设置百分比,父元素默认的高度百分比是0,宽度百分比是100,不设置子元素将无法显示出来。如下方的代码中为了让红盒子顺利显示,它的父元素(html、body、蓝色div)都要设置height的百分比,少一个红盒子都无法显示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动流</title>
<style>
html{height: 100%;padding:0}
body{height: 100%;padding:0}
</style>
</head>
<body>
<div style="width: 20%;height: 20%;background-color: blue">
<div style="width: 20%;height: 20%;background-color: red"></div>
</div>
</body>
</html>
二、浮动流
浮动流是一种半脱离文档流的排版方式,浮动流的元素有以下特点:
- 不再区分行内、块级、行内块级元素,都可以水平移动
- 无论是什么级的元素都可以设置宽高
- 浮起的元素可以看成处于文档层的上方,如果一个元素浮起了,下面的元素会顶上去填充浮起元素原来的位置,并且浮起的元素会遮盖下方顶上来的元素
另外设置浮动流以后的元素,margin:0 auto会失效。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动流</title>
</head>
<body>
<div style="width: 50px;height: 50px;background-color:blue ;float:left"></div>
<div style="width: 80px;height: 80px;background-color:green "></div>
</body>
</html>
浮动流float只能设置left或者right,没有center这个值,也就是说元素浮起以后要么向左靠,要么向右靠,不能保持在中间位置。
如果想让两个元素处在同一行,有两种方法,一种是把它们设置为浮动流,另外一种是设置元素为行内块级元素,display:inline-block。
浮动流被称为半脱离文档流的原因是元素浮起以后垂直位置依然要依靠浮起以前的位置来确定,如果是全脱离则元素在水平与垂直方向都可以自由移动了,起位置完全不受原先在文档流中位置影响了。
而浮起元素贴靠的原则是:
- 先浮在前,后浮在后,左浮靠左浮,右浮靠右浮
- 浮起元素垂直位置以自身当前垂直位置为准,如果前面的元素浮起了,则下面的元素要先顶上去以后再找浮起的垂直位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动流</title>
</head>
<body>
<div style="width: 50px;height: 50px;background-color:blue ;float:left"></div>
<div style="width: 80px;height: 80px;background-color:green;float:left "></div>
<div style="width: 100px;height: 100px;background-color:red"></div>
<div style="width: 50px;height: 50px;background-color:pink;float:left "></div>
</body>
</html>
上方代码中蓝色盒子先浮起向左靠,然后绿色盒子会顶上蓝色盒子原先的位置,绿色盒子再浮起则是处于蓝色盒子相同的垂直位置,而蓝色盒子已经在该垂直位置上左浮了,因此绿色盒子浮起靠在蓝色盒子的后面。红色盒子不浮起,顶上蓝色绿色盒子空缺的位置,粉色盒子以红色盒子上靠完以后的垂直位置开始向左浮起。
当父级元素宽度无法容纳浮起元素时,浮起元素会先找前面元素的左下点作为垂直位置的起始点,贴靠在其空白处,如果此元素也无法容纳浮起元素,则浮起元素再找前一个元素,以此类推直到找到父元素最左侧为止,此时无论父元素能否容纳,浮起元素都会显示在该位置。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动流</title>
</head>
<body>
<div style="width:150px ;height: 150px;background-color: black">
<div style="width: 70px;height: 70px;background-color:blue ;float:left"></div>
<div style="width: 50px;height: 50px;background-color:red;float: left"></div>
<div style="width: 50px;height: 50px;background-color:pink;float:left "></div>
<div style="width: 50px;height: 50px;background-color:yellow;float:left "></div>
</div>
</body>
</html>
上方的代码中父元素是黑色的,蓝红粉黄四个子盒子浮起,如果父盒子能容纳则是会并列在第一行。但是当粉色盒子浮起时父盒子已经无法容纳它了,因此粉色盒子找到蓝色盒子的左下点,贴靠在它的空白处。而当黄色盒子浮起时,前面浮起的盒子左下侧都没法容纳它了,因此它会以上面三个盒子的最下侧(也就是粉色盒子的最下侧)为垂直方向起始位置,贴靠在父盒子的最左侧。
文字或者行内块级元素会围绕在浮动元素的周围。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动流</title>
</head>
<body>
<div style="width: 50px;height: 50px;background-color:blue ;float:left"></div>
<!--word-break: break-all必须写上-->
<div style="width: 100px;height: 100px;background-color:red;word-break: break-all">12121332121</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浮动流</title>
</head>
<body>
<div style="width: 100px;height: 100px;background-color:blue ;float:left"></div>
<img src="图片" width="30px" height="30px">
<img src="图片" width="30px" height="30px">
<img src="图片" width="30px" height="30px">
<img src="图片" width="30px" height="30px">
</body>
</html>
在企业开发中浮动流布局也经常被用到,通常网页布局会按从外向内,从上往下的顺序先把大盒子布局好,然后在大盒子内使用浮动流布局小元素的位置。
另外当父盒子不设置宽高时,本质是这个父盒子高度为0%,宽度为100%,其真实大小是被里面子盒子撑开的大小。此时如果子盒子浮动起来,父盒子会瞬间消失(塌陷回高度0%时的状态)。为了避免父元素塌陷给页面布局带来的影响,咱们有三种常见的解决方案:
<!--方案一:外墙法-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<div style="width: 100px;height: 100px;background-color:blue;float: left">子元素</div>
</div>
<!--外墙-->
<!--clear: both表示该元素的左右两侧不能有浮动元素,如果左侧出现浮动元素则该元素移到浮动元素下方,另外只有块级元素才有clear-->
<div style="clear: both"></div>
<div style="width: 100px;height: 100px;background-color:yellow">content</div>
</body>
</html>
<!--方案二:内墙法-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<div style="width: 100px;height: 100px;background-color:blue;float: left">子元素</div>
<!--内墙-->
<div style="clear: both"></div>
</div>
<div style="width: 100px;height: 100px;background-color:yellow">content</div>
</body>
</html>
<!--方案三:伪类法-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/*zoom:1是为了解决兼容问题*/
.clearfix:after{content: "";display: table;clear: both;*zoom:1}
.box1{width: 100px;height: 100px;background-color:blue;float: left}
.box2{width: 100px;height: 100px;background-color:yellow}
</style>
</head>
<body>
<div class="clearfix">
<div class="box1">子元素</div>
</div>
<div class="box2">content</div>
</body>
</html>
另外在上一章中提到过一个问题,如果两个盒子嵌套,父盒子没有边框,子盒子的margin-top会把两个盒子都定下来.这个问题的本质是父元素没有边框,子元素的margin-top不能参照父元素,那么就会去参照body,因此父元素和子元素会一起被顶下去。这个问题同样可以使用伪类法解决,咱们可以在父元素before位置设置一个table当做参照物。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.clearfix:before{content: "";display: table;*zoom:1}
.box1{width: 100px;height: 100px;background-color:red}
.box2{width: 50px;height: 50px;background-color:blue;margin-top: 30px}
</style>
</head>
<body>
<div class="clearfix box1">
<div class="box2"></div>
</div>
</body>
</html>