css浮动布局以及清除浮动的几种办法

什么是浮动布局

float 浮动布局, 默认 none 关闭浮动,取 left/right 该元素就会向其容器元素的左/右边框平移,当碰到另外一个同级浮动的元素时停止平移,超出容器会自动换行,不可以继承。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>浮动演示</title>
		<style>
			.left,.right {
				 /* 添加浮动,元素统一向左浮动,向右同理 float:right*/
				float: left;
				width: 300px; 
				height: 300px;
				background-color: blue;
			}
			/* 可以利用层叠性将右盒子向右浮动,覆盖掉上面统一声明的向左浮动 */
			.right {
				/* float: right; */
				background-color: pink;
			}
			
		</style>
	</head>
	<body>
		<div class="left">
			左盒子
		</div>
		<div class="right">
			右盒子
		</div>
	</body>
</html>

在这里插入图片描述

浮动特点

float存在多层结构布局里(见图1),可以理解为在原来页面上面多了一层放浮动的元素,但float只能左右移动不能上下移动。

  • 脱离文档流,通过设置元素的浮动属性(float),可以使其脱离正常的文档流。浮动元素会向左或向右移动,直到遇到父元素的边界或另一个浮动元素。浮动元素在文档流空出的位置,由后续的(非浮动)元素填充上去,块级元素直接填充上去,若跟浮动元素的范围发生重叠,浮动元素覆盖块级元素;
  • 不脱离文本流/不遮挡文本,有文字环绕效果(见图2)。元素浮动围绕文本流:浮动元素会影响周围的文本流,使文本环绕在浮动元素的周围。这使得可以创建各种排列和布局效果,如图片与文字环绕、多列布局等。;
  • 行内元素不填充空位,有空隙就会插入;
  • 溢出处理:如果包含浮动元素的父元素没有设置适当的高度或清除浮动,可能会导致父元素的高度塌陷。可以通过清除浮动(clear)来解决这个问题
  • 元素重叠问题:浮动元素可能会重叠,特别是当它们的宽度超过了父容器的宽度时。为了避免重叠,可以使用适当的宽度设置、清除浮动或使用CSS网格布局等方式。
  • 灵活的布局方式:浮动布局在一些场景下具有灵活的布局能力,可以创建多列布局、实现自适应宽度和响应式布局等效果。通过合理设置浮动属性和宽度,可以实现各种复杂布局的需求。
  • 兼容性:CSS浮动布局具有广泛的兼容性,能够在大多数现代浏览器中正常工作。然而,它也存在一些兼容性问题,尤其在处理较复杂布局时。随着新的布局技术的发展和广泛的支持,建议在设计布局时综合考虑其他替代方案,如Flexbox和CSS Grid。
  • 需要注意的是,由于CSS浮动布局对文档流的影响较大,容易产生一些副作用和难以控制的布局问题。为了更好地管理布局和使代码更具可维护性,建议使用更现代的布局技术,如Flexbox和CSS Grid。这些技术提供更强大、灵活且更易于管理的布局方案,适用于各种复杂的布局需求。

图1-层叠上下文
图2-浮动与非浮动元素相邻

浮动布局优点

  1. 实现文字环绕效果
  2. 当元素浮动了起来之后,它有着块级元素的一些性质例如可以设置宽高等,但它与inline-block还是有一些区别的,第一个就是关于横向排序的时候,float可以设置方向而inline-block方向是固定的;还有一个就是inline-block在使用时有时会有空白间隙的问题
  3. 浮动可以改变元素的默认排列方式,即脱离标准流,这使得网页布局更加灵活多变

为什么需要清除浮动

一般来说,为了自适应,父盒子A是不设置高度的,有时候两个A的块级子元素为了在同一行显示,就会让A的块级子元素设置float浮动,这时候子元素就脱离了标准流,而其父盒子A没有脱离标准流,他们不在同一层级了,所以在不清除浮动的情况下,浮动的元素不会撑开父盒子高度,此时父盒子高度为0,和父盒子A同级的盒子B就会顶上去,占据A的位置,所以需要给父盒子A清除浮动所带来的负面影响,让父盒子A在子元素浮动的情况下,A也能有高度,不被它的同级元素占据它的位置。

  • 下面我们展示一下不清除浮动的情况下
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

此时可以看到,父盒子A高度并没有被子元素1和子元素2撑开,所以父盒子A的位置就被同级盒子B占据,盒子B顶了上去。由于子元素1和子元素2是浮动状态,脱离了标准流,所以层级高于标准流的盒子B
在这里插入图片描述

清除浮动的几种办法

思路

清除浮动,实际上就是为了清除浮动所带来的负面影响,即让没有设置高度的父盒子A拥有高度,不影响下方元素的布局

方法1:给父盒子添加高度

最简便的办法,自然是给父盒子A添加高度,这样就不会影响下方元素的布局了

