Reputation: 29
I am trying to create a grid similar to this website by using Material-UI. However when the height of one card changes every card height changes. I tried to use direction="row"
and direction="column"
but it doesn't seem to work. I was wondering if there a way to change the height of the image inside depending on the size of the image while having a grid like the website above.
All I can see at the moment is this:
Here is my code for the card:
import React from 'react';
import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import CardMedia from '@material-ui/core/CardMedia';
import CardContent from '@material-ui/core/CardContent';
import CardActions from '@material-ui/core/CardActions';
import Avatar from '@material-ui/core/Avatar';
import IconButton from '@material-ui/core/IconButton';
// import Typography from '@material-ui/core/Typography';
import FavoriteIcon from '@material-ui/icons/Favorite';
import ShareIcon from '@material-ui/icons/Share';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import { useStyles } from '../style/card.styles';
export default function Cards({ profile, sourceImage }) {
const classes = useStyles();
return (
<Card className={classes.root} style={{ height: '100%' }}>
<CardHeader
avatar={
<Avatar aria-label="recipe" src={profile} className={classes.avatar}>
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title="Shrimp and Chorizo Paella"
subheader="September 14, 2016"
/>
<CardContent>
<CardMedia
className={classes.media}
image={sourceImage}
title="Paella dish"
/>
{/* <img src={sourceImage} style={{ maxHeight: '20rem' }} /> */}
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<FavoriteIcon />
</IconButton>
<IconButton aria-label="share">
<ShareIcon />
</IconButton>
</CardActions>
</Card>
);
}
And the layout page:
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import Cards from './Card';
import vertical from '../images/v1.jfif';
import horizontal from '../images/h1.png';
import '../style/card.css';
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
paper: {
height: 140,
width: 100,
},
control: {
padding: theme.spacing(2),
}
}));
export default function HomePage() {
const imagess = [vertical, horizontal, vertical, horizontal]
const classes = useStyles();
return (
<Grid container justify="center" className={classes.root} spacing={2}>
<Grid item xs={12}>
<Grid container alignItems="flex-start" justify="center" spacing={1}>
{imagess.map((image, index) => (
<Grid key={index} item>
<Cards profile={""} sourceImage={image} />
</Grid>
))}
</Grid>
<Grid container alignItems="flex-start" justify="center" spacing={1}>
{imagess.map((image, index) => (
<Grid key={index} item>
<Cards profile={""} sourceImage={image} />
</Grid>
))}
</Grid>
</Grid>
</Grid>
);
}
Upvotes: 0
Views: 2202
Reputation: 1547
I think what you are looking for is a masonry grid. It's worth a google search.
What these packages do is calculate positions within a container on page load and resize. One example for react could be react-responsive-masonry
Example usage with react-responsive-masonry
import React from "react"
import Masonry, {ResponsiveMasonry} from "react-responsive-masonry"
// The number of columns change by resizing the window
class MyWrapper extends React.Component {
render() {
return (
<ResponsiveMasonry
columnsCountBreakPoints={{350: 1, 750: 2, 900: 3}}
>
<Masonry>
<ChildA />
<ChildB />
{/* Children */}
<ChildY />
<ChildZ />
</Masonry>
</ResponsiveMasonry>
)
}
}
// The number of columns don't change by resizing the window
class MyWrapper extends Component {
render() {
return (
<Masonry columnsCount={3}>
<ChildA />
<ChildB />
{/* Children */}
<ChildY />
<ChildZ />
</Masonry>
)
}
}
In case of the material ui you would basically replace the Grid
and only render cards inside the Masonry
.
Upvotes: 2