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

MUI Grid v2响应式断点在可展开抽屉中失效求助

问题分析与解决方案

核心原因

MUI Grid v2的xs、sm这类断点是基于浏览器视口宽度,而非父容器(抽屉)的宽度。哪怕你的抽屉只有450px宽,只要浏览器视口宽度≥600px(sm断点默认值),就会触发sm={4}的规则,每行显示3个元素。这就是抽屉宽度变化时布局没跟着变的原因。

解决办法(无需改用传统Grid)

你可以通过两种方式实现基于抽屉宽度的响应式布局:

方法1:用自定义媒体查询绑定父容器宽度

直接在Grid容器的sx中针对抽屉的宽度范围设置列数,替代默认的视口断点:

<Box>
  <Grid 
    container 
    spacing={2} 
    sx={{
      padding: '20px',
      // 抽屉宽度<600px时,每行2列
      '@media (max-width: 599.9px)': {
        gridTemplateColumns: 'repeat(2, 1fr)',
      },
      // 抽屉宽度≥600px时,每行3列
      '@media (min-width: 600px)': {
        gridTemplateColumns: 'repeat(3, 1fr)',
      },
    }}
  >
    {catalog.map((item, key) => (
      <Grid key={key}> {/* 不需要再设置xs/sm,容器已定义列数 */}
        <Card className="media-catalog-item" sx={{height:'250px'}}>
          <CardContent sx={{padding:'0px'}}>
            <div className="media-item-title">{item.info.label}</div>
            <div onClick={()=>{clickMedia(item)}}>
              <img src={"https://example.com" + item.overlay}></img>
              <img src={"https://example.com" + item.thumbnail}></img>
            </div>
            <div className= {list ? "list-item-footer" : "grid-item-footer"}>{item.info.displayName}</div>
          </CardContent>
          <CardActions>
            <Button onClick={() => {notesOperations(item)}}>Notes</Button>
            <Button onClick={() => {keywordsOperations(item)}}>Keywords</Button>
          </CardActions>
        </Card>
      </Grid>
    ))}
  </Grid>
</Box>

方法2:用useMediaQuery监听抽屉宽度

如果抽屉的宽度是动态可控的(比如用状态管理),可以用useMediaQuery结合自定义断点:

import { useMediaQuery } from '@mui/material';

// 假设抽屉宽度存在状态drawerWidth
const isDrawerNarrow = useMediaQuery(`(max-width: ${600 - 1}px)`);

return (
  <Box>
    <Grid 
      container 
      spacing={2} 
      sx={{padding:'20px'}}
      columns={isDrawerNarrow ? 2 : 3}
    >
      {catalog.map((item, key) => (
        <Grid size={1} key={key}> {/* 占满每列宽度 */}
          {/* Card内容保持不变 */}
          <Card className="media-catalog-item" sx={{height:'250px'}}>
            <CardContent sx={{padding:'0px'}}>
              <div className="media-item-title">{item.info.label}</div>
              <div onClick={()=>{clickMedia(item)}}>
                <img src={"https://example.com" + item.overlay}></img>
                <img src={"https://example.com" + item.thumbnail}></img>
              </div>
              <div className= {list ? "list-item-footer" : "grid-item-footer"}>{item.info.displayName}</div>
            </CardContent>
            <CardActions>
              <Button onClick={() => {notesOperations(item)}}>Notes</Button>
              <Button onClick={() => {keywordsOperations(item)}}>Keywords</Button>
            </CardActions>
          </Card>
        </Grid>
      ))}
    </Grid>
  </Box>
);

总结

不需要改用带item属性的传统Grid,问题根源是默认断点绑定视口而非父容器。通过自定义媒体查询或动态列数设置,就能实现基于抽屉宽度的响应式布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:15:40