Creating a Thrilling Triple Image Transformation on Hover using Material-UI

Here is a Codepen showcasing a triple hover effect on an image: Codepen

I attempted to recreate this effect as a styled component in React Typescript using MUI and MUI Image, but encountered an error with my styling that is preventing it from working in my React App. Can someone help me identify the issue? I defined my CSS styles in a const variable and applied them 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; }'

Answer №1

To start, I condensed the styles object by eliminating unused or incorrect styles like picCaption or pix:nth:child(1). Additionally, all instances of :nth-child() were replaced with :nth-of-type() due to concerns about safety as discussed in this Stack Overflow thread.

In this approach, there are only two pertinent style objects: picContainer for the outer <Box/> and img for the MUI <Image/> wrapper. The pic class can be utilized within the styling object, allowing for nesting to prevent redundancy similar to how it functions in scss.

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

This being my initial encounter with <Image/> from mui-image, I encountered some complexities. As the image is wrapped within a MUI image class that comes with its own styling, specifying custom values for wrapperClassName, width, and height was essential to prevent distortion.

// 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 outcome mirrors the Codepen linked in the question:

https://i.sstatic.net/iGHM3.gif

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on creating event hooks within VUE 2.0 component connections

I have successfully created two dynamic components. Now, I am looking to trigger the "logThat(someObj)" method of component-two using events: $emit/$on with the arguments being passed as shown in this code snippet: Vue.component('component-one', ...

Tips for successfully passing an object as a prop in nextjs

Struggling to understand how to pass an object as a prop using useState in Next JS. My javascript functions include a lorem ipsum generator, housed in a component called Paragraphs. This component requires two properties: Number of paragraphs Sentence le ...

Providing API parameters to ReactJS components imported in jsx

I have a reg_form.jsx file that includes a GenderField with three options defined by the backend and sent through an API. These values are crucial for validation on both the backend and frontend, so I want to avoid duplicating them. With around 30 fields ...

I am encountering an error message that states "Uncaught TypeError: Cannot read property 'use' of undefined."

https://i.sstatic.net/HcwYr.png Error: Unable to access the 'use' property of an undefined object ...

What is the best approach to implementing React Hooks in Typescript when using Context?

I have implemented the following code snippet in my new React Native project to enable Dark Mode using TailwindCSS: import React, { createContext, useState, useContext } from 'react'; import { Appearance } from 'react-native'; import { ...

"Enhance your Vue components with a directive to customize or adjust element attributes

I have a variety of elements structured like this: <some-custom-component :errors="formErrors.has(getErrorKey('town'))" :error-messages="formErrors.getAll(getErrorKey('town'))" ></some-custom-component> The formErrors ...

How Can I Transfer Queries from the Front End to the Backend Using the Fetch API?

Looking to transfer a search query from my React front end over to my Express back end in order for the Twitter API route to retrieve the correct data. The snippet below shows where I'm accessing the Twitter API. Initially, I used req.query to view JS ...

Is it possible to upload numerous profiles into the MYSQL database using this WP template?

Apologies in advance if my question is unclear, but in simple terms, I am looking to automate the process of uploading hundreds of profiles and jobs to this WP template: The developer of this template has stated that it is not possible to do this through ...

Troubleshooting a WordPress Blog Homepage CSS Dilemma

My goal is to keep the featured image size consistent on the main blog page. I made adjustments to this code: HTML: <div class="featured-image-excerpt"> <img class="attachment-post-thumbnail size-post-thumbnail wp-post-image" src="http://mrod ...

FirebaseError: The type 'Hc' was expected, but instead, a custom Yc object was provided

I've encountered an issue while attempting to perform a batch entry. The error I'm facing involves passing an array in a .doc file. Interestingly, this approach seems to work perfectly fine on another function where I pass an array into a .doc us ...

Tips for utilizing javascript document.createElement, document.body, and $(document) in an HTML web resource for Microsoft CRM code reviews

Let me start off by saying that I am not a regular blogger and I am feeling quite confused. If my question is unclear, please provide guidance for improvement. I recently submitted a Microsoft CRM PlugIn to the Microsoft Code Review. I am new to Javascrip ...

Tips for seamlessly integrating an overlay into a different image

My current system is set up to overlay the image when you check the checkboxes. However, I'm facing an issue with positioning the image inside the computer screen so it's not right at the edge. Can anyone provide assistance with this? <html&g ...

Error 404: Unable to locate webpack bundle.js

As I dive into learning about Webpack configuration, I keep encountering errors in my console. It appears that my webpack app.bundle.js file is not being found. The page successfully loads with the content of my HTML file displaying, but the app.bundle.js ...

Sending texture URL as a prop in react-three-fibre

Recently, I delved into using react-three-fibre and stumbled upon this intriguing example. It showcased loading an SVG image through the component instead of directly in the function. The idea resonated with me as I aimed to reuse the same component while ...

An unexpected issue arose while preloading the page in Next.js

I recently developed a small application that seemed to be working fine. However, when I tried to build the file using the command npm run build, I encountered some errors. Below is the error message that I received. I've looked at a few references bu ...

Dealing with the element not present error in Protractor can be managed by using various

Is there a way to achieve similar Exception handling in Protractor as we can with Selenium webdriver in Java? When dealing with element not found exceptions, what is the most effective approach to handle them using Protractor? ...

The issue causing "ReferenceError: fetch is not defined" is causing the test to fail

There seems to be an issue with my project where 'node-fetch' is installed, but the rest of the files are not importing it and the tests are not failing import { IQuery } from 'models/IQuery.interface'; import { NextApiRequest, NextApiR ...

Add different input strings to an array within the scope when there is a change in the input value (AngularJS)

My goal is to populate an empty array within the scope with strings. The number of elements in this array can vary depending on what the user types in the player count input field. $scope.playerNames = []; To achieve this, I am using a $watch function th ...

Expanding Arrays through Functional Inheritance

Through the concept of functional inheritance, objects can be extended by using them as the context for a function call and assigning to this. However, this approach does not seem to work as expected when dealing with the Array constructor. var ctx = { ...

Tips for showcasing the outcome of an SQL query on an HTML page

I need assistance with displaying the output of an SQL query on my website. My server-side is using NodeJs and client-side is VueJs. After querying my database, I received the following result: [ { Time_Stamp: 2019-12-09T11:54:00.000Z, Time_Sta ...