0

There is this Codepen with a working tripple hover effect on an image: Codepen

When I try to rebuild it as styled component on React Typescript with MUI and MUI Image accepted by MUI I am getting an error in my style={...} and cant get it to work in my React App. Can anyone help why? I declared my css in a const styles and apply it inline.

App.tsx

import React from 'react';
import { Box } from '@mui/material';
import Image from 'mui-image';

const styles = {
   body:{
       background: "#3d4552",
       fontFamily: "arial",
       fontSize: "12px",
       color: "#fff",
   },
   
   img: {
       border: "1px solid #d2d2d2",
       padding: "3px",
       boxShadow: "0 0 15px rgba(0,0,0,.1)",
   },
   
   picContainer: {
       maxWidth: "210px",
       maxHeight: "210px",
       margin: "50px",
   },
   
   pic: {
       background: "#fff",
       position: "absolute",
       transition: "all 0.2s ease",
       backfaceVisibility:"hidden",
   },
   
   "pix:nth:child(1)": {
       zIndex: 3,
   },
   
   "pic:nth-child(2)": {
       zIndex: 1,
   },
   
   "pic:nth-child(3)": {
       zIndex: 2,
   },
   
   "picContainer:hover .pic:nth-child(1)": {
       transform: "rotate(15deg)",
       transition: "all 0.5s ease",
   },
   
   "picContainer:hover .pic:nth-child(2)": {
       transform: "rotate(7deg)",
       transition: "all 0.10s ease",
   },
   
   "picContainer:hover .pic:nth-child(3)": {
       transform: "rotate(-5deg)",
   },
   
   picCaption: {
       background: "#82a3d4",
       padding: "10px 15px",
       color: "#fff",
       fontSize: "12px",
       position: "relative",
       zIndex: "10",
       top: "90px",
       left: "200px",
       borderRadius: "3px",
       transition: "all 0.5s ease",
       opacity: 0,
   },
   
   "picCaption:hover": {
       background: "#607fae",
   },
   "picContainer:hover .pic-caption": {
       left:"230px",
       opacity: 1,
   },
   
};

function Hover() {

   return (
<Box style={styles.picContainer}>
   <Image src="https://via.placeholder.com/150" style={styles.pic}  />
   <Image src="https://via.placeholder.com/150" style={styles.pic} />
   <Image src="https://via.placeholder.com/150" style={styles.pic} />
</Box>
   );
}

export { Hover };

The error:

(property) MuiImageProps.style?: React.CSSProperties | undefined

Type '{ background: string; position: string; transition: string; backfaceVisibility: string; }' is not assignable to type 'Properties<string | number, string & {}>'.
  Types of property 'backfaceVisibility' are incompatible.
    Type 'string' is not assignable to type 'BackfaceVisibility | undefined'.ts(2322)

index.d.ts(28, 5): The expected type comes from property 'style' which is declared here on type 'IntrinsicAttributes & MuiImageProps & { children?: ReactNode; }'

1 Answers1

1

First of all, I minified the styles object by removing unused or erroneous styles such as picCaption or pix:nth:child(1). I've also replaced all occurrences of :nth-child() with :nth-of-type() since nth-child is potentially unsafe.

For this solution there are only two relevant style objects, picContainer which will be applied to the outer <Box/> and img for the mui <Image/> wrapper. The pic class can be referenced inside the styling object. We can make use of nesting to avoid repetition, analogous to scss this also works here.

const styles = {
  picContainer: {
    maxWidth: "210px",
    maxHeight: "210px",
    margin: "50px",

    "&:hover": {
      ".pic:nth-of-type(1)": {
        transform: "rotate(15deg)",
        transition: "all 0.5s ease",
      },
      ".pic:nth-of-type(2)": {
        transform: "rotate(7deg)",
        transition: "all 0.10s ease",
      },
      ".pic:nth-of-type(3)": {
        transform: "rotate(-5deg)",
      },
    },
    ".pic": {
      position: "absolute",
      transition: "all 0.2s ease",
      backfaceVisibility: "hidden",

      "&:nth-of-type(2)": {
        zIndex: 1,
      },
      "&:nth-of-type(3)": {
        zIndex: 2,
      },
    },
  },
  img: {
    backgroundColor: "#fff",
    border: "1px solid #d2d2d2",
    padding: "3px",
    boxShadow: "0 0 15px rgba(0,0,0,.1)",
  },
};

Now since its my first time working with <Image/> from mui-image I found it tricky here. The image gets wrapped inside a MUI image class which comes with its own styling. Using wrapperClassName and custom width, height was necessary here to avoid the image from being expanded and stretched.

// Hover.tsx

  return (
    <Box sx={styles.picContainer}>
      <Image
        wrapperClassName="pic"
        width={150}
        height={150}
        src="https://via.placeholder.com/150"
        style={styles.img}
      />
      <Image
        wrapperClassName="pic"
        width={150}
        height={150}
        src="https://via.placeholder.com/150"
        style={styles.img}
      />
      <Image
        wrapperClassName="pic"
        width={150}
        height={150}
        src="https://via.placeholder.com/150"
        style={styles.img}
      />
    </Box>
  );

The result is identical to the Codepen that has been provided in the question:

enter image description here

sm3sher
  • 2,764
  • 1
  • 11
  • 23
  • Wow your explanation makes so much sense to me right now thanks for the help! –  Jul 25 '22 at 22:47