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
相关产品推荐
相关产品推荐

