How to align items at the center in material-ui styling

I have a row of cards inside a container that I want to align in the center with equal spacing around them. I am using the material-ui UI library for the layout. Despite adding the justifyContent: center property, the cards are not evenly spaced.

This is how the current UI appears:

https://i.sstatic.net/fo2iz.png

There seems to be extra space on the right side of the last card. The spacing scale reveals this:

Here's the code snippet 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:

https://i.sstatic.net/xmnnG.png

I'm not very experienced with MUI, so any help in fixing this issue and achieving the desired layout would be greatly appreciated.

Answer №1

Click here to see a demonstration of how to evenly space your cards using

justifyContent = "space-evenly"
and alignItems = "center".

https://example.com/theme-dark

https://example.com/image.png

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>
  );
}

Answer №2

If you're looking to achieve this, a little hacky approach can do the trick.

Similar questions have been asked before, and you can find some alternative solutions here and here.

Building on the insights from those discussions, I've put together a sample code here, utilizing a 'hacky' technique with a custom hook that provides window dimensions.

Now, let's dive into the code:


const cards = [1, 2, 3, 4, 5];

// Constants related to card maxWidth
const maxWidth = 300;

// Calculating total Cards Width based on screen size
const totalwidth = maxWidth * cards.length;

// Getting actual screen width
const { width } = useWindowDimensions();

// Checking if screen width is smaller than total cards width
const screenSmallerThanAllCardsWidth = width < totalwidth + 20;// added +20 for safety

The hacky - adding 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
          }}
        />
      );
    }

Rendering the component:

<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 they exist
      {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;
}

Answer №3

Make the following adjustments:

  1. Take out the spacing and justifyContent properties from the Grid container.
  2. If you want spacing, add padding to the Grid items.
  3. The Grid items should use a display of flex with the
    justifyContent="center"
    property.

Check out a sample on Codesandbox. Borders have been added for better visualization.

Answer №4

It seems like a good idea to wrap each Card in Grid with justifyContent="center" and alignItems="center"

<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 diverse group of reptiles, with over 6,000 species found across all continents except Antarctica
          </Typography>
        </CardContent>
        <CardActions>
          <Button size="small">Share</Button>
          <Button size="small">Learn More</Button>
        </CardActions>
      </Card>
    </Grid>
  ))}
</Grid>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to track the amount a user scrolls once they have reached the bottom of a page using Javascript?

It's a popular UI pattern on mobile devices to have a draggable element containing a scrollable element. Once the user reaches the end of the scrollable content, further scrolling should transition into dragging the outer element. For example, in this ...

Error: Element type is invalid: a string was anticipated, but not found

I recently experimented with the example provided in React's documentation at this link and it functioned perfectly. My objective now is to create a button using material-ui. Can you identify what is causing the issue in this code? import * as R ...

Error in React: The <Route> component should only be used within a <Routes> element and not rendered directly. Make sure to enclose your <Route> within a <Routes> component

As a newcomer to React, I've encountered an error that has me stumped on how to resolve it. Specifically, I'm trying to add a link to app.js for navigation to Matter.js. My backend runs Python Flask while the front-end reads data from this server ...

I want to update the toggle switches within the GridToolbarColumnsButton component from MUI's DataGrid to checkboxes

Currently, I am developing a website where one of the pages has tabular data fetched from the backend. To filter this table, I utilized Mui filters from datagrid({...data}components={{ toolbar: CustomToolbar }}). Among these filters is a GridToolbarColumns ...

The Chakra UI Modal overlay consistently envelops the entire screen

<> <Button onClick={onOpen}>Trigger modal</Button> <Modal onClose={onClose} isOpen={isOpen} isCentered> <ModalOverlay /> <ModalContent> <ModalHeader>Modal Title</ModalHeader> <Moda ...

Shopping with CommerceJS just got easier with the convenience of using PayPal

Hey there! I'm currently working on an exciting e-commerce project, creating a new store from scratch. However, I've hit a roadblock when it comes to setting up the checkout process. I'm using CommerceJS and integrating PayPal transactions w ...

