关于overflow,w3school定义是:

overflow:auto 如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。

我对于overflow:auto的初级理解是,设置父元素height/width,若子元素溢出,则自动显示纵向/横向滚动条。

很长时间我是这么理解的,但是现在和flex布局一起就发现有点问题,在深入了解后,接触了BFC概念。


1.使用多层(两层)overflow:auto,了解overflow如何运作

<div style="background-color: gray;height: 50vh;width:500px;display:flex;flex-direction: column;">
    <div>
        header
    </div>
    <div style="display: flex;flex:1;overflow:auto;"><!--定义第一个overflow-->
        <div style="flex:1;background-image: linear-gradient(#e66465, #9198e5);overflow:auto;"><!--定义第二个overflow-->
            <p style="height:300px;width:100px;background-color:cadetblue;">111</p><!--定义高度以溢出父元素-->
        </div>
        <div style="flex:1;background-color:#e66465">second</div>
    </div>
</div>

如果不定义第一个overflow的情况,仅定义第二个overflow:auto的情况下

内容并未被正常裁剪。

若仅定义第一个overflow,未定义第二个overflow的情况下

滚动条下拉发现子元素内容溢出,父元素级别被正常裁剪(背景)

根据这个现象分析,overflow仅影响当前元素下子元素的溢出行为,无法指定子元素的子元素溢出行为,也就是常说的子元素不继承。

overflow怎样裁剪——根据当前定义元素的高度来裁剪。由于这里第一个overflow元素的高度会自动变化,overflow总会认为无需裁剪。


2.flex布局中,overflow:hidden元素可被压缩至0

从上面的例子看出,下方元素溢出时,根据flex弹性布局规则,将压缩其他元素(上方header)部分。

header压缩至最小高度将不再压缩,作为flex直接子元素,不设置宽高时,最小高度是根据该元素内容撑开决定的

若此时将header部分设置为overflow:hidden 或 height:0,就可被flex压缩至0

利用这种特性,我想到了一个元素全屏的实现,还是上面的例子,我简化一下

<div style="background-color: gray;height: 100vh;width:100vw;display:flex;flex-direction: column;">
    <div style="overflow: hidden;height: 40%;">
        header
    </div>
    <div id="fullscreen" style="display: flex;flex:1;overflow:auto;">
        <div style="flex:1;background-color: #e66465;overflow:auto;">
            <button onclick="fullscreen()">full screen</button>
            <p style="height:100vh;width:100px;background-color:cadetblue;"></p>
        </div>
    </div>
</div>
<script>
    function fullscreen(){
        let fullscr = document.getElementById('fullscreen');
        let overflow = fullscr.style.overflow;
        fullscr.style.overflow =  overflow == 'auto' ? 'visible' : 'auto';
    }
</script>

点击按钮,去除下方元素overflow属性,使高度随内容撑开,此时根据flex布局,将压缩上方header,达成效果。


3.同理flex布局中,内容被文字撑开,导致不能根据flex压缩

<div style="display: flex;justify-content: space-between;width:200px">
    <div style="flex:1;background-color: #9198e5;">1111111111111111</div>
    <div style="background-color: #e66465;">right</div>
</div>

 

如上,定义了父级元素宽度为200px,由于子元素内容过多,在正常情况下,元素最小宽度由文字决定,此时宽度>200,溢出父级元素。

这个时候可以使用overflow:hidden,或 width:0,由flex决定宽度。

使用overflow:hidden:

使用overflow:hidden;text-overflow:ellipsis;

<div style="display: flex;justify-content: space-between;width:200px">
    <div style="flex:1;background-color: #9198e5;overflow: hidden;text-overflow: ellipsis;">11111111111111111111111</div>
    <div style="background-color: #e66465;">right</div>
</div>

达成效果


2022.07.04补充

虽然overflow:hidden 能使flex来计算元素宽/高,且overflow:hidden 为BFC。

但这并不是BFC造成的!

如果想使flex元素不因为子元素内容而影响原有的flex-grow的布局(由flex去计算元素的宽/高)

则可在flex子元素中设置width:0或height:0

因为有的时候,overflow:hidden会截断元素内的元素。(如悬浮提示)


PS:

  • flex:1; 与overflow:hidden 或 width/height:0 搭配经常会达成预期的flex效果。
  • flex-grow: 1根据剩余空间分配比例。flex:1根据flex容器所有空间分配比例。

参考资料

  1. 深入理解BFC
  2. 深入理解CSS溢出overflow
  3. 块级格式化上下文(MDN)

  4. 如何解决flex文本溢出问题 - 掘金 (juejin.cn)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