问题
1. Current Appearance
I have a Material UI Grid container with 4 Grid items. Within each Grid item is a Typography component containing a title and a Card with some content, as shown below:
2. Desired appearance
I would like the Cards to fill the remaining height of the Grid items and not exceed it. This is my desired output:
3. Undesirable appearance (card height = 100%)
I have tried making the height of the Cards 100% but this means each Card takes on the height of its parent (the Grid item), and the height of the parent = Typography + Card (rather than the remaining space minus the Typography), so the result is that the Card then exceeds the height of the parent Grid item as below:
What is the best way to overcome this problem? I'm using Material UI's Grid to make the breakpoints easy and consistent with the rest of my project, so ideally the solution would use that approach.
Here is the code:
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;
Many thanks,
Katie
回答1:
To solve this, you need to set a height for each individual Grid Item. Then you can display the Grid Item flexed with the flex-direction of "column". Next, you can set the height of the card to 100% as you had before. The default display mechanism in the Material-UI grid is not set to flex so the card will extend outside of the border since they use things like negative margins.
The code is below:
// 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>
);
};
Checkout stackblitz for a live example.
回答2:
to make the Card
remaining height always, give a height to Typography
. let's say the height of Typography
is 20px
and then set the height of the CardItem
as 100% - (height of the typography_
i.e; `height:'calc(100% - 20px)'. It'll take the remaining height.
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>
来源:https://stackoverflow.com/questions/65815511/make-child-of-material-ui-grid-item-stretch-to-fit-the-remaining-height-of-the-p