CSS - 高度塌陷问题

2019-07-23  本文已影响0人  辻子路

父元素如果不指定高度,那么它的高度是由子元素高度决定,也就是被内容撑开。 例如:

<html>
<head>
    <style>
        .box1 {
            border: 10px red solid;
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
        }
    </style>
</head>

<body>
    <div class="box1">
        <div class="box2"> </div>
    </div>
</body>
</html>

展示:

image.png
这时候我们给box2设置浮动(float:left),这时候它就脱离了文档流。那这时候父元素的高度就没有内容撑着了,也就是所谓的高度塌陷。
展示:
image.png
这时候我们就想到如果把父元素设置高度不就行了么。 可以是可以,但是原本我们父元素的高度是自适应子元素内容高度的,写死了也就没有适应这么一说了。所以这个方案是不推荐的。

那怎么解决呢?
这里就要引入一个块格式化上下文
)(Block Formatting Context,BFC)概念。那它有什么作用呢?

如何开启?上面的链接里面已经详细介绍了。
然后我们来依次看下效果。

<html>
<head>
    <style>
        .box1 {
            background-color: #E7A1C5;
        }

        .box2 {
            height: 100px;
            background-color: #C8CDF5;
            margin-top: 10px
        }
    </style>
</head>
<body>
    <div class="box1">
        <div class="box2"></div>
    </div>
</body>
</html>

实际效果:

image.png
我们发现子元素设置了margin-top,可是实际上也作用于父元素了,它们重叠了。那上面说到BFC可以解决这个问题,那我们现在来开启下,给父元素设置overflow:hidden; 这时效果如下:
image.png
<html>

<head>
    <style>
        .box1 {
            background-color: #E7A1C5;
            width: 100px;
            height: 100px;
            float: left;
        }

        .box2 {
            height: 200px;
            width: 200px;
            background-color: #C8CDF5;
        }
    </style>
</head>

<body>
    <div class="box1">

    </div>
    <div class="box2"></div>
</body>

</html>

展示:

image.png
由于box1设置了浮动,脱离文档流,这时box2就会上移,被box1覆盖。
我们不想box2被box1覆盖,那这时只需要给box2设置overflow:hidden就可以了。
效果:
image.png
<html>
<head>
    <style>
        .box1 {
            border: 10px red solid;
            overflow:hidden;   /*开启BFC*/
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left
        }
    </style>
</head>

<body>
    <div class="box1">
        <div class="box2"> </div>
    </div>
</body>
</html>

我们这次给box1开启了BFC,这时候我们就已经解决了高度塌陷的问题了。
但是这样的解决方式有几个缺点:

<html>
<head>
    <style>
        .box1 {
            border: 10px red solid;
            float:left
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left
        }
    </style>
</head>

<body>
    <div class="box1">
        <div class="box2"> </div>
    </div>
</body>
</html>

效果:

image.png
虽然解决了高度塌陷问题,可是和我们原来想要的效果不一致了(父元素宽度没了)。

有没有什么解决方案是没有副作用的呢? 我们来看看clear这个属性。
首先我们先来一段代码

<!DOCTYPE html>
<html lang="en">

<head>
    <style>
        .box1 {
            width: 100px;
            height: 100px;
            background-color: lightgreen;
            float: left;
        }

        .box2 {
            width: 200px;
            height: 200px;
            background-color: yellow;
        }

        .box3 {
            width: 300px;
            height: 300px;
            background-color: lightblue;
        }
    </style>
</head>

<body>
    <div class="box1"></div>
    <div class="box2"></div>
    <div class="box3"></div>
</body>

</html>

效果:


image.png

那clear是干嘛的呢?它的作用是清除其它元素对当前元素的影响。它有几个可选值:

说了这么多,还是没解决高度塌陷问题。这时候我们在原来的box2下面再加个box3。

<html>

<head>
    <style>
        .box1 {
            border: 10px red solid;
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
    </style>
</head>

<body>
    <div class="box1">
        <div class="box2">
        </div>
        <div class="box3">a</div>
    </div>
</body>

</html>

效果:

image.png
我们发现,由于box2脱离了文档流,那么这时父元素就被box3给撑开了。
联想到clear是清除浮动给当前元素带来的影响,那这时候我们给box3设置个clear:left再看下:
image.png
我们发现现在和我们要的越来越近了,现在只不过box3多了个a,我们把它去掉看看:
image.png
解决!所以我们的解决方案是在高度塌陷的父元素最后加一个空的div,clear设置为both(因为我们不知道是左浮还是右浮)。

但是,html还是会多出一个div。那么我们怎么才能不要这个div,又能解决高度塌陷呢,答案是:after,我们给box1设置

.box1:after{
    content:'';
    clear:both;
    display: block;
}

这才是完美解决方案~

上一篇 下一篇

猜你喜欢

热点阅读