CSS浮动

260 阅读6分钟

1.标准流

在理解浮动这个概念之前,我们先揭示一个已有但不明了的概念:标准流

标准流是指html中的标签按照默认的方式排列布局,例如,块级元素是独占一行显示,而行内块元素在一行内可以显示多个,而当元素超过父元素或网页的边缘时会自动换行。

2.浮动

定义

与标准流相对应的也就是今天要说的浮动,浮动的定义如下:

使用浮动(float)就是创造一个浮动框,赋予一个浮动的属性值(例如left/right),被声明的标签会变为一个浮动框,浮动框会根据属性值向父元素的相应方位贴近,直到触碰到父元素边缘或前一个浮动框的边缘。

元素的浮动在实际开发中非常常用,例如,在W3School网页中红色方框的部分(包括许多网页的第一栏都是这一类情况),当需要块级元素放在同一行显示时,我们使用浮动属性:

image.png

左边的W3school的logo图标与右边的搜索框是靠边对齐(一个左对齐,一个右对齐)的,这在标准流中很难确保其两者之间的距离,若设定一个固定的外边距,当网页大小变化时会出现一些问题,这时候我们需要使用浮动来帮助我们布局。

在CSS中,浮动的代码语法如下:

float: left;

覆盖的情况(脱标

如上是一个向左浮动的声明,在元素设置了浮动属性后,则不会占用原本位置的文档流,浮动元素常与标准流父级元素(块级)搭配使用,如果父元素中出现了多个子盒子,那么没有浮动的元素会占用浮动元素的位置,出现脱离标准流的情况(脱标),这种情况只会发生在浮动框之后的标准流元素,而不会影响之前的,我们以代码的形式来看看为什么会出现这种情况:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .nav {
            height: 500px;
            width: 1000px;
            background-color: pink;
        }

        .box {
            float: left;
            height: 300px;
            width: 300px;
            background-color: purple;
        }

        .box2 {
            height: 200px;
            width: 500px;
            background-color: blue;
        }
    </style>
</head>

<body>
    <div class="nav">
        <div class="box">

        </div>
        <div class="box2">

        </div>
    </div>
</body>

</html>

在代码中,我们使用三个div盒子进行演示,其中,类名为box的盒子设置了浮动属性,以下是这三个盒子的的位置关系:

image.png 紫色的盒子(浮动元素)覆盖住了蓝色的盒子,紫色盒子原本文档流位置空了出来,这就有覆盖的现象。如果我们给三个盒子都加上一些内容,情况又会怎么变化呢?

image.png 可以看到,虽然文档流的位置被空了出来,但是盒子内的内容并没有被覆盖,而是遵循标准流的显示模式,比如父盒子的文本内容独占一行。

当浮动元素之前有一个标准流(块级)元素时,标准流元素按照标准流的形式正常显示,而后才是浮动元素,例如在一个浮动div之前有另一个标准流div,它以块级元素的显示模式显示,独占一行,下一行才会显示具有浮动属性的div盒子,而不会覆盖之前的盒子。

浮动元素会具有行内块的显示模式,不需要转换显示模式即可设置一些相关属性。

多块级元素的浮动

前面提到,浮动元素常搭配一个标准流父元素使用,这种方法有以下几大优点:

  1. 更好的约束浮动元素的布局
  2. 方便控制页面各个元素的分布
  3. 可对父元素设置一些样式来优化布局

我们都知道,div标签在标准流中是以块级元素的模式显示,并不能同行显示;而浮动框可以贴近前一浮动框的边缘,实现同行显示,如此,我们可以通过给div盒子设置浮动属性,这样就可以在父盒子中使用div标签。

为什么不用元素显示转换?

元素模式转换也可实现块级元素同行显示,但元素模式转换有个缺点:转换后的元素在显示时与相邻的元素会出现一条缝隙,这不利于我们对页面布局的绝对控制。

3.清除浮动

浮动盒子搭配标准流父盒子在网页布局中使用频率非常高,但是有时会带来一些问题,我们需要给父盒子设置高来限制浮动盒子,但在实际的网页制作中,同一页面在不同时期会有不同的显示内容,内容的体量也大不相同,我们难以保证父盒子的大小在我们预期内,那么不设置高度呢?如果让内容物的实际多少来控制盒子的大小,会达到我们要的效果吗?我们对上面提到的代码进行简单的更改,把子盒子都改为浮动元素,取消父盒子的高度:

        .nav {
            /* height: 500px; */
            width: 1000px;
            border: 5px solid pink;
            /* 这里我们给父盒子加一个5像素宽的边框,方便我们观察父盒子的大小。 */
            background-color: pink;
            
        }

        .box {
            float: left;
            height: 300px;
            width: 300px;
            background-color: purple;
        }

        .box2 {
            float: left;
            /* 增加浮动属性,子盒子都浮动。 */
            height: 200px;
            width: 500px;
            background-color: blue;
        }

现在父盒子会如愿变为我们需要的大小吗?

image.png 父盒子居然只剩下边框?为什么父盒子没有如我们所愿被子盒子撑开?我们回到上文中浮动元素的一个重要性质:脱标:

浮动元素会脱离标准流的显示模式,不再占用原来的文档流位置空间。

两个子盒子都设置了浮动属性,都不再占用父盒子的文档流空间,导致父盒子认为这里没有任何东西,所以就没有高度。如何解决这个问题?清除浮动可以解决这个现象:

清除浮动实质上是清除浮动元素脱离标准流带来的影响

1.额外标签

在最后一个浮动元素末尾加一个块级元素的空标签并对其添加声明:

clear: both;

2.overflow

为父元素添加:

overflow: hidden;

3.after伪元素

为父元素添加:

            .clearfix:after {
                content: "";
                display: block;
                height: 0;
                clear: both;
                visbility: hidden;
            }
            .clearfix {
                *zoom: 1;
                /*这行代码目的是为了兼容IE6、IE7*/
            }

4.双伪元素

为父元素添加:

            .clearfix:before,
            .clearfix:after {
                content: "";
                display: table;
            }
            .clearfix:after {
                clear: both;
            }
            .clearfix {
                *zoom: 1;
                /* 同上,为兼容IE6、IE7 */
            } 

PS:清除浮动代码的实际意义本人还未学习,只先记住了此代码,已在清除浮动的标题处添加搜索链接