The Image component wrapper has a fixed width and can't be changed.
I created a codesandbox to illustrate the issue.
https://codesandbox.io/s/image-component-isnt-fluid-vsho0
This is a really common layout, images in columns. They have a final width but they should still be fluid.
If I remove the width
and height
props then the Image
component will use the deviceSizes
setting which is not ideal as those are generic.
I was wondering if we could turn that fixed size off as the padding on the internal wrapper already takes care of maintaining the image ratio.
I understand why that is there, it helps mitigate layout shifting, and I appreciate that but it's really rare when an image is fixed, 100% of the time. The web has passed that point long ago.
I also wanna start a conversation. Should the Image
component use the sizes
attribute and respect media queries? Using this codesandbox as an example, these images should probably be served as the following sizes="(max-width: 768px) 768px, 269px"
. We want a bigger image that will be 100% of the viewport and then go back to their max size.
I can't really think of too many occasions when I set the exact width/height of an image in pixels rather than a percentage. On mobile for example, it's pretty common to set a header image (above the fold) to width:100%
As mentioned, If say the component width is set to 900, an inline style will be set on the image wrapper to max-width:100% width: 900px
. To address this I can target the wrapper and set width:100% !important
but it would be nice to have the component default to fluid.
Isn't unsized
property there for bypassing width and height? :)
https://nextjs.org/docs/api-reference/next/image
Isn't
unsized
property there for bypassing width and height? :)
https://nextjs.org/docs/api-reference/next/image
True, that is an option but in my case the images are above the fold (banner images).
I understand why that is there, it helps mitigate layout shifting
Indeed, which is why we recommend using width
and height
instead of unsized
.
A possible solution for a future version of next/image
, is using a combination of all three (width
and height
and unsized
) to indicate width: 100%
but still maintain the aspect ratio.
There's a draft spec for CSS aspect-ratio, but we can't rely on browser support at this time, so we would need to implement a similar solution with inline styles.
I wanna go as far as to say that those two wrapping div
s are completely unnecessary.
Passing the width
and height
to the image will make sure we avoid too much layout shift.
And if you wanna have an image that keeps its ratio but is fluid, it's as simple as this
<img src="" srcset="" width="300" height="400" style="width: 100%; height: auto" />
I think the Image
component should return what the name implies, an img
. The web standards will keep improving it, for example the css property aspect-ratio
, different loading
standards might come in the future as well. The rest is up to the developer
Also, maintaining just an img
tag will make sure that object-fit
and other css properties are respected and work as you intended.
@marlonmarcello Any additional properties are already passed to the underling <img>
element, so you can use object-fit
today.
The team discussed how to make the image "fluid" or "responsive" and we decided to introduce a new attribute for layout
that allows for values such as fixed
, intrinsic
, or responsive
.
We also are going to double down on discouraging unsized
usage because the layout options will solve those use cases.
@styfle if I use object-fit
today it will be relative to the wrapping div, let's say I wanted to have a full width header with a variable height of 45vh for example with a cover image that is width: 100%; height: 100%; object-fit: cover; object-position: center
, the image would be relative to the wrapping div and not my header whereas with just an img
tag, that would work as intended.
With the fear of sounding like a jerk I would ask you if you mind explaining the reasoning behind the need for two wrapping divs?
We can probably use a single <div>
wrapper instead of two. The second one can be a sibling to the <img>
to ensure the aspect ratio is correct.
We can probably use a single
<div>
wrapper instead of two. The second one can be a sibling to the<img>
to ensure the aspect ratio is correct.
The PR looks good though, it seems to accommodate the problems with the root wrapper. I just tried it out and it's working on my end :partying_face:
Are these changes already on canary version?
Are these changes already on canary version?
They are now
There are still some minor issues about this, at least for us! Please check this link and let me know if some of you encounter same problem!
Most helpful comment
Also, maintaining just an
img
tag will make sure thatobject-fit
and other css properties are respected and work as you intended.