浮动布局【CSS】

本文详细介绍了CSS中的浮动布局,包括浮动元素如何脱离文档流、内联排列以及导致的父元素高度坍塌问题。同时,文章讨论了多种清除浮动的方法,如clear属性、插入空块级元素和使用伪元素,以及利用overflow属性来避免高度坍塌。通过对这些方法的探讨,有助于理解和解决浮动布局带来的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 什么是浮动

浮动方式布局就是使用 float 属性,使元素脱离文档流,浮动起来。
浮动元素会脱离文档流并向左/向右浮动,直到碰到父元素或者另一个浮动元素。

1.1 特征

1.1.1 脱离文档流

脱离文档,也就是说浮动不会影响普通元素的布局。即其他div不会被设置浮动的div浮动位置影响,但是文字仍会为被浮动div让位。因为设置浮动的div只脱离了文档流并未脱离文本流。请添加图片描述
从上图可以看出,默认三个设置了宽高的block元素,本来会格子独占一行;如果框1设置了向左/向右浮动,他会忽略框2和框3,直到碰到父元素;同时也存在盖住普通元素的风险。请添加图片描述
如图所示,其他div在定位时会忽略被浮动div,而文字不会忽略。

1.1.2 可以内联排列

浮动会向左/向右浮动,直到碰到另一个浮动元素为止,这是浮动可以内联排列的特征。也就是说,浮动可以设置宽高,并且能够一行多个,是介于block和inline之间的存在。

1.1.3 会导致父元素高度坍塌

浮动会脱离文档流,这个问题对整个页面布局有很大的影响。

子元素设置浮动,若父元素内部若无其他未设置浮动的元素,切父元素未设置高度,则会出现父元素高度坍塌问题。

我们可通过clear浮动来解决。

1.1.4 案例

<div class="topDiv">
  <div class="floatDiv">float left</div>
  <div class="textDiv">Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut.
  </div>
</div>
<div class="bottomDiv">Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut.
</div>
    .topDiv {
        width: 500px;
        border: 2px solid black;
    }
    
    .floatDiv {
        width: 100px;
        height: 100px;
        border: 2px dotted red;
        color: red;
        margin: 4px;
        float: left;
    }
    
    .bottomDiv {
        width: 500px;
        height: 100px;
        margin: 5px 0;
        border: 2px dotted black;
    }
    
    .textDiv {
        color: blue;
        border: 2px solid blue;
    }

请添加图片描述

2. 清除浮动

2.1 clear清除浮动

还是开篇的例子,我们给需要清除浮动的元素添加如下样式:

.textDiv {
    color: blue;
    border: 2px solid blue;
    clear: left;
}

原理:

通过上面的样式,.textDiv告诉浏览器,我的左边不允许有浮动的元素存在,请清除掉我左边的浮动元素。然而,因为浮动元素(.floatDiv)位置已经确定,浏览器在计算.textDiv的位置时,为满足其需求,将.textDiv渲染在浮动元素下方,保证了.textDiv左边没有浮动元素。同时可以看出,父元素的高度也被撑起来了,其兄弟元素的渲染也不再受到浮动的影响,这是因为.textDiv仍然在文档流中,它必须在父元素的边界内,父元素只有增加其高度才能达到此目的,可以说是一个意外收获。(clear的值为both也有相同的效果,通俗理解就是,哪边不允许有浮动元素,clear就是对应方向的值,两边都不允许就是both)

但是,如果我们把HTML中的.floatDiv和.textDiv交换一下位置呢?

<div class="topDiv">
  <div class="textDiv">Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut.
  </div>
  <div class="floatDiv">float left</div>
</div>
<div class="bottomDiv">Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut.
</div>

无论.textDiv是否应用清除浮动,情况都是下面的样子:
请添加图片描述
.textDiv的位置先确定了,于是浮动元素就紧接着.textDiv下方渲染在父元素的左侧。然而,父元素的高度并没有被撑起来,没有将浮动影响“内化”,导致浮动影响到了接下来的元素排版。
看来,为达到撑起父元素高度的目的,使用clear清除浮动的方法还是有适用范围的。我们需要更加通用和可靠的方法。

