提示

本文主要讲解 CSS 的浮动布局。@ermo

# 浮动布局

# 结构伪类选择器

根据 HTML 元素之间的结构来寻找标签的方式称为结构伪类选择器。

有以下几种语法:

  • E:first-child,父元素中的第一个子元素
  • E:last-child,父元素中的最后一个子元素
  • E:nth-child(n),父元素中的任意一个子元素,n 为个数
  • E:nth-last-child(n),父元素中的任意一个子元素,倒叙查询,n 为个数
<!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>
        li:first-child {
            background-color: red;
        }
        li:last-child {
            background-color: red;
        }
        li:nth-child(2) {
            background-color: red;
        }
        li:nth-last-child(3) {
            background-color: red;
        }
    </style>
</head>
<body>
    <ul>
        <li>1li</li>
        <li>2li</li>
        <li>3li</li>
        <li>4li</li>
        <li>5li</li>
        <li>6li</li>
        <li>7li</li>
    </ul>
</body>
</html>

上例中 nth 可以写数学公式,按照某种规则选取元素。

  • 2n、even,偶数
  • 2n+1、2n-1、odd,奇数
  • -n+5,找到前5个元素
  • n+5,找到后5个元素

# 伪元素

网页中的非主题内容可以用伪元素表示,比如 banner 切换,有以下2中语法:

  • ::before,在父元素的最前面添加一个伪元素
  • ::after,在父元素的最后面添加一个伪元素
<!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 {
            width: 100px;
            height: 100px;
            background-color: pink;
        }

        div::before {
            content: '床前'
        }

        div:after {
            content: '月光'
        }
    </style>
</head>
<body>
    <div></div>
</body>
</html>

伪元素默认是行内元素,并且 content 属性必须添加。

# 浮动

文档流也称为普通流(normal flow),表示 HTML 元素在网页的默认排列方式。

比如 div 元素默认自动换行,span 元素默认一行展示,这些都是正常的文档流。

如果要改变正常的文档流,就需要使用到浮动的概念。

浏览器在解析行内块元素的时候,如果代码有换行,元素之间有间隔。

<!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 {
            width: 100px;
            height: 100px;
            display: inline-block;
            
        }
        .div1 {
            background-color: pink;
        }
        .div2 {
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <!-- 不换行可以解决间隔问题,但是代码会变得不容易阅读 -->
    <div class="div1">div1</div>
    <div class="div2">div2</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>
        div {
            width: 100px;
            height: 100px;
        }
        .div1 {
            background-color: pink;
            float: left;
        }
        .div2 {
            background-color: skyblue;
            float: left;
        }
    </style>
</head>

<body>
    <div class="div1">div1</div>
    <div class="div2">div2</div>
</body>

</html>

float 属性有两个可选值:

  • float: left;,元素向左浮动
  • float: 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>
        .top {
            margin: 0 auto;
            width: 800px;
            /* 子元素设置浮动,父级元素没有高度,后面的标准流元素会受影响 */
            /* height: 200px; */
            background-color: pink;
        }
        .bottom {
            height: 50px;
            background-color: green;
        }
        .left {
            float: left;
            width: 200px;
            height: 200px;
            background-color: grey;
        }
        .right {
            float: right;
            width: 590px;
            height: 200px;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div class="top">
        <div class="left"></div>
        <div class="right"></div>
    </div>
    <div class="bottom">

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

清除浮动有几种方法:

(1)父元素设置高度

(2)额外标签

需要在父元素内部最后添加块元素,设置 clear: 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>
        .top {
            margin: 0 auto;
            width: 800px;
            /* height: 200px; */
            background-color: pink;
        }
        .bottom {
            height: 50px;
            background-color: green;
        }
        .left {
            float: left;
            width: 200px;
            height: 200px;
            background-color: grey;
        }
        .right {
            float: right;
            width: 590px;
            height: 200px;
            background-color: skyblue;
        }
        .clearfix {
            clear: both;
        }
    </style>
</head>
<body>
    <div class="top">
        <div class="left"></div>
        <div class="right"></div>
        <div class="clearfix"></div>
    </div>
    <div class="bottom">

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

(3)单伪元素清除浮动

可以通过 ::after 伪元素清除浮动。单伪元素清除浮动和额外标签法原理相同。

<!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>
        .top {
            margin: 0 auto;
            width: 800px;
            height: 200px;
            background-color: pink;
        }
        .bottom {
            height: 50px;
            background-color: green;
        }
        .left {
            float: left;
            width: 200px;
            height: 200px;
            background-color: grey;
        }
        .right {
            float: right;
            width: 590px;
            height: 200px;
            background-color: skyblue;
        }
        .clearfix::after {
            content: '';
            display: block;
            clear: both;
            visibility: hidden;
        }
    </style>
</head>
<body>
    <div class="top clearfix">
        <div class="left"></div>
        <div class="right"></div>
        <div class="clearfix"></div>
    </div>
    <div class="bottom">

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

(4)双伪元素清除浮动

    <style>
        .clearfix::before,
        .clearfix::after {
            content: '';
            display: table;
        }
        .clearfix::after {
            clear: both;
        }
    </style>

(5)使用 overflow 属性

通过给父元素添加 overflow 属性同样可以清除浮动。

<!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>
        .top {
            margin: 0 auto;
            width: 800px;
            height: 200px;
            background-color: pink;
            overflow: hidden;
        }
        .bottom {
            height: 50px;
            background-color: green;
        }
        .left {
            float: left;
            width: 200px;
            height: 200px;
            background-color: grey;
        }
        .right {
            float: right;
            width: 590px;
            height: 200px;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div class="top">
        <div class="left"></div>
        <div class="right"></div>
    </div>
    <div class="bottom">

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