CSS 浮动布局

360 阅读3分钟

一、文档流

1、正常文档流

文档流即元素在页面中出现的先后顺序;正常文档流又称为普通文档流或者普通流,即 W3C 标准所说的 normal flow。正常文档流,将一个页面从上到下分为多行,其中块元素独占一行,相邻行内元素在每一行中按照从左到右排列,直到该行排满,也就是默认情况下页面内的元素布局情况。

正常文档流也可以说成是没有使用浮动和定位去改变的默认情况下的 HTML 文档结构。

2、脱离文档流

脱离文档流即脱离正常的文档流,可以使用两种方式改变正常的文档流:浮动和定位。

二、浮动

1、元素不浮动

使用 float 来实现浮动布局,其取值有两个:left 和 right ,当元素不设置浮动的时候,有如下代码:

<!DOCTYPE html>
<html>
    <head>
        <meta name="keywords" content="个人主页,HTML学习笔记"/>
        <meta name="author" content="Like_Frost"/>
        <meta name="description" content="学习示例"/>
        <meta name="copyright" content="版权所有,转载前请联系"/>
        <style type="text/css">
            .father{
                width: 200px;
                background-color: yellowgreen;
                overflow: hidden;
            }
            .father div{
                padding: 15px;
                margin: 10px;
            }
            .son1{
                background-color: wheat;
            }
            .son2{
                background-color: palevioletred;
            }
        </style>
    </head>
    <body>
        <div class="father">
            <div class="son1">son1</div>
            <div class="son2">son2</div>
        </div>
    </body>
</html>

在浏览器中效果如下:

image.png

Q&A:为什么父元素要设置 overflow:hidden?因为在盒模型中,有一个 margin 重叠规则,即所有的毗邻盒子会合并 margin 并共享 margin,毗邻指的是同级或者嵌套的元素,且他们之间没有空白元素、padding、border 分割。

去掉 overflow:hidden 这句代码,会出现如下情况:

image.png

由图可见,父元素和子元素的 margin 合为一个 margin,所以效果相当于子元素的一个 margin 不生效。

那么要怎么解决 margin 重叠的现象呢? 可以为父元素增加 border/padding/overflow:hidden; 或者给父元素/子元素增加 float/position:absolute(CSS 2.1 规定浮动和绝对定位元素不参与 margin 折叠)。

2、第一个 div 浮动

给第一个 div 加上 float:left 属性,效果如下:

image.png

由于 div 左浮动,所以他的宽度不延伸,而是由内容决定他的宽度,下一个 div 元素则紧贴它。

3、两个 div 均浮动

给两个 div 均加上 float:left,有如下效果:

image.png

两个元素的宽度均由文字决定,且 margin 生效(CSS 2.1 规定浮动和绝对定位元素不参与 margin 折叠)

浮动可以使元素移到左边或者右边,并且允许后面的文字或元素环绕它。浮动最常用于实现水平方向上的并排布局。

三、清除浮动

浮动会影响周围的元素,而且会引发许多意想不到的问题,可以使用 clear 属性来清除浮动带来的影响。

clear 属性有三个取值:left、right、both,即清除左浮动、清除右浮动、清除所有浮动。

在上面的两个 div 浮动的例子中,若不清除浮动,会有如下效果:

image.png

会发现父元素不见了!因为在这个例子里,我们要求父元素包裹子元素,所以不能给父元素定义高度,当把全部子元素均设置浮动时,他们就脱离了文档流,所以不能把父元素撑开,为了让父元素正常显示,可以使用添加一个清除浮动的空元素的方式来解决,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta name="keywords" content="个人主页,HTML学习笔记"/>
        <meta name="author" content="Like_Frost"/>
        <meta name="description" content="学习示例"/>
        <meta name="copyright" content="版权所有,转载前请联系"/>
        <style type="text/css">
            .father{
                width: 200px;
                background-color: yellowgreen;
            }
            .father div{
                padding: 15px;
                margin: 10px;
            }
            .son1{
                background-color: wheat;
                float: left;
            }
            .son2{
                background-color: palevioletred;
                float: left;
            }
            .clear{
                clear: both;
            }
        </style>
    </head>
    <body>
        <div class="father">
            <div class="son1">son1</div>
            <div class="son2">son2</div>
            <div class="clear"></div>
        </div>
    </body>
</html>

可以看到,父元素可以显示了,但是多了一个空行,不太美观:

image.png

还可以使用 overflow:hidden 来解决:

<!DOCTYPE html>
<html>
    <head>
        <meta name="keywords" content="个人主页,HTML学习笔记"/>
        <meta name="author" content="Like_Frost"/>
        <meta name="description" content="学习示例"/>
        <meta name="copyright" content="版权所有,转载前请联系"/>
        <style type="text/css">
            .father{
                width: 200px;
                background-color: yellowgreen;
                overflow: hidden;
            }
            .father div{
                padding: 15px;
                margin: 10px;
            }
            .son1{
                background-color: wheat;
                float: left;
            }
            .son2{
                background-color: palevioletred;
                float: left;
            }
        </style>
    </head>
    <body>
        <div class="father">
            <div class="son1">son1</div>
            <div class="son2">son2</div>
        </div>
    </body>
</html>

较为美观,是想要的效果:

image.png

清除浮动还有许多其他方式,如 after 伪元素等,了解即可。