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;
}
You need to:
spacing
and justifyContent
props from Grid container.flex
with justifyContent="center"
prop.Here is a sample on Codesandbox . I just added borders to demonstrate it better.
I think wrapping each Card in Grid that has justifyContent="center" alignItems="center" will do
<Grid container direction="row">
{cards.map(() => (
<Grid xs={4} item justifyContent="center" alignItems="center">
<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>
))}
</Grid>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.