Next.js Image Fill in Masonry List

Viewed 889

I'm facing issue where normal HTML img tag works just fine inside my Masonry List, but when I'm using Next.js Image Component with layout fill, it doesn't render anything.

My Styles:

const ImageList = styled('ul', {
    columnCount: 3,
    columnGap: 10,
    display: 'block',
    listStyleType: 'none',
    overflowY: 'auto',
    padding: 0,
    margin: 0
})

const ImageListItem = styled('li', {
    position: 'relative',
    display: 'inline-block',
    lineHeight: 0,
    height: 'auto',
    marginBottom: 10
})

HTML Skeleton:

   <ImageList>
            {detailImage.map((image, idx) => {
                return (
                    <ImageListItem key={`_${idx}`}>
                        <Image
                            src={image.src}
                            alt={image.alt}
                            blurDataURL={image.blurDataURL}
                            placeholder={'blur'}
                            layout={'fill'}
                            objectFit={'cover'}
                        />

                        {/* <img
                            src={image.src}
                            style={{
                                width: '100%',
                                height: '100%',
                                objectFit: 'cover'
                            }}
                        /> */}
                    </ImageListItem>
                )
            })}
        </ImageList>

EDIT Because I'm getting all images from CMS and have width/height I used the padding-top trick to create box and then I use next/image with object-fit: cover.

Code Example:

      <ImageListItem key={`_${idx}`}>
        <Box
          css={{
            display: 'inline-flex',
            pt: `${100 / (image.width! / image.height!)}%`
          }}
        >
          <Box css={{ position: 'absolute', inset: 0, m: 0 }} as={'figure'}>
            <Image
              src={image.src}
              alt={image.alt}
              blurDataURL={image.blurDataURL}
              placeholder={'blur'}
              layout={'fill'}
              objectFit={'cover'}
            />
          </Box>
        </Box>
      </ImageListItem>
1 Answers

When you use layout='fill' it's necesary a parent container for each image and this container needs to have position: relative;. Maybe it doesn't show anything because its parent elements don't have the width property.

This is the description in the documentation:

When fill, the image will stretch both width and height to the dimensions of the parent element, provided the parent element is relative. This is usually paired with the objectFit property. Ensure the parent element has position: relative in their stylesheet.

Related