【问题标题】:Make child of Material UI Grid item stretch to fit the remaining height of the parent container使 Material UI Grid 项目的子项拉伸以适应父容器的剩余高度
【发布时间】:2021-04-25 04:05:14
【问题描述】:

1。当前外观

我有一个包含 4 个网格项的 Material UI 网格容器。每个 Grid 项中都有一个 Typography 组件,其中包含一个标题和一个带有一些内容的 Card,如下所示:

2。理想的外观

我希望卡片填充网格项目的剩余高度并且不超过它。这是我想要的输出:

3。不良外观(卡片高度 = 100%)

我已经尝试将卡片的高度设置为 100%,但这意味着每张卡片都采用其父级(网格项目)的高度,并且父级的高度 = 排版 + 卡片(而不是剩余空间减去Typography),所以结果是 Card 超出了父 Grid 项的高度,如下所示:

解决这个问题的最佳方法是什么?我正在使用 Material UI 的 Grid 来简化断点并与我的项目的其余部分保持一致,因此理想情况下,解决方案将使用这种方法。

代码如下:

import React from 'react';

const useStyles = makeStyles(theme => ({
   // stretch: { height: '100%' }, // Un-commenting this results in undesirable appearance 3 (see image 3 above)
    outline: { border: '1px solid red' },
}));

const Sections= () => {
  const classes = useStyles();

  return (
    <Grid container spacing={3} justify="space-between" alignItems="stretch" className={classes.outline}>
      <Grid item xl={2} lg={2} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 1</Typography>
          <Card className={classes.stretch}><CardContent>Lots and lots and lots and lots and lots and lots of content</CardContent></Card>
      </Grid>
   <Grid item xl={4} lg={4} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 2</Typography>
          <Card className={classes.stretch}><CardContent>Not much content</CardContent></Card>
   </Grid>
   <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 3</Typography>
          <Card className={classes.stretch}><CardContent>Not much content</CardContent></Card>
   </Grid>
   <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 4</Typography>
          <Card className={classes.stretch}><CardContent>Not much content</CardContent></Card>
   </Grid>
</Grid>
  );
};


export default Sections;

非常感谢,

凯蒂

【问题讨论】:

  • 我认为您遗漏了部分代码。例如每张卡片上方的附加“大标题”。您能否更新代码 sn-p 以包含它?谢谢
  • 我创建了一个stackblitz 实例,我相信它会达到您想要的结果。有趣的是,我取消了您的样式的注释,并且它似乎正在工作。有一些问题是您的 &lt;Grid /&gt; 标记的顺序不正确,所以这可能是您的样式以前不起作用的原因。
  • 谢谢查尔斯 - 我已经修改了代码,希望它现在看起来正确吗?正如您所建议的,我也意识到在错误的位置有一个结束标记 。除此之外,我可以看到您的代码正在运行,但我不明白其中的区别?与我自己的代码相比,我不得不大量简化此处显示的代码,所以我试图找出差异!你介意解释一下吗?非常感谢!
  • 实际上 - 我可以看到我担心该解决方案不起作用。如果您将边框应用到网格,那么您会看到它类似于上面的图像 3。 Cards 超出了父 Grid 的高度。非常感谢您的帮助!
  • 凯蒂,我在我的第一个解决方案中意识到了这个问题并更新了它。我希望它有帮助!感谢您提供的图片显示了预期的结果。

标签: javascript css reactjs material-ui


【解决方案1】:

要解决这个问题,您需要为每个单独的 Grid Item 设置一个高度。然后您可以显示以“列”的 flex-direction 弯曲的 Grid Item。接下来,您可以像以前一样将卡片的高度设置为 100%。 Material-UI 网格中的默认显示机制未设置为 flex,因此卡片将延伸到边框之外,因为它们使用负边距之类的东西。

代码如下:

// imports omitted

const useStyles = makeStyles(theme => ({
  stretch: { height: "100%" },
  item: { display: "flex", flexDirection: "column" } // KEY CHANGES
}));

export const Sections = () => {
  return (
    <Grid container spacing={2} justify="space-between" alignItems="stretch">
      <Item xl={2} lg={2} md={6} xs={12} title="Big Title 1" content="Lots and lots and lots and lots and lots and lots of content!" />
      <Item xl={4} lg={4} md={6} xs={12} title="Big Title 2" content="Not much content" />
      <Item xl={3} lg={3} md={6} xs={12} title="Big Title 3" content="Not much content" />
      <Item xl={3} lg={3} md={6} xs={12} title="Big Title 4" content="Not much content" />
    </Grid>
  );
}

const Item = ({ title, content, ...rest }) => {
  const classes = useStyles();

  return (
    <Grid className={classes.item} item {...rest}>
      <Typography>{title}</Typography>
      <Card className={classes.stretch}>
        <CardContent>{content}</CardContent>
      </Card>
    </Grid>
  );
};

查看stackblitz 以获取实时示例。

【讨论】:

  • 绝对完美!我无法找到令人满意的答案的天才解决方案!真的非常感谢你。我为此苦恼了几天,所以再次感谢查尔斯 - 太棒了:)
【解决方案2】:

要始终保持Card 的剩余高度,请为Typography 指定高度。假设Typography 的高度为20px,然后将CardItem 的高度设置为100% - (height of the typography_,即; `高度:'计算(100% - 20px)'。它会占用剩余的高度。

const useStyles = makeStyles((theme) => ({
    stretch: {
        height: 'calc(100% - 20px)'
    }, // Un-commenting this results in undesirable appearance 3 (see image 3 above)
    outline: { border: "1px solid red" }
}));
<Grid
  container
  spacing={3}
  justify="space-between"
  alignItems="stretch"
  className={classes.outline}>
  <Grid item xl={2} lg={2} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 1</Typography>
    <Card className={classes.stretch}>
      <CardContent>
        Lots and lots and lots and lots and lots and lots of content
      </CardContent>
    </Card>
  </Grid>
  <Grid item xl={4} lg={4} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 2</Typography>
    <Card className={classes.stretch}>
      <CardContent>Not much content</CardContent>
    </Card>
  </Grid>
  <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 3</Typography>
    <Card className={classes.stretch}>
      <CardContent>Not much content</CardContent>
    </Card>
  </Grid>
  <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 4</Typography>
    <Card className={classes.stretch}>
      <CardContent>Not much content</CardContent>
    </Card>
  </Grid>
</Grid>

【讨论】:

  • 谢谢拉吉夫!对于任何乐于确定第一个孩子身高的人来说,这是一个很好的答案。出于这个原因,我投了赞成票。我已将上面查尔斯的答案标记为正确答案,因为我相信如果标题超过两行,这可以解决。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2019-09-13
  • 2020-09-10
  • 2014-12-23
  • 1970-01-01
  • 2017-06-30
  • 2014-08-15
  • 1970-01-01
  • 2021-12-29
相关资源
最近更新 更多