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

实现Modal筛选弹窗高度渐进变化 避免展开下拉时直接跳至85%高度

问题原因

现有代码的高度逻辑为:任意筛选下拉触发展开状态时,直接将模态框容器高度设置为85%,且未配置任何高度过渡规则。同时CSS原生不支持height: auto与固定高度值之间的补间动画,因此模态框会直接跳变到最大高度,无法跟随下拉内容展开动态平滑增高。

修复方案

基础适配(下拉为普通文档流场景)

如果你的四个筛选下拉组件展开时属于正常文档流、可以撑开父容器高度,直接修改容器样式即可,不需要手动绑定展开状态判断高度:

  • 修改基础style配置,新增高度过渡规则、最大高度限制,默认高度随内容自适应
const style = {
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    width: 300,
    bgcolor: 'background.paper',
    border: '1px solid #000',
    boxShadow: 24,
    p: 4,
    overflow: 'auto',
    // 高度变化时添加300ms平滑缓动过渡
    transition: 'height 0.3s ease',
    // 限制最大高度不超过预设的85%
    maxHeight: '85%',
    // 默认高度跟随内容自动适配
    height: 'auto'
};
  • 删除Box组件上原有硬编码的高度判断内联样式,直接复用style配置即可
<Box sx={style}>
    {/* 原有模态框内的标题、筛选项、按钮代码保持不变 */}
</Box>

修改后,父容器会自动跟随子下拉组件的展开高度平滑增长,直到高度触达85%的上限后自动出现滚动条,不会一次性直接跳变到最大高度。

特殊场景适配(下拉为绝对定位脱离文档流场景)

如果筛选下拉组件用了绝对定位、展开时无法撑开父容器高度,就通过已有的展开状态标记动态计算高度,保留过渡效果:

  1. 先统计当前处于展开状态的筛选项数量
  2. 根据展开数量动态计算容器高度,同时保留最大高度限制
export default function ModalWindow() {
    const [open, setOpen] = React.useState(false);
    const [isFilterMethodExpanded, setIsFilterMethodExpanded] = React.useState(false);
    const [isFilterStatusCodeExpanded, setIsFilterStatusCodeExpanded] = React.useState(false);
    const [isFilterLinkExpanded, setIsFilterLinkExpanded] = React.useState(false);
    const [isFilterDateExpanded, setIsFilterDateExpanded] = React.useState(false);
    const handleOpen = () => setOpen(true);
    const handleClose = () => setOpen(false);

    // 统计展开的筛选项数量
    const expandedFilterCount = [
        isFilterMethodExpanded,
        isFilterStatusCodeExpanded,
        isFilterLinkExpanded,
        isFilterDateExpanded
    ].filter(Boolean).length;

    return (
        <div>
            <Button onClick={handleOpen}><FilterAltIcon /></Button>
            <Modal
                open={open}
                onClose={handleClose}
                disableScrollLock={true}
            >
                <Box 
                    sx={style}
                    style={{
                        // 收起状态高度自适应,每展开1个筛选项增加对应高度(可根据实际下拉高度调整120px这个值)
                        height: expandedFilterCount === 0 ? 'auto' : `calc(220px + ${expandedFilterCount * 120}px)`,
                        maxHeight: '85%'
                    }}
                >
                    {/* 原有内部代码保持不变 */}
                </Box>
            </Modal>
        </div>
    );
}

注意:不要直接在height: auto和固定百分比/像素值之间直接加过渡,浏览器无法计算auto值对应的中间过渡帧,必然会出现跳变。用maxHeight限制、或者动态计算可量化的固定高度值,才能实现平滑的高度变化效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:54:22