Safari flex 内容上方的子水平滚动条(内容高度不正确)

Posted

技术标签:

【中文标题】Safari flex 内容上方的子水平滚动条(内容高度不正确)【英文标题】:Safari flex child horizontal scrollbar over content (incorrect content height) 【发布时间】:2020-11-29 05:45:37 【问题描述】:

我正在创建一个带有子项的水平滚动 div(flex 子项)。

它在任何地方都很好用,除了 Safari。

它可能不会在 *** 代码示例中显示问题,因为它依赖于“所有”父级的高度属性。这就是为什么我将 html 和 body 设置为 100% 的高度。

html, body 
        height: 100%;
        width:100%;
    
    
    #flexCont 
        display: flex;
        flex-direction: column;
        height: 100%;
    

    #scrollable 
        height:150px;
        white-space:nowrap;
        overflow-y:hidden;
        overflow-x:scroll;

        /* just for visualization */
        border:1px solid black;
        width:250px;
    

    .item 
        display: inline-block;
        height:100%;

        /* just for visualization */
        border-bottom:15px solid black;
        box-sizing: border-box;
        margin-right:5px;
        width:50px;
        background: red;
    
<html>
    <body>
    
    <div id="flexCont">
    <div id="scrollable">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    </div>
    
    </body>
    </html>

问题是 Safari 将 .item 的高度设置为 #scrollable 的高度 (150px) 的 100%,即使显示了水平滚动条并且内容区域更小 (135px)。

它会导致滚动条出现在内容上。

Chrome 和其他设备按预期将.item 的高度正确设置为 135px(假设滚动条为 15px)。

如前所述,它取决于所有父母的身高属性。这意味着如果我从htmlbody#flexCont 中删除height 100%,它会正确呈现。此外,如果我删除 display flex 或至少 flex-direction column,它也会正确呈现。

我添加了底部黑色边框以更好地可视化它。如果看不到,则隐藏在滚动条后面。

知道怎么解决吗?

底部 15 像素(黑色)在 Chrome 上和 Safari 上的滚动条后面可见。

编辑:该死的 Safari...添加 border-bottombox-sizing 在尝试使用 max-height:fill-available 修复它时(至少)会产生另一个问题。解决方案必须进行无边界测试。

【问题讨论】:

我无法复制此问题。正如预期的那样,Chrome 和 Safari 的 .item 都是 150 像素。 @Mattijs 150px 如果显示滚动条,则不是预期的。 #scrollable 高度为 150px,滚动条应为 15px,因此内容 (.items) 应为 135px;设置calc(100% - 15px) 使其在除 Safari 之外的任何地方都短 15 像素。 在 macOS 和 ios 滚动条叠加,不占用任何空间,就好像它们被绝对定位一样。 如前所述,当我从父母那里删除height 100% 或删除display flex 时,它不会发生。无论哪种方式,这都是奇怪的行为。 啊,好吧,我现在看到不一致了! 【参考方案1】:

height: fill-available; 添加到.item 似乎可以解决问题。

.item 
    height: 100%;
    height: -webkit-fill-available;

编辑: 删除了 -moz-fill-availablefill-available,因为它们不需要解决 Safari 中的问题并且会破坏 Firefox 中的布局。 此外请注意,在 Safari 中,如果您希望 .item 的所有子级具有基于其父级 (.item) 的高度,则必须对它们使用 -webkit-fill-available,这会产生更多问题。

【讨论】:

该死,它有效,但只有在底部边框存在时。如果它被删除,它会再次中断。没想到。 天哪,尝试保留box-sizing border box 并尝试不同(更高)的底部边框像素值......它会发疯。 哈哈我没有意识到。我已经用现在似乎可以无国界工作的解决方案更新了我的答案! 让我补充一点。 -webkit- 前缀“修复”了 Safari 中的问题,但 -moz- 在 Firefox 中破坏了它。此外,在接受fill-available 值的浏览器中,如果您希望.item 拥有100% 高度的孩子,您必须继续为这些孩子使用fill-available。不幸的是,它需要权衡取舍。所以我只会保留-webkit- 前缀属性和100% 作为后备,它在Safari 中修复它,而不会在其他任何地方破坏它。我会将它报告为 webkit 错误,从长远来看,这可能是最好的解决方案。

以上是关于Safari flex 内容上方的子水平滚动条(内容高度不正确)的主要内容,如果未能解决你的问题,请参考以下文章

带有水平滚动条的 pre/code 元素破坏了 Firefox 上的 flex 布局

QT滚动条的问题?

在 iOS Safari 中使用 iScroll 和输入时,键盘会将滚动条推到视口上方并卡住

FLEX - 禁用滚动条的鼠标滚动?

怎么给easyui中的datagrid加水平滚动条

隐藏 iframe 上的水平滚动条?