React Material UI - 响应式 CardMedia

时间:2021-01-30 21:39:28

标签: css reactjs flexbox responsive-design material-ui

目前,我正在尝试使用 React Material UI(使用 Card,...)构建一个画廊。 我有一些问题要使图库响应,因为我可能有不同的封面尺寸:

enter image description here

这是我使用的代码:

我的卡片实现:

import React from "react";
import { makeStyles } from '@material-ui/core/styles';

import Card from "@material-ui/core/Card";
import CardMedia from "@material-ui/core/CardMedia";
import CardActionArea from '@material-ui/core/CardActionArea';

const useStyles = makeStyles((theme) => ({
    gameRoot: {
        position: "relative",
        height: "100%"
    },
    gameCover: {
        zIndex: 1
    }
}));

function CardEntry(props) {
    const {game} = props;
    const classes = useStyles(props);

    function watchGame() {
       // some redirecting stuff not needed for this POC
    }

    return (
        <Card className={classes.gameRoot}>

                <CardActionArea onClick={watchGame}>
                    <CardMedia
                        component="img"
                        className={classes.gameCover}
                        image={game.imagePath}
                        title={game.title}
                    />
                </CardActionArea>
            
        </Card>
    );

}

export default CardEntry;

我所拥有的 HOC 画廊所称的:

import React from "react";

import { makeStyles } from '@material-ui/core/styles';

import Grid from "@material-ui/core/Grid";
import CardEntry from "./CardEntry";

// To dynamically change the number of items depending of browser
const useStyles = makeStyles((theme) => ({
    // inspired by the settings https://www.youtube.com/gaming uses ;)
    gameEntry: {
        // 2 items on [0, sm]
        [theme.breakpoints.only('xs')]: {
            "flex-basis": "calc((100% / 2) - 1%)"
        },
        // 4 items on [sm, md[
        [theme.breakpoints.only('sm')]: {
            "flex-basis": "calc((100% / 4) - 1%)"
        },
        // 8 items on [md, infinity]
        [theme.breakpoints.up('md')]: {
            "flex-basis": "calc((100% / 8) - 1%)"
        },
    }
}));

// The gallery component
function GamesGallery(props) {
    const classes = useStyles(props);

    const currentGames = [/*See comment below*/]

    return (
        <Grid
            container
            spacing={1}
            style={
                {
                    rowGap: "15px"
                }
            }
        >
            {
                currentGames
                    .map(game => 
                            <Grid 
                                key={game.playlistId ?? game.videoId} 
                                item 
                                className={classes.gameEntry}
                            >
                                <CardEntry game={game}/>
                            </Grid>
                    )
            }
        </Grid>
    );
}

为了测试,这里有一些数据(带有极端情况)我可以在 currentGames 变量中:

[
   {
      "title": "Astérix & Obélix XXL",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ7hPe8RxhK3FTXoqdFNL0BG/cover.webp",
      "playlistId": "PLRfhDHeBTBJ7hPe8RxhK3FTXoqdFNL0BG"
   },
   {
      "title": "Astérix & Obélix XXL 2",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ6FTJ2LSrdL4MaFM1Pl5nfo/cover.webp",
      "playlistId": "PLRfhDHeBTBJ6FTJ2LSrdL4MaFM1Pl5nfo"
   },
   {
      "title": "Astérix & Obélix XXL 2 : Mission Ouifix",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ6lDdIcNMFKsCzWtItCEcBq/cover.webp",
      "playlistId": "PLRfhDHeBTBJ6lDdIcNMFKsCzWtItCEcBq"
   },
   {
      "title": "Beyond Good & Evil",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ7GRN3EnqBEvfki5uAKiw5Z/cover.webp",
      "playlistId": "PLRfhDHeBTBJ7GRN3EnqBEvfki5uAKiw5Z"
   },
   {
      "title": "Bully",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ4l1G59ZVCUuTuZ-btLpPnm/cover.webp",
      "playlistId": "PLRfhDHeBTBJ4l1G59ZVCUuTuZ-btLpPnm"
   },
   {
      "title": "Chicken Invaders 5 - Cluck of the dark side",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ5x3Al4O71diHmivHNIRn2B/cover.webp",
      "playlistId": "PLRfhDHeBTBJ5x3Al4O71diHmivHNIRn2B"
   },
   {
      "title": "Guns Gore & Cannoli",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ6oiHK7lfTbOQlMWVHecx2I/cover.webp",
      "playlistId": "PLRfhDHeBTBJ6oiHK7lfTbOQlMWVHecx2I"
   },
   {
      "title": "Guns Gore & Cannoli 2",
      "imagePath": "https://jy95.github.io/yt_gaming_library/covers/PLRfhDHeBTBJ4ivg1J2leFzeuABXobVFNO/cover.webp",
      "playlistId": "PLRfhDHeBTBJ4ivg1J2leFzeuABXobVFNO"
   }
]

提前致谢,

1 个答案:

答案 0 :(得分:1)

好吧,如果我正确理解您的主要目的,修改 MuiCardActionArea-rootCardMedia-root 将解决您的问题。还请检查这两个关于在 material-ui 中覆盖样式和 cardActionArea api 的链接。 https://material-ui.com/customization/components/ https://material-ui.com/api/card-action-area/

这是可以解决您的问题的更正代码:

`CaedEntry.js`

import React from "react";
import { makeStyles } from '@material-ui/core/styles';

import Card from "@material-ui/core/Card";
import CardMedia from "@material-ui/core/CardMedia";
import CardActionArea from '@material-ui/core/CardActionArea';

const useStyles = makeStyles((theme) => ({
    gameRoot: {
        position: "relative",
        height: "100%"
    },
    gameCover: {
        zIndex: 1,
        height: "inherit"
    },
    MuiCardActionArea:{
        height: "inherit",
        zIndex: 1
    }
}));

function CardEntry(props) {
    const {game} = props;
    const classes = useStyles(props);

    function watchGame() {
       // some redirecting stuff not needed for this POC
    }

    return (
        <Card className={classes.gameRoot}>

                <CardActionArea classes={{root: classes.MuiCardActionArea}} onClick={watchGame}>
                    <CardMedia
                        component="img"
                        classes={{root: classes.gameCover}}
                        image={game.imagePath}
                        title={game.title}
                    />
                </CardActionArea>
            
        </Card>
    );

}

export default CardEntry;

enter image description here