Skip to content

Conversation

@Rajdeepc
Copy link
Contributor

@Rajdeepc Rajdeepc commented Nov 10, 2025

Description

Picker menus inside overlays on Safari/iOS couldn't scroll to the bottom after selecting an item and reopening. The menu would appear truncated (90px height instead of the full 947px), making lower items inaccessible.

Root cause

A timing issue in PlacementController: the overlay's height measurement occurred before the menu's scrollIntoView operation completed. Safari's layout engine needed an additional frame to fully render the menu after scroll repositioning, but computePlacement() was measuring prematurely, capturing the collapsed/transitional state rather than the final rendered height.

Fix

Added a 1-frame requestAnimationFrame delay in PlacementController.computePlacement() specifically for:

  • Safari/WebKit browsers (detected via user agent)
  • Overlays containing sp-menu elements
  • Excludes submenus (which need immediate positioning for hover responsiveness)

This allows Safari's layout engine to complete scrollIntoView and stabilize the menu's rendered height before the overlay calculates positioning and applies size constraints.

Why Safari-specific

Chrome's layout engine completes scrollIntoView synchronously within the same frame, while Safari/WebKit requires an additional frame for the layout to settle. This is a known Safari rendering behavior, not a bug.

Solution

PlacementController Timing Fix (PlacementController.ts)

Adds a 1-frame delay in PlacementController for Safari browsers when rendering picker menus inside overlays, allowing scrollIntoView to complete before height measurement. Excludes submenus to maintain hover responsiveness.

async computePlacement(): Promise<void> {
    const { options, target } = this;
    
    await (document.fonts ? document.fonts.ready : Promise.resolve());
    
    // NEW: Wait for content to fully render and settle
     //Safari/iOS-specific fix: Add small delay for picker menus to allow scrollIntoView to complete
        const isSafari =
            /WebKit/.test(navigator.userAgent) &&
            !/Chrome/.test(navigator.userAgent);

        // Check if this is a submenu overlay (slot="submenu")
        // Submenus need immediate positioning for hover responsiveness
        const isSubmenu = Array.from(this.host.elements).some(
            (el) => el.getAttribute?.('slot') === 'submenu'
        );

        if (isSafari && !isSubmenu) {
            const hasMenu = Array.from(this.host.elements).some(
                (el) =>
                    el.tagName === 'SP-MENU' || el.querySelector?.('sp-menu')
            );

            if (hasMenu) {
                // Wait 1 frame for Safari layout to settle after scrollIntoView
                await new Promise((resolve) => requestAnimationFrame(resolve));
            }
        }
}

Motivation and context

  • Users cannot access all menu items after the first selection
  • Affects pickers in modal dialogs, popovers, and other overlay contexts
  • Reproducible in Safari (desktop and iPad) ⚠️
  • Chrome works correctly (but fix is still needed for consistency)

Related issue(s)

Screenshots (if appropriate)


Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed at the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published.
  • I have included updated documentation if my change required it.

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Descriptive Test Statement

    1. Go here
    2. Open this in iPad
    3. Click on Open Overlay button
    4. Scroll and select any item
    5. close and open again and scroll
  • Descriptive Test Statement

    1. Go here
    2. Do this action
    3. Expect this result

Breaking Changes

None. This is a bug fix with no API changes.

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

@changeset-bot
Copy link

changeset-bot bot commented Nov 10, 2025

🦋 Changeset detected