How can the presence of a CSS rule prevent another from being applied?

My attempt to create this HTML file in Chrome posed some challenges: <style> br { }​ [required] { border-width: 3px; border-color: red; } </style> <input required /> The entire content of the file is shown above. However, I noti ...

Vercel React App encounters compilation issue with error code 127 in "react-scripts build" operation

I am new to React and facing issues deploying my React Application using CRA on vercel. I keep encountering an error message "react-scripts build" exited with 127. I have attempted to remove node modules, package.json lock file, and reinstall them. Additi ...

Looking for a method to incorporate an onclick function into a column for renderCell within the MUI Datagrid. Any suggestions?

I'm currently developing a react application and utilizing the MUI Datagrid to present some data. I have incorporated a rendercell to insert an edit icon which should trigger a pop-up modal when clicked. Below is the column setup. export const specifi ...

Ways to eliminate double slashes from URL in Next Js. Techniques for intercepting and editing a request on the server side using getServerSideProps

Looking to manipulate a server-side request - how can this be accomplished? http://localhost//example///author/admin/// The desired output is: http://localhost/example/author/admin/ In Next Js, how can duplicate slashes in a URL be eliminated and req ...

MUI Modal overlay for stylish Ionic select dialogues

In my react application, I am utilizing the MUI library, but there are instances where I still need to incorporate Ionic framework in the code. ISSUE: When opening MUI modal windows that contain Ionic selects, the select modals end up being covered by the ...

Adapting CSS styles according to the height of the viewport

Goldman Sachs has an interesting webpage located here. One feature that caught my eye is the header that appears as you scroll down, with squares changing from white to blue based on the section of the page. I'm curious about how they achieved this ef ...

Using the pages folder in NextJS may lead to static exports being blocked due to the utilization of useContext

I am encountering an issue with a Next.JS project where it functions properly with 'npm run dev', but encounters a problem when exporting. In this simplified example, I have removed almost everything from componentA except the useContext stateme ...

Adding a three-dimensional perspective to an HTML5 canvas without utilizing CSS3 or WebGL

Here is a canvas I am working with: http://jsbin.com/soserubafe Here is the JavaScript code associated with it: var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var w = canvas.width; var h = canvas.height; var cw=canvas. ...

The hintText property in Material UI's Chip-input component seems to be malfunctioning

I am using a ChipInput component from here. I need to display a hint text when the input is empty. <div className={classes.headline}> <ChipInput hintText='Type anything' onChange={this.handleTagChange} /&g ...

There seems to be an issue with React-hook-form and material-ui not retaining value changes in the onBlur() method

Stepping into the realm of react-hook-form is a new experience for me. I'm putting in effort to grasp everything, but there are still some pieces missing from the puzzle. Seeking assistance akin to Obiwan Kenobi! The Dilemma at Hand: An <Textfiel ...

Warning from Cytoscape.js: "The use of `label` for setting the width of a node is no longer supported. Please update your style settings for the node width." This message appears when attempting to create

I'm currently utilizing Cytoscape.js for rendering a dagre layout graph. When it comes to styling the node, I am using the property width: label in the code snippet below: const cy = cytoscape({ container: document.getElementById('cyGraph&apo ...

Creating a promise instance with the axios create method

As someone who is new to TypeScript, I am learning as I go along. One thing I want to do is create an axios instance that can be reused in my code by passing props only where needed. The framework I'm using is React. // Located in a utils folder // a ...

Utilizing the sx prop for MUI v5 Theme.spacing with a pre-defined object

I have implemented a custom spacing function for MUI v5 as shown below. const theme = createTheme({ spacing: (value) => { const spaces = { small: "12px", large: "24px" }; if (typeof value === 'number&a ...

Customize the MUI Theme to exclusively manage the style of <TextField color="primary"/> component

I am seeking to create a <TextField color='primary'/> with a customized global style. Instead of using styled-components, I believe applying the style in MUI theme provides better control. My query is how can I apply the style exclusively ...