From 3e0b69862ac1e943443f94063c856e58f16fa9ec Mon Sep 17 00:00:00 2001 From: Erin O'Connell Date: Wed, 4 Nov 2026 20:06:19 -0700 Subject: [PATCH] Fix image sizes attribute for constrained layout Astro assumes images can fill the viewport, but Starlight caps the content column at 47rem, so browsers picked oversized srcset candidates. Set sizes to the real max display width. --- src/avifImageService.mjs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/avifImageService.mjs b/src/avifImageService.mjs index 1f7dafd36..c7edb35a2 100644 --- a/src/avifImageService.mjs +++ b/src/avifImageService.mjs @@ -3,6 +3,11 @@ import sharp from "sharp"; sharp.concurrency(1); +// Width of the Starlight content column: keep in sync with --sl-content-width in +// src/assets/css/variables.css. Images can never be displayed wider than this. +const CONTENT_WIDTH_REM = 47; +const CONTENT_WIDTH_PX = CONTENT_WIDTH_REM * 16; + export default { ...sharpService, @@ -10,6 +15,20 @@ export default { validateOptions(options, config) { if (options.src?.format !== "svg") { options.format = "avif"; + + // Astro's "constrained" layout generates + // sizes="(min-width: px) px, 100vw" + // which tells the browser the image may fill the whole viewport. Here it + // never does (the content column is capped), so browsers pick huge + // srcset candidates: the 3840w file on a 1440px laptop at 2x, or the 2048w + // file on a 1080p monitor at 1x. Use the real maximum display width instead. + // Images narrower than the column keep Astro's value, which is already correct. + if ( + options["data-astro-image"] === "constrained" && + options.width > CONTENT_WIDTH_PX + ) { + options.sizes = `(min-width: ${CONTENT_WIDTH_REM}rem) ${CONTENT_WIDTH_REM}rem, 100vw`; + } } return sharpService.validateOptions(options, config); },