[英]NextJS Image component with fixed witdth and auto height
I am using NextJS Image component.我正在使用 NextJS Image 组件。 I want the image to fill 100% width and take as much height as it needs to maintain the aspect ratio.我希望图像填充 100% 的宽度,并根据需要保持纵横比的高度。 I have tried many different variations of this code but it will not work unless I define a fixed height on the parent div.我尝试了此代码的许多不同变体,但除非我在父 div 上定义固定高度,否则它将无法工作。
export default function PhotoCard({ img }: Props) {
return (
<div className="relative w-full h-32 my-2">
<Image alt={img.title} src={img.url} layout="fill" objectFit="cover" />
</div>
);
}
As Next.js has mentioned in their documentation, width and height properties are required in order to avoid layout shift, using layout="fill" will only fill the container height and width that is previously set.正如 Next.js 在他们的文档中提到的那样,为了避免布局偏移,需要 width 和 height 属性,使用 layout="fill" 只会填充先前设置的容器高度和宽度。 This basically means that in order to maintain the aspect ratio, you have to know the image height and width in advance.这基本上意味着为了保持纵横比,您必须提前知道图像的高度和宽度。
Luckily though, Next.js also provided us a work around with this problem with an event called onLoadingComplete
, which gives us an event parameter that contains both image natural height and width.幸运的是,Next.js 还通过一个名为onLoadingComplete
的事件为我们提供了解决此问题的方法,该事件为我们提供了一个包含图像自然高度和宽度的事件参数。
<Image
layout="fill"
src="/cat.jpg"
onLoadingComplete={e => console.log(e)} // {naturalHeight: ..., naturalWidth: ...}
/>
There are plenty of options that you can do to maintain image aspect ratio with this information, like useState
to set the height and the width of the element or make the image responsive, depends on your need.您可以使用许多选项来使用此信息保持图像纵横比,例如useState
设置元素的高度和宽度或使图像响应,这取决于您的需要。 In any case, hope this was helpful.无论如何,希望这会有所帮助。
The experimental next/future/image
component, introduced in Next.js 12.2, makes this easier to achieve. Next.js 12.2 中引入的实验性next/future/image
组件使这更容易实现。 It's enabled in next.config.js
under the experimental
flag.它在experimental
标志下的next.config.js
中启用。
module.exports = {
experimental: {
images: {
allowFutureImage: true
}
},
// Other configs
}
The next/future/image
component allows styling the underlying image directly using style
/ className
. next/future/image
组件允许直接使用style
/ className
设置底层图像的样式。 This means you can apply width: 100%
and height: auto
on the Image
component directly.这意味着您可以直接在Image
组件上应用width: 100%
和height: auto
。
import Image from 'next/future/image';
<Image
src={img1}
width="0"
height="0"
sizes="100vw"
style={{ width: '100%', height: 'auto' }}
/>
Or, if using Tailwind CSS.或者,如果使用 Tailwind CSS。
import Image from 'next/future/image';
<Image
src={img1}
width="0"
height="0"
sizes="100vw"
className="w-full h-auto"
/>
As stated in @juliomalves
's answer, you can use the experimental next/future/image
component.正如@juliomalves
的回答中所述,您可以使用实验性的next/future/image
组件。 However, I would like to share an alternative workaround.但是,我想分享一个替代解决方法。 This basically consists of modifying the styles of the span
that wraps Next.js' images and the styles of the image itself.这基本上包括修改包装 Next.js 图像的span
的 styles 和图像本身的 styles。 Example:例子:
.image-container {
width: 100%;
}
.image-container > span {
position: unset !important;
}
.image {
object-fit: cover;
width: 100% !important;
position: relative !important;
height: unset !important;
}
I have found a solution without using next/future/image
and with using css
with width-[100%]
on the parent div like so.我找到了一个解决方案,不使用next/future/image
并在父 div 上使用宽度为width-[100%]
的css
,就像这样。
<div
className="mx-auto w-[100%] md:bg-card md:w-[720px] max-w-4/5"
key={img.imageProps.src}
>
<Image
placeholder="blur"
{...img.imageProps}
layout={'responsive'}
alt={`${chapterData.chapterNumber} image`}
/>
</div>
{...img.imageProps}
is a object that looks like this that has original height and width. {...img.imageProps}
是一个 object,看起来像这样,具有原始高度和宽度。
export type ImageProps = {
blurDataURL: string;
src: string;
height: number;
width: number;
type?: string | undefined;
};
You can get these image props using something like plaiceholder
, it comes loaded with blurImage
data url.您可以使用plaiceholder
之类的工具获取这些图像道具,它带有blurImage
数据 url。
const convertImages = async (image: string) => {
const { base64, img } = await getPlaiceholder(image, { size: 14 });
return {
imageProps: {
...img,
blurDataURL: base64,
},
};
};
OR或者
You can create your own function to get the height
and width
for each image individually before displaying it, which is required by the next <Image/>
Hope this helps.您可以创建自己的 function 以在显示之前单独获取每个图像的height
和width
,这是下一个<Image/>
所需的,希望对您有所帮助。
You can try to set width and height with "%" way..您可以尝试使用“%”方式设置宽度和高度..
<Image src={image.url} alt={image.title} width="100%" height="100%" layout="responsive" objectFit="contain"/>
or you can set the width with the "vw" property like this..或者您可以像这样使用“vw”属性设置宽度..
<Image src={image.url} alt={image.title} width="100vw" height="100%" layout="responsive" objectFit="contain"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.