A full-viewport scrim used to dim background content behind sheets, modals, and tooltips.
Keep — with minor fixes before native handoff
Overlay is correctly token-bound and maps cleanly to native primitives (SwiftUI
.presentationBackground, Compose Scrim). Before linking, resize to Fill parent, decide whether a standard-strength variant is needed, and annotate the tap-to-dismiss contract.In Context
Overlay sits between page content and a floating surface (bottom sheet, dialog, drawer). It dims the content below to focus attention on the surface above.
Live Preview
Properties
background
surface above
DS Health
Reusable
Partial
Works as the dim layer behind any modal surface, but the fixed 360×640 frame forces consumers to resize on every use. Should Fill parent.
Self-contained
Pass
Owns its fill and opacity, bound to a semantic token. Nothing external required to render.
Consistent
Partial
Token is named
overlay-strong suggesting a standard-strength companion, but only one strength is exposed as a component. Naming implies a set of two.Composable
Partial
Intended to sit behind sheets/dialogs/drawers, but lacks fill-parent sizing and a documented z-index order.
Behavior
| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Show / hide | Yes | Yes | Not defined | Fades with the presentation transition of its owning surface. |
| Tap to dismiss | Yes | Yes | Not annotated | Contract: tap-scrim dismisses unless surface is marked modal. |
| Scroll lock | N/A | N/A | Handled by surface | Owning sheet/dialog locks background scroll on mount. |
| Focus / a11y | Yes | Yes | Implicit | Scrim itself is not focusable — owning surface traps focus. |
Open Issues
- No strength variants. Only
bg/color-bg-overlay-strong(56%) is exposed. Token name implies a standard-strength (32%) counterpart that isn't surfaced. Consider aStrength = Standard | Strongproperty. C2 · Variant & Property Naming - Fixed frame size 360×640. Forces consumers to resize the instance every time. Should use auto-layout Fill on both axes so it scales to any parent. C4 · Native Mappability
- Tap-to-dismiss contract not annotated. The standard behavior (tap-scrim dismisses, unless the surface is modal) should be documented on the component so designers and devs agree on the contract. C5 · Interaction State Coverage
- No Code Connect mapping. Trivial once the size and variant questions above are settled. C7 · Code Connect Linkability
Design Recommendations
- Set frame to Fill parent. Change both width and height from fixed to Fill so Overlay adapts to any container (phone, tablet, custom sheet). Matches how native
Scrimbehaves. Composition - Decide on strength variants. Two paths: (a) add
Strength = Standard (32%) | Strong (56%)property and bind to two tokens, matching Material 3; or (b) keep a single 56% strength and rename the token fromoverlay-strongtooverlayso the name stops implying a second variant exists. Property - Annotate the dismiss contract. Add a description on the component: "Tap-outside dismisses the surface above, unless the surface is modal (requires explicit action)." This closes the gap between designer intent and developer implementation. Docs
- Document layer order. Add a short note:
Content → Overlay → Floating surface (Sheet / Dialog / Drawer). Prevents teams from accidentally putting the floating surface under the scrim. Docs - Naming note (informational). Other DS call this primitive Scrim (Material 3), Backdrop (Fluent / Polaris), Mask (Ant), Blanket (Atlassian), Underlay (Spectrum). Team keeps Overlay — worth documenting here so cross-DS references aren't confusing. Docs
Styles
Default · Strong
DES DEV
The only current variant — a flat translucent fill at 56% opacity of the overlay color. Drop it behind any sheet, dialog, or drawer.
Properties
Surface
Background
Properties
Name Overlay
Variants 1
Properties None exposed
Inner layer dim
Surface above sheet
Background tone light
Colors
Scrim #020E228F (56% alpha)
Layout
Width (sticker sheet) 360
Height (sticker sheet) 640
Recommended sizing Fill × Fill
Corner radius 0
Border None
Padding None
Typography
N/A No text layers
Scrim — Colors
Single-purpose dimming layer placed under modal/sheet surfaces.
| Role | Token | Default |
|---|---|---|
| Scrim | bg/color-bg-overlay-strong | #020E22 @ 56% |
Property Mapping
| Figma Property | SwiftUI | Compose |
|---|---|---|
| None exposed | EBOverlay() — no parameters today. | EBOverlay(modifier: Modifier = Modifier) |
| (proposed) Strength | .ebStrength(.standard | .strong) | strength = EBOverlayStrength.Standard | Strong |
| (proposed) onDismiss | .onTapGesture { onDismiss() } | Modifier.clickable { onDismiss() } |
Accessibility
| Requirement | iOS | Android |
|---|---|---|
| Not focusable itself | Overlay is decorative. Do not expose it to VoiceOver — focus belongs to the surface above. | Use Modifier.clearAndSetSemantics { } on the scrim so TalkBack ignores it. |
| Modal announcement | The sheet/dialog above owns .accessibilityAddTraits(.isModal). | The sheet/dialog above owns semantics { paneTitle = "..." } and modal behavior. |
| Tap-to-dismiss target | Full-screen tap area counts as the dismiss hit region — comfortably above the 44×44pt target. | Full-screen tap area — comfortably above the 48×48dp target. |
| Reduce transparency | Respect UIAccessibility.isReduceTransparencyEnabled — fall back to an opaque dim color if true. | Respect Settings.Global.TRANSITION_ANIMATION_SCALE and high-contrast mode — increase opacity or swap to solid dim. |
Criteria Scorecard
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Ready | Inner layer named dim — semantic and accurate. |
| C2 | Variant & Property Naming | Needs Refinement | No properties exposed. Token name overlay-strong implies a standard-strength counterpart that isn't available. Either add a Strength property or drop the -strong qualifier from the token. |
| C3 | Token Coverage | Ready | Fill bound to bg/color-bg-overlay-strong. |
| C4 | Native Mappability | Needs Refinement | Maps cleanly to SwiftUI .presentationBackground and Compose Scrim, but fixed 360×640 frame needs to become Fill × Fill before linking. |
| C5 | Interaction State Coverage | Needs Refinement | Tap-to-dismiss behavior is implicit — should be annotated on the component as a documented contract. |
| C6 | Asset & Icon Quality | Not Applicable | No assets or icons. |
| C7 | Code Connect Linkability | Not Mapped | No Code Connect mapping yet. Trivial once sizing and strength are finalized. |
Variants Inventory (1 total)
Single variant — no property matrix.
| # | Name | Node | Dimensions | Fill | Notes |
|---|---|---|---|---|---|
| 1 | Overlay / Strong | 47:329691 | 360 × 640 | bg/color-bg-overlay-strong | Default state — the single shipped variant. |
1.0.0 — April 2026Major
Initial Assessment · node 47:329691
DS Health — Single-variant scrim, token-bound fill. Reusable/Composable flagged Partial due to fixed frame size. Documented
BaselineC2 — Strength variants — Only
C2strong (56%) exposed, token name implies a standard counterpart. OpenC4 — Fill parent — Current 360×640 frame should be Fill × Fill. Open
C4C5 — Dismiss contract — Tap-to-dismiss not annotated on the component. Open
C5C7 — Code Connect — No mapping registered. Open
C7Naming note — Other DS call this Scrim / Backdrop / Mask / Blanket / Underlay. Team keeps Overlay. Documented for cross-DS reference. Convention
Info