Field guide
Plan the fallback before the feature
Define the task that must stay usable, then add browser capabilities at a clear boundary.
Name the task that must survive
A fallback starts with a user's task. Someone needs to read an explanation, choose an option, or submit a form. Write that task down before choosing the presentation. A contextual panel might become an inline note; an animated change can become an immediate update. The fallback succeeds when the person can still complete the task and understand the result.
This follows progressive enhancement: establish a usable foundation, then add capabilities where the browser can provide them. It also gives the team a concrete acceptance condition. The discussion becomes about access to the task and the benefit of the enhancement.
Sources: MDN: Progressive enhancement
Put the working version in the document
Build the simple state first. Keep text readable, links navigable, controls labeled, and forms capable of ordinary submission. For a component that will use container queries, begin with a flexible layout outside the query. Add refinements when a suitable ancestor supplies the size information. The base layout should still make sense when those refinements are ignored.
For contextual help, an ordinary section or linked explanation makes a useful starting point. Add a toggle only when it can open the content. Review the initial markup as carefully as the polished state: essential instructions should not disappear because enhancement code failed to initialize.
Sources: CSS Conditional Rules: container queries, MDN: Container query fallbacks
Add one clear enhancement boundary
Place the support decision close to the feature that needs it. CSS feature queries can guard declarations; JavaScript can check an API entry point before calling it. Choose a test for the actual capability you use. Checking a browser name gives you a much less direct answer than checking the method or declaration.
Keep the original action easy to call. An animated update and an immediate update should share the function that changes the content. An observer can trigger optional loading while an explicit load button remains available. This separation also makes failures easier to diagnose: you can exercise the task without first reproducing an animation or observation callback.
Sources: MDN: Implementing feature detection
Exercise the simpler path deliberately
Make the fallback a visible test case. Run the interaction with the enhancement disabled, with narrow space, with long content, and with keyboard input. Confirm that a dismissed panel has a sensible focus destination and that delayed optional content has a clear route to load. Test the actual fallback environment where possible; forcing a branch in a modern browser cannot reproduce every older-browser behavior.
Motion deserves a separate check. The prefers-reduced-motion media feature exposes the user's request for reduced motion. For optional view transitions, a direct content update is a straightforward response. The important outcome is that choosing less animation leaves the same information and actions available.
Sources: MDN: prefers-reduced-motion
Write down what completion means
Keep a short checklist with the component: the task succeeds in the base state, the enhancement has a measurable purpose, the support check matches the implementation, and the important interaction paths have been exercised. Record which checks were run and which environments still need coverage. That makes a review useful even when someone else performs the next round of testing.
Our recommendation is to retain the fallback as part of the design, with the same care given to its labels and spacing. When support changes later, the recorded task and checks give you a clear basis for simplifying the implementation without losing the behavior people depend on.