Skip to content

Contain retained scroll chaining with overscroll-behavior #793

Description

@wieslawsoltes

Merged implementation status — 20 September 2026

PR #794 merged to WebScene main at 8be49a9528efb86c86f47574997a03e93215f205 and closed this issue. It implements shorthand/axis CSSOM, compact cold state, per-axis retained wheel-chain containment, and authored correctness/performance gates. Consolidation #76 consumes it at 70f924666b797ba10a78dccb95f286578a6234c1; local vscode-demo pins it at 6c1e571b and remains unpushed.

git diff --check passed before merge. No build, test, WPT, visual, package, memory, lifecycle, accessibility, or benchmark command ran; those acceptance items remain open as zero evidence under their owning epics.

Parent epic: #235
Layout owner: #240
Interaction owner: #260
Performance owner: #243
Visual owner: #259
Release owner: #227

Problem

Unchanged Code OSS 645f29cc3176500b4b5762ba887cf2a7f0ffdf2c contains 12 overscroll-behavior declarations. The workbench root uses none to suppress viewport bounce, while Markdown preview, Chat, question carousels, voice input, sessions/mobile shells, and overlay views use contain to stop boundary wheel gestures from escaping into an ancestor panel.

WebScene main 3dc62a1c7a81f0820af771849aae60350cde30f0 does not expose the shorthand or -x/-y longhands. Its wheel default action walks ancestors whenever the hit scroll target cannot move, so nested panels can scroll the workbench behind them. Accepting the declarations without connecting them to the retained scroll default action would be a false compatibility claim.

Focused implementation

  • expose overscroll-behavior, overscroll-behavior-x, and overscroll-behavior-y through native/managed metadata and CSSOM;
  • parse one/two-value shorthand plus auto, contain, and none longhands with global-keyword behavior;
  • retain both axes as a compact cold-style policy without enlarging the hot node record;
  • during wheel ancestor traversal, stop each exhausted axis at a qualifying scroll container when its policy is contain or none;
  • preserve the other axis, normal auto chaining, root viewport ownership, smooth/discrete scheduling, scroll events, and existing cancellation;
  • add no timer, frame participant, document scan, platform widget, browser shell, or Code OSS patch.

contain and none have the same scroll-chain boundary in this slice. WebScene already has no native rubber-band affordance; future overscroll affordance control must remain explicit rather than inventing visual behavior here.

Authored quality and performance gates

  • canonical/longhand CSSOM, one/two-value serialization, mutation/removal, invalid writes, cascade, and global keywords;
  • nested vertical and horizontal boundary chaining for auto, contain, and none, including mixed per-axis policy;
  • root viewport, iframe isolation, wheel cancellation, discrete/precise input, detach/navigation cleanup, and scroll-event order;
  • 4,096 nested scroll containers with bounded ancestor probes, zero added layout from policy mutation, bounded publications, stable memory, and no sustained frame demand;
  • exact unchanged Code OSS Markdown/Chat/workbench region and scroll interaction comparison with Chromium.

Acceptance status

Per the active implementation-only direction, source review and git diff --check may precede merge; unexecuted gates remain zero evidence.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    vscode-oss/plannedPlanned for the AppScene/WebScene VS Code OSS integration

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions