I have an area of my Next.js app which is the selected photo of a photo gallery so it has to stay fixed in size as people flip through the selected image or a photo is loading. I have a responsive layout but if really pressed, I'd say that this pixel area is 566px*425px.
I'm confused about how to actually do this. Here's the closest I've been able to get it, but the problem is that I get overflow of the image when the aspect ratio exceeds 566x425 and for images that have an aspect ratio below 566x425 it will stretch it in the Y direct. What I really want is to have a fixed box and then if the aspect ratios differ from the max size, you'll see letterboxes either along the sides or on the top and bottom.
<div
style={{
position: 'relative',
width: '566px',
height: '425px',
}}
>
<Image
src={currCommit.image.url}
alt="Current Image"
layout={'fill'}
objectFit="cover"
/>
</div>
In the HTML, put the player <iframe> in a <div> container. In the CSS for the <div>, add a percentage value for padding-bottom and set the position to relative, this will maintain the aspect ratio of the container. The value of the padding determines the aspect ratio. ie 56.25% = 16:9.
To create an exact aspect ratio, divide the height by the width. For example: 2:3 aspect ratio: 3 ÷ 2 = 1.5, so you'd drag the slider to 150. 3:2 aspect ratio: 2 ÷ 3 = .
Ooh I got it! The key was to set the parent div to a fixed size and relative and then set the Image
to a layout of fill and an objectFit of contain. The only downside to this approach is I need to set media queries so it will scale for smaller sizes.
<div className="relative item-detail">
<Image src={currCommit.image.url} alt="Current Image" layout={'fill'} objectFit={'contain'} />
</div>
Then in the css I set:
.item-detail {
width: 300px;
height: 225px;
}
there's better solution i think, NextImage
have callback property onLoadingComplete:
A callback function that is invoked once the image is completely loaded and the placeholder has been removed.
The onLoadingComplete function accepts one parameter, an object with the following properties: naturalWidth, naturalHeight
you can use the natural properties to set image ratio without loosing NextImage's layout
functionality like this:
const NaturalImage = (props: ImageProps) => {
const [ratio, setRatio] = useState(16/9) // default to 16:9
return (
<NextImage
{...props}
// set the dimension (affected by layout)
width={200}
height={200 / ratio}
layout="fixed" // you can use "responsive", "fill" or the default "intrinsic"
onLoadingComplete={({ naturalWidth, naturalHeight }) =>
setRatio(naturalWidth / naturalHeight)
}
/>
)
}
the only downside is the aspect ratio applied only after image loaded, so the placeholder using the default ratio (in this case 16:9 - common), and this can cause CLS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With