CSS浮动

https://github.com/qianguyihao/Web/blob/master/02-CSS基础/07-浮动.md

浮动的性质

浮动是css里面布局用的最多的属性。

现在有两个div,分别设置宽高。我们知道,它们的效果如下:

<!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>
    .box1 {
      width: 200px;
      height: 300px;
      background-color: yellowgreen;
    }

    .box2 {
      width: 300px;
      height: 300px;
      background-color: skyblue;
    }
  </style>
</head>

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

</html>

image
此时,如果给这两个div增加一个浮动属性,比如float: left;,效果如下:

image
这就达到了浮动的效果。此时,两个元素并排了,并且两个元素都能够设置宽度、高度了(这在上一段的标准流中,不能实现)。

浮动想学好,一定要知道三个性质。接下来讲一讲。

性质1:浮动的元素脱标

脱标即脱离标准流。我们来看几个例子。

证明1:

image

<!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>
    .box1 {
      float: left;
      width: 200px;
      height: 300px;
      background-color: yellowgreen;
    }

    .box2 {
      /* float: left; */
      width: 300px;
      height: 300px;
      background-color: skyblue;
    }
  </style>
</head>

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

</html>

上图中,在默认情况下,两个div标签是上下进行排列的。现在由于float属性让上图中的第一个<div>标签出现了浮动,于是这个标签在另外一个层面上进行排列。而第二个<div>还在自己的层面上遵从标准流进行排列

证明2:

image

<!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>
        span {
            float: left;
            width: 200px;
            height: 200px;
            background-color: yellowgreen;
        }
    </style>
</head>

<body>
    <span>生命壹号,永不止步</span>
</body>

</html>

上图中,span标签在标准流中,是不能设置宽高的(因为是行内元素)。但是,一旦设置为浮动之后,即使不转成块级元素,也能够设置宽高了。

所以能够证明一件事:一旦一个元素浮动了,那么,将能够并排了,并且能够设置宽高了。无论它原来是个div还是个span。所有标签,浮动之后,已经不区分行内、块级了。

性质2:浮动的元素互相贴靠

我们来看一个例子就明白了。

我们给三个div均设置了float: left;属性之后,然后设置宽高。当改变浏览器窗口大小时,可以看到div的贴靠效果:

img

我们给三个div均设置了float: left;属性之后,然后设置宽高。当改变浏览器窗口大小时,可以看到div的贴靠效果:

img

上图显示,3号贴左墙的时候,并不会往1号里面挤。

同样,float还有一个属性值是right,这个和属性值left是对称的。

性质3:浮动的元素有“字围”效果

来看一张图就明白了。我们让div浮动,p不浮动。

image

<!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>
        div {
            float: left;
        }

        img {
            width: 60%;
        }

        p {
            background-color: chocolate;
        }
    </style>
</head>

