我正在尝试显示头像图像的网格。在过渡状态下,我希望出现图像的骨架表示。为此,我正在使用 @material-ui/lab/Skeleton
。
我遇到的问题是,因为我的图像设置为使用 height: auto, width: 100%
在网格内自动缩放,以及显示在图像各不相同,没有我可以传递给骨架组件的设置高度值。
如果您缩小沙盒屏幕的宽度,就会看到这导致的问题。网格元素的高度增加导致圆形骨架开始变形为椭圆形。
这里是否有一个解决方案可以使我的行为类似于图像的 height: auto, width: 100%
?
到目前为止,我所拥有的完整代码在下方和此处的沙箱中:https://codesandbox.io/s/skeleton-scaling-y00cd .
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Avatar from "@material-ui/core/Avatar";
import Skeleton from "@material-ui/lab/Skeleton";
import Typography from "@material-ui/core/Typography";
import clsx from "clsx";
import Grid from "@material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
root: {
textAlign: "center",
height: "100%",
width: "100%"
},
title: {
marginTop: theme.spacing(1)
},
avatarRoot: {
// width: '100%',
// height: 'auto',
// minHeight: '273px',
},
withTitle: {
margin: "auto"
},
img: {},
content: {
lineHeight: "1.4em"
},
link: {
color: "inherit",
textDecoration: "none"
},
icon: {},
fillContainer: {
height: `auto`,
width: `100%`,
fontSize: "4em"
},
container: {
marginTop: "250px"
},
fallback: {
height: "75%",
width: "auto"
},
loader: {},
avatarLoader: {
height: "75%",
width: "100%"
},
titleLoader: {
width: "60%",
margin: "auto",
marginTop: "8px",
height: "5%"
},
contentLoader: {
width: "40%",
margin: "auto",
marginTop: "8px",
height: "5%"
},
testImg: {
borderRadius: "100%",
height: "auto",
width: "100%"
},
isLoading: {
display: "none"
},
imgContainer: {
paddingTop: "100%",
borderRadius: "100%",
backgroundPosition: "center",
backgroundSize: "contain",
backgroundImage: "url(https://via.placeholder.com/500)"
}
}));
export default function ImageAvatars() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={1} className={classes.container}>
<Grid container item xs={3} spacing={0} direction="column">
<Avatar
src={"https://via.placeholder.com/500"}
variant="circle"
className={clsx(classes.avatarRoot, {
[classes.isLoading]: false,
[classes.withTitle]: true,
[classes.fallback]: false,
[classes.fillContainer]: true
})}
/>
<Typography className={classes.title}>MUI Avatar</Typography>
<Typography className={classes.content}>test test test</Typography>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<div className={classes.imgContainer} />
<div>
<Typography className={classes.title}>background image</Typography>
<Typography className={classes.content}>test test test</Typography>
</div>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<img
className={classes.testImg}
src={"https://via.placeholder.com/500"}
alt={"test"}
/>
<div>
<Typography className={classes.title}>image el</Typography>
<Typography className={classes.content}>test test test</Typography>
</div>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<Skeleton
variant="circle"
className={clsx(classes.avatarLoader, classes.avatarRoot)}
/>
<Skeleton className={clsx(classes.titleLoader, classes.title)} />
<Skeleton className={clsx(classes.contentLoader, classes.content)} />
</Grid>
</Grid>
</div>
);
}
最佳答案
以下解决方案基于此处的文章:https://css-tricks.com/aspect-ratio-boxes/#article-header-id-3
解决方案的要点是使用以百分比表示的 padding-top 来创建具有特定纵横比的框(在本例中为正方形)。百分比填充基于宽度,即使在指定 padding-top 或 padding-bottom 时也是如此,因此 100% 的 padding-top 会产生等于宽度的填充高度。
相关的 CSS/JSS 是:
avatarSkeletonContainer: {
height: 0,
overflow: "hidden",
paddingTop: "100%",
position: "relative"
},
avatarLoader: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%"
},
然后按如下方式使用:
<Grid container item xs={3} spacing={0} direction="column">
<div className={classes.avatarSkeletonContainer}>
<Skeleton variant="circle" className={classes.avatarLoader} />
</div>
<Skeleton className={clsx(classes.titleLoader, classes.title)} />
<Skeleton className={clsx(classes.contentLoader, classes.content)} />
</Grid>
这是我修改你的沙箱的完整代码:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Avatar from "@material-ui/core/Avatar";
import Skeleton from "@material-ui/lab/Skeleton";
import Typography from "@material-ui/core/Typography";
import clsx from "clsx";
import Grid from "@material-ui/core/Grid";
const useStyles = makeStyles(theme => ({
root: {
textAlign: "center",
height: "100%",
width: "100%"
},
title: {
marginTop: theme.spacing(1)
},
withTitle: {
margin: "auto"
},
content: {
lineHeight: "1.4em"
},
link: {
color: "inherit",
textDecoration: "none"
},
fillContainer: {
height: `auto`,
width: `100%`,
fontSize: "4em"
},
container: {
marginTop: "250px"
},
fallback: {
height: "75%",
width: "auto"
},
avatarSkeletonContainer: {
height: 0,
overflow: "hidden",
paddingTop: "100%",
position: "relative"
},
avatarLoader: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%"
},
titleLoader: {
width: "60%",
margin: "auto",
marginTop: "8px",
height: "5%"
},
contentLoader: {
width: "40%",
margin: "auto",
marginTop: "8px",
height: "5%"
},
testImg: {
borderRadius: "100%",
height: "auto",
width: "100%"
},
isLoading: {
display: "none"
},
imgContainer: {
paddingTop: "100%",
borderRadius: "100%",
backgroundPosition: "center",
backgroundSize: "contain",
backgroundImage: "url(https://via.placeholder.com/500)"
}
}));
export default function ImageAvatars() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={1} className={classes.container}>
<Grid container item xs={3} spacing={0} direction="column">
<Avatar
src={"https://via.placeholder.com/500"}
variant="circle"
className={clsx(classes.avatarRoot, {
[classes.isLoading]: false,
[classes.withTitle]: true,
[classes.fallback]: false,
[classes.fillContainer]: true
})}
/>
<Typography className={classes.title}>MUI Avatar</Typography>
<Typography className={classes.content}>test test test</Typography>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<div className={classes.imgContainer} />
<div>
<Typography className={classes.title}>background image</Typography>
<Typography className={classes.content}>test test test</Typography>
</div>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<img
className={classes.testImg}
src={"https://via.placeholder.com/500"}
alt={"test"}
/>
<div>
<Typography className={classes.title}>image el</Typography>
<Typography className={classes.content}>test test test</Typography>
</div>
</Grid>
<Grid container item xs={3} spacing={0} direction="column">
<div className={classes.avatarSkeletonContainer}>
<Skeleton variant="circle" className={classes.avatarLoader} />
</div>
<Skeleton className={clsx(classes.titleLoader, classes.title)} />
<Skeleton className={clsx(classes.contentLoader, classes.content)} />
</Grid>
</Grid>
</div>
);
}
关于javascript - 在可变高度网格行中处理@material-ui骨架缩放的好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59461615/