I'm using the MUI Card and CardMedia components in my app but can't figure out how to overlay text on top of the image. This is a simplified example of what I'm trying:
<Card>
<CardMedia image={this.props.preview} style={styles.media}/>
<div style={styles.overlay}>
this text should overlay the image
</div>
</Card>
const styles = {
media: {
height: 0,
paddingTop: '56.25%' // 16:9
},
overlay: {
position: 'relative',
top: '20px',
left: '20px',
color: 'black',
backgroundColor: 'white'
}
}
I've tried placing the text div in above the CardMedia, below it, inside it, outside the Card entirely, and using different position values but can't figure this out at all. The beta versions of MUI included an overlay property on the CardMedia, but the v1 library doesn't seem to have anything like that.
Any know how to properly do this? Thanks in advance for any help!
Your CSS is off, you'll want to absolutely position the styles.overlay, and make sure the Card is position relative
Try something like this:
<Card style={styles.card}>
<CardMedia image={this.props.preview} style={styles.media}/>
<div style={styles.overlay}>
this text should overlay the image
</div>
</Card>
const styles = {
media: {
height: 0,
paddingTop: '56.25%' // 16:9
},
card: {
position: 'relative',
},
overlay: {
position: 'absolute',
top: '20px',
left: '20px',
color: 'black',
backgroundColor: 'white'
}
}
Use the code below if you want to have an overlay like the Card in version 0. Remember to set the position of the container to relative so the absolute position of the overlay can take effect:
<Card sx={{ maxWidth: 345 }}>
<Box sx={{ position: 'relative' }}>
<CardMedia
component="img"
height="200"
image="https://mui.com/static/images/cards/contemplative-reptile.jpg"
/>
<Box
sx={{
position: 'absolute',
bottom: 0,
left: 0,
width: '100%',
bgcolor: 'rgba(0, 0, 0, 0.54)',
color: 'white',
padding: '10px',
}}
>
<Typography variant="h5">Lizard</Typography>
<Typography variant="body2">Subtitle</Typography>
</Box>
</Box>
{...}
</Card>
Related
I discovered this nice 3D Hover Image Effect - https://codepen.io/kw7oe/pen/mPeepv
With the help of tutorials and guides I know I can style a component with Materials UI and apply it this way the CSS what I do. In the example link the Image is declared as background in CSS. I did it not in CSS but with the MUI Image tag. However it does not throw errors but its not working at all and I am unsure as why.
For the information I build it in React TS.
import React from 'react';
import { Box, Typography } from '#mui/material';
import Image from 'mui-image';
const styles = {
body: {
background: '#ECECEC',
},
footer: {
width: '50%',
marginLeft: '25%',
textAlign: 'center',
fontFamily: 'Julius Sans One, sans-serif',
marginTop: '24px',
},
container: {
maxWidth: '720px',
margin: '24px auto 48px auto',
},
h1: {
fontFamily: 'Montserrat, sans-serif',
textTransform: 'uppercase',
},
h2: {
fontFamily: 'Julius Sans One, sans-serif',
fontSize: '2.5rem',
},
row: {
marginTop: '12px',
},
column: {
display: 'inlin-block',
textAlign: 'center',
},
figure: {
overflow: 'hidden',
},
'a:hover': {
textDecoration: 'none',
},
'column img': {
display: 'block',
width: '100%',
height: '300px',
},
tdimension: {
width: '300px',
height: '300px',
margin: '20px auto 40px auto',
perspective: '1000px',
},
'tdimension a ': {
display: 'block',
width: '100%',
height: '100%',
backgroundSize: 'cover',
transformStyle: 'preserve-3d',
transform: 'rotateX(70deg)',
transition: 'all 0.8s',
},
'tdimension:hover a': {
transform: 'rotateX(20deg)',
},
'tdimension a:after': {
content: '',
position: 'absolute',
left: 0,
bottom: 0,
width: '100%',
height: '40px',
background: 'linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.1))',
transform: 'rotateX(90deg)',
transformOrigin: 'bottom',
},
};
function Hover() {
return (
<Box style={styles.container}>
<Box style={styles.row}>
<Typography style={styles.h1}>Image Hover Effect</Typography> <Typography style={styles.h2}>3D Hover Effect</Typography>
</Box>
<Box style={styles.row}>
<Box style={styles.tdimension}>
<Image src="https://mir-s3-cdn-cf.behance.net/project_modules/disp/e8346826957515.56361c2106f3f.png" style={styles['tdimension a ']}/>
</Box>
</Box>
</Box>
);
}
export { Hover };
I would replace all style attributes with sx since MUI encourages the usage of sx prop and prefers it over style attribute:
https://mui.com/system/the-sx-prop/
I would also stick to the background url inside the <a/> since the 3D Hover Effect transformations are being applied to that tag.
return (
<Box sx={styles.container}>
<Box sx={styles.row}>
<Typography sx={styles.h1}>Image Hover Effect</Typography>
<Typography sx={styles.h2}>3D Hover Effect</Typography>
</Box>
<Box sx={styles.row}>
<Box sx={styles.tdimension}>
</Box>
<Divider sx={{ padding: "1px" }} />
</Box>
</Box>
);
Now inside your styles object wrap everything related to tdimension inside a nested styling object. Your <Box/> makes use of styles.tdimension and this way all your substyling won't get lost.
...
tdimension: {
width: "300px",
height: "300px",
margin: "20px auto 40px auto",
perspective: "1000px",
a: {
background:
'url("https://mir-s3-cdn-cf.behance.net/project_modules/disp/e8346826957515.56361c2106f3f.png")',
display: "block",
width: "100%",
height: "100%",
backgroundSize: "cover",
transformStyle: "preserve-3d",
transform: "rotateX(70deg)",
transition: "all 0.8s",
},
"&:hover a": {
transform: "rotateX(20deg)",
},
"a:after": {
content: '""',
position: "absolute",
left: 0,
bottom: 0,
width: "100%",
height: "40px",
background: "linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.1))",
transform: "rotateX(90deg)",
transformOrigin: "bottom",
},
},
The result should be pretty identical to the codepen now.
I'm facing issue where normal HTML img tag works just fine inside my Masonry List, but when I'm using Next.js Image Component with layout fill, it doesn't render anything.
My Styles:
const ImageList = styled('ul', {
columnCount: 3,
columnGap: 10,
display: 'block',
listStyleType: 'none',
overflowY: 'auto',
padding: 0,
margin: 0
})
const ImageListItem = styled('li', {
position: 'relative',
display: 'inline-block',
lineHeight: 0,
height: 'auto',
marginBottom: 10
})
HTML Skeleton:
<ImageList>
{detailImage.map((image, idx) => {
return (
<ImageListItem key={`_${idx}`}>
<Image
src={image.src}
alt={image.alt}
blurDataURL={image.blurDataURL}
placeholder={'blur'}
layout={'fill'}
objectFit={'cover'}
/>
{/* <img
src={image.src}
style={{
width: '100%',
height: '100%',
objectFit: 'cover'
}}
/> */}
</ImageListItem>
)
})}
</ImageList>
EDIT
Because I'm getting all images from CMS and have width/height I used the padding-top trick to create box and then I use next/image with object-fit: cover.
Code Example:
<ImageListItem key={`_${idx}`}>
<Box
css={{
display: 'inline-flex',
pt: `${100 / (image.width! / image.height!)}%`
}}
>
<Box css={{ position: 'absolute', inset: 0, m: 0 }} as={'figure'}>
<Image
src={image.src}
alt={image.alt}
blurDataURL={image.blurDataURL}
placeholder={'blur'}
layout={'fill'}
objectFit={'cover'}
/>
</Box>
</Box>
</ImageListItem>
When you use layout='fill' it's necesary a parent container for each image and this container needs to have position: relative;. Maybe it doesn't show anything because its parent elements don't have the width property.
This is the description in the documentation:
When fill, the image will stretch both width and height to the
dimensions of the parent element, provided the parent element is
relative. This is usually paired with the objectFit property. Ensure
the parent element has position: relative in their stylesheet.
i am trying to show the avatar image curve outside the sidebar border line.
i took the persistent drawer from mui v5 as an example and here is the codesandbox link
my target is to be like follows
in this example my drawer style is as followed:
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
//position: "relative",
"& .MuiDrawer-paper": {
width: drawerWidth,
boxSizing: "border-box"
}
}}
variant="persistent"
anchor="left"
open={open}
>
and the Avatar's style inside the drawer header as followed:
<Avatar
alt="test"
src="./test.jpg"
sx={{
//position: "absolute",
width: "120px",
height: "120px",
marginLeft: "150px"
}}
/>
how can i achieve such style? please help me on this
Add following styles
<Drawer
sx={{
"& .MuiDrawer-paper": {
position: "relative",
overflowY: "visible"
},
}}
>
<Avatar
sx={{
position: "absolute",
top: 20,
right: -60,
}}
/>
Besides setting its position to absolute, you need to divide the Avatar size by 2, then negate it to move half of the Avatar outside of the Drawer. See this example:
<Avatar
sx={{
position: "absolute",
top: 40,
right: -60 / 2, // half the avatar size. negate it to move half outsize
width: 60,
height: 60
}}
{...}
/>
i am using View overlay and ActivityIndicator to hide loading map in the background. The solution i am using is View with absolute position to make it on top of everything and putting activityindicator on top, so there is something happening.
The issue is, that because the ActivityIndiator size cant be set to specific pixels on iOS, i dont know what is its size and thus i cant center it properly. Or i didnt figure out way to do it.
Here is some code:
<View style={styles.whiteOverlay}>
<ActivityIndicator style={styles.indicator} size="large" color={colors.color4} />
</View>
whiteOverlay: {
width: screen.height,
height: screen.height,
backgroundColor: 'white',
position: 'absolute',
zIndex: 20
},
indicator: {
zIndex: 21,
position: 'absolute',
left: screen.width/2,
top: screen.height/2
}
This positions the indicator offseted from center. I can put there some magic numbers to make it work for a specific device, guessing the size of the indicator, but it then doesnt work on other devices. Thanks for any help.
If you want to center the ActivityIndicator on the screen, you can set the style like this.
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", zIndex: 20 }}>
<ActivityIndicator
size="large" color={colors.color4}
/>
</View>
orYou can use style'sposition
<View style={styles.whiteOverlay} >
<ActivityIndicator
size="large" color={colors.color4}
/>
</View >
...
whiteOverlay: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
}
Couple options;
NON-Flex
whiteOverlay: {
width: screen.height,
height: screen.height,
backgroundColor: 'white',
position: 'absolute',
zIndex: 20
},
indicator: {
zIndex: 21,
position: 'absolute',
left: 50%,
top: 50%,
transform: translate(-50%, -50%)
}
WITH-Flex (assumes indicator renders as child of overlay);
whiteOverlay: {
width: screen.height,
height: screen.height,
backgroundColor: 'white',
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 20
}
I am using a material ui library for my react project (material-ui.com) and want to add my logo in the center of the appbar component.
I tried with the following code:
<AppBar position="sticky" >
<Toolbar>
<img src={'../logo.svg'} className={classes.logo} alt="logo" />
</Toolbar>
</AppBar>
And the styling is:
logo: {
margin: 'auto',
textAlign: 'center',
maxWidth: '50%',
maxHeight: '70%',
}
It "kind of" works. By this I mean in Chrome and Firefox the logo size is different and in IE it overlapping the appbar.
I am looking how to center this logo in the middle of the bar where it is relatively consistent among all browsers.
I have created running example can be found on link
<AppBar position="sticky" >
<Toolbar>
<div style={classes.logoHorizontallyCenter}>
<img src={'../logo.svg'} className={classes.logo} alt="logo" />
</div>
</Toolbar>
</AppBar>
Styling:
var classes = {
logo: {
margin: 'auto',
textAlign: 'center',
maxWidth: '50%',
maxHeight: '70%',
},
logoHorizontallyCenter: {
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)'
}
};
Please try to provide example on sandbox so that it would be easy for the person to help you out.