Setting the height of an element based on the height of its background image

Hey there! I'm currently working with this component in my app, and right now, the height of the ButtonBase element is fixed. I fetch an image from the backend and use it as a backgroundImage for the ImageImagine component. I want to dynamically adjust the height of the ButtonBase so that the background image in ImageImagine can maintain its original aspect ratio.

import React, { useState } from 'react';
import {
  Box,
  ButtonBase as MuiButtonBase,
  IconButton,
  Typography,
  styled,
} from '@mui/material';

import Label from './Label';
import Favorite from './Favorite';
import MintingContextButton from './MintingContextButton';

import StatusLabel from 'src/components/StatusLabel';
import PublicLabel from 'src/components/PublicLabel';

import { IMAGINE_STATUS } from 'src/constants';
import { authDomain } from 'src/config';

const ButtonBase = styled(MuiButtonBase)(({ theme }) => ({
  position: 'relative',
  height: 342,
  width: '100%',
  borderRadius: 32,
  [theme.breakpoints.down('xs')]: {
    width: '100% !important', // Overrides inline-style
    height: 326,
  },
  '&:hover': {
    '& .imageTitle': {
      opacity: 1,
      transition: theme.transitions.create('opacity'),
      zIndex: 1,
    },
    '& .imageBackdrop': {
      opacity: 0.7,
    },
    '& .MuiIconButton-favorite': {
      opacity: 1,
      transition: theme.transitions.create('opacity'),
      zIndex: 12,
    },
    '& .MuiButton-minting': {
      opacity: 1,
      transition: theme.transitions.create('opacity'),
      zIndex: 12,
    },
  },
}));

const ContextContainer = styled('span')(() => ({
  position: 'absolute',
  width: '100%', // should be on if a real mint button
  height: '100%',
  display: 'flex',
  flexDirection: 'column',
  justifyContent: 'space-between',
  padding: 16,
  zIndex: 1, // Remove if real mint button
}));

const StyledStatusLabel = styled(StatusLabel)(() => ({
  position: 'absolute',
  left: 16,
  top: 16,
  zIndex: 1,
}));

const MintIconButton = styled(IconButton)(() => ({
  position: 'absolute',
  left: 16,
  top: 16,
  zIndex: 1,
  background: 'rgba(0, 0, 0, 0.7)',
  '&:hover': {
    background: 'rgba(128, 58, 254, 0.9)',
  },
}));

const ImageTitle = styled('span')(({ theme }) => ({
  opacity: 0,
  textAlign: 'left',
}));

const ImageBackdrop = styled('span')(({ theme }) => ({
  position: 'absolute',
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  backgroundColor: theme.palette.common.black,
  opacity: 0,
  transition: theme.transitions.create('opacity'),
  borderRadius: 32,
}));

const ImageImagine = styled('span')(() => ({
  position: 'absolute',
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
  backgroundSize: 'cover',
  backgroundPosition: 'center 40%',
  borderRadius: 32,
}));

const GalleryItem = ({
  imagine,
  imagine: {
    id,
    title,
    status,
    isMyFavorite,
    public: publicStatus,
    context: imgContext,
    thumb_url: imgUrl,
    count_favorites: countFavorites,
  },
  onOpen,
  onClose,
  ...props
}) => {
  const [isHoverFavorite, setHoverFavorite] = useState(false);

  return (
    <>
      <ButtonBase
        className="MuiButtonBase-gallery"
        disableRipple
        focusRipple
        onClick={(event) => onOpen(event, id)}
      >
        <ContextContainer>
          <Box display="flex" justifyContent="space-between">
            <Box
              display="flex"
              visibility={status === IMAGINE_STATUS.COMPLETE && 'hidden'}
            >
              <StyledStatusLabel status={status} />
            </Box>
            {status === IMAGINE_STATUS.COMPLETE && (
              <React.Fragment>
                <Favorite
                  imagineId={id}
                  isMyFavorite={isMyFavorite}
                  isHoverFavorite={isHoverFavorite}
                  isHidden
                  onHoverFavorite={setHoverFavorite}
                  count={countFavorites}
                />
              </React.Fragment>
            )}
          </Box>
          <ImageTitle className="imageTitle">
            <Typography color="textPrimary" variant="subtitle1" noWrap>
              {title}
            </Typography>
            <Box
              display="flex"
              justifyContent="space-between"
              alignItems="center"
            >
              {imgContext && <Label>{imgContext}</Label>}
              <PublicLabel publicStatus={publicStatus} />
            </Box>
          </ImageTitle>
        </ContextContainer>
        <ImageImagine
          style={{
            backgroundImage: `url(${
              imgUrl ?? `${authDomain}/images/glitchcat.gif`
            })`,
          }}
        />
        <ImageBackdrop className="imageBackdrop" />
      </ButtonBase>
    </>
  );
};

export default GalleryItem;

Answer №1

Did you attempt adjusting the height property of the ButtonBase element to height: auto and setting the min-height to min-height: fit-content?

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

Animate a div once the parent section becomes visible while scrolling

I previously had this function working, but it seems that I have somehow messed it up in the process. My current setup includes a scroll hijack feature that navigates users to a new section or card each time they scroll. The script adds a visible class w ...

Troubleshooting Axios Error while Sending Data in MERN Stack Application

In my development setup, I'm testing model validation specifically for the length of a name variable. The front-end is configured at http://localhost:3000/ using React + axios, while the back-end utilizes express + node. To enable communication betwe ...

Tips for retrieving a nested data value within an array

I am currently puzzled by the undefined error I encounter when attempting to access a value using dot notation. The following illustrates my point: My goal is to retrieve the value from within the nested object in the headline color array: ...

In Safari, my layout is disrupted by the mere mention of the word 'City'

There's something strange happening in Safari that I can't quite figure out. Here's how my layout looks in Chrome: https://i.sstatic.net/lPhnP.png But when viewed in Safari, it looks like this: https://i.sstatic.net/IMnQb.png For some r ...

Tips for removing a Material UI chip component using the Material UI GitHub label selector demonstration

I recently experimented with the autocomplete feature of Material UI using the github label picker example. I made some modifications and you can check out the sandbox below: https://codesandbox.io/s/material-demo-hwi3l?file=/demo.js The Autocomplete func ...

Encountering a Typescript error with Next-Auth providers

I've been struggling to integrate Next-Auth with Typescript and an OAuth provider like Auth0. Despite following the documentation, I encountered a problem that persists even after watching numerous tutorials and mimicking their steps verbatim. Below i ...

The getStaticProps() function is failing to send data over to the components

I am currently learning how to use Next.js by following the guide on nextjs.org. My question is, when I use the getStaticProps function, it seems to fetch and log the data correctly inside the function. However, when I pass the data (which is the props ob ...

Encountering a Next.js TypeScript Build Error related to the Type 'OmitWithTag<InputFormProps, keyof PageProps, "default">' issue

`I am currently working on a project in Next Js using TypeScript. During the build process with npm run build, I encountered the following errors in the terminal: # Type 'OmitWithTag<InputFormProps, keyof PageProps, "default">' do ...

Ensure that the Div element remains visible on the screen while contained within a

Is there a way to maintain the position of elements on the right side of a div without using position: fixed, while still keeping the div within its parent container? See the desired layout. I need the "Stays in view" element to stay within its parent div ...

The issue at hand is that the Mongo Atlas model is in place, but for some reason,

I recently delved into using Next.js and I am a newcomer to backend technologies. I have successfully established a connection with MongoDB Atlas using Mongoose, however, the user object data from the post request is not being created as a document in th ...

The voting system will increase or decrease by 1 to 5 during each round

Recently, I added a voting system to my website inspired by this source. It's functioning well, but there is an issue where each vote can sometimes count for more than one. You can view the source code on the original website and test it out live here ...

Using React and Typescript: Passing functions as props to other components

In this setup, we have three main components: Toggle, ToggleMenu, and Wrapper. The Toggle component is designed to be universal and used for various functions. The Wrapper component, on the other hand, is meant to change the background color only when the ...

A guide to displaying a single field from a Firestore document using React

For our fourth-semester university project, we are creating a quiz application using React with MaterialUI for styling and Firestore as the database. I am currently facing challenges in displaying/rendering data from a document in Firestore. The Firestor ...

How to Clean Up Your Line Chart: A Guide for Chart.js React Users

I'm currently utilizing a chartJs line chart in my react application. The chart displays data values (such as 65, 59, 80 etc) on the chart itself. Is there a way to hide or remove these values? https://i.sstatic.net/eP4sp.png Below is the code snipp ...

Error: Invalid JSON format detected at the beginning of the data, causing a SyntaxError at line 1, column 1

My goal is to retrieve data from an Oracle database located inside a Docker container using a SQL query and display the response as a dropdown in a web interface. Here is the server-side GET method: app.get('/api/getDropdownOptions', (req, res) = ...

The collaboration of TooltipClasses and FabProps is causing issues with the functionality of SpeedDialAction in Material UI React

While configuring the SpeedDial component in React's Material UI, I encountered the following requirements: Adjust the background color of the speeddial button Modify the background color of speeddialactions Change the font size of the tooltip displ ...

The React-strap carousel is not displaying the uploaded image

In my component for displaying a list of images, there is a method called OnfileChange as shown below: onFileUplod = (body: any) => { const response = new ApiHelper().MakeRequestWithBody( "SftpImage", "PUT", body ); ...

Styling the arrow of a CSS select box

Is it possible to place a dropdown arrow inside a select box? I have tried, but the arrow always displays behind the select box. How can I modify the CSS code to position the arrow properly inside the select box? .form-item-custom-search-types::before { ...

When attempting to run npm start, an error message appears indicating a failed compilation due to the inability to resolve

Error compiling ./node_modules/jest-serializer/build/index.js Module not located: Unable to find 'v8' in 'C:\Users\Desktop\reactapp\react-project\node_modules\jest-serializer\build' This issue arose du ...

Tips for reducing unnecessary re-renders using React Hooks, function components, and optimizing functions based on a list of items

List of items to display Provided a list of items fetched from the server: const itemsFetched = { "1": { id: "1", value: "test" }, "2": { id: "2", value: "another row" } } ...