如何在 material-ui 中使项目居中对齐

4
我正在一个容器行内渲染一些卡片,并需要在中心对齐它们,并围绕等距离空间。我使用UI库material-ui进行布局。尽管我已经添加了justifyContent: center属性,但是这些卡片周围的间距并不均匀。 这是当前界面的样子: enter image description here 请注意最后一张卡片右侧的额外空间。检查后,间距比例如下所示: ```css .card { margin-right: 32px; }
.card:last-of-type { margin-right: 0; } ``` 到目前为止的代码如下:
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>
  );
};

如果我删除容器包装器<Container maxWidth="xl">,那么界面将呈现如下效果:

enter image description here

我不是MUI的专家,如果有人能够帮助纠正问题并实现所需结果,将非常有帮助。
4个回答

4

这里是一个现场演示,可以使您的卡片均匀分布。使用justifyContent = "space-evenly"alignItems = "center"

编辑MediaCard材料演示(分叉)

输入图像描述

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

1
这似乎有效,但使用 'justify-content':'space-evenly' 似乎无法正确地将卡片包装在新行中。假设我们将数组更改为:const cards = [1, 2, 3, 4, 5];。那么第五张卡片将呈现在第二行的中心位置,尽管第五张卡片应该与第一张卡片并排在第二行中呈现。 - program_bumble_bee

2
你需要做以下几点:
  1. 从Grid容器中删除spacingjustifyContent属性。
  2. 如果你想要有间距,就在Grid项目中添加间距(填充)。
  3. Grid项目应该具有flex的显示方式,并带有justifyContent="center"属性。

这里是Codesandbox上的示例。我只是添加了边框以更好地演示它。


2
你可以通过一点小技巧来完成这个任务。
像你的问题一样,这里还有一些其他类似的问题herehere,提供了一些实现你想要的功能的替代方案。
基于上述问题的答案,我使用一个自定义钩子创建了一个hackycodesample,该钩子返回窗口的尺寸。
那么,让我们看看代码:

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


“hacky”是一个形容词,意思是“笨拙的、不专业的”。这句话的意思是:“笨拙地添加额外的(n-1)个填充div。”
let divsHacky= [];

  if (screenSmallerThanAllCardsWidth)
    for (var i = 0; i < cards.length - 1; i++) {
      divsHacky.push(
        <Box
          key={i}
          sx={{
            width: maxWidth,
            height: 0
          }}
        />
      );
    }

组件渲染:
<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>

窗口尺寸自定义钩子:
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;
}

虽然我很感激这个答案,但我不确定这种权宜之计的解决方案在长期运行中是否可靠。 - program_bumble_bee
当然,没问题! - Luis Paulo Pinto

0

我认为将每个卡片包装在具有justifyContent="center" 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 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>
  ))}
</Grid>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接