Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Center align items in material-ui

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:

enter image description here

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:

enter image description here

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.

like image 801
bubble-cord Avatar asked Oct 20 '25 11:10

bubble-cord


2 Answers

Here is a live demo that spaces your cards out evenly. Use justifyContent = "space-evenly" in conjunction with alignItems = "center".

Edit MediaCard Material Demo (forked)

enter image description here

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>
  );
}
like image 134
pez Avatar answered Oct 23 '25 01:10

pez


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;
}
like image 36
Luis Paulo Pinto Avatar answered Oct 23 '25 00:10

Luis Paulo Pinto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!