关于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容器所有空间分配比例。