一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情
float 属性可以指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它
float 属性最初只用于在一段文本内浮动图像, 实现文字环绕的效果,也就是实现图文环绕效果
但是早期的CSS标准中并没有提供好的左右布局方案, 因此在一段时间里面它成为网页多列布局的最常用工具
但如今出现flex布局和grid布局后,已经很少再去使用浮动进行布局和定位
绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果
可以通过float属性让元素产生浮动效果
值 | 说明 |
---|---|
none | 不浮动,默认值 |
left | 向左浮动 |
right | 向右浮动 |
浮动规则
-
元素一旦浮动后, 脱离标准流
- 朝着向左或向右方向移动,直到自己的边界紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止
- 如果元素是向左(右)浮动,浮动元素的左(右)边界不能超出包含块的左(右)边界
- 定位元素会层叠在浮动元素上面
<!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>
.box {
width: 300px;
height: 300px;
background-color: red;
padding: 30px;
}
.left,
.right {
background-color: blue;
color: #fff;
}
.left {
float: left;
}
.right {
float: right;
}
</style>
</head>
<body>
<div class="box">
<span class="left">left</span>
<span class="right">right</span>
</div>
</body>
</html>
- 浮动元素之间不能层叠
- 如果一个元素浮动,另一个浮动元素已经在那个位置了,后浮动的元素将紧贴着前一个浮动元素
- 如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止
- 浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出
- 这里指代的行内级元素除了行内级元素、inline-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>Document</title>
<style>
.container {
width: 300px;
background-color: gray;
display: flow-root;
}
.box {
width: 150px;
height: 150px;
color: #000;
}
.box1 {
background-color: red;
float: left;
}
.box2 {
background-color: #0f0;
}
span {
color: skyblue;
}
</style>
</head>
<body>
<!--
div.container的高度由内容撑开
可以看到div.box1向左浮动 div.box2上移 的时候
文本2依旧在原位,且不占据空间
-->
<div class="container">
<div class="box box1">1</div>
<!--
因为div.box1向左浮动了
所以div.box2自动上移,被div.box1覆盖
但是因为浮动元素不能覆盖行内级元素
所以文本2还是在原位,不会上移
-->
<div class="box box2">2</div>
</div>
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptate, ad.</span>
</body>
</html>
<!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>
.box {
width: 300px;
border: 1px solid red;
background-color: rgba(0, 0, 0, 0.3);
}
img {
width: 150px;
float: left;
}
</style>
</head>
<body>
<div class="box">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel, numquam?
Temporibus a soluta velit? Eos voluptatem earum quos assumenda vitae.
<img src="./images/favicon.ico">
Labore fugit explicabo minus consequuntur nobis repellat earum consequatur eveniet?
Nulla, ipsum esse vel omnis ab ducimus illo labore nostrum.
</div>
</body>
</html>
- 行内级元素、inline-block元素浮动后,其顶部将与所在行的顶部对齐
- 也就是说浮动只能进行左浮动和右浮动
- 无法实现上浮动和下浮动
- 对于位于同一行的多个浮动元素而言,他们之间的对齐方式是
顶部对齐
应用场景
去除元素间间隙
我们可以使用浮动来解决行内级元素、inline-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>Document</title>
<style>
.box {
width: 100px;
height: 100px;
display: inline-block;
}
.box1 {
background-color: #f00;
}
.box2 {
background-color: #0f0;
}
.box3 {
background-color: #00f;
}
</style>
</head>
<body>
<!--
为了增加代码的可读性
我们会在元素之间添加空格并进行换行
但是浏览器解析的时候,会默认将换行解析为空格
所以这就导致了元素和元素之间默认会产生一定的间隙
-->
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</body>
</html>
解决方法 | 说明 | 备注 |
---|---|---|
去除空格和换行 | 不利于代码的可维护性和可读性 | 不推荐 |
将父元素的font-size 设置为0 | font-size是个继承属性 这就意味着 在子元素中,需要将font-size的值进行重置 否则所有元素的font-size皆会为0,页面什么都不显示 | 不推荐 |
将元素按照相同的方向进行浮动 | 浮动元素之间没有间隙,且各个浮动元素之间不会覆盖 | |
为元素开启定位 | 通过调整元素的定位来移除元素间的空格 | |
使用margin 的负值 | 通过margin的负值 | |
设置父元素的display为flex | 开启BFC | 推荐 |
浮动结合margin负值模拟nth-child的效果
<!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>
.container {
width: 1190px;
background-color: rgba(0, 0, 0, 0.5);
display: inline-block;
}
.wrap {
/*
因为对于border-box而言
fatherWidth = marginLeft + marginRight + width
1190 = -5 + -5 + auto
此时子元素的宽度就成为了 1200px
也就是通过将margin的值设置为负值
将width拉伸为1200px
从而模拟:nth-of-child(5n)的效果
*/
margin: 0 -5px;
}
.box {
width: 230px;
height: 322px;
line-height: 322px;
text-align: center;
font-size: 25px;
background-color: #00f;
color: #fff;
/*
因为元素设置了 margin: 0 -5px;
必然导致div.box的位置向左偏移了5px
所以需要在子元素调整回来
*/
margin: 0 5px 10px;
float: left;
}
</style>
</head>
<body>
<div class="container">
<!--
额外嵌套一层以便于通过设置margin的负值来拉伸容器
-->
<div class="wrap">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
<div class="box box7">7</div>
<div class="box box8">8</div>
</div>
</div>
</body>
</html>
基本案例
<!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>
.container {
display: flow-root;
width: 1190px;
background-color: #333;
margin: 0 auto;
}
.wrap {
margin-right: -10px;
}
.box {
width: 290px;
height: 180px;
line-height: 180px;
text-align: center;
margin-right: 10px;
margin-bottom: 10px;
background-color: red;
float: left;
font-size: 26px;
color: #fff;
}
.item {
height: 370px;
}
</style>
</head>
<body>
<div class="container">
<!--
在内容和容器盒子之间多包裹一层div
以便于设置负的margin来对整体进行布局
-->
<div class="wrap">
<div class="box item">1</div>
<div class="box item">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>
</div>
</body>
</html>
清除浮动
浮动元素由于脱离了标准流,变成了脱标元素,所以不再向父元素汇报高度
所以父元素计算总高度时,就不会计算浮动子元素的高度,导致了高度坍塌的问题
解决父元素高度坍塌问题的过程,一般叫做清浮动(清理浮动、清除浮动)
也就是让父元素计算总高度的时候,把浮动子元素的高度算进去
clear
我们清除浮动最常见的方式是使用clear属性
clear 属性
可以指定一个元素是否必须移动(清除浮动后)到在它之前的浮动元素下面
值 | 说明 |
---|---|
none | 默认值,无特殊要求 |
left | 要求元素的顶部低于之前生成的所有左浮动元素的底部 --- 清除左浮动 |
right | 要求元素的顶部低于之前生成的所有右浮动元素的底部 --- 清除右浮动 |
both | 要求元素的顶部低于之前生成的所有浮动元素的底部 --- 清除左浮动和右浮动 |
<!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>
.box {
width: 600px;
background-color: red;
color: #fff;
}
.content {
width: 300px;
background-color: blue;
float: left;
}
.line {
clear: both;
}
</style>
</head>
<div class="box">
<div class="content">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus, omnis.
Consequuntur dolorum laboriosam incidunt rem deleniti neque autem ad odio?
Neque iusto velit porro ut qui quis, ex doloremque tenetur.
</div>
<!--
添加空元素 目的是为了清除浮动
div.line元素必须在浮动元素的下边
相对于起到一个占位符的作用
这样父元素div.box就可以知道浮动元素的高度
此时父元素的高度就会撑开,后边的元素也就不会自动上移
-->
<div class="line"></div>
</div>
<body>
</body>
</html>
但是使用html元素清除浮动的时候,我们需要在页面中创建很多的空的html元素用于清除浮动
这必然会增加很多无意义的空标签,维护麻烦,所以我们可以使用伪元素来实现相同的功能
<!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>
.box {
width: 600px;
background-color: red;
color: #fff;
}
.content {
width: 300px;
background-color: blue;
float: left;
}
.clear-fix::after {
content: '';
clear: both;
/*
默认伪元素是行内级非替换元素
默认的宽度为内容的宽高
所以默认是0px * 0px 并无法起到占位清除浮动的作用
所以需要设置display: block;
或 display: inline-block; + width: 100%;
*/
display: block;
/*
兼容老版本 --- 现代浏览器可以不用
在一些老版本浏览器里面
伪元素如果不设置对应的内容的时候
会有默认的内容存在
所以需要隐藏元素, 并将高度置为零
*/
visibility: hidden;
height: 0;
}
</style>
</head>
<div class="box clear-fix">
<div class="content">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus, omnis.
Consequuntur dolorum laboriosam incidunt rem deleniti neque autem ad odio?
Neque iusto velit porro ut qui quis, ex doloremque tenetur.
</div>
</div>
<body>
</body>
</html>