CSS — 浮动

100 阅读5分钟

1. 什么是浮动

为盒子设置 float 属性,盒子就变成了一个浮动的盒子。

浮动的设计初衷:实现文字环绕效果

例子:

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  border: pink solid 10px;
}

p {
  background-color: rgb(230, 83, 174);
}

.floatDiv {
  width: 300px;
  height: 30px;
  float: left;
  background-color: skyblue;
  opacity: .6;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        @import url(./float.css);
    </style>
</head>

<body>
    <h1>Simple float example</h1>
    <div class="floatDiv"></div>
    <p> 
        文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字
    </p>

    <p>
        汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字汉字
    </p>

</body>

</html>

image.png 从上例可看出,即使盒子浮动了,脱离了正常文档流,也覆盖在没有浮动的元素上了,但是其并没有将文本内容也覆盖掉。

2. 浮动造成什么影响

2-1. 影响与自身同级的盒子的排列

从第一点的例子中可看出,浮动盒子会覆盖在其后的一个盒子上面,但是不会覆盖其后一个盒子中的内容。

2-2. 无法撑开其父级盒子的高度

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  border: pink solid 10px;
}

p {
  background-color: rgb(230, 83, 174);
}
.floatDiv {
  width: 300px;
  height: 30px;
  float: left;
  background-color: skyblue;
  opacity: .6;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>floatEffect</title>
    <style>
        @import url(./floatEffect.css);
    </style>
</head>

<body>
    <h1>Simple float example</h1>
    <div class="parentFloatDiv">
        <div class="floatDiv"></div>
    </div>
    <p> 
        与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级
    </p>
</body>
</html>

image.png

从这个例子可以看到,当没有设置 floatDiv 盒子的父盒子的高度时,即使给 floatDiv 设置了高度,其父盒子的高度仍然不能被撑开,高度仍然是0

2-3. 影响与其父级盒子同级的盒子的排列

由于父盒子的高度无法被浮动的子盒子撑开,所以自然会影响与父盒子同级的盒子的排列。

3. 如何消除浮动

3-1. 解决浮动盒子的父盒子与其同级盒子之间的影响。

3-1-1. 触发 BFC

什么是 BFC

简单来说,可以将 BFC 想成是一个容器,这个容器的特点是其内和其外的元素的排列互不影响。设置 overflow: hidden; 来使一个盒子具有 BFC 特性:

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  border: pink solid 10px;
}

p {
  background-color: rgb(230, 83, 174);
}

.parentFloatDiv {
  overflow: hidden;
  background-color: blue;
}

.floatDiv {
  width: 300px;
  height: 30px;
  float: left;
  background-color: skyblue;
  opacity: .6;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>floatEffect</title>
    <style>
        @import url(./clearFloat.css);
    </style>
</head>

<body>
    <h1>Simple float example</h1>
    <div class="parentFloatDiv">
        <div class="floatDiv"></div>
    </div>
    <p> 
        与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级
    </p>
</body>
</html>

image.png

此时,父盒子的高度可被子盒子撑开。

3-1-2. clear

给浮动的子盒子的父盒子添加一个伪元素::after,给这个伪元素添加 claer:both

伪元素清除浮动的核心原理其实是在给父元素增加块级容器,同时对块级容器设置clear属性,使其能够正常按照块级容器排列方式那样排列在浮动元素的下面。同时,父元素的同级元素也会正常排列在伪元素形成的块级元素后面,而不受浮动影响。

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  border: pink solid 10px;
}

p {
  margin: 0;
  background-color: rgb(230, 83, 174);
}


.parentFloatDiv {
  background-color: blue;
}

.floatDiv {
  width: 300px;
  height: 30px;
  float: left;
  background-color: skyblue;
  /* opacity: .6; */
}

/* 解决浮动盒子的父盒子与其同级盒子之间的影响:clear */
.clearfix::after {
  display: block;
  overflow: hidden;
  content: '伪元素的内容哦';
  clear: both;
  height: 0;
  background: slateblue;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>floatEffect</title>
    <style>
        /* 解决浮动盒子的父盒子与其同级盒子之间的影响:BFC  */
        /* @import url(./clearFloat-BFC.css); */
        
        /* 解决浮动盒子的父盒子与其同级盒子之间的影响:clear  */
        @import url(./clearFloat-clear.css);
    </style>
</head>

<body>
    <h1>Simple float example</h1>
    <div class="parentFloatDiv clearfix">
        <div class="floatDiv"></div>
    </div>
    <p> 
        与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级
    </p>
</body>
</html>

image.png

3-2. 解决浮动盒子与其同级盒子之间的影响。

给浮动的盒子后面,放一个盒子B并设置 clear:both 属性,这个B盒子就可以按照正常文档流排放在浮动的盒子后面,此时B盒子之后的盒子也可以正常排列、且父盒子的高度也可以被正常撑开。

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  border: pink solid 10px;
}

p {
  margin: 0;
  background-color: rgb(230, 83, 174);
}

.parentFloatDiv {
  background-color: blue;
}


.floatDiv {
  width: 300px;
  height: 30px;
  float: left;
  background-color: skyblue;
  /* opacity: .6; */
}

/* 消除浮动盒子与其同级的盒子之间的影响 */
.floatDivNext {
  background-color: palegoldenrod;
  clear: both;
  height: 0;
  display: block;
}

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>floatEffect</title>
    <style>
        @import url(./clearFloatPeers.css);
    </style>
</head>
<!-- 消除浮动盒子与其同级的盒子之间的影响 -->
<body>
    <h1>Simple float example</h1>
    <div class="parentFloatDiv clearfix">
        <div class="floatDiv"></div>
        <p class="floatDivNext"></p>
        <p> 
            与floatDiv同级
        </p>
    </div>
    <p> 
        与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级、与parentFloatDiv同级
    </p>
    
</body>
</html>

image.png

参考文献: 可能是最全面最易懂的解析前端浮动的文章