-1

I am having a grid of cards and I want to align the grid center wrt the page and align the cards left wrt to the grid, responsively adapting to different screen sizes.

Say if there are 10 cards, and the screen size is such that only 4 cards will fit on a row, then the first and second rows would have 4 cards each while the third row would have 2 cards aligned to the left. And the spacing on both sides of the grid will be evenly distributed.

I tried to wrap the Grid in a div, but it failed as the Grid was taking up 100% screen width. I tried setting the Grid width to min-content, but then there was only 1 card left on each row. If I set Grid align to center, the trailing cards on the last row would be centered.

EDIT: the following is the code I have. MyCard.tsx is the Card component while CardList.tsx is the div/Grid component.

MyCard.tsx

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    card: {
      minWidth: 325,
      marginBottom: '1vh',
      marginLeft: '0.5vw',
      marginRight: '0.5vw',
      backgroundColor: theme.palette.background.paper,
      color: theme.palette.secondary.contrastText,
      boxShadow: '3px black',
    },
    media: {
      height: 170,
    },
    cardContent: {
      padding: '5px 15px',
      height: 80,
    },
})

const MyCard: React.FC<MyCardProp> = (props: MyCardProp) => {
  const isDesktopOrLaptop = useMediaQuery({
    query: '(min-device-width: 1224px)',
  })
  const theme = useTheme()
  const classes = useStyles(theme

  return (
    <Card className={classes.card}>
    <CardMedia
        className={classes.media}
        image={props.imageURL}
    />
    <CardContent className={classes.cardContent}>
        <Typography gutterBottom variant="h5" component="h2">
        {props.title}
        </Typography>
        <Typography variant="body2" color="textSecondary" component="p">
        {props.description}
        </Typography>
        </CardContent>
        <CardActions
        className={classes.bottomBar}
        onClick={() => {
            // Do something here.
        }}
        disableSpacing
        >
        <IconButton>
        <Typography className={classes.bottomBarText} variant="h5">
            {props.title}
        </Typography>
        <ArrowForwardIcon />
        </IconButton>
    </CardActions>
    </Card>
  )
}

CardList.tsx

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      display: "flex",
      justifyContent: "center",
      alignItems: "center",
    },
    grid: {
      marginTop: 20,
      overflowX: "auto",
      flexGrow: 0,
    },
    greyText: {
      color: "#666666",
    ard
  })
)

const CardList: React.FC<CardListProps> = (props: CardListProps) => {
  const theme = useTheme()
  const classes = useStyles(theme)

  const cards = useSelector<RootState, Card[]>(
    (state: RootState) => state.cards.data
  )

  return (
    <div className={classes.root}>
      <Grid
        container
        className={classes.grid}
        wrap={"nowrap"}
        direction={props.direction}
      >
      {cards.length ? (
        cards.map((card, i) => {
          return (
            <MyCard
              data={card.data}
            />
          )
       }) : null}
    </div>
  )
}

Thank you in advance for any advice.

3tbraden
  • 667
  • 1
  • 10
  • 21

1 Answers1

0

I finally came across another post here that solved the problem.

The key is to add the following styling to the Grid container.

display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-gap: 10px;
justify-content: center;
align-content: flex-start;
margin: 0 auto;
text-align: center;
margin-top: 10px;

In particular, grid-template-columns: repeat(auto-fill, 100px); did the trick where 100px should be the desired column width.

3tbraden
  • 667
  • 1
  • 10
  • 21