S-scroll-box inside s-modal cannot be constrained to scroll — modal content area grows instead

API version: 2026-01 (Polaris web components)

Extension target: purchase.checkout.shipping-option-list.render-after


What we’re building:

We’re migrating a checkout UI extension from the React component API (2025-10) to the new Polaris web components API (2026-01). The extension displays a selection modal with a two-column layout: a scrollable list of options on the left, and a map on the right.

What works in the React API (2025-10):

In the React component API, we have been using dvh units to constrain the ScrollView’s height and enable scrolling. This was working for years up to two or three weeks ago, when the behavior silently changed, breaking our app layout. Since then, it seems you’ve been pushing unannounced breaking changes to the layouting system of React checkout UI components every Monday, and our team wakes up every other Monday to the bad surprise of a broken checkout UI extension in production… not great.

What breaks in the web components API (2026-01):

In the Polaris web components API, the equivalent s-scroll-box inside s-modal does not scroll. Instead, it expands to its full content height and pushes the modal content taller, scrolling everything including the title.

<s-grid-item overflow="hidden" blockSize=”100%”>

  <s-scroll-box>

    {/\* option list — does NOT scroll, grows the modal instead \*/}

  </s-scroll-box>

</s-grid-item>

<s-grid-item>

  <s-map ... />

</s-grid-item>

What we’ve tried (none of these work):

  1. blockSize=“100%” / maxBlockSize=“100%” on every ancestor (s-grid, s-grid-item, s-scroll-box) — percentage-based heights don’t resolve because the s-modal content slot does not appear to have an explicit/fixed height. In CSS, height: 100% only works when the parent has an explicit height. The modal content area seems to use intrinsic sizing (grows with content), so 100% effectively resolves to auto.

  2. overflow=“hidden” on parent s-grid and s-grid-item — has no effect because the grid itself doesn’t have a constrained height (same root cause as above).

  3. minBlockSize=“0px” on s-grid-item (the standard CSS Grid trick to prevent min-height: auto from overriding 1fr track sizing) — does not help because the grid container itself is unconstrained.

  4. gridTemplateRows=“100%” on the outer s-grid — same issue; 100% doesn’t resolve.

Root cause:

The s-modal content slot does not expose a fixed/explicit block size to its children. This means:

  • Percentage-based sizing (blockSize=“100%”) is ineffective on any descendant

  • overflow=“hidden” on grids is ineffective because the grids grow with content

  • There is no “fill” keyword available in the web components SizingProps (unlike the React API’s ScrollView which supports maxBlockSize=“fill”)

The SizeUnits type only accepts `` ${number}px | ${number}% | 0 ``, so there’s no way to reference the available space. The old React API had “fill” which solved this.

What we’d need (any of the following would unblock us):

  1. The s-modal content slot should have an explicit block size so that blockSize=“100%” propagates correctly to children — this is the most fundamental fix.

  2. Viewport units (dvh, dvb, etc.) added to SizeUnits so we can size components relative to the viewport without TypeScript casts.

  3. ocumentation on the recommended pattern for placing a s-scroll-box inside a s-modal with size=“max” in a constrained layout.

Environment:

  • api_version = “2026-01”

  • @shopify/ui-extensions (latest)

  • Extension type: ui_extension

  • Framework: Preact

Hello? @Liam-Shopify maybe? This is quite urgent as we have no workarounds but fixed height which creates an ugly experience for our ~1000 shopify stores and their customers.

We really really care about creating the most beautiful and usable checkout experience, and I think you guys do too, so can you please suggest a workaround or solution?

Thank you!

Up! This is still ongoing!

@Alan_G Maybe?