简体   繁体   English

NextJS 具有固定宽度和自动高度的图像组件

[英]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>
      );
    }

This is the current behaviour这是当前的行为应用程序中的图像

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 以在显示之前单独获取每个图像的heightwidth ,这是下一个<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM