Theme switches must not drop state or focus
Aliases: persist state across theme · color-scheme remount · keep focus on theme change
What it is
If switching light and dark remounts the page, a half-filled form, the control that had keyboard focus, scroll position and an open menu can all reset. A theme is a skin, not a navigation. Theme switches must not drop state or focus: appearance changes, the user is still on the same control, the same uncommitted input, the same scroll offset.
Low-vision users change contrast or appearance mid-task because the current screen cannot be read. If the change drops focus, they are sent back to the top of the page — the assistive setting has been turned into a destructive action.
Why it happens
Many implementations store the theme on a class or attribute of the root, and the framework unmounts the whole tree to swap style trees. Unmounting tears down focus, uncommitted values in controlled inputs, scroll-container offset, open popovers, and the sentence a live region was reading. The browser’s own appearance switch (system dark) usually recomputes style without unmounting; an in-product theme button that routes, full-refreshes, or remounts the root loses more than the system switch.
Lost focus has a further accessibility cost. Keyboard users get “where am I” from focus alone; a screen-reader browse position reset by remount makes the header play again. Clearing uncommitted fields is data loss, not a visual reskin.
Studying it
On a half-filled form, an open dialog, and focus mid-list, fire the in-product theme toggle and the system appearance toggle. Record the focused element, field values, scroll offset, and whether the dialog stays open.
Independent variables: switch implementation (root attribute only / full refresh / unmount-remount), source (product button / system). Dependent variables: whether focus remains on the original control, whether uncommitted values remain, scroll-offset delta, whether the dialog was closed, whether the reader re-reads the header.
Keyboard-only is required: pointer users can see the picture is still there and miss that focus has returned to the address bar. Split “appearance did change” from “task position remains” — the first is a successful reskin, the second is this criterion.
Where it stops holding
If theme change is designed to take effect only after sign-in again, that is a product policy and should be declared on the toggle, not executed silently mid-form. Some canvas or WebGL scenes must rebuild a context to recolour; the application has to serialise state and pour it back, and cannot expect DOM focus to survive. A full-document navigation (a link that leaves the page) drops state for reasons unrelated to theme. When the OS changes appearance while the app is suspended (phone backgrounded and restored), some platforms redraw on resume; focus policy has to be measured against that lifecycle separately.
Applying it
- Let the theme toggle change only a root appearance attribute or variables. Do not refresh the page or unmount the tree to reskin.
- Compare
document.activeElement(or the platform equivalent) before and after: it should be the same control, not the document root or the address bar. - Put uncommitted input, open overlays and scroll position on the theme-switch regression; any reset is a functional regression, not a visual miss.
- How to check: keyboard-focus a mid-form field, type a few characters, then hit the theme toggle. After appearance changes, focus is still in that field, the characters remain, and there is no need to Tab again from the header. Lost focus or a cleared field is a fail.
Related
- Same group: J2.15.1 Contrast in dark mode must be recalculated, not reused from the light palette · J2.15.2 System-forced high contrast can override custom colours and distort the design · J2.15.3 Images and icons need variants prepared for dark backgrounds
- Nearby: J3.02 Focus Order and Focus Traps · J5.12 Live Regions and Dynamic Announcements · J5.13 System Accessibility Settings
- Search terms:
theme switch focus·persist state across theme·color-scheme remount