Skip to content

OverlaySystem

X-01 · Composites

All elements · OverlaySystem on the Composites page

Last checked 2026-10-22 · Awaiting approval · Accessibility tests

Copies the bun run a11y:approve command for OverlaySystem.

OverlaySystem

X-01WCAG 2.2 AA · Passed #445

Dialogs behave like windows in an operating system. A [data-window-area] is the view area they live in; each dialog.qf-overlay[data-window] inside it drags by its header, snaps to the edges and corners of that area, resizes from eight grips, raises to the front when it is clicked or focused, and minimizes to a dock. js/windows.js writes the geometry; the nine data-snap rects, the grips, the dock and the drop-zone ghost are CSS.

In an app the area is the whole .qf-shell, not its content: windows stack at --qf-z-window, above the nav and the app bar, and snap over them; minimized windows become tabs in a dock along the foot of the screen, at --qf-z-dock, and snapped windows stop above it. Menus, popovers, toasts and the narrow nav drawer stay above both.

The full-screen page is overlay-system.html, inside the app shell. The specimen below is copied from overlay-system.html by bun scripts/design-pages/build-composite-pages.mjs — edit that file, not this one; --check fails when they drift.

Axis Values
[data-window-area] flag — the bounding view area windows are positioned inside; the app's .qf-shell
.qf-overlay[data-window] flag — make the dialog an OS-style window (drag · snap · resize · raise)
[data-snap] left · right · top · bottom · top-left · top-right · bottom-left · bottom-right · maximized — absent is floating
[data-state] active (front window) · minimized (docked; wins over active)
[data-window-action] minimize · maximize · close — on a button in .qf-window-controls
[data-ds-open-window] · [data-ds-close-window] opens that window id (non-modal show()) · closes the window it is in
[data-window-title] · [data-window-icon] label and sprite id for the dock chip; default to the window's own title and icon
.qf-overlay__resize[data-edge] n · e · s · w · ne · nw · se · sw — resize grips, injected by js/windows.js
.qf-snap-preview[data-snap] · .qf-dialog-dock drop-zone ghost and the dock of minimized windows
[data-window-minimizable] false — a window that must be answered (a confirmation) does not minimize
qf-window-snap · -minimize · -restore · -close bubbling events on the window, so a framework that renders it can follow its state
--qf-window-dock the dock's height on its area, written by js/windows.js; snap rects stop above it
Windows: drag, snap, resize and dock
Open a window
CS-2041 · Water damage
Status
In review
Adjuster
Jane Doe
Opened
11 Sep 2026
Reserve
$14,200
HO-3 renewal.docx

Endorsement 4 adds water back-up cover to the renewal term. Drag this title bar to an edge to snap the window; drag any border to resize it.

Adjusters on this claim
Owner
Jane Doe
Field
Marcus Webb
Desk
Priya Raman
Edit saved search

The search on screen differs from the saved one. Update saves the name and the search as they are now.

Loss photos (12)

Opened from the toolbar with data-ds-open-window. New windows cascade from the top-left of the area.

Activity

Escape closes the focused window and returns focus to the control that opened it.

Drag the title bar — edge = half · corner = quadrant · top = maximizedDrag any border — eight grips, min 20rem × 10remAlt + Arrow — snap left / right / up / downDouble-click the title bar — toggle maximizedMinimize — tabs dock along the bottomEscape or Close — focus returns to the opener

Guidance

When to use

  • Use it when users need several objects open at once to compare or copy between them, such as a case, its policy and its photos.
  • Use it when an object opened from Search, a DataGrid or a list should stay open while the user keeps working in the list.
  • Use it to host a QEditor office file, which always opens as its own window.
  • Use the dock when users park open work for later in the same session.

When to consider something else

  • Use a modal Overlay when the user must finish or cancel one task before doing anything else. See Overlay.
  • Use a Confirmation for a short yes or no decision about a destructive action. See Confirmation.
  • Use a two-pane view, as in the Inbox, when users step through records one at a time. See Inbox.
  • Use a Task pane for a side panel tied to the current document rather than a free-floating object. See TaskPane.

Usability

Do
  • Place every window inside a [data-window-area], normally the app's .qf-shell, so windows snap over the nav and app bar and minimize to a dock along the foot of the screen.
  • Give every window a .qf-overlay__title that names the object, plus data-window-icon so its dock chip is recognizable.
  • Open windows with data-ds-open-window on the control that represents the object, so focus can return to it.
  • Keep the standard .qf-window-controls (Minimize, Maximize, Close) in every window header.
  • When the window's content draws the whole chrome (QEditor in an iframe), set data-chrome="editor" and render no header: the window keeps a hairline edge, and the content reports its title-bar drags and control clicks to qfWindows.dragStart/dragMove/dragEnd, toggleMaximize, minimize and close, and draws the qf-window-state event's active and maximized state. Name it with aria-label and give it data-window-title and data-window-icon for its dock chip. Inside the content, its own outer frame is a data-presentation="fullscreen" window, which js/windows.js never drags, resizes, snaps or maximizes: only the host window moves.
  • Let new windows cascade from the area's top-left instead of stacking at one position.
Don’t
  • Do not use a window for a blocking decision; windows are non-modal and the page behind stays usable.
  • Do not make dragging the only way to move or size a window; snap keys and Maximize must stay available.
  • Do not open a second copy of an object that is already open; opening it again raises the existing window.
  • Do not place windows outside a window area, where snapping and the dock have no bounds.

Accessibility

Keyboard

OverlaySystem keyboard
Keys Action
Tab Moves through the window's controls; focusing any control inside a window raises it to the front.
Enter or Space On an opener, opens or raises its window; on a dock chip, restores the minimized window.
Escape Closes the focused window and returns focus to the control that opened it.
Alt+Arrow keys or Cmd+Arrow keys Snaps the window: Up maximizes, Left and Right snap to halves, Up and Down from a half snap to quarters, and Down from maximized restores floating.
Enter on Maximize Toggles between maximized and the previous size; the button reports its state with aria-pressed.

Roles and names

  • Each window is a non-modal <dialog class="qf-overlay" data-window> opened with show(), not showModal().
  • The binding must name each window with aria-labelledby pointing at its .qf-overlay__title; the static markup does not.
  • Window controls are icon-only buttons labeled Minimize, Maximize and Close; Maximize carries aria-pressed.
  • Resize grips and the snap preview ghost are aria-hidden="true"; dock chips are real buttons labeled with the window title.
  • data-state="active" marks the front window and data-state="minimized" a docked one; neither is announced, so state changes must not rely on them alone.

Focus

  • Opening a window does not move focus in the reference; the binding must move focus into the new window (its first control or title).
  • Closing returns focus to the opener; restoring from the dock focuses the first header button.
  • Windows do not trap focus; Tab can leave a window to reach the page and other windows.
  • A front window must not fully hide the focused control in another window or the page (2.4.11).

Other requirements

  • Header drag and edge resizing are pointer-only; the Alt+Arrow snaps and the Maximize button are the alternatives 2.5.7 Dragging Movements requires.
  • Window content must reflow when snapped to a quarter or shown at 320 CSS pixels wide (1.4.10).
  • Window control buttons are data-size="sm"; confirm they meet 24 by 24 CSS pixels (2.5.8).
  • Snapping and raising must not animate for users who set prefers-reduced-motion (2.3.3).

Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.

Accessibility tests

WCAG 2.2 AA · Passed

Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.

OverlaySystem test checklist
Area Automated A person checks
General Passed Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme.
Zoom Passed At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping.
Keyboard Passed Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (5 rows)
Screen reader Passed With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items)

Approving. When the checklist passes on the checked run, record it with bun run a11y:approve -- overlay-system --by "Your name" and commit a11y/approvals.json with the rebuilt pages. All test status

Package

Consumers link one stylesheet, css/classic/index.css, which includes every element. The files below are where this element is defined.

OverlaySystem package
Source css/classic/components/overlays.css
css/classic/composites/documents.css
css/classic/composites/office-shell.css
css/classic/composites/overlay-system.css
css/classic/composites/windows.css
Specimens also use Box · Button · Card · Chip · Control · Field · Form · Icon · Overlay · Table · Text · Toolbar
Sprites sprites/icons.svg
React Not yet available: the React binding has not started.

Latest updates

OverlaySystem latest updates
Date Version Breaking Description
2026-10-20 0.1 Yes Classic is the only skin: css/modern/ and js/skin.js are removed, so consumers link css/classic/index.css directly (no data-skin-sheet swap) and keep data-skin="classic" on <html> for scripts. The skin switch is gone from the site's app bar, the shell's identity menu and the Office review strip; theme stays. The per-skin composite pages are single pages: composites/shell.html, inbox.html, overlay-system.html and search.html replace the *.classic.html and *.modern.html pairs
2026-10-20 0.1 No OverlaySystem: the save-search window the search toolbar's bookmark opens, non-modal (Edit saved search: Name, a note when the search on screen differs, Delete… · Cancel · Save as new · Update), classic skin

All release notes