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

Material UI SwipeableDrawer固定元素移动端滚动时偏移问题

问题分析

你遇到的是移动端弹性滚动(overscroll)导致fixed定位元素偏移的典型问题:position: fixed 是相对于浏览器视口定位的,当移动端滚动到内容边缘继续滑动时,浏览器会触发弹性滚动,视口的实际视觉位置会被“拉动”,进而带动fixed定位的按钮偏移。同时原方案中按钮脱离抽屉容器独立定位,未与抽屉的滚动上下文绑定,也是问题根源之一。

解决方案:改用Flex布局固定按钮在抽屉底部

放弃position: fixed,通过Flex布局让按钮固定在抽屉内部底部,完全脱离视口定位的依赖,同时确保抽屉内部滚动独立于页面。具体修改如下:

  1. 给SwipeableDrawer设置Flex布局,让内容区和按钮区垂直排列
  2. 内容区设置flex: 1和overflowY: auto,实现内部滚动
  3. 按钮区直接作为Flex布局的尾部元素,自然固定在抽屉底部

修改后的代码示例:

<SwipeableDrawer
  anchor={anchor}
  open={state[anchor]}
  onClose={toggleDrawer(anchor, false)}
  onOpen={toggleDrawer(anchor, true)}
  // 开启抽屉内部滚动,锁定页面背景滚动
  ModalProps={{ scroll: 'paper' }}
  sx={{
    display: 'flex',
    flexDirection: 'column',
    height: '80vh', // 自定义抽屉高度,根据需求调整
  }}
>
  {/* 可滚动的长内容区 */}
  <Box sx={{ flex: 1, overflowY: 'auto', padding: 2, paddingBottom: '64px' }}>
    {/* 替换为你的长内容 */}
    {Array.from({ length: 50 }).map((_, idx) => (
      <Typography key={idx} variant="body1" mb={1}>
        长内容行 {idx + 1}
      </Typography>
    ))}
  </Box>

  {/* 固定在抽屉底部的操作按钮区 */}
  <Box
    sx={{
      backgroundColor: "#fff",
      display: "flex",
      width: "100%",
      borderTop: '1px solid #e0e0e0',
      "> *": {
        flex: "1",
      },
    }}
  >
    <Button onClick={toggleDrawer(anchor, false)}>Cancel</Button>
    <Button onClick={toggleDrawer(anchor, false)}>Submit</Button>
  </Box>
</SwipeableDrawer>
关键说明
  • ModalProps={{ scroll: 'paper' }}:确保抽屉打开时,只有抽屉内部内容可滚动,页面背景被锁定,避免页面滚动干扰抽屉内的元素定位
  • Flex布局:内容区通过flex:1占满抽屉剩余空间,按钮区自然停靠在底部,完全不受视口滚动影响
  • paddingBottom:给内容区添加底部内边距,避免长内容被按钮区遮挡

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:53:12