Progressive Enhancement
Progressive enhancement builds from a semantic HTML baseline outward, adding CSS and JavaScript as optional layers. It yields resilient, accessible sites that work across browsers and survive failed assets, lowering support cost and risk.
Best Practice: Progressive Enhancement
Progressive enhancement is a frontend strategy that starts from a working baseline of semantic HTML, then adds CSS for presentation and JavaScript for behavior in layers. The core content and functions stay usable even when CSS fails, JavaScript is blocked, or the network is slow. The term was coined by Steven Champeon in 2003. It matters because it produces resilient sites that serve the widest range of browsers, devices, and assistive technologies, which lowers support cost and reduces the risk of a single failed asset breaking the whole page.
Step-by-Step Implementation Guidance
- Write the content and structure in semantic HTML first. Make sure forms, links, and key flows work with HTML alone.
- Confirm the baseline by loading the page with CSS and JavaScript disabled.
- Add a CSS layer for layout and visual design without changing the meaning of the markup.
- Add JavaScript as an enhancement, using feature detection to gate advanced behavior.
- Treat each capability as optional: when an API is missing, fall back to the baseline rather than failing.
- Test across older browsers, throttled networks, and screen readers to verify the layers degrade cleanly.
Common Mistakes Teams Make When Ignoring This Practice
- Rendering all content client-side so the page is blank without JavaScript.
- Using non-semantic markup (div soup) that breaks keyboard and screen-reader access.
- Relying on browser sniffing instead of feature detection.
- Treating accessibility and no-JS support as a later phase that never arrives.
- Shipping a single large bundle whose failure removes core functionality.
Tools and Techniques That Support This Practice
- Feature detection libraries such as Modernizr.
- Server-side rendering and static generation (Next.js, Astro, Eleventy).
- The
<noscript>element and native HTML form validation. - Lighthouse and axe for accessibility and resilience checks.
- CSS
@supportsfor conditional styling.
How This Practice Applies to Different Migration Types
- Cloud Migration: Keep server-rendered fallbacks so a CDN or edge outage still serves usable HTML.
- Database Migration: Ensure read paths degrade to cached or static content when a backing store is briefly unavailable.
- SaaS Migration: Verify embedded third-party widgets enhance rather than gate core flows in the new vendor's environment.
- Codebase Migration: When porting to a new framework, preserve the semantic HTML baseline before re-adding interactivity.
Checklist
- Core content and flows work with HTML only.
- Page is usable with CSS disabled.
- JavaScript enhancements use feature detection.
- No-JS fallbacks exist for critical actions.
- Tested on old browsers and slow networks.
- Screen-reader and keyboard paths verified.