52

I have a Next.js app, and I need an image that fills the full height of its container while automatically deciding its width based on its aspect ratio.

I have tried the following:

<Image
    src="/deco.svg"
    alt=""
    layout="fill"
/>

This snippet compiles successfully, but on the frontend, I see the following error:

Error: Image with src "/deco.svg" must use "width" and "height" properties or "unsized" property.

This confuses me because according to the docs, these properties are not required when using layout="fill".

Zsolt Meszaros
  • 15,542
  • 12
  • 36
  • 40
Jake
  • 1,197
  • 1
  • 10
  • 20

6 Answers6

76

This is what worked for me:

<div style={{width: '100%', height: '100%', position: 'relative'}}>
  <Image
    alt='Mountains'
    src='/mountains.jpg'
    layout='fill'
    objectFit='contain'
  />
</div>
francis
  • 2,165
  • 20
  • 23
  • 8
    Yup, the parent of Image must have `relative` properties. – Asad S Sep 29 '21 at 15:04
  • 1
    you are setting the absolute values for height and width , but the question states in percentage – Hussam Khatib Nov 28 '21 at 10:43
  • 1
    I just would like to add something to this answer, In my case, where I needed the image to be aligned to the left, you can add the attribute objectPosition="left"; It is passed to css object-position: "left"; More info - https://developer.mozilla.org/en-US/docs/Web/CSS/object-position – Piltsen May 10 '22 at 15:40
24
<img src="/path/to/image.jpg" alt="" title="" />

In NextJS

<Image src="/path/to/image.jpg" alt="" title="" width="100%" height="100%" layout="responsive" objectFit="contain"/>
Muhammet Can TONBUL
  • 2,702
  • 3
  • 21
  • 36
8

Here is a way: For example I want to have an image that covers the whole width & height of its container which is a div.

<div className={'image-container'}>
  <Image src={path} layout="fill" className={'image'} />
</div>

And here is the style: (There is a container div that occupies half width & height of viewport & my image will cover it.)

// Nested Styling
.image-container {
    width: 50vw;
    height: 50vh;
    position: relative;

    .image {
        width: 100%;
        height: 100%;
        position: relative !important;
        object-fit: cover; // Optional
    }
}

// Or Normal Styling
.image-container {
    width: 50vw;
    height: 50vh;
    position: relative;
  }
.image-container .image {
    width: 100%;
    height: 100%;
    position: relative !important;
    object-fit: cover; // Optional
}
Peyman Baseri
  • 99
  • 1
  • 3
  • 5
  • 1
    That is one of the best solution I've found for distant image. For local images, it's way more easier, but for dynamically loaded images this solution is working like a charm. – GRosay Oct 03 '21 at 09:22
6

I think also provide object-fit attribute on the Image element like this:-

<Image
    alt="Mountains"
    src="/mountains.jpg"
    layout="fill"
    objectFit="cover"
  />

Example provided by Nextjs can be https://github.com/vercel/next.js/blob/canary/examples/image-component/pages/layout-fill.js

Sonu Nigam
  • 229
  • 1
  • 6
0

In case you dont want to use absolute values for height and width , that is in px etc , you can do something like this

    <div style={{ position: "relative", width: "100%", paddingBottom: "20%" }} >
  <Image
    alt="Image Alt"
    src="/image.jpg"
    layout="fill"
    objectFit="contain" // Scale your image down to fit into the container
  />
</div>

Original source https://stackoverflow.com/a/66358533/12242764

Hussam Khatib
  • 320
  • 2
  • 13
-1

If someone use NextJS with styled components. It works:

 const Container = styled.div`
  width: 100%;

  div, span {
    position: unset !important;
  }

  .image {
    object-fit: contain;
    width: 100% !important;
    position: relative !important;
    height: unset !important;
  }
`;

      <Container>
            <Image src={ src }
                   layout="fill"
                   className={ "image" }          
            />
        </Container>
benson23
  • 8,765
  • 8
  • 15
  • 32
BartD
  • 27
  • 3