3

I am struggling with Gatsby-image to provide the right image size to different resolution. I have an image of size 1920x367 (width x height) and the issue is visible when window size is small (mobile for example) because gatsy-image is using an image of 490x92 to cover a container of 437x354.

Here you can see the image when window size is big. Here when window size is low.

GraphQL query:

configHowWeWork: file(relativePath: { eq: "howwework/howwework-header.jpg" }) {
    childImageSharp {
        fluid(maxWidth: 1920, maxHeight: 367) {
            ...GatsbyImageSharpFluid_withWebp
        }
    }
}

Gatsby-image:

<div className="intro intro-page intro-container">
    {configHowWeWork.childImageSharp.fluid && (
        <Img
            className="intro-background"
            fluid={configHowWeWork.childImageSharp.fluid}
            alt="alt"
        />
    )}
</div>

Relevant CSS:

.intro-container {
    position: relative;
}

.intro-background {
    position: absolute!important;
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
    left: 0;
    top: 0;
    z-index: 0;
    overflow: hidden;
}

Question: How can I avoid to request an image of size 490x92 (same initial aspect ratio) and instead provide one that can fill up 437x354 (cropping or clipping is what I want, but without zooming in) without streching height.

What I already tried:

  1. I tried to use FILL as fit in gatsby query to overcome aspect ratio constraint, but it did not the trick.
  2. Using presentationSize.

Thanks for you answer.

EDIT: THe only one solution found is to create a square image with dimension max(width, height), but in my case is always width. In this way I achieve good quality with low and high resolution (mobile and desktop, for example), but I am wasting too much resource:

  • With a desktop resolution image generated is 1920x1920, but container dimension is 1920x367.
  • With a mobile resolution is not so unbalanced, but still bigger the necessary with height.

I am sure I am missing something because could not be so difficult to just create a responsive wide hero image.

EDIT 2: I can not get why image quality is good if I switch to mobile resolution with Responsive Design Mode in Firefox, but quality is not good if I use a resolution comparable to previous mobile but without Responsive Design Mode.

lezan
  • 759
  • 6
  • 23

2 Answers2

2

I overcome issue with 3 images and art direction, I am no able to do better than that.

First, query images:

headerLarge: file(relativePath: { eq: "image-L.jpg" }) {
    childImageSharp {
        fluid(maxWidth: 1920, webpQuality: 100) {
            ...GatsbyImageSharpFluid_withWebp
            ...GatsbyImageSharpFluidLimitPresentationSize
        }
    }
}
headerMedium: file(relativePath: { eq: "image-M.jpg" }) {
    childImageSharp {
        fluid(maxWidth: 900, webpQuality: 100) {
            ...GatsbyImageSharpFluid_withWebp
            ...GatsbyImageSharpFluidLimitPresentationSize
        }
    }
}
headerSmall: file(relativePath: { eq: "image-S.jpg" }) {
    childImageSharp {
        fluid(maxWidth: 500, webpQuality: 100) {
            ...GatsbyImageSharpFluid_withWebp
            ...GatsbyImageSharpFluidLimitPresentationSize
        }
    }
}

Create sources array:

const sourcesImage = [
    {
        ...headerSmall.childImageSharp.fluid,
        media: '(max-width: 500px)',
    },
    {
        ...headerMedium.childImageSharp.fluid,
        media: '(max-width: 900px)',
    },
    {
        ...headerLarge.childImageSharp.fluid,
        media: '(max-width: 3840px)',
    },
];

Use sources with gatsby-image:

<Img
    fluid={sources}
/>
lezan
  • 759
  • 6
  • 23
0

Fluid images in Gatsby stretches across the container (e.g: for a container whose max width is 800px, the automatic sizes would be: 200px, 400px, 800px, 1200px and 1600px). If you want more control over which sizes are output you can use the srcSetBreakpoints parameter. Applied to your code:

configHowWeWork: file(relativePath: { eq: "howwework/howwework-header.jpg" }) {
    childImageSharp {
        fluid(maxWidth: 1920, srcSetBreakpoints: [ 400, 600, 960, 1280, 1920 ]) {
            ...GatsbyImageSharpFluid_withWebp
        }
    }
}

As you can see srcSetBreakpoints is an array of integers with your custom values. This will provide a srcSet to your image with the desired sizes.

You can play with them to check which ones fit your requirements. In addition, I would remove the maxHeight parameter since it may cause you a limitation query because it restricts the aspect ratio of your image in small sizes, it's automatically calculated using the maxWidth provided.

Another hack that may help you is to change CSS object-fit to contain property in some resolutions to fit 100% of the container.

References/Interesting readings:

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • He, thanks for takeyour time for answer this question. I already tried to use only `maxWidth` to avoid aspect ratio constrain (actually what I pasted before it is a left over). Also, if I add srcSetBreakpoints does not resolve my issue, because gatsby-image (actually sharp) is still generating an image with aspect ratio (400x76 as size). Am I missing something? – lezan Sep 18 '20 at 10:56
  • What happens if you just set a `minHeight` value? – Ferran Buireu Sep 18 '20 at 11:36
  • Without `srcSetBreakpoints` and `object-fit: contain;`, right? `minHeight` on image wrapper or ``? – lezan Sep 18 '20 at 13:58
  • Try adding to with `imgStyle` but does not work, still same result. – lezan Sep 18 '20 at 14:31
  • Can you try another GraphQL fragment? – Ferran Buireu Sep 20 '20 at 16:22
  • You mean fluid or fixed? Or just without `_withWebp`? – lezan Sep 21 '20 at 14:52