简体   繁体   中英

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 :

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

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

Using css flex-box , I did achieved the main functionality:

<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?

  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.

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>

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM