-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[gatsby-plugin-sharp] Fluid image with specified aspect ratio #11851
Comments
You could probably just trample <Img fluid={{ ...image.fluid, aspectRatio: 1 }} /> |
That will change how the image is displayed with CSS, but not the aspect ratio of the actual image file. So it kind of works, but then I'm probably going to load a bigger image than I need to, so part of it gets hidden rather than an actual cropped image. |
At the moment there is not a real fix for this I guess you could simulate it with multiple GraphQL queries?
If you can give us some more context and perhaps a reproduction that might help us answer your issue. |
Hi @wardpeet I'm starting to think this may be more of a feature request than a question, then. I'm wanting to get a set of images (I guess it's called GatsbyImageSharpFluid ?) to pass into a
One use case I can think of is a gallery of images with thumbnails. I'd like to produce square thumbnails from the original images which can be clicked to view the full image. The thumbnail grid is responsive, so I don't want to use Here's an example of the kind of thing it would be good for, in case my explanation wasn't very clear: https://www.zomato.com/vancouver/suika-fairview-vancouver/photos |
Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open! Thanks for being a part of the Gatsby community! 💪💜 |
This issue is not stale. |
I don't know if these labels apply anymore, either:
I think this is a feature request now. |
So I did some digging, and you can set aspect ratio with fluid. It's not explicitly stated in the docs but if you set both When both options are set, the //line 442 of gatsby-plugin-sharp/src/index.js
const dimensionAttr = fixedDimension === `maxWidth` ? `width` : `height`
const otherDimensionAttr = fixedDimension === `maxWidth` ? `height` : `width`
const images = sortedSizes.map(size => {
const arrrgs = {
...options,
[otherDimensionAttr]: undefined,
//WIDTH SET HERE
[dimensionAttr]: Math.round(size),
}
//IF BOTH MAXWIDTH AND MAXHEIGHT SET
if (options.maxWidth !== undefined && options.maxHeight !== undefined) {
//HEIGHT SET HERE
arrrgs.height = Math.round(size * (options.maxHeight / options.maxWidth))
}
return queueImageResizing({
file,
args: arrrgs, // matey
reporter,
})
}) Should we update the docs to explicitly state this? I previously thought this wasn't possible as well. |
@VGoose Will that only work if the source image is larger than the maxWidth and maxHeight? I thought that maxWidth and maxHeight was meant to set an upper bounds on the image dimensions. If it's being used to set the aspect ratio... that seems like unexpected behaviour actually. What I expected fluid to do with maxWidth and maxHeight is that all the images in the source set are still the natural aspect ratio of the image, but the largest image in the set will not be wider than maxWidth or taller than maxHeight. |
It works when maxWidth and/or maxHeight is larger than the source size, too. maxWidth & maxHeight sets the default src break points: //line 366 of gatsby-plugin-sharp/src/index.js
const fixedDimension =
options.maxWidth === undefined ? `maxHeight` : `maxWidth`
...
//line 409
if (!options.srcSetBreakpoints || !options.srcSetBreakpoints.length) {
fluidSizes.push(options[fixedDimension] / 4)
fluidSizes.push(options[fixedDimension] / 2)
fluidSizes.push(options[fixedDimension] * 1.5)
fluidSizes.push(options[fixedDimension] * 2)
fluidSizes.push(options[fixedDimension] * 3)
} And the upper bound is actually set by the actual image dimensions. //line 429 of gatsby-plugin-sharp/src/index.js
const filteredSizes = fluidSizes.filter(
size => size < (fixedDimension === `maxWidth` ? width : height)
)
// Add the original image
filteredSizes.push(fixedDimension === `maxWidth` ? width : height) The current parameter names are definitely misleading. |
Hmm... I'm wondering if there's a situation where someone might actually want the behaviour I thought setting both maxHeight and maxWidth did... |
//line 393 gatsby-plugin-sharp/src/index.js
//presentationWidth is derived from maxWidth or maxHeight
if (!options.sizes) {
options.sizes = `(max-width: ${presentationWidth}px) 100vw, ${presentationWidth}px`
} This tells the browser for screen sizes beyond I'm not sure if browsers respects this, though. For example if your |
This is something I've found is missing in the past too.
If I understand you correctly, then absolutely. Say my design is to have a grid of squares. It's elastic. There might be different numbers of columns depending on the viewport width, and the squares may be different sizes depending on the viewport width. That means that "fluid" is what we want, if I understand all the options correctly. Now say we have a set of images we want to display in these squares. The images are at various aspect ratios. I might want them not to be cropped, for them all to be contained within their squares. My CSS will centre each within its container. In this case I'd want The above is what I would expect to happen if I set both Or I might want to display them in the same grid but with all of them cropped to be square. In this case I'd expect to still send If this is what happens currently when you use
I can't speak for all browsers, and the spec document is very long and I couldn't find what I wanted, but I just did a little test in Firefox, and Firefox will choose the smallest item from the srcset whose advertised width is the same as or greater than the matching slot found in <img src="http://placehold.it/100x100?text=src" sizes="100vw" srcset="http://placehold.it/100x100 100w, http://placehold.it/200x200 200w, http://placehold.it/300x300 300w, http://placehold.it/400x400 400w"> there is only one (I believe browsers aren't strictly required to follow this. If a browser already loaded the 400w version it may not bother making a new request for the 300w version should the viewport get narrower.) But I don't think this talk about |
I made a bug for this #12972 @missmatsuko there's a way to get the behavior you want. You have to overwrite the width and height of the img created by <Img ..... imgStyle={{width: 'auto'; height: 'auto'}} /> This will get the browser to respect the |
@VGoose I don't think there's any issue with the There may or may not be an issue with the default width and height applied to the img element, but I don't think that's really the point. The developer will absolutely be setting styles on the img tag or gatsby-image's wrappers if necessary. But the crux of this, I think, is to do with how gatsby-plugin-sharp interprets its arguments, and to do with which images it then chooses to generate. These images are what's fed into your img tag's srcset, and they need to be what you're expecting for the width/height/sizes attributes you're configuring it with to function as you intend. I ran a test and when setting I did notice, however, that the placeholder thumbnail image is not cropped -- it's coming out as 20x20. That, I think, is a bug. |
@tremby OK now that I understand it a little better I can answer your previous questions.
It's happening server side.
If you're using //line 392
// If the users didn't set default sizes, we'll make one.
if (!options.sizes) {
options.sizes = `(max-width: ${presentationWidth}px) 100vw, ${presentationWidth}px`
}
Completely agree.
Yes, I think this read this in another issue. I'll try and find it. Should I document all this in #12972? |
Yeah, that should really be documented. I had a look to see if information about it would come up in the graphql browser. The property shows up, but no information about it. Yes, you can set the sizes attribute in the call to
Be my guest. I'm going to close this one since the functionality being asked for is currently possible. |
@VGoose please document it 👍 |
I searched quite a while for this, and ironically noticed later that the fragment squareImage on File {
childImageSharp {
fluid(maxWidth: 200, maxHeight: 200) {
...GatsbyImageSharpFluid
}
}
} https://www.gatsbyjs.org/docs/working-with-images/#using-fragments-to-standardize-formatting |
I was using the method referenced above by @lunelson, but am now getting an error: in GraphiQL: Any thoughts ? |
@gxwheel152 are you getting this error in the GraphQL Explorer? I think those fragments only work in Gatsby... |
I was having trouble using it in components that were not pages --- I switched to this and then it worked in the components as well.
|
On using the GatsbyImageSharpFluid fragment in graphiQL, or the GraphQL explorer: It looks like they should add support for that in the near future, but... If you want, you can just paste in the definition of the fragment into graphiQL outside of your query. The fragments are defined in node_modules/gatsby-transformer-sharp/fragments.js -- or just search "fragment GatsbyImageSharpFluid" in VS code with the "files to exclude" option unchecked
|
Summary
Is there a way to force a crop/aspect ratio using
fluid
?I want to create a set of image cropped to squares to use as thumbnails.
I could use
resize
, but that only provides one src with the exact height and width provided.I could use
fixed
, which is a bit better because it creates srcs for different pixel densities, but that doesn't consider the image could be displayed at different sizes depending on the viewport.Relevant information
https://www.gatsbyjs.org/packages/gatsby-plugin-sharp/
Environment (if relevant)
File contents (if changed)
gatsby-config.js
: N/Apackage.json
: N/Agatsby-node.js
: N/Agatsby-browser.js
: N/Agatsby-ssr.js
: N/AThe text was updated successfully, but these errors were encountered: