实现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%的上限后自动出现滚动条,不会一次性直接跳变到最大高度。
特殊场景适配(下拉为绝对定位脱离文档流场景)
如果筛选下拉组件用了绝对定位、展开时无法撑开父容器高度,就通过已有的展开状态标记动态计算高度,保留过渡效果:
- 先统计当前处于展开状态的筛选项数量
- 根据展开数量动态计算容器高度,同时保留最大高度限制
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
相关产品推荐
相关产品推荐

