Перейти к содержимому
Skip to content
← All articles

Graceful Degradation vs Progressive Enhancement: Strategies and Real-World Examples

Two Philosophies for Resilient Web Development

Graceful degradation and progressive enhancement are two complementary approaches to building web applications that work across diverse browsers, devices, and network conditions. While they share the goal of broad accessibility, they differ fundamentally in starting point and mindset.

Graceful degradation starts with the full experience and ensures it degrades acceptably when capabilities are missing. Progressive enhancement starts with a solid baseline and layers on enhancements when capabilities are available. The distinction matters because it shapes architecture, testing strategy, and the default experience users receive.

Graceful Degradation Explained

Graceful degradation is a top-down approach: build the complete, feature-rich experience first, then add fallbacks for less capable environments. The core assumption is that most users have modern browsers, and fallbacks protect the minority with older or limited technology.

How It Works

Example: Image Gallery with WebP

<picture>
  <source srcset="gallery/photo-1.avif" type="image/avif">
  <source srcset="gallery/photo-1.webp" type="image/webp">
  <img src="gallery/photo-1.jpg"
       alt="Mountain landscape at sunset"
       loading="lazy"
       width="800" height="600">
</picture>

This uses modern image formats (AVIF, WebP) with automatic fallback to JPEG. Browsers that support newer formats get smaller files and better quality; others get the reliable JPEG.

Example: CSS Grid with Flexbox Fallback

.card-grid {
  /* Fallback for browsers without Grid support */
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card-grid > .card {
  flex: 1 1 calc(33.333% - 1rem);
  min-width: 280px;
}

/* Enhanced layout for Grid-capable browsers */
@supports (display: grid) {
  .card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1.5rem;
  }

  .card-grid > .card {
    flex: none;
    min-width: auto;
  }
}

Progressive Enhancement Explained

Progressive enhancement is a bottom-up approach: start with the most basic, universally supported experience, then layer on advanced features for capable environments. The core assumption is that content and core functionality should be accessible to everyone, with enhancements improving the experience when possible.

The Three Layers

  1. Content layer (HTML) — semantic, well-structured HTML that delivers all core content and functionality. Forms submit, links navigate, content is readable.
  2. Presentation layer (CSS) — visual design, layout, typography, and responsive behavior. The page works without CSS but looks better with it.
  3. Behavior layer (JavaScript) — interactive enhancements, dynamic updates, animations, and rich UI patterns. Everything works without JS, but JS makes it faster and smoother.

Example: Form Enhancement

<!-- HTML: Works without JavaScript -->
<form action="/api/contact" method="POST">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" required>

  <label for="message">Message</label>
  <textarea id="message" name="message" required
            minlength="10" maxlength="2000"></textarea>

  <button type="submit">Send Message</button>
</form>
// JavaScript: Enhances the form when available
const form = document.querySelector('form');
if (form) {
  form.addEventListener('submit', async function(e) {
    e.preventDefault();
    const btn = form.querySelector('button[type="submit"]');
    btn.disabled = true;
    btn.textContent = 'Sending...';

    try {
      const data = new FormData(form);
      const response = await fetch(form.action, {
        method: 'POST',
        body: data
      });

      if (response.ok) {
        form.innerHTML = '<p class="success">Message sent successfully!</p>';
      } else {
        throw new Error('Server returned ' + response.status);
      }
    } catch (err) {
      btn.disabled = false;
      btn.textContent = 'Send Message';
      // Fall back: allow normal form submission
      form.submit();
    }
  });
}

When to Use Each Approach

ScenarioRecommended ApproachReason
Content websites, blogsProgressive enhancementContent must be universally accessible
E-commerce checkoutProgressive enhancementRevenue depends on maximum accessibility
Real-time collaboration toolsGraceful degradationCore functionality requires modern API документацию
Video/audio editorsGraceful degradationComplex functionality needs modern browser features
Government/public servicesProgressive enhancementLegal accessibility requirements, diverse user base
Internal admin dashboardsGraceful degradationControlled environment, known browser versions

Feature Detection Patterns

Both approaches rely on feature detection rather than browser detection. Here are key patterns:

CSS Feature Detection

/* Check for specific CSS feature support */
@supports (backdrop-filter: blur(10px)) {
  .modal-overlay {
    backdrop-filter: blur(10px);
    background: rgba(0, 0, 0, 0.3);
  }
}

@supports not (backdrop-filter: blur(10px)) {
  .modal-overlay {
    background: rgba(0, 0, 0, 0.7);
  }
}

/* Check for container queries */
@supports (container-type: inline-size) {
  .card-wrapper {
    container-type: inline-size;
  }

  @container (min-width: 400px) {
    .card { flex-direction: row; }
  }
}

JavaScript Feature Detection

// Check for Intersection Observer before using it
if ('IntersectionObserver' in window) {
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('animate-in');
        observer.unobserve(entry.target);
      }
    });
  }, { threshold: 0.1 });

  document.querySelectorAll('.animate-on-scroll').forEach(el => {
    observer.observe(el);
  });
} else {
  // Fallback: show all elements immediately
  document.querySelectorAll('.animate-on-scroll').forEach(el => {
    el.classList.add('animate-in');
  });
}

Common Mistakes to Avoid

Testing Both Approaches

Conclusion

Graceful degradation and progressive enhancement are not mutually exclusive — the best web applications use both strategically. Start with progressive enhancement as the default mindset, ensuring core content and critical paths work universally. Apply graceful degradation for complex interactive features that fundamentally require modern browser capabilities. The goal is the same: every user gets the best possible experience their environment can support.

Check your website right now

Check now →
More articles: Performance
Performance
Image Optimization for Web Performance
14.03.2026 · 16 views
Performance
CDN Cache Invalidation: Strategies for Delivering Fresh Content
16.03.2026 · 17 views
Performance
Gzip vs Brotli: Web Compression Compared
16.03.2026 · 56 views
Performance
Latency vs Throughput: Understanding Network Performance Metrics
16.03.2026 · 18 views