Latest commit: edd1dda

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 78 packages
Name Type
@spectrum-web-components/overlay Patch
@spectrum-web-components/picker Patch
@spectrum-web-components/combobox Patch
@spectrum-web-components/contextual-help Patch
@spectrum-web-components/menu Patch
@spectrum-web-components/popover Patch
@spectrum-web-components/tooltip Patch
@spectrum-web-components/bundle Patch
@spectrum-web-components/truncated Patch
@spectrum-web-components/action-menu Patch
@spectrum-web-components/breadcrumbs Patch
@spectrum-web-components/action-bar Patch
@spectrum-web-components/card Patch
@spectrum-web-components/accordion Patch
@spectrum-web-components/action-button Patch
@spectrum-web-components/action-group Patch
@spectrum-web-components/alert-banner Patch
@spectrum-web-components/alert-dialog Patch
@spectrum-web-components/asset Patch
@spectrum-web-components/avatar Patch
@spectrum-web-components/badge Patch
@spectrum-web-components/button-group Patch
@spectrum-web-components/button Patch
@spectrum-web-components/checkbox Patch
@spectrum-web-components/clear-button Patch
@spectrum-web-components/close-button Patch
@spectrum-web-components/coachmark Patch
@spectrum-web-components/color-area Patch
@spectrum-web-components/color-field Patch
@spectrum-web-components/color-handle Patch
@spectrum-web-components/color-loupe Patch
@spectrum-web-components/color-slider Patch
@spectrum-web-components/color-wheel Patch
@spectrum-web-components/dialog Patch
@spectrum-web-components/divider Patch
@spectrum-web-components/dropzone Patch
@spectrum-web-components/field-group Patch
@spectrum-web-components/field-label Patch
@spectrum-web-components/help-text Patch
@spectrum-web-components/icon Patch
@spectrum-web-components/icons-ui Patch
@spectrum-web-components/icons-workflow Patch
@spectrum-web-components/icons Patch
@spectrum-web-components/iconset Patch
@spectrum-web-components/illustrated-message Patch
@spectrum-web-components/infield-button Patch
@spectrum-web-components/link Patch
@spectrum-web-components/meter Patch
@spectrum-web-components/modal Patch
@spectrum-web-components/number-field Patch
@spectrum-web-components/picker-button Patch
@spectrum-web-components/progress-bar Patch
@spectrum-web-components/progress-circle Patch
@spectrum-web-components/radio Patch
@spectrum-web-components/search Patch
@spectrum-web-components/sidenav Patch
@spectrum-web-components/slider Patch
@spectrum-web-components/split-view Patch
@spectrum-web-components/status-light Patch
@spectrum-web-components/swatch Patch
@spectrum-web-components/switch Patch
@spectrum-web-components/table Patch
@spectrum-web-components/tabs Patch
@spectrum-web-components/tags Patch
@spectrum-web-components/textfield Patch
@spectrum-web-components/thumbnail Patch
@spectrum-web-components/toast Patch
@spectrum-web-components/top-nav Patch
@spectrum-web-components/tray Patch
@spectrum-web-components/underlay Patch
@spectrum-web-components/base Patch
@spectrum-web-components/grid Patch
@spectrum-web-components/opacity-checkerboard Patch
@spectrum-web-components/reactive-controllers Patch
@spectrum-web-components/shared Patch
@spectrum-web-components/styles Patch
@spectrum-web-components/theme Patch
@spectrum-web-components/eslint-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Nov 10, 2025

📚 Branch Preview

🔍 Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-5868

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

@Rajdeepc Rajdeepc changed the title Rajdeep/ipad scroll issue fix(overlay): Picker menu scrolling issue inside overlays Nov 10, 2025
@Rajdeepc Rajdeepc self-assigned this Nov 10, 2025
@Rajdeepc
Copy link
Contributor Author

trim.2B4F5229-CADA-4597-9650-51F00C5F7E89.MOV

@Rajdeepc Rajdeepc added Status: WIP PR is a work in progress or draft Mobile Issues or PRs that impact mobile devices iOS Issues or PRs related specifically to iOS devices, including iPad. Browser: Safari SEV 2 significant problem re: design, usability, or functionality of the system/components for some users labels Nov 11, 2025
@Rajdeepc Rajdeepc changed the title fix(overlay): Picker menu scrolling issue inside overlays fix(overlay): Picker menu scrolling issue inside overlays in Safari iPad Nov 11, 2025
@Rajdeepc Rajdeepc changed the title fix(overlay): Picker menu scrolling issue inside overlays in Safari iPad fix(picker): scrolling issue inside overlays in Safari iPad Nov 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Browser: Safari iOS Issues or PRs related specifically to iOS devices, including iPad. Mobile Issues or PRs that impact mobile devices SEV 2 significant problem re: design, usability, or functionality of the system/components for some users Status: WIP PR is a work in progress or draft

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Scrolling picker inside of another overlay closes it on touch devices

2 participants