Responsive images#1051
Conversation
|
|
||
| For that reason, this RFC includes image service crop support as a goal, though it is not a blocker for the initial feature. | ||
|
|
||
| #### New `ImageTransform` properties |
There was a problem hiding this comment.
This is a technical detail, but it might be the perfect time to add ImageTransform to the interfaces we allow users to extend (in packages/astro/src/types/public/extendables.ts in next) so that image services can define some other props they support.
|
I've updated the implementation details part of the RFC based on things I've discovered while prototyping. |
|
Hey! I‘m excited to see work being picked up again on the image components. I read the rfc and don’t really understand how values for the sizes attribute are created when „responsive“ layout is used. Is there JS being injected or how does the component know how large the image is show at different breakpoints? |
|
@carlcs It generates a sizes attribute based on the assumption that it's the full width of the screen when downsized. You'd need to pass your own if this is incorrect. |
|
@ascorbic that‘s perfect if we can still set sizes manually! You might want to change docs a bit because this part is a bit misleading. |
|
Hi @ascorbic , I really love this feature! Is there a timeline for it to go from experimental to stable? |
|
It would be great to enable support for: img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}I've got a background image that I'm using as a wallpaper, I just want it to act like My current working solution is: <Picture
class:list={["NebulaHero", className]}
src={bgHero}
decoding="async"
alt=""
loading="eager"
fetchpriority="high"
layout="full-width"
/>
<style>
.NebulaHero {
position: absolute;
inset: 0;
height: 100% !important;
}
</style> |
|
@jasikpark you should be able to do that now. You need to use a class rather than ---
import { Image } from "astro:assets";
import penguin from "../assets/penguin.jpg";
---
<Image src={penguin} alt="a penguin" layout="full-width" class="cover"/>
<style>
.cover {
height: 100%;
position: absolute;
inset: 0;
}
</style> |
|
I encountered a specificity issue when using Tailwind with responsive images. Changing the selector doesn’t resolve the problem because Tailwind’s I believe the styles applied by responsive images shouldn't exist. The sizes, width, and height attributes in HTML already provide a solid fallback for CSS and shouldn’t interfere with styling. The way responsive images impose styles contradicts the original intent of these attributes. I previously saw Astro as a framework that stays close to native behavior and maintains predictability, which is why I chose it. However, its responsive image implementation feels overly complex, and I don’t find it appealing. |
|
@yinhx3 thanks for your feedback. One of the main reasons we have the experimental features and RFC process is to get feedback on APIs and implementations. I was planning to simplify these styles and lower the specificity. I was originally going to use |
|
Cascade layers aren't supported in many of the browser versions that Astro currently supports. Is there a way to use them in a backward-compatible way? |
|
@ascorbic Can you clarify the necessity of adding styles? They seem to serve the same function as attributes. |
|
@yinhx3 the object-fit/position styles are to ensure consistent behaviour, whether or not the image service supports cropping. There is an argument to be made that they're not so important now that most of the built-in image services support cropping (Vercel is the main exception). The next version will be removing the height, and the options that used the specific width and height of the image in the styles |
|
@ascorbic I’m sure you’ve considered this more thoroughly than I have, especially in terms of performance and image service integration. My perspective is that if certain styles for |
|
@yinhx3 the |
|
@ascorbic I agree with your perspective. Generating images of different sizes and populating the |
|
I am considering changing the name of the layout option |
I think this fits the definition we currently have for the experimental docs: "The image will scale to fit the container, maintaining its aspect ratio, but will not exceed the specified dimensions." "Constrained" certainly implies a limit. (And, I believe this matches Gatsby's image plugin naming?) Seems like a good choice! In any event, not naming one of the options the name of the feature seems like a smart move in general! |
|
@sarah11918 I'd forgotten it was the same as Gatsby image! Their docs have a nice video showing the difference. |
|
This has now been updated with the changes to the layout name and simplified styles, included in withastro/astro#13677 |
|
I did some digging into responsive images, it works really well in the current version! I opened a bug report related to duplicate / identical files being generated with different hash withastro/astro#13819 And I'd like to propose to please consider the use case of Retina screenshots in .md files. The use case I believe is very common: some images in .md files are 1x resolution, some are 2x. How do you handle these correctly? (Without breaking into MDX). I mean some kind of pattern needs to be used in the .md file, either filenames like I'm migrating from Ghost, where I made a client side JS to recognise this pattern and set the size correctly. But with Astro's responsive images, I cannot do this, it needs to be signaled to the responsive image pipeline before rendering. Can you recommend a way to do this? My only idea is to make a Remark plugin, but it's not clear how to do this. Is there any simpler way? My proposal is basically to auto-recognise |
|
@hyperknot Re the second point, it's a long time since I built it but IIRC by default Gatsby does the same as us for constrained images: it includes 1x and 2x, plus screen widths that are smaller than the 1x size. This is to allow for scaling-down on smaller screens. The difference with fullWidth is that it only uses the screen widths. |
|
@ascorbic You are right that it should not hardcoded filename patters. Yesterday, I dig into it and realized a very minimal, simple rehype plugin can do this task properly, no hard coding needed. So users themselves can set up whatever logic they want, they can use query strings, hash or even alt text hints. It's as simple as this: Now the part which I could not figure out is how to integrate it into the rest of the pipeline. I guess outside of forking Astro, it's not possible today? What I did was the same client side JS hack, like I used on Ghost: This works, but give a flash + downloads the wrong image initially + probably Google also doesn't like it. So it'd be really nice to have this integrated in the image pipeline. About the magic string "data-retina2x", of course that's just a string for my use case. A better one would be "dpr" for Device Pixel Ratio. Or devicePixelRatio and then we are consistent with the Web API. So my proposal is the following:
I think this way it'd be universal, yet very user-friendly, only requiring a tiny rehype plugin. |
|
@ascorbic I'd be happy to start contributing to this PR. What is the best way to connect? Discord #contribute channel? |
|
@hyperknot we don't usually have more than one contributor to an RFC PR. People can give feedback, but the author of the PR is the one who would integrate any changes. I'm happy to consider specific proposals and suggestions. |
|
I am making this a call for consensus with a goal to get this in 5.10. |

Summary
Implements opinionated best practices in Astro Image, generating srcset, sizes and styles automatically.
Links