R4.05.3progressive enhancementdesign

Progressive enhancement is the basic strategy for divergence

Aliases: feature detection · capability detection · graceful degradation · @supports

What it is

Given that spec and implementation fork, and that mobile viewports and IMEs disagree, the strategy that still stands on the web is not a branch on the browser’s name. It is progressive enhancement: make the task a completable HTML document first (links go somewhere, forms submit, content can be read), then stack convenience with CSS and JS when the capability is present. If enhancement fails, the task remains. Sniffing the User-Agent to “switch the whole UI if this is browser X” rots when an engine changes its defaults, an embedded WebView lies, or a new engine appears.

This is which side to stand on when divergence is the standing condition—not a catalogue of viewport and keyboard mechanics, and not a proof that spec and implementation differ. Those are the illness; progressive enhancement is the treatment that still works next year.

Why it happens

The document layer leans on the small subset engines already align on: links, semantic structure, form GET/POST, text a screen reader can speak. It does not ask for a particular widget chrome, and it does not ask for the visual viewport API. The enhancement layer asks, through feature detection (@supports, object detection, media queries), “can this process do the thing now?” rather than “who are you?” If it can, add client-side validation, local storage, smoother scrolling, custom widgets. If it cannot, the user can still POST the form to the server and still finish the task along links.

Sniffing rots because it writes a temporary implementation roster as a permanent identity. Engines change UA strings, share kernels, and report a desktop brand from a system WebView. Feature detection follows APIs that actually exist in this process; the roster may go stale, the detection result is current. Graceful degradation that “builds the full client then cuts features” tends to drop the task first on the outlier engine. Progressive enhancement reverses the order: keep the task, treat convenience as a layer that can come off.

Where it stops holding

An application that cannot exist without a particular API (a realtime collaborative canvas, client-only codecs) has no submittable document layer. Enhancement then degrades to “refuse clearly if unsupported,” not to pretending a form will do. Pages embedded in a super-app or a native shell that pins a kernel version can skip a few detection layers, but should still keep the document layer because shells upgrade and swap kernels. Accessibility does not arrive automatically with enhancement: a custom widget that exists only in JS leaves assistive technology with empty divs when script is off. Enhancement has to add name, role, and keyboard operation together, or the prettier layer is the exclusion.

Applying it

  • Keep the primary task completable with links and form posts when CSS or JS is missing or fails. Mark client validation, infinite scroll, and custom date widgets as enhancements, not as preconditions.
  • Decide whether to enable enhancement with @supports and runtime detection. Do not branch layout or features on the UA string.
  • When a custom widget lives on the enhancement layer, ship keyboard operation and a name and role assistive technology can read. Otherwise stay on the native control.
  • Verify by completing sign-up, checkout, or submit with JS off in one engine, then the same path in an engine that lacks a given enhancement API: the task finishes rather than going white. Spoof another browser’s UA and confirm the UI does not swap in a different logic. Any door that “requires browser X to begin” has fallen back to sniffing.

Related

  • Same group: R4.05.1 Specified behavior and implemented behavior diverge · R4.05.2 Mobile browsers have distinctive viewport and keyboard behavior
  • Adjacent: R3.16 Low-end devices and degradation · R4.14 The consistency cost of cross-platform frameworks
  • Search terms: progressive enhancement · feature detection · graceful degradation · @supports

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R4.05.3