From ffc9188466882680722cc28ed07b6e14bb3c8067 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 21:36:05 +0000 Subject: [PATCH 1/3] fix: use container queries for MediaBlock responsive sizing Switch MediaBlock from viewport-based breakpoints (md:, lg:) to CSS container query breakpoints (@sm:, @lg:) so responsive image sizing adapts to the parent container width instead of the viewport. This fixes incorrect sizing when MediaBlock is embedded in narrower containers like the blog post layout (max-w-[48rem]). Also update InlineMediaBlock sizes attribute to use conservative container-relative pixel estimates instead of viewport-relative vw units. Changes: - MediaBlock: Add @container to wrapper div, use @sm:/@lg: container query classes instead of md:/lg: viewport breakpoints - MediaBlock: Remove unused cssVariables import - InlineMediaBlock: Replace vw-based sizes hints with container-aware pixel estimates Closes #757 Co-authored-by: Rachel Fryan --- src/blocks/InlineMedia/Component.tsx | 13 +++++++++++-- src/blocks/Media/Component.tsx | 24 +++++++++++++----------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/blocks/InlineMedia/Component.tsx b/src/blocks/InlineMedia/Component.tsx index 88d32bcb..d4d8d753 100644 --- a/src/blocks/InlineMedia/Component.tsx +++ b/src/blocks/InlineMedia/Component.tsx @@ -19,6 +19,16 @@ const verticalAlignClasses = { baseline: 'align-baseline', } +// Maps percentage width to a conservative pixel estimate for the sizes attribute. +// Uses container-relative values instead of viewport-relative (vw) so the browser +// picks an appropriately sized image when the block is inside a narrower container. +const sizesForWidth: Record = { + '25': '(max-width: 640px) 25vw, 192px', // ~25% of a ~768px container + '50': '(max-width: 640px) 50vw, 384px', // ~50% of a ~768px container + '75': '(max-width: 640px) 75vw, 576px', // ~75% of a ~768px container + '100': '(max-width: 640px) 100vw, 768px', // full container width +} + type WidthSize = keyof typeof widthClasses function isWidthSize(size: string): size is WidthSize { @@ -50,8 +60,7 @@ export const InlineMediaComponent = ({ } else if (isWidthSize(resolvedSize)) { sizeClass = widthClasses[resolvedSize] imgSizeClass = 'w-full h-auto' - // Approximate sizes hint for responsive images - sizes = `${resolvedSize}vw` + sizes = sizesForWidth[resolvedSize] ?? '100vw' } else if (isFixedHeight) { imgSizeClass = 'h-full w-auto' sizes = '96px' diff --git a/src/blocks/Media/Component.tsx b/src/blocks/Media/Component.tsx index fe16d260..df598c30 100644 --- a/src/blocks/Media/Component.tsx +++ b/src/blocks/Media/Component.tsx @@ -6,11 +6,8 @@ import { cn } from '@/utilities/ui' import type { MediaBlock as MediaBlockProps } from '@/payload-types' import { Media } from '@/components/Media' -import { cssVariables } from '@/cssVariables' import getTextColorFromBgColor from '@/utilities/getTextColorFromBgColor' -const { breakpoints } = cssVariables - type Props = MediaBlockProps & { isLayoutBlock: boolean captionClassName?: string @@ -36,14 +33,17 @@ export const MediaBlockComponent = (props: Props) => { const bgColorClass = `bg-${backgroundColor}` const textColor = getTextColorFromBgColor(backgroundColor) + // Uses container query breakpoints (@sm, @md, @lg) so sizing responds to the + // parent container width rather than the viewport. This ensures correct + // behavior when the block is embedded in a narrower container (e.g. post layout). const getImageSizeClasses = () => { switch (imageSize) { case 'small': - return 'max-w-xs md:max-w-sm lg:max-w-md' + return 'max-w-xs @sm:max-w-sm @lg:max-w-md' case 'medium': - return 'max-w-sm md:max-w-lg lg:max-w-2xl' + return 'max-w-sm @sm:max-w-lg @lg:max-w-2xl' case 'large': - return 'max-w-md md:max-w-2xl lg:max-w-4xl' + return 'max-w-md @sm:max-w-2xl @lg:max-w-4xl' case 'full': return 'max-w-full' case 'original': @@ -52,16 +52,17 @@ export const MediaBlockComponent = (props: Props) => { } } - // sizes prop hints to browser what image width to request based on imageSize setting - // Uses breakpoints from cssVariables for consistency with other image components + // sizes prop hints to the browser what image width to request. + // Uses conservative estimates based on the container size the block will + // actually occupy, rather than the full viewport width. const getSizesForImageSize = () => { switch (imageSize) { case 'small': - return `(max-width: ${breakpoints.md}px) 100vw, 384px` // max-w-sm = 24rem = 384px + return '(max-width: 640px) 100vw, 384px' // small caps at max-w-md = 28rem = 448px case 'medium': - return `(max-width: ${breakpoints.md}px) 100vw, 672px` // max-w-2xl = 42rem = 672px + return '(max-width: 640px) 100vw, 672px' // medium caps at max-w-2xl = 42rem = 672px case 'large': - return `(max-width: ${breakpoints.md}px) 100vw, 896px` // max-w-4xl = 56rem = 896px + return '(max-width: 640px) 100vw, 896px' // large caps at max-w-4xl = 56rem = 896px case 'full': return '100vw' case 'original': @@ -75,6 +76,7 @@ export const MediaBlockComponent = (props: Props) => {
Date: Fri, 12 Jun 2026 09:09:47 -0700 Subject: [PATCH 2/3] Make comments more concise and use breakpoint variable instead of px value --- src/blocks/InlineMedia/Component.tsx | 5 ++--- src/blocks/Media/Component.tsx | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/blocks/InlineMedia/Component.tsx b/src/blocks/InlineMedia/Component.tsx index d4d8d753..2fde53d3 100644 --- a/src/blocks/InlineMedia/Component.tsx +++ b/src/blocks/InlineMedia/Component.tsx @@ -19,9 +19,8 @@ const verticalAlignClasses = { baseline: 'align-baseline', } -// Maps percentage width to a conservative pixel estimate for the sizes attribute. -// Uses container-relative values instead of viewport-relative (vw) so the browser -// picks an appropriately sized image when the block is inside a narrower container. +// Maps percentage width to a sizes attribute, using container-relative pixel +// estimates so the browser picks an appropriately sized image in narrow containers. const sizesForWidth: Record = { '25': '(max-width: 640px) 25vw, 192px', // ~25% of a ~768px container '50': '(max-width: 640px) 50vw, 384px', // ~50% of a ~768px container diff --git a/src/blocks/Media/Component.tsx b/src/blocks/Media/Component.tsx index df598c30..a9916421 100644 --- a/src/blocks/Media/Component.tsx +++ b/src/blocks/Media/Component.tsx @@ -6,8 +6,11 @@ import { cn } from '@/utilities/ui' import type { MediaBlock as MediaBlockProps } from '@/payload-types' import { Media } from '@/components/Media' +import { cssVariables } from '@/cssVariables' import getTextColorFromBgColor from '@/utilities/getTextColorFromBgColor' +const { breakpoints } = cssVariables + type Props = MediaBlockProps & { isLayoutBlock: boolean captionClassName?: string @@ -33,9 +36,8 @@ export const MediaBlockComponent = (props: Props) => { const bgColorClass = `bg-${backgroundColor}` const textColor = getTextColorFromBgColor(backgroundColor) - // Uses container query breakpoints (@sm, @md, @lg) so sizing responds to the - // parent container width rather than the viewport. This ensures correct - // behavior when the block is embedded in a narrower container (e.g. post layout). + // Container query breakpoints (@sm, @md, @lg) so sizing tracks the parent + // container width rather than the viewport, e.g. when embedded in a post layout. const getImageSizeClasses = () => { switch (imageSize) { case 'small': @@ -52,17 +54,16 @@ export const MediaBlockComponent = (props: Props) => { } } - // sizes prop hints to the browser what image width to request. - // Uses conservative estimates based on the container size the block will - // actually occupy, rather than the full viewport width. + // Hints the image width to request, using conservative estimates based on the + // container size the block actually occupies rather than the full viewport. const getSizesForImageSize = () => { switch (imageSize) { case 'small': - return '(max-width: 640px) 100vw, 384px' // small caps at max-w-md = 28rem = 448px + return `(max-width: ${breakpoints.sm}px) 100vw, 384px` // small caps at max-w-md = 28rem = 448px case 'medium': - return '(max-width: 640px) 100vw, 672px' // medium caps at max-w-2xl = 42rem = 672px + return `(max-width: ${breakpoints.sm}px) 100vw, 672px` // medium caps at max-w-2xl = 42rem = 672px case 'large': - return '(max-width: 640px) 100vw, 896px' // large caps at max-w-4xl = 56rem = 896px + return `(max-width: ${breakpoints.sm}px) 100vw, 896px` // large caps at max-w-4xl = 56rem = 896px case 'full': return '100vw' case 'original': From b5cd929b28f55d72625f82846103337624bed968 Mon Sep 17 00:00:00 2001 From: rchlfryn Date: Fri, 12 Jun 2026 09:12:23 -0700 Subject: [PATCH 3/3] Update Inline Media components to use variable breakpoint --- src/blocks/InlineMedia/Component.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/blocks/InlineMedia/Component.tsx b/src/blocks/InlineMedia/Component.tsx index 2fde53d3..1fd13ecb 100644 --- a/src/blocks/InlineMedia/Component.tsx +++ b/src/blocks/InlineMedia/Component.tsx @@ -1,8 +1,11 @@ import type { InlineMediaBlock } from '@/payload-types' import { Media } from '@/components/Media' +import { cssVariables } from '@/cssVariables' import { cn } from '@/utilities/ui' +const { breakpoints } = cssVariables + type Props = Omit const widthClasses = { @@ -22,10 +25,10 @@ const verticalAlignClasses = { // Maps percentage width to a sizes attribute, using container-relative pixel // estimates so the browser picks an appropriately sized image in narrow containers. const sizesForWidth: Record = { - '25': '(max-width: 640px) 25vw, 192px', // ~25% of a ~768px container - '50': '(max-width: 640px) 50vw, 384px', // ~50% of a ~768px container - '75': '(max-width: 640px) 75vw, 576px', // ~75% of a ~768px container - '100': '(max-width: 640px) 100vw, 768px', // full container width + '25': `(max-width: ${breakpoints.sm}px) 25vw, 192px`, // ~25% of a ~768px container + '50': `(max-width: ${breakpoints.sm}px) 50vw, 384px`, // ~50% of a ~768px container + '75': `(max-width: ${breakpoints.sm}px) 75vw, 576px`, // ~75% of a ~768px container + '100': `(max-width: ${breakpoints.sm}px) 100vw, 768px`, // full container width } type WidthSize = keyof typeof widthClasses