<body>
    <div>
        <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic3.zhimg.com%2Fv2-bb53fee23811cd64e086084d9f88c9c2_r.jpg&refer=http%3A%2F%2Fpic3.zhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1633278276&t=0434b3f01460375153317aa46b8f0454"
            alt="" srcset="">
    </div>
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. In dui est, imperdiet vitae faucibus vel, malesuada ac
        lectus. Proin tempus nulla in feugiat finibus. Sed vitae ipsum ipsum. Pellentesque diam lacus, lobortis in purus
        id, malesuada imperdiet purus. Donec eleifend lorem a lectus tristique accumsan. Etiam ipsum tortor, aliquam et
        mauris sit amet, sagittis tristique nisi. Etiam nisl nibh, dictum sed interdum eu, vehicula et lectus. Praesent
        et velit ut erat feugiat rutrum.

        Etiam venenatis lacus nec velit ultricies mattis. Proin commodo lectus leo, finibus tempor leo pretium ac.
        Nullam ultrices metus eget elit viverra, condimentum aliquet lorem lobortis. Donec tincidunt, metus ut dignissim
        consequat, eros ligula dictum eros, sed pulvinar odio eros id ligula. Curabitur dignissim ante in leo consequat
        dapibus sed in nulla. Fusce vel pharetra leo, a bibendum orci. Etiam feugiat a nisl vel consequat. Mauris mattis
        nulla id odio tincidunt hendrerit.

        Praesent lacinia diam at maximus fringilla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non
        eleifend sem. Etiam suscipit et nisi vitae placerat. Nulla facilisi. In fringilla posuere neque sed ultrices.
        Quisque vulputate sollicitudin turpis sit amet fringilla. Proin vitae bibendum mauris. Aenean ornare justo vel
        vestibulum posuere. Donec et leo at nisi sollicitudin ultricies sed pretium ante. Proin bibendum faucibus
        tempor.

        In efficitur eros sed convallis fermentum. Ut enim risus, condimentum eu luctus sit amet, mattis vitae mauris.
        Nulla facilisi. Mauris fermentum consectetur lorem ac imperdiet. Morbi euismod, magna in rhoncus condimentum,
        eros ex dignissim velit, id elementum neque justo non sapien. Ut feugiat velit odio, id vulputate augue luctus
        sit amet. Curabitur vestibulum dui sed est sodales, ac bibendum mi consequat. Cras facilisis nisl ut feugiat
        ultrices.

        Donec dictum aliquam neque, in semper turpis gravida vitae. Aenean convallis feugiat massa. Nam pretium
        porttitor tempor. Sed vitae porttitor lacus. Aliquam erat volutpat. Vestibulum finibus auctor felis, eleifend
        placerat purus dignissim non. Integer venenatis massa odio, ac facilisis enim efficitur sit amet. In non eros
        bibendum, varius elit quis, luctus erat.
    </p>
</body>

</html>

上图中,我们发现:div挡住了p,但不会挡住p中的文字,形成“字围”效果。

总结:标准流中的文字不会被浮动的盒子遮挡住。(文字就像水一样)

关于浮动我们要强调一点,浮动这个东西,为避免混乱,我们在初期一定要遵循一个原则:永远不是一个东西单独浮动,浮动都是一起浮动,要浮动,大家都浮动。

性质4:收缩

收缩:一个浮动的元素,如果没有设置width,那么将自动收缩为内容的宽度(这点非常像行内元素)。

举例如下:

image

<!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>
        div {
            float: left;
            background-color: chocolate;
        }
    </style>
</head>

<body>
    <div>生命壹号1</div>
</body>

</html>

上图中,div本身是块级元素,如果不设置width,它会单独霸占整行;但是,设置div浮动后,它会收缩

浮动的补充(做网站时注意)

image

<!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>
        * {
            padding: 0;
            margin: 0;
        }

        div {
            width: 400px;
            height: 400px;
            background-color: pink;
        }

        .para1 {
            float: left;
            width: 100px;
            height: 300px;
            background-color: blue;
        }

        .para2 {
            float: left;
            width: 250px;
            height: 300px;
            background-color: green;
        }
    </style>
</head>

<body>
    <div>
        <p class="para1"></p>
        <p class="para2"></p>
    </div>
</body>

</html>

上图所示,将para1和para2设置为浮动,它们是div的儿子。此时para1+para2的宽度小于div的宽度。效果如上图所示。可如果设置para1+para2的宽度大于div的宽度,我们会发现,para2掉下来了:

image

<!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>
        * {
            padding: 0;
            margin: 0;
        }

        div {
            width: 400px;
            height: 400px;
            background-color: pink;
        }

        .para1 {
            float: left;
            width: 100px;
            height: 300px;
            background-color: blue;
        }

        .para2 {
            float: left;
            width: 350px;
            height: 300px;
            background-color: green;
        }
    </style>
</head>

<body>
    <div>
        <p class="para1"></p>
        <p class="para2"></p>
    </div>
</body>

</html>

布置一个作业

布置一个作业,要求实现下面的效果:

img

<!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 type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        .header {
            width: 970px;
            height: 103px;
            /*居中。这个语句的意思是:居中:*/
            margin: 0 auto;
        }

        .header .logo {
            float: left;
            width: 277px;
            height: 103px;
            background-color: red;
        }

        .header .language {
            float: right;
            width: 137px;
            height: 49px;
            background-color: green;
            margin-bottom: 8px;
        }

        .header .nav {
            float: right;
            width: 679px;
            height: 46px;
            background-color: green;
        }

        .content {
            width: 970px;
            height: 435px;
            /*居中,这个语句今天没讲,你照抄,就是居中:*/
            margin: 0 auto;
            margin-top: 10px;
        }

        .content .banner {
            float: left;
            width: 310px;
            height: 435px;
            background-color: gold;
            margin-right: 10px;
        }

        .content .rightPart {
            float: left;
            width: 650px;
            height: 435px;
        }

        .content .rightPart .main {
            width: 650px;
            height: 400px;
            margin-bottom: 10px;
        }

        .content .rightPart .links {
            width: 650px;
            height: 25px;
            background-color: blue;
        }

        .content .rightPart .main .news {
            float: left;
            width: 450px;
            height: 400px;
        }

        .content .rightPart .main .hotpic {
            float: left;
            width: 190px;
            height: 400px;
            background-color: purple;
            margin-left: 10px;
        }

        .content .rightPart .main .news .news1 {
            width: 450px;
            height: 240px;
            background-color: skyblue;
            margin-bottom: 10px;
        }

        .content .rightPart .main .news .news2 {
            width: 450px;
            height: 110px;
            background-color: skyblue;
            margin-bottom: 10px;
        }

        .content .rightPart .main .news .news3 {
            width: 450px;
            height: 30px;
            background-color: skyblue;
        }

        .footer {
            width: 970px;
            height: 35px;
            background-color: pink;
            /*没学,就是居中:*/
            margin: 0 auto;
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <!-- 头部 -->
    <div class="header">
        <div class="logo">logo</div>
        <div class="language">语言选择</div>
        <div class="nav">导航条</div>
    </div>

    <!-- 主要内容 -->
    <div class="content">
        <div class="banner">大广告</div>
        <div class="rightPart">
            <div class="main">
                <div class="news">
                    <div class="news1"></div>
                    <div class="news2"></div>
                    <div class="news3"></div>
                </div>
                <div class="hotpic"></div>
            </div>
            <div class="links"></div>
        </div>
    </div>

    <!-- 页尾 -->
    <div class="footer"></div>
</body>

</html>

效果

image

浮动的清除

这里所说的清除浮动,指的是清除浮动与浮动之间的影响

前言

通过上面这个例子,我们发现,此例中的网页就是通过浮动实现并排的。

比如说一个网页有header、content、footer这三部分。就拿content部分来举例,如果设置content的儿子为浮动,但是,这个儿子又是一个全新的标准流,于是儿子的儿子仍然在标准流里。

从学习浮动的第一天起,我们就要明白,浮动有开始,就要有清除。我们先来做个实验。

下面这个例子,有两个块级元素div,div没有任何属性,每个div里有li,效果如下:

image

<!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 type="text/css">
        li {
            width: 100px;
            height: 20px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <div class="box1">
        <ul>
            <li>生命壹号1</li>
            <li>生命壹号2</li>
            <li>生命壹号3</li>
            <li>生命壹号4</li>
        </ul>
    </div>
    <div class="box2">
        <ul>
            <li>许嵩1</li>
            <li>许嵩2</li>
            <li>许嵩3</li>
            <li>许嵩4</li>
        </ul>
    </div>
</body>

</html>

上面这个例子很简单。可如果我们给里面的<li>标签加浮动。效果却成了下面这个样子:

代码如下:

image

<!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 type="text/css">
        li {
            float: left;
            width: 100px;
            height: 20px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <div class="box1">
        <ul>
            <li>生命壹号1</li>
            <li>生命壹号2</li>
            <li>生命壹号3</li>
            <li>生命壹号4</li>
        </ul>
    </div>
    <div class="box2">
        <ul>
            <li>许嵩1</li>
            <li>许嵩2</li>
            <li>许嵩3</li>
            <li>许嵩4</li>
        </ul>
    </div>
</body>

</html>

上图中,我们发现:第二组中的第1个li,去贴靠第一组中的最后一个li了(我们本以为这些li会分成两排)。

这便引出我们要讲的:清除浮动的第一种方式。

那该怎么解决呢?

方法1:给浮动元素的祖先元素加高度

造成前言中这个现象的根本原因是:li的父亲div没有设置高度,导致这两个div的高度均为0px(我们可以通过网页的审查元素进行查看)。div的高度为零,导致不能给自己浮动的孩子,撑起一个容器。

撑不起一个容器,导致自己的孩子没办法在自己的内部进行正确的浮动。

好,现在就算给这个div设置高度,可如果div自己的高度小于孩子的高度,也会出现不正常的现象:

image

div {
    height: 10px;
}

li {
    float: left;
    width: 100px;
    height: 20px;
    background-color: pink;
}

给div设置一个正确的合适的高度(至少保证高度大于儿子的高度),就可以看到正确的现象:

总结:

如果一个元素要浮动,那么它的祖先元素一定要有高度。

有高度的盒子,才能关住浮动。(记住这句过来人的经验之语)

只要浮动在一个有高度的盒子中,那么这个浮动就不会影响后面的浮动元素。所以就是清除浮动带来的影响了。

方法2:clear:both;

网页制作中,高度height其实很少出现。为什么?因为能被内容撑高!也就是说,刚刚我们讲解的方法1,工作中用得很少。

那么,能不能不写height,也把浮动清除了呢?也让浮动之间,互不影响呢?

这个时候,我们可以使用clear:both;这个属性。如下:

image

<!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 type="text/css">
        li {
            float: left;
            width: 100px;
            height: 20px;
            background-color: pink;
        }

        .box2 {
            clear: both;
        }
    </style>
</head>

<body>
    <div class="box1">
        <ul>
            <li>生命壹号1</li>
            <li>生命壹号2</li>
            <li>生命壹号3</li>
            <li>生命壹号4</li>
        </ul>
    </div>
    <div class="box2">
        <ul>
            <li>许嵩1</li>
            <li>许嵩2</li>
            <li>许嵩3</li>
            <li>许嵩4</li>
        </ul>
    </div>
</body>

</html>

clear就是清除,both指的是左浮动、右浮动都要清除。clear:both的意思就是:不允许左侧和右侧有浮动对象。

这种方法有一个非常大的、致命的问题,它所在的标签,margin属性失效了。读者可以试试看。

margin失效的本质原因是:上图中的box1和box2,高度为零。

方法3:隔墙法

上面这个例子中,为了防止第二个div贴靠到第二个div,我们可以在这两个div中间用一个新的div隔开,然后给这个新的div设置clear: both;属性;同时,既然这个新的div无法设置margin属性,我们可以给它设置height,以达到margin的效果(曲线救国)。这便是隔墙法。

我们看看例子效果就知道了:

image

<!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 type="text/css">
        * {
            margin: 0;
        }

        li {
            float: left;
            width: 100px;
            height: 20px;
            background-color: pink;
        }

        .cl {
            clear: both;
        }

        .h16 {
            height: 16px;
        }
</style>
</head>

<body>
    <div class="box1">
        <ul>
            <li>生命壹号1</li>
            <li>生命壹号2</li>
            <li>生命壹号3</li>
            <li>生命壹号4</li>
        </ul>
    </div>

    <div class="cl h16"></div>

    <div class="box2">
        <ul>
            <li>许嵩1</li>
            <li>许嵩2</li>
            <li>许嵩3</li>
            <li>许嵩4</li>
        </ul>
    </div>
</body>

</html>

上图这个例子就是隔墙法。

内墙法:

近些年,有演化出了“内墙法”:

为了讲内墙法,我们先记住一句重要的话:一个父亲是不能被浮动的儿子撑出高度的。举例如下:

(1)我们在一个div里放一个有宽高的p,效果如下:(很简单)

image

<!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 type="text/css">
        div {
            background-color: green;
        }

        p {
            width: 100px;
            height: 100px;
            background-color: red;
        }
    </style>
</head>

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

</html>

(2)可如果在此基础之上,给p设置浮动,却发现父亲div没有高度了:

image

p {
    float: left;
    width: 100px;
    height: 100px;
    background-color: red;
}

(3)此时,我么可以在div的里面放一个div(作为内墙),就可以让父亲div恢复高度:

image

<!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 type="text/css">
        div {
            background-color: green;
        }

        p {
            float: left;
            width: 100px;
            height: 100px;
            background-color: red;
        }

        .cl {
            clear: both;
        }
    </style>
</head>

<body>
    <div>
        <p></p>
        <div class="cl"></div>
    </div>
</body>

</html>

与外墙法相比,内墙法的优势(本质区别)在于:内墙法可以给它所在的家撑出宽度(让box1有高)。即:box1的高度可以自适应内容。

而外墙法,虽然一道墙可以把两个div隔开,但是这两个div没有高,也就是说,无法wrap_content。

清除浮动方法4:overflow:hidden;

我们可以使用如下属性:

overflow:hidden;

overflow即“溢出”, hidden即“隐藏”。这个属性的意思是“溢出隐藏”。顾名思义:所有溢出边框的内容,都要隐藏掉。

overflow:hidden;的本意是清除溢出到盒子外面的文字。但是,前端开发工程师发现了,它能做偏方。如下:

一个父亲不能被自己浮动的儿子,撑出高度。但是,只要给父亲加上overflow:hidden; 那么,父亲就能被儿子撑出高了。这是一个偏方。

举个例子:

image

<!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 type="text/css">
        * {
            margin: 0;
        }

        li {
            float: left;
            width: 100px;
            height: 20px;
            background-color: pink;
        }

        .box1 {
            overflow: hidden;
            background-color: yellowgreen;
        }
</style>
</head>

<body>
    <div class="box1">
        <ul>
            <li>生命壹号1</li>
            <li>生命壹号2</li>
            <li>生命壹号3</li>
            <li>生命壹号4</li>
        </ul>
    </div>

    <div class="box2">
        <ul>
            <li>许嵩1</li>
            <li>许嵩2</li>
            <li>许嵩3</li>
            <li>许嵩4</li>
        </ul>
    </div>
</body>

</html>

浮动清除的总结

我们在上一段讲了四种清除浮动的方法,本段来进行一个总结。

浮动的元素,只能被有高度的盒子关住。 也就是说,如果盒子内部有浮动,这个盒子有高,那么妥妥的,浮动不会互相影响。

加高法

工作上,我们绝对不会给所有的盒子加高度,这是因为麻烦,并且不能适应页面的快速变化。

clear:both;

最简单的清除浮动的方法,就是给盒子增加clear:both;表示自己的内部元素,不受其他盒子的影响。

浮动确实被清除了,不会互相影响了。但是有一个问题,就是margin失效。两个div之间,没有任何的间隙了。

隔墙法

在两部分浮动元素中间,建一个墙。隔开两部分浮动,让后面的浮动元素,不去追前面的浮动元素。
墙用自己的身体当做了间隙。

我们发现,隔墙法好用,但是第一个div,还是没有高度。如果我们现在想让第一个div,自动根据自己的儿子撑出高度,我们就要想一些“小伎俩”。

内墙法:

内墙法的优点就是,不仅仅能够让后部分的p不去追前部分的p了,并且能把第一个div撑出高度。这样,这个div的背景、边框就能够根据p的高度来撑开了。

overflow:hidden;

这个属性的本意,就是将所有溢出盒子的内容,隐藏掉。但是,我们发现这个东西能够用于浮动的清除。
我们知道,一个父亲,不能被自己浮动的儿子撑出高度,但是,如果这个父亲加上了overflow:hidden;那么这个父亲就能够被浮动的儿子撑出高度了。这个现象,不能解释,就是浏览器的偏方。
并且,overflow:hidden;能够让margin生效。

posted @ 2021-09-04 01:15  我係死肥宅  阅读(100)  评论(0编辑  收藏  举报