.father-box {
  width: 300px;
  height: 100px;
}

可以看到,父盒子设置了高度,下方的盒子B的布局就不会受影响了
在这里插入图片描述
优点:方便快速,代码简洁
缺点:在浮动元素高度不确定的时候不适用

方法2:父盒子添加overflow: hidden

.father-box {
  width: 300px;
  overflow: hidden;
}

或者

.father-box {
  width: 300px;
  zoom: 1;
}

此方法直接通过触发BFC,实现清除浮动。必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
优点:代码简洁
缺点:内容增多的时候容易造成不会自动换行导致内容被隐藏掉,无法显示要溢出的元素,且ie6 7底下不支持BFC;不能和position配合使用,因为超出的尺寸的会被隐藏,

方法3:父盒子添加overflow: auto

.father-box {
  width: 300px;
  overflow: auto;
}

或者

.father-box {
  width: 300px;
  zoom: 1;
}

此方法直接通过触发BFC,实现清除浮动。必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
优点:代码简洁
缺点:内部宽高超过父级div时,会出现滚动条。且ie6 7底下不支持BFC。

方法4:额外标签法

给浮动的子元素同级下设置一个空的div元素(这个div和浮动的子元素同级,在同一父盒子中),空的div元素在css中设置样式为{clear:both;}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
      overflow: hidden;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .clear {
      clear: both;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
      <div class="clear"></div>
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

优点:通俗易懂,方便
缺点:添加无意义标签,语义化差

方法5:使用after伪元素清除浮动(推荐)

给浮动元素的父盒子添加伪元素,同时为了兼容 IE6,7 同样需要配合zoom使用
伪元素清除浮动,实际上也是类似于额外标签法,给伪元素后边加上一个没有高度的同级元素,只不过这个元素是用伪元素实现的,避免了标签过多造成代码错乱的问题

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
    }
    .clearfix::after {
      content: "";
      clear: both;
      display: block;
      visibility: hidden;
      font-size: 0;
      height: 0;
    }
    .clearfix {
      zoom: 1;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box clearfix">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

优点:符合闭合浮动思想,结构语义化正确
缺点:ie6-7不支持伪元素:after,使用zoom:1触发hasLayout,使元素根据自身内容计算宽高

方法6:使用双伪元素清除浮动(推荐)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
    }
    .clearfix::after, .clearfix::before {
      content: "";
      display: table;
    }
    .clearfix::after {
      clear: both;
    }
    .clearfix {
      *zoom: 1;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box clearfix">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

优点:代码更简洁
缺点:用zoom:1触发hasLayout.

方法7:父级同时浮动

此方法就是在子元素浮动的时候,父元素也跟着浮动,这样父元素和子元素同时处于脱标流状态,父元素的高度将被子元素撑开。但是不建议这样做,因为这又需要处理父元素浮动所带来的负面影响。

方法8:父级设置成inline-block

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
      display: inline-block;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

可以看出,浮动是解决了,但是父盒子也拥有了行内块元素的一些缺点,即下方多了空隙
在这里插入图片描述
优点:暂时没想到
缺点:父盒子也拥有了行内块元素的一些缺点,如父级的margin左右auto失效,无法使用margin: 0 auto;居中了,父盒子下方还有了几像素的间隙

方法9:br标签清除浮动

br 标签自带clear属性,将它设置成both其实和添加空div原理是一样的,在父盒子内部最后加上br标签,并给br标签的clear属性设置为both

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
      <br clear="both" />
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

优点:暂无
缺点:不符合工作中:结构、样式、行为,三者分离的要求

方法10:父级div定义display:table

将父盒子设置display: table; 可以清除子元素浮动带来的负面影响

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>清除浮动</title>
  <style>
    .main {
      width: 500px;
      height: 300px;
      border: 1px solid red;
      margin: 150px auto;
    }
    .father-box {
      width: 300px;
      display: table;
    }
    .son-one {
      width: 100px;
      height: 100px;
      float: left;
      background-color: rosybrown;
    }
    .son-two {
      width: 100px;
      height: 100px;
      float: left;
      background-color: sandybrown;
    }
    .bottom-box {
      width: 300px;
      height: 50px;
      background-color: skyblue;
      text-align: right;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="father-box">
      <div class="son-one">A的子元素1</div>
      <div class="son-two">A的子元素2</div>
    </div>
    <div class="bottom-box">同级盒子B</div>
  </div>
</body>
</html>

优点:无
缺点:会产生新的未知问题,不建议使用

关于BFC

关于css中BFC的概述,可以参考我另一篇文章CSS中的BFC

文章参考
https://blog.csdn.net/h_qingyi/article/details/81269667
https://www.cnblogs.com/nxl0908/p/7245460.html
https://blog.csdn.net/promiseCao/article/details/52771856
https://blog.csdn.net/bitkuang/article/details/82320365

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值