React Material UI 带有卡片的响应式网格
React Material UI responsive Grid with Card
我正在尝试使用应具有相同高度(包括图像)的卡片创建响应式网格布局。我正在使用 React 和 Material-UI.
我已经折腾了好几个小时了,想不出解决办法。 “弹性”部分对我来说似乎非常不直观。请帮忙。
这是一个非常小而简单的代码片段:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
cardGrid: {
flexGrow: 1,
paddingTop: 16,
},
card: {
flex: 1,
height: '100%',
backgroundColor: 'red',
},
cardActionArea: {
flex: 1,
height: '100%',
backgroundColor: 'green',
},
cardMedia: {
height: '0',
paddingTop: '56.25%', // 16:9
},
cardContent: {
flex: 1,
backgroundColor: blue[600],
},
cardContentTitle: {
flex: 1,
backgroundColor: blue[400],
},
cardContentRating: {
backgroundColor: blue[300],
},
cardContentDistance: {
backgroundColor: blue[200],
}
}),
);
// ...
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
dataList.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Card className={classes.card}
onClick={handleCardClick}
key={`OverviewItem-${data.id}`}
>
<CardActionArea className={classes.cardActionArea}>
{
data.previewURL &&
<CardMedia
className={classes.cardMedia}
image={data.previewURL}
title={data.title}
/>
}
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5" className={classes.cardContentTitle}>
{data.title}
</Typography>
<Typography className={classes.cardContentRating}>
Some text
</Typography>
<Typography className={classes.cardContentDistance}>
Some other text
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
))
}
</Grid>
</Container>
我想要达到的目标:
- 图片应位于每张卡片的顶部
- “一些文本”和“其他一些文本”应该移到底部
似乎我必须在下树时多次写入“flex:1”和“height:'100%'”,并且在某些时候它会完全中断,如下面的屏幕截图所示:
上面的代码片段看起来像这样:
简单地将 Grid Item 的子项扩展到其最大高度并且仍然能够按我的需要对齐它们有什么神奇之处。
例如整个卡片应覆盖网格项目的区域,图像下方的标题部分应展开以将图像移至顶部,将“一些文本”和“其他一些文本”移至底部。
任何 hints/ideas 不胜感激!
我能够在没有卡片和图像的情况下实现我想要的。但是让树变大并因此嵌套更深,破坏了一切,我不明白为什么。
这是简单的片段和结果:
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
toiletOverviews.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Box
display="flex"
flexDirection="column"
style={{height: '100%', backgroundColor: 'purple'}}
>
<Typography
variant="h5"
style={{flex:1, backgroundColor: blue[800]}}
>
{data.title}
</Typography>
<Typography
style={{backgroundColor: blue[600]}}
>
Some text
</Typography>
<Typography
style={{backgroundColor: blue[400]}}
>
Some other text
</Typography>
</Box>
</Grid>
))
}
</Grid>
</Container>
我想通了!我不知道的重要部分是 display:"flex"
仅应用于当前元素及其直接子元素。对于其子项的子项,它将不适用。
现在的解决方案是将它正确地应用于所有必要的元素。副作用是图像不再显示。它的 width/height 为零。此处的解决方法是将 width:"100%"
添加到 CardMedia 元素。
我正在尝试使用应具有相同高度(包括图像)的卡片创建响应式网格布局。我正在使用 React 和 Material-UI.
我已经折腾了好几个小时了,想不出解决办法。 “弹性”部分对我来说似乎非常不直观。请帮忙。
这是一个非常小而简单的代码片段:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
cardGrid: {
flexGrow: 1,
paddingTop: 16,
},
card: {
flex: 1,
height: '100%',
backgroundColor: 'red',
},
cardActionArea: {
flex: 1,
height: '100%',
backgroundColor: 'green',
},
cardMedia: {
height: '0',
paddingTop: '56.25%', // 16:9
},
cardContent: {
flex: 1,
backgroundColor: blue[600],
},
cardContentTitle: {
flex: 1,
backgroundColor: blue[400],
},
cardContentRating: {
backgroundColor: blue[300],
},
cardContentDistance: {
backgroundColor: blue[200],
}
}),
);
// ...
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
dataList.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Card className={classes.card}
onClick={handleCardClick}
key={`OverviewItem-${data.id}`}
>
<CardActionArea className={classes.cardActionArea}>
{
data.previewURL &&
<CardMedia
className={classes.cardMedia}
image={data.previewURL}
title={data.title}
/>
}
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5" className={classes.cardContentTitle}>
{data.title}
</Typography>
<Typography className={classes.cardContentRating}>
Some text
</Typography>
<Typography className={classes.cardContentDistance}>
Some other text
</Typography>
</CardContent>
</CardActionArea>
</Card>
</Grid>
))
}
</Grid>
</Container>
我想要达到的目标:
- 图片应位于每张卡片的顶部
- “一些文本”和“其他一些文本”应该移到底部
似乎我必须在下树时多次写入“flex:1”和“height:'100%'”,并且在某些时候它会完全中断,如下面的屏幕截图所示:
上面的代码片段看起来像这样:
简单地将 Grid Item 的子项扩展到其最大高度并且仍然能够按我的需要对齐它们有什么神奇之处。
例如整个卡片应覆盖网格项目的区域,图像下方的标题部分应展开以将图像移至顶部,将“一些文本”和“其他一些文本”移至底部。
任何 hints/ideas 不胜感激!
我能够在没有卡片和图像的情况下实现我想要的。但是让树变大并因此嵌套更深,破坏了一切,我不明白为什么。
这是简单的片段和结果:
<Container className={classes.cardGrid} maxWidth="xl">
<Grid
container
direction="row"
justify="space-evenly"
alignItems="stretch"
spacing={2}
>
{
toiletOverviews.map(data => (
<Grid item
key={`GridItem-${data.id}`} xs={12} sm={6} md={4} lg={2} xl={1}
>
<Box
display="flex"
flexDirection="column"
style={{height: '100%', backgroundColor: 'purple'}}
>
<Typography
variant="h5"
style={{flex:1, backgroundColor: blue[800]}}
>
{data.title}
</Typography>
<Typography
style={{backgroundColor: blue[600]}}
>
Some text
</Typography>
<Typography
style={{backgroundColor: blue[400]}}
>
Some other text
</Typography>
</Box>
</Grid>
))
}
</Grid>
</Container>
我想通了!我不知道的重要部分是 display:"flex"
仅应用于当前元素及其直接子元素。对于其子项的子项,它将不适用。
现在的解决方案是将它正确地应用于所有必要的元素。副作用是图像不再显示。它的 width/height 为零。此处的解决方法是将 width:"100%"
添加到 CardMedia 元素。