I am rendering some cards in a container row and need to align them in the center with equal spacing around.
I am using UI library material-ui for the layout. Even though I have added the justifyContent: center
property, the cards have uneven spacing around them.
This is what the current UI looks like:
Notice the extra space on the right side of the last card. On inspecting, the spacing scale looks like this:
Here is the code so far:
const Home = ({ cards }) => {
return (
<Container maxWidth="xl">
<Grid
container
justifyContent="center"
spacing={3}
my={8}
>
{cards.map((card) => {
return (
<Grid item xs={12} sm={6} md={3}>
<Card sx={{ maxWidth: 300 }}>
<CardActionArea>
<CardMedia
component="img"
height="140"
image="../../bg2.png"
alt="green iguana"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
{card.title}
</Typography>
<Typography variant="body2" color="text.secondary">
{card.description}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button size="small" color="primary">
View More
</Button>
</CardActions>
</Card>
</Grid>
);
})}
</Grid>
</Container>
);
};
If I remove the container wrapper <Container maxWidth="xl">
, then the UI looks like this:
I am not a very good hand at MUI, If anyone can help to rectify the issue and achieve desired results, will be really helpful.
Here is a live demo that spaces your cards out evenly. Use justifyContent = "space-evenly"
in conjunction with alignItems = "center"
.
import * as React from "react";
import Card from "@mui/material/Card";
import CardActions from "@mui/material/CardActions";
import CardContent from "@mui/material/CardContent";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Grid from "@mui/material/Grid";
export default function MediaCard() {
const cards = [1, 2, 3];
return (
<Grid
container
direction="row"
justifyContent="space-evenly"
alignItems="center"
>
{cards.map(() => (
<Card sx={{ maxWidth: 345 }}>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Lizard
</Typography>
<Typography variant="body2" color="text.secondary">
Lizards are a widespread group of squamate reptiles, with over
6,000 species, ranging across all continents except Antarctica
</Typography>
</CardContent>
<CardActions>
<Button size="small">Share</Button>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
))}
</Grid>
);
}
You can accomplish this with a little hacky.
There are some others questions like yours as you can see here and here with some alternatives to accomplish what you want.
Based on the answers to the above questions, I've created a codesample using this hacky with a custom hook that returns the dimensions of the window.
So, let`s go to the code:
const cards = [1, 2, 3, 4, 5];
// const related to the card maxWidth
const maxWidth = 300;
// const related to the total Cards Width - based on how cards the screen contains.
const totalwidth = maxWidth * cards.length;
// get the actual width of the screen
const { width } = useWindowDimensions();
// Check if the width screen is smaller than the total count of all cards width
// and if yes, we do the hacky mentioned above.
const screenSmallerThanAllCardsWidth = width < totalwidth + 20;// just added +20 to garantee
The hacky - add extra (n - 1) filler divs
let divsHacky= [];
if (screenSmallerThanAllCardsWidth)
for (var i = 0; i < cards.length - 1; i++) {
divsHacky.push(
<Box
key={i}
sx={{
width: maxWidth,
height: 0
}}
/>
);
}
The component render:
<Grid container direction="row" justifyContent="space-around">
{cards.map((item, index) => (
<Grid item my={1} key={index}>
<Card sx={{ maxWidth }}>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Lizard
</Typography>
<Typography variant="body2" color="text.secondary">
Lizards are a widespread group of squamate reptiles, with over
6,000 species, ranging across all continents except Antarctica
</Typography>
</CardContent>
<CardActions>
<Button size="small">Share</Button>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Grid>
))}
// Render the divsHacky if exists
{divsHacky}
</Grid>
The windowDimensions custom hook:
import { useState, useEffect } from "react";
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowDimensions;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With