Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React MUI: How to create a flex-box like grid using the Grid component

I am using React and MUI as the UI library for my application. I have a big list of elements that I want to order in a specific way. Using the Grid component would normally solve the problem.

 <Grid container
                direction="row"
                justifyContent="start"
                alignItems="center"
                spacing={4}
                className={classes.Grid}
            >
                {Cards.map(c => (
                    <Grid item xs key={c._id} >
                        <Card id={c._id} title={c.title} description={c.description} />
                    </Grid>
                ))}
</Grid>

Styles:

const useStyles = makeStyles({
    Grid: {
        margin: "auto!important",
        width: "90vw!important",
    }
});

Every single element in the grid has a specific height and width. Using the code, this is what the result looks like:

 _ _ _   _ _ _   _ _ _   _ _ _   _ _ _   _ _ _   _ _ _
|     | |     | |     | |     | |     | |     | |     |
|     | |     | |     | |     | |     | |     | |     |
|_ _ _| |_ _ _| |_ _ _| |_ _ _| |_ _ _| |_ _ _| |_ _ _|

         _ _ _           _ _ _          _ _ _  
        |     |         |     |        |     | 
        |     |         |     |        |     | 
        |_ _ _|         |_ _ _|        |_ _ _| 

Also the spacing between each item does not remain static. It is manipulated by the screen size. A wider screen will result into a bigger gap between each element. What I really do want:

 _ _ _   _ _ _   _ _ _   _ _ _   _ _ _   _ _ _   _ _ _
|     | |     | |     | |     | |     | |     | |     |
|     | |     | |     | |     | |     | |     | |     |
|_ _ _| |_ _ _| |_ _ _| |_ _ _| |_ _ _| |_ _ _| |_ _ _|

 _ _ _   _ _ _   _ _ _   
|     | |     | |     | 
|     | |     | |     | 
|_ _ _| |_ _ _| |_ _ _| 

This is where I got using css flex-box:

<Box
        sx={{
               display: "flex",
               justifyContent: "center" ,
               gap: "20px",
               flexWrap: "wrap",
               margin: "auto",
               width: "90vw",
           }}
       >
                {Cards.map(c => (
     <Card key={c._id} id={c._id} title={c.title} description={c.description}/>
                ))}
</Box>

If the screen size is too small, the last element on the row will be wraped on the next row. But there is only one problem, the columns on the last row are centered, but I just want them to be positioned at the start of the row, with the same gap size. So how can I really achieve something similar to what I want?

like image 329
Artiom O Avatar asked Sep 15 '25 21:09

Artiom O


2 Answers

CSS

display: "grid",
gridTemplateColumns: "repeat(auto-fill, 220px)", //the width of the card 
justifyContent: "center",
gridGap: "20px",

Body

<Box className={classes.List}> //css
    {Cards.map(c => (
        <Grid item xs key={c._id} >
            <Card id={c._id} title={c.title} description={c.description} />
        </Grid>
    ))}
</Box>
like image 193
Artiom O Avatar answered Sep 17 '25 11:09

Artiom O


  1. If you want to use grid, give appropriate value in the breakpoint sx, md, etc. Also, you don't need to pass the props: direction, justifyContent and alignItems to the Grid container
<Grid item xs={3} md={3} key={c._id}>
...
</Grid>

example:

<Grid container spacing={4}>
   {Cards.map((c) => (
     <Grid item xs={3} md={4} key={c._id}>
         ...
     </Grid>
   ))}
</Grid>

  1. For FlexBox: just remove justifyContent='center' props.
like image 25
nightElf Avatar answered Sep 17 '25 11:09

nightElf