You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome中Grid容器与内容高度过渡速率不一致问题排查

问题

这是一个用Grid实现内容高度过渡的手风琴组件简化(夸张化)示例,过渡效果能正常运行,但在Chrome里表现异常:容器(.accordion)的高度增长速度比内容快,内容需要一段时间才能跟上高度变化,过渡期间容器底部会出现间隙。Firefox里表现完全正常。换不同过渡函数(比如linear)只会影响容器的过渡效果,高度差问题依然存在。想问这是Chrome的bug吗?如果是,有没有解决办法?

代码示例

CSS

.accordion {
    display: grid;
    grid-template-rows: minmax(0, 0fr) min-content;
    transition: grid-template-rows 3000ms;
    border: 1px solid;
    padding: 1rem;
}
    
.accordion.open {
    grid-template-rows: minmax(0, 1fr) min-content;
}
    
.content {
    overflow: hidden;
}

HTML

<div class="accordion">
    <div class="content">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam asperiores aut deserunt eaque incidunt labore laudantium minus nam omnis placeat quas quo, reprehenderit rerum soluta veritatis! Accusamus aliquam atque autem consequatur cumque, deserunt doloremque dolorum eaque eligendi esse est eum excepturi fugit hic impedit incidunt minus odit quae, ut voluptas.
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam asperiores aut deserunt eaque incidunt labore laudantium minus nam omnis placeat quas quo, reprehenderit rerum soluta veritatis! Accusamus aliquam atque autem consequatur cumque, deserunt doloremque dolorum eaque eligendi esse est eum excepturi fugit hic impedit incidunt minus odit quae, ut voluptas.
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam asperiores aut deserunt eaque incidunt labore laudantium minus nam omnis placeat quas quo, reprehenderit rerum soluta veritatis! Accusamus aliquam atque autem consequatur cumque, deserunt doloremque dolorum eaque eligendi esse est eum excepturi fugit hic impedit incidunt minus odit quae, ut voluptas.
    </div>
    <button onclick="this.parentElement.classList.toggle('open');">toggle</button>
</div>
分析与解决办法

这确实是Chrome在处理Grid行过渡时的渲染bug,核心原因是Chrome在过渡grid-template-rows中的fr单位时,容器高度计算和内容高度的更新不同步,导致出现间隙。

下面提供两种解决思路:

方案一:改用max-height实现(推荐)

放弃Grid行过渡,改用内容元素的max-height属性实现手风琴效果,这种方式在各浏览器表现更一致,代码也更简洁:

修改后的CSS

.accordion {
    border: 1px solid;
    padding: 1rem;
}

.content {
    max-height: 0;
    overflow: hidden;
    transition: max-height 3000ms;
}

.accordion.open .content {
    max-height: 2000px; /* 设置一个足够大的值,覆盖内容的最大高度即可 */
}

HTML部分无需修改,保持原代码即可。

方案二:保留Grid布局(需JS辅助)

如果一定要保留Grid结构,可以通过JavaScript动态计算内容高度,同步容器的Grid行高度和内容高度,避免不同步问题:

修改后的代码

CSS

.accordion {
    display: grid;
    grid-template-rows: minmax(0, 0fr) min-content;
    transition: grid-template-rows 3000ms;
    border: 1px solid;
    padding: 1rem;
}

.content {
    overflow: hidden;
    height: 0;
    transition: height 3000ms;
}

JavaScript

const toggleBtn = document.querySelector('button');
const accordion = toggleBtn.parentElement;
const content = accordion.querySelector('.content');

toggleBtn.addEventListener('click', () => {
    if (accordion.classList.contains('open')) {
        // 关闭时重置高度
        content.style.height = '0';
        accordion.style.gridTemplateRows = 'minmax(0, 0fr) min-content';
        setTimeout(() => accordion.classList.remove('open'), 3000);
    } else {
        // 打开时计算真实高度并设置
        const contentHeight = content.scrollHeight;
        content.style.height = `${contentHeight}px`;
        accordion.style.gridTemplateRows = `minmax(0, ${contentHeight}px) min-content`;
        accordion.classList.add('open');
    }
});

这种方式需要额外的JS逻辑,适合必须保留Grid布局的场景。

内容的提问来源于stack exchange,提问作者vvye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 14:07:16