Ensure the Next/Image component fits neatly inside a div without distorting its aspect ratio, and keep the

I've been attempting to style a NextJS image in a way that it has rounded corners, expands to fit its container div (which is blue in the image), and maintains its aspect ratio (only known at runtime). However, what I currently have is not working as expected - the image does not receive the border-radius, but rather the surrounding box (depicted in black on the image) receives it. I'm struggling to find a solution that allows the dynamic image size while still applying the border radius. Another factor to consider is that all of this is happening within a fixed-positioned div (shown in red on the image) that encompasses the entire popup.

https://i.stack.imgur.com/eneSH.png

I've tested the code snippet below based on recommendations from other sources, and although it almost works, the issue remains with the image not getting the desired rounded corners because the box around it is larger than the content, resulting in rounding the box instead of the image itself.

{/* Card that shows on click */}
            <div className='fixed z-10 w-full h-full left-0 top-0 invisible bg-black/[.6]' id={'hidden-card-' + title} onClick={hideEnlargement}>
                <div className='w-[80%] h-[80%] translate-x-[calc(50vw-50%)] translate-y-[calc(50vh-60%)] rounded-2xl'>
                    <Image
                        src={img} 
                        alt={alt}
                        quality={100}
                        className="rounded-2xl bg-black m-auto"
                        fill={true}
                        style={{"objectFit" : "contain"}}
                    />

                </div>
                
            </div>

Answer №1

Here are some simple adjustments to make this code work:

  1. Replace w-full h-full left-0 top-0 with inset-0 for brevity. This sets all margins to 0.
  2. In the wrapper div for your image, round the corners and set overflow to hidden. Remove the translate-x class as well. Use h-3/4 and w-3/4 for 75% width and height.
  3. Set your image's height and width to 100% with an object-fit of cover. Cover fills the space without cropping, while fill will crop the image if necessary.
<div
  className="fixed inset-0 z-10 bg-black/[.6]"
  id={'hidden-card-' + title}
  onClick={hideEnlargement}
>
  <div className="rounded-2xl overflow-hidden h-3/4 w-3/4 m-auto translate-y-[calc(50vh-50%)]">
  <Image
    src={img}
    alt={alt}
    quality={100}
    className="bg-black w-full h-full object-cover"
    fill={true}
    />
  </div>
</div>

Check out the Stackblitz demo

Edit

To prevent cropping and maintain rounded corners and aspect ratio, pass width and height properties to the Next/Image component. Otherwise, set the fill prop to true.

The fill prop absolutely positions the image, eliminating natural flow. To avoid this, provide image dimensions in the props.

Below is an example modal structure:

// Assuming you pass props with img containing
// src, alt, width, and height
<div
  className="fixed inset-0 z-10 bg-black/[.6] grid place-content-center"
  onClick={closeModal}
>
  <Image
    src={img.src}
    alt={img.alt}
    width={img.width}
    height={img.height}
    quality={100}
    className="max-w-[95vw] max-h-[95vh] rounded-2xl animate-bounceIn"
  />
</div>

This approach centers everything using grid place-content-center. No need for extra transformations or margins. Set max-width and max-height to constrain the image within the viewport. However, disparity between actual size and constrained size may occur. Using object-fit: contain can fix this, albeit at the cost of losing rounded corners.

You could alternatively manually optimize images and use img or picture tags.

Explore the new Stackblitz Demo

The updated demo includes various images with different dimensions. Data structure is shown in the pages/api/images.js file. The new "modal" component is located in the `pages/components/Modal.js file.

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

Joomla CSS styling malfunctioning

I've been exploring the creation of an in line menu using Joomla 1.6 and CSS. The issue arises when Joomla removes <span class="dmenu"> from the document before saving, despite having all cleanup options turned off. This led me to try a couple ...

Upon clicking the button, provide the client with the Cloudinary link

In my Next.js project, I am using Cloudinary to generate secure URLs for images. The URL is stored in the variable result.secure_url within my app/page.js file. The button functionality is defined in app/components/Cloudinary.js and imported into app/pag ...

I encountered an error while attempting to import a file into Firebase Storage

I've been struggling to upload files from Firebase Storage and encountering errors despite reading the documentation and various blogs on the topic. I'm looking for the most effective approach to resolve this issue. import { storage } from ' ...

Is it possible to change the color of specific days of the week (like Mondays, Tuesdays, etc.) in JQueryUI's datepicker?

Is it possible to customize the appearance of specific weekdays (such as all Mondays, all Tuesdays for the entire year) in the JQueryUI datepicker by changing their color? While there are existing methods to select certain dates and disable holidays, I h ...

Tips for effectively managing loading state within redux toolkit crud operations

Seeking guidance on efficiently managing the loading state in redux-toolkit. Within my slice, I have functionalities to create a post, delete a post, and fetch all posts. It appears that each operation requires handling a loading state. For instance, disp ...

What is the best method for extracting and storing search suggestions data with selenium?

Initially, I had posted this inquiry before, and my apologies for reposting. However, I am still struggling to comprehend why the code works for the individual who responded but not for me. How can one retrieve values from search suggestions after enterin ...

Issue with orientation change when using webkit-overflow-scrolling: touch;

I am currently facing an issue with a fixed position div that has a specified width. The problem arises when the content is long enough to require overflow in one device orientation (landscape), but not the other (portrait) - scrolling stops working if the ...

What is the method for displaying x-axis dates below a highchart?

I'm encountering an issue with Highcharts where dates are not showing under the chart when passing series data as an array of objects. See result image The documentation mentions using an object instead of an array ([1649153340000, 45]docs I need t ...

Issue with Firebase Auth: Property 'auth' is undefined and cannot be read

I've been on a quest for answers everywhere to resolve this error. Strangely, my code was functioning perfectly fine last week but is facing issues today. I am trying to utilize Firebase auth to set up a sign-up page for my app, but I constantly encou ...

"Troubleshooting: Unspecified getInitialProps in Nextjs when passing it to a layout component

Greetings, I am a newcomer to Next.js and facing an issue with passing dynamic properties to the header component. Despite using getInitialProps in Next.js successfully, I encounter the problem of receiving 'UNDEFINED' when these properties are p ...

Align the items in the Material UI grid centrally within the grandparent grid container

Here is a Grid component that I am working with: <Grid container height="100vh" direction="column"> <Grid item alignSelf="flex-end"> <Button variant="text">List Your Property</Button> ...

Utilize TypeScript function types in React for enhanced functionality

I have made the decision to refactor a project that was originally created with vanilla JavaScript and now I want to transition it to TypeScript. One issue I am facing is how to pass a function as a type on an interface. Although I referred to the TypeScr ...

Achieving the desired display position in CSS3 with bootstrap: Steps to follow

I am attempting to create a unique icon by combining two different bootstrap icons together: https://i.stack.imgur.com/RWiQn.png Despite trying various margin adjustments like top and right, I have not been able to achieve the desired effect. Here is wha ...

Finding image input loading

When working with the following code: <input type="image" ... onLoad="this.style.opacity = 1" /> Everything seemed to be functioning well in IE, but encountered an issue in Chrome where the onLoad event failed to trigger upon image load. It's ...

Is there a way to display my array within my React component using JavaScript?

I am working with an element that looks like this: const DropdownElements = [ { key: 1, title: "City", placeholder: "Select City", apiUrl: "https://api.npoint.io/995de746afde6410e3bd", type: "city&qu ...

Guide on creating a darkening effect for lights

Seeking assistance on how to create a light-off effect when clicking on any of my textboxes. I discovered this concept on the following website: What I aim to achieve is that upon clicking a specific textbox, it will be highlighted. Upon clicking the sam ...

ReactJS: Parent component triggering re-render due to child component update

In the parent component, set up the default class by extending the component: renderChildren() { let children = Mongo.Collection.find().fetch(); // array of objects return children.map((child) => ( <Child key={child._id} child={child} /> ...

Changing the color of a textarea in ReactJS using materialUI when focused

I have been experimenting with changing the default color of a TextField in material UI using CSS. After referencing the CSS injection order in material UI and some stackoverflow answers, I was able to come up with a solution. However, I also tried a diffe ...

Even though I included a key prop for each item, I am still encountering the error message stating that every child in a list should have a distinct "key" prop

I have been trying to retrieve data from a rest API and display it as text on my browser. However, I am encountering the following error: index.js:1 Warning: Each child in a list should have a unique "key" prop. Below is how I have set up the key prop. ...

Styling with CSS and Angular: Loading background images dynamically with a greyscale effect

Incorporating the image displayed above as a background photo in CSS is my current objective using Angular. My aim is to alter the photo path for each new item added to my list. As it stands, the styles are hardcoded, resulting in a constant image that fun ...