css|🎉关于那些年浮动带来的高度塌陷问题

262 阅读5分钟

1、对浮动的理解

在了解什么是浮动之前我们先了解一下html元素在普通流排列方式。在普通流中,元素是按照它在 HTML 中的出现的先后顺序自上而下依次排列布局的,在排列过程中所有的行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为一整行。如果没有特殊样式指定,所有元素默认都是按照普通流方式排列布局,即普通流中元素的位置由该元素在 HTML 文档中的位置决定的。

浮动使元素脱离文档普通流,漂浮在普通流之上的。浮动元素依然按照其在普通流的位置上出现,然后尽可能的根据设置的浮动方向向左或者向右浮动,直到浮动元素的外边缘遇到包含框或者另一个浮动元素为止,且允许文本和内联元素环绕它。浮动会产生块级框(相当于设置了display:block),而不管该元素本身是什么。

image (28).png

就如上图的显示的div1,div2,div3就是按照普通流排列布局方式呈现的,而后面的div4,div5,div6中的div5的布局方式就不一样了,因为我给div5设置了向左浮动。此时div5脱离普通流,漂浮在普通流之上,所以导致原来div5在普通流中的位置空了出来,div6自动补上去(普通流(div6)表现的和浮动元素不存在一样)。

2、清除浮动

浮动导致元素已不在普通流中,所以在排列布局的时候文档中的普通流表现的和浮动元素不存在一样,当浮动元素的高度超出包含框的时候,会出现包含框不会自动撑高来包裹浮动元素,即所谓的“高度塌陷”。如下图所示

image (29).png

无浮动

    <style>
        .father { background-color: #7fffd4;}
        .son1 {background-color: #87ceeb;height: 100px;width: 100px;}
        .son2 {background-color: #f5f5dc;height: 100px;width: 100px;}
        .son3 {background-color: #ffe4c4; height: 100px;width: 100px;}
    </style>
<body>
    <div class="father">
        <div class="son1"></div>
        <div class="son2"></div>
        <div class="son3"></div>
    </div>
</body>

image (30).png

浮动后

子元素脱离了文档流,父元素的高度不会被撑开,成为高度塌陷

    <style>
        .father { background-color: #7fffd4;}
        .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
        .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
        .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
    </style>
<body>
    <div class="father">
        <div class="son1"></div>
        <div class="son2"></div>
        <div class="son3"></div>
    </div>
</body>

image (31).png

方式一

给父容器添加after伪类

    <style>
        .father { background-color: #7fffd4;}
        .father::after{content: '';display: block;clear: both;}
        .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
        .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
        .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
    </style>
<body>
    <div class="father">
        <div class="son1"></div>
        <div class="son2"></div>
        <div class="son3"></div>
    </div>
</body>

image (32).png

方式二

给父元素添加样式overflow: hidden;或者overflow: auto;(不推荐该用法,使用hidden时当内容较多时会被遮挡,使用auto时内容较多会出现滚动条。构建块格式化上下(BFC))

    <style>
        .father { background-color: #7fffd4;overflow: hidden;}
        .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
        .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
        .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
    </style>
<body>
    <div class="father">
        <div class="son1"></div>
        <div class="son2"></div>
        <div class="son3"></div>
    </div>
</body>

方式三

子元素最后添加空标签,并设置clear:both的样式(不推荐使用,可能会增加很多空标签,代码冗余)

    <style>
    .father { background-color: #7fffd4;}
    .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
    .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
    .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
    .blank{clear: both;}
    </style>
    <body>
        <div class="father">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son3"></div>
            <div class="blank"></div>
        </div>
    </body>

方式四

给父容器设置高度 (不推荐,当浮动元素和设置的容器高度不一样时会出现问题,适合固定高度布局时使用)

   <style>
        .father { background-color: #7fffd4;height :100px;}
        .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
        .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
        .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
   </style>
    <body>
        <div class="father">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son3"></div>
        </div>
    </body>

方式五

让父元素一起浮动(不推荐,可能会影响父元素的兄弟元素和其父元素的排列布局)

<style>
  <style>
            .father { background-color: #7fffd4;float: left;width:100%;}
            .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
            .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
            .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
        </style>
    <body>
        <div class="father">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son3"></div>
        </div>
    </body>

方式六

给父元素设置display:table或者display:inline-block(构建块格式化上下文(BFC))

    <style>
          /* .father { background-color: #7fffd4;display: table;width: 100%;} */
        .father { background-color: #7fffd4;display: inline-block;width: 100%;}
        .son1 {float:left;background-color: #87ceeb;height: 100px;width: 100px;}
        .son2 {float:left;background-color: #f5f5dc;height: 100px;width: 100px;}
        .son3 {float:left;background-color: #ffe4c4; height: 100px;width: 100px;}
    </style>
    </head>
    <body>
        <div class="father">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son3"></div>
        </div>
    </body>

3、BFC

常见的定位方式

普通流 (normal flow)

在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

浮动 (float)

在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

绝对定位 (absolute positioning)

在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。

BFC块级格式化上下文

BFC(Block Formatting Contexts) 块级格式化上下文

BFC内部的元素布局不会影响到外部元素

触发BFC的条件

  • body根元素
  • 浮动元素,float值除了none以外
  • 绝对定位元素(absloute、fixed)
  • display的值(inline-block、table-cell、flex)
  • overflow除了visible以外的值

BFC特性

1、同一个BFC下外边距会发生折叠

<style>
    div {
        width: 100px;
        height: 100px;
        background-color: aquamarine;
        margin: 100px;
    }
</style>

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

image (33).png

2、解决折叠:让元素不在属于同一个BFC,并且设置其中的一个是BFC,利用overflow: hidden;触发

    p {
        width: 100px;
        height: 100px;
        background-color: aquamarine;
        margin: 100px;
    }

    .container {
        overflow: hidden;
    }
</style>
</head>

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

image (34).png

3、清除浮动

<body>
    <div style="border: 2px solid #000;">
        <div style="height:100px;width:100px;background-color:beige;float: left"></div>
    </div>
</body>

image (35).png

<body>
    <div style="border: 2px solid #000;**overflow: hidden;**">
     <div style="height:100px;width:100px;background-color:beige;float: left"></div>
    </div>
</body>

image (36).png

4、 实现2栏自适应布局

没有实现BFC,浮动的元素会覆盖其他元素

<body>
    <div style="height: 100px;width: 100px;float: left;background-color: antiquewhite;">我是一个左浮动的元素</div>
    <div style="height: 200px;width: 200px;background-color: blueviolet;">我是一个没有设置浮动, 
        也没有触发 BFC 元素, width: 200px; height:200px; background: #eee;</div>
</body>

image (37).png

设置BFC,实现2栏自动布局,左边的宽度固定,右边会自动适应剩下的宽度

<body>
    <div style="width: 500px;">
        <div style="height: 100px;width: 100px;float: left;background-color: antiquewhite;">我是一个左浮动的元素</div>
        <div style="height: 200px;background-color: blueviolet;**overflow: hidden;"**>我是一个没有设置浮动,
            也没有触发 BFC 元素, height:200px; background: #eee;</div>
    </div>
</body>

image (38).png

定位

1、relative定位

relative相对自己默认的位置。定位基点是自己默认位置;必须搭配topbottomleftright这四个属性一起使用

image (39).png

2、absolute定位

absolute相对于上级元素一般是父元素进行定位,有限制条件是父元素的定位不能是static,定位基点:上级元素(一般是父元素);absolute定位也必须搭配topbottomleftright这四个属性一起使用。

        .relative {
            position: relative;
        }

        .absolute {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

image (40).png

3、fixed定位

相对于浏览器视口定位,定位基点是浏览器窗口

    <div class="fixed">fixed</div>
        .fixed {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

image (41).png

4、sticky定位

当滑动到某一点时,发生固定 有效规则: 父级的overflow必须是visible 必须搭配topbottomleftright这四个属性一起使用,不能省略

        .backgorund {
            position: -webkit-sticky;
            position: sticky;
            top: 0;

        }  

案例:图片叠加

20220318134802.gif

案例:标题栏

20220318134357.gif

参考👀

zhuanlan.zhihu.com/p/25321647

blog.csdn.net/sinat_36422…

blog.csdn.net/u013356907/…