(这里澄清一下,单从元素清除浮动的角度,clear完全已经达到了目的,它已经使得.textDiv特定的方向上不再有浮动元素,清除浮动其实仅仅针对需要清除浮动的元素本身而言,只关注自身需求是否达到,和外界没有什么关系,它不关注浮动是否超出父元素,以及浮动是否影响到后续元素排列。我们只是利用了浮动的一些特性达到某些目的,但这不是清除浮动关心的问题,只不过,相对于清除浮动,我们可能更加关心这些特性能为我们做些什么而已。我的理解是,清除浮动和撑起父元素高度其实是两个不同的问题,在这里,可以简单地理解为工具和目的之间的关系,接下来要讨论的两个方法都是在利用清除浮动这个工具在解决问题,它并不是清除浮动这个工具本身。不过,我们经常将两者混为一谈。)

2.2 父元素结束标签之前插入清楚浮动的块级元素

HTML结构如下,在有浮动的父级元素的末尾插入了一个没有内容的块级元素div:

<div class="topDiv">
    <div class="textDiv">...</div>
    <div class="floatDiv">float left</div>
    <div class="blankDiv"></div>
</div>
<div class="bottomDiv">...</div>
.topDiv {
    width: 500px;
    border: 2px solid black;
}
.floatDiv {
    width: 100px;
    height: 100px;
    border: 2px dotted red;
    color: red;
    margin: 4px;
    float: left;
}
.bottomDiv {
    width: 500px;
    height: 100px;
    margin: 5px 0;
    border: 2px dotted black;
}
.textDiv {
    color: blue;
    border: 2px solid blue;
}
// 区别在这里
.blankDiv {
    clear: both; // or left
}

请添加图片描述
原理无需多讲,和第一个例子里.textDiv应用clear清除浮动,撑起父级元素高度的原理完全一样。这里强调一点,即,在父级元素末尾添加的元素必须是一个块级元素,否则无法撑起父级元素高度。

2.3 利用伪元素

HTML结构如下,为了惯例相符,在.topDivdiv上再添加一个clearfix类:

<div class="topDiv clearfix">
    <div class="textDiv">...</div>
    <div class="floatDiv">float left</div>
</div>
<div class="bottomDiv">...</div>
// 省略基本的样式
// 区别在这里
.clearfix:after {
    content: '.';
    height: 0;
    display: block;
    clear: both;
}

该样式在clearfix,即父级元素的最后,添加了一个:after伪元素,通过清除伪元素的浮动,达到撑起父元素高度的目的。注意到该伪元素的display值为block,即,它是一个不可见的块级元素(有的地方使用table,因为table也是一个块级元素)。你可能已经意识到,这也只不过是前一种清除浮动方法(添加空白div)的另一种变形,其底层逻辑也是完全一样的。前面的三种方法,其本质上是一样的。

2.4 利用overflow清除浮动

首先直观地看看,overflow是如何清除浮动的。

<div class="topDiv">
    <div class="floatDiv">float left</div>
    <div class="textDiv">...</div>
</div>
<div class="bottomDiv">...</div>
.topDiv {
    width: 500px;
    padding: 4px;
    border: 2px solid black;

    // 区别在这里
    overflow: auto;
}
.floatDiv {
    width: 100px;
    height: 100px;
    border: 2px dotted red;
    color: red;
    margin: 4px;
    float: left;
}
.bottomDiv {
    width: 500px;
    height: 100px;
    margin: 5px 0;
    border: 2px dotted black;
}
.textDiv {
    color: blue;
    border: 2px solid blue;
}

仅仅只在父级元素上添加了一个值为autooverflow属性,父元素的高度立即被撑起,将浮动元素包裹在内。看起来,浮动被清除了,浮动不再会影响到后续元素的渲染(严格讲,这和清除浮动没有一点关系,因为不存在哪个元素的浮动被清除,不纠结这个问题)。其实,这里的overflow值,还可以是除了"visible"之外的任何有效值,它们都能达到撑起父元素高度,清除浮动的目的。不过,有的值可能会带来副作用,比如,scroll值会导致滚动条始终可见,hidden会使得超出边框部分不可见等。那它们是如何做到浮动清除的呢?

要讲清楚这个解决方案的原理,有一个概念始终是绕不过去,那就是块格式化上下文(BFC),然而这又是一个非常抽象的概念。这里不多赘述,我们会在另一篇文章中详细的讲解。BFC(Block Formatting Context)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值