如何解决HTML+CSS中高度塌陷的问题?

518 阅读4分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

一、高度塌陷的含义

在文档流中,当父元素不设置高度height,完全是被子元素给撑开的,也就是说子元素有多高,父元素就有多高。但是当为子元素设置浮动或定位等脱离文档流的操作后 ,子元素就会导致父元素的高度塌陷,由于父元素高度塌陷了,则父元素的所有元素都会向上移动及会影响其他元素的布局,这样页面布局就会出现混乱,所以在开发当中一定要尽量避免高度塌陷。 7013fe9ae21351f1b3461d1e77fce82a.gif

二、解决高度塌陷的方法

方法①:父元素高度写固定值

可将父元素的高度写具体值,即写死以避免塌陷的问题,但高度有了固定值后父元素的高度就无法自适应子元素的高度,也会造成不便,因此不建议使用该方法。

`.box1 {
    /* 给父元素的高度加固定值 */
    height: 100px;
    border: 10px solid #58bc58;
}`

方法②:设置浮动

把父元素(即发生高度塌陷的元素)也设置浮动,此方法弊端较大,虽然可以撑开父元素,不过会产生浮动问题,即导致下边的元素上移从而出现元素重叠/覆盖,影响整体页面布局,若父元素也有父元素呢?总不能一直浮动到body吧?可见此方法也不能很好地解决问题。

`.box1 {
    width: 100%;
    float: left;
}`

方法③:overflow: hidden;

给父元素设置overflo:hidden;溢出隐藏属性,此方法代码少且简单,副作用也较小

弊端:在和position定位一起用的时候,会把溢出盒子的部分隐藏掉。

`.box1 {
    width: 100%
    overflow: hidden;
}`

方法④:转变成inline-block行内块元素

把父元素的元素类型转变成行内块元素,此方法可以解决问题,但会导致宽度丢失,不推荐使用。

`.box1 {
    width: 100%
    display: inline-block;
}`

方法⑤:添加空白标签,如div

直接在高度塌陷的父元素的最后添加一个空白标签div,由于这个div并没有浮动,所以他可以撑开父元素的高度,然后对该div进行清除浮动,这样可以通过这个空白的div来撑开父元素的高度,基本没有副作用。使用这种方式虽然可以解决问题,但是会在页面中增加结构负担,产生代码冗余,该方法所有的浏览器都兼容

`div{
    /* 空白标签div,添加清除浮动属性 */
    clear: both;
}`

方法⑥:万能清除法

通过after伪类元素添加一个空白的块元素,css加下列属性,并给要清除的div加上相对应的类名。

此方法可以很好地解决塌陷问题,不过代码量相对其他方法较多。

`.box::after{
        content: "";
        display: block;
        clear: both;
        /* height: 0;overflow: hidden; 为了解决 IE 浏览器的兼容问题 */
        height: 0;
        overflow: hidden;
        /* visibility:hidden;为了去隐藏content中的内容 */
        visibility: hidden;
}`
  

三、关于高度塌陷的问题可引出一个关于BFC的概念 BFC:根据W3C标准,在页面中的元素都有一个隐含的属性叫做Block Formatting Context,直译为“块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box(块)参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。该属性可以设置打开或者关闭,默认是关闭的,开启BFC有助于避免高度塌陷的问题。

**当元素开起BFC属性后,元素具有如下的特性: **

①.内部的Box会在垂直方向上一个接一个的放置。

②.垂直方向上的距离由margin决定

③.bfc的区域不会与float的元素区域重叠。

④.计算bfc的高度时,浮动元素也参与计算

⑥.bfc就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。

开启BFC的方法:

①.浮动元素,float 除 none 以外的值;

②.定位元素,position(absolute,fixed);

③.display 为以下其中之一的值 inline-block,table-cell,table-caption;

④.overflow 除了 visible 以外的值(hidden,auto,scroll);