Lancé un sitio de marketing el mes pasado que tiene una puntuación de 100 en todas las categorías de Lighthouse. Total de JavaScript enviado al cliente: cero bytes. No "casi cero" o "mínimo" -- literalmente nada. Los formularios funcionan, la navegación funciona, hay un toggle de modo oscuro, y las transiciones de página se sienten rápidas. Hace cinco años eso habría requerido compromisos serios. En 2026, la plataforma ha avanzado hasta un punto donde zero-JS no es una limitación -- es una opción arquitectónica legítima.

Pero aquí está lo que la mayoría de artículos sobre mejora progresiva no entienden: no se trata de ser purista u odiar JavaScript. Se trata de tomar decisiones intencionales sobre qué se ejecuta dónde. Déjame mostrarte cómo abordamos esto en Social Animal, qué ha cambiado en 2026 que hace que zero-JS sea viable para más proyectos que nunca, y cuándo absolutamente deberías recurrir a código del lado del cliente.

Tabla de Contenidos

Progressive Enhancement & Zero-JS Websites in 2026

Qué significa realmente Progressive Enhancement en 2026

La mejora progresiva ha existido desde principios de los 2000, pero la mayoría de desarrolladores con los que hablo aún la entienden mal. Piensan que significa "construir primero una versión HTML deficiente, y luego hacerla buena con JavaScript". Eso es al revés.

La mejora progresiva significa que tu experiencia base funciona. Punto. HTML es tu fundación. CSS añade la capa visual. JavaScript -- si lo necesitas -- añade interactividad encima. Cada capa es aditiva. Si alguna capa falla, las capas debajo aún funcionan.

En 2026, esta filosofía se ha vuelto más práctica que nunca porque las capacidades base de HTML y CSS se han expandido dramáticamente. Cosas que requerían JavaScript hace cinco años ahora tienen soluciones nativas de la plataforma:

  • Acordeones y widgets de divulgación<details> y <summary>
  • Modales y diálogos → elemento <dialog>
  • Validación de formularios → Constraint Validation API
  • Desplazamiento suavescroll-behavior: smooth
  • Modo oscuro@media (prefers-color-scheme) con trucos del selector :has()
  • Carruseles → CSS scroll snap con scrollbar-width
  • Popovers y tooltips → Popover API
  • Posicionamiento de anclaje → CSS Anchor Positioning
  • Transiciones de vista → View Transitions API (Nivel 2 para entre documentos)

La plataforma web en 2026 no es la plataforma web de 2020. Hemos tenido una expansión masiva de lo que es posible sin scripting.

La Plataforma lo ha Cambiado Todo

La Popover API

La Popover API alcanzó soporte completo entre navegadores en 2024 y para ahora es production-ready en todos lados que importa. Antes de esto, cada tooltip, menú desplegable y notificación de toast necesitaba JavaScript. Ahora:

<button popovertarget="my-menu">Menu</button>
<nav popover id="my-menu">
  <a href="/about">About</a>
  <a href="/work">Work</a>
  <a href="/contact">Contact</a>
</nav>

Eso es todo. Haz clic en el botón, aparece el popover. Haz clic afuera, se despide. Presiona Escape, se despide. La gestión del foco se maneja. Accesible por defecto. Cero JavaScript.

CSS Anchor Positioning

Este es el que realmente abrió las puertas. Posicionar un tooltip en relación a su disparador solía requerir JavaScript para medir posiciones del DOM. CSS Anchor Positioning (baseline en 2025, completamente estable ahora) lo maneja declarativamente:

.trigger {
  anchor-name: --my-trigger;
}

.tooltip {
  position: fixed;
  position-anchor: --my-trigger;
  top: anchor(bottom);
  left: anchor(center);
  translate: -50% 8px;
}

Combina esto con la Popover API y tienes tooltips completamente posicionados y accesibles con cero código del lado del cliente.

Cross-Document View Transitions

View Transitions Nivel 2 es lo que hace que los sitios zero-JS se sientan como SPAs. Añades una at-rule CSS y de repente navegar entre páginas tiene transiciones animadas suaves:

@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: fade-out 0.2s ease;
}

::view-transition-new(root) {
  animation: fade-in 0.2s ease;
}

Chrome, Edge y Safari todos lo soportan ahora. Firefox se espera más adelante este año. Esta característica única elimina una de las razones más grandes por las que los equipos elegían SPAs -- rendimiento percibido a través de transiciones animadas.

El Selector `:has()`

El selector :has() (a veces llamado el "selector padre") ha sido estable desde 2024 y es genuinamente transformador para interactividad solo CSS:

/* Toggle dark mode sin JS */
html:has(#dark-mode:checked) {
  color-scheme: dark;
  --bg: #1a1a2e;
  --text: #eee;
}

Con un checkbox oculto y una <label>, tienes un toggle de modo oscuro funcionando. Sin JavaScript. El estado persiste durante la sesión y puedes incluso sincronizarlo a localStorage mediante un pequeño script de mejora si quieres persistencia entre visitas.

Patrones Solo CSS que Reemplazan JavaScript

Permíteme catalogar los patrones que usamos regularmente. No estoy hablando de arte CSS o demostraciones de novedad -- estos son patrones de producción que enviamos a clientes reales.

Patrón Enfoque Antiguo (JS) Enfoque 2026 (CSS/HTML) Soporte de Navegadores
Menús desplegables Event listeners, focus traps Popover API + :has() 95%+
Acordeones Toggle de clases, gestión ARIA <details> + ::details-content 96%+
Modales Librerías focus trap, scroll lock <dialog> + ::backdrop 97%+
Pestañas Show/hide panels, ARIA tabs Botones radio + :has() + scroll-snap 95%+
Carruseles Swiper.js, Flickity scroll-snap + scroll-timeline 93%+
Tooltips Popper.js, Floating UI Popover API + Anchor Positioning 90%+
Validación de formularios Lógica de validación personalizada Constraint Validation + :user-valid 95%+
Animaciones de scroll Intersection Observer, GSAP animation-timeline: scroll() 88%+
Toggle de tema localStorage + manipulación del DOM Checkbox + :has() + color-scheme 96%+
Transiciones de página Enrutamiento del lado del cliente Cross-document View Transitions 85%+

Esa tabla representa probablemente el 80% de los patrones interactivos en un sitio de marketing o plataforma de contenido típica. Todo lograble sin enviar ni un solo kilobyte de JavaScript.

El Patrón de Pestañas

Aquí hay uno que me encanta particularmente. Pestañas solo CSS usando botones de radio:

<div class="tabs">
  <input type="radio" name="tab" id="tab1" checked>
  <label for="tab1">Features</label>
  <input type="radio" name="tab" id="tab2">
  <label for="tab2">Pricing</label>
  <input type="radio" name="tab" id="tab3">
  <label for="tab3">FAQ</label>
  
  <div class="panels">
    <div class="panel" id="panel1">Features content...</div>
    <div class="panel" id="panel2">Pricing content...</div>
    <div class="panel" id="panel3">FAQ content...</div>
  </div>
</div>
.tabs:has(#tab1:checked) .panels { --active: 0; }
.tabs:has(#tab2:checked) .panels { --active: 1; }
.tabs:has(#tab3:checked) .panels { --active: 2; }

.panels {
  display: flex;
  overflow: hidden;
  translate: calc(var(--active) * -100%) 0;
  transition: translate 0.3s ease;
}

.panel {
  min-width: 100%;
}

Cambio de pestaña suave y animado sin JavaScript. Añade role="tablist" y atributos ARIA apropiados para accesibilidad, y tienes un componente listo para producción.

Progressive Enhancement & Zero-JS Websites in 2026 - architecture

Interactividad HTML-First

Más allá de CSS, el propio HTML ha se ha vuelto mucho más capaz. Déjame destacar patrones que usamos.

El Elemento ``

Sé que <dialog> ha existido por un tiempo, pero muchos equipos aún recurren a una librería modal. No lo hagas. El diálogo nativo maneja atrapamiento de foco, bloqueo de scroll, Escape para cerrar, y el pseudo-elemento ::backdrop para overlays.

La única salvedad: necesitas un pequeño bit de JavaScript para abrir un diálogo modal (llamando .showModal()). Pero para mejora progresiva, puedes hacer que el disparador sea un enlace a una página separada, luego mejorar con JS si está disponible:

<a href="/contact" class="js-dialog-trigger" data-dialog="contact-form">
  Get in touch
</a>

<dialog id="contact-form">
  <form method="dialog">
    <!-- form fields -->
    <button type="submit">Send</button>
  </form>
</dialog>

Sin JavaScript: el usuario navega a /contact. Con JavaScript: el diálogo se abre inline. Ambos funcionan. Eso es mejora progresiva.

Formularios Sin JavaScript

Los formularios son la mayor ganancia para enfoques zero-JS. Los formularios HTML nativos envían datos a servidores. Eso es para lo que fueron diseñados. Con frameworks modernos del lado del servidor, no necesitas e.preventDefault() y llamadas fetch():

<form action="/api/contact" method="POST">
  <input type="email" name="email" required>
  <textarea name="message" required minlength="10"></textarea>
  <button type="submit">Send</button>
</form>

Las pseudo-clases :user-valid y :user-invalid (ahora baseline) te permiten estilar estados de validación sin JS, pero solo después de que el usuario haya interactuado -- sin más bordes rojos al cargar la página.

input:user-invalid {
  border-color: var(--error);
  outline-color: var(--error);
}

input:user-valid {
  border-color: var(--success);
}

Frameworks del Lado del Servidor que Envían Zero JS

Elegir el framework correcto importa enormemente para la mejora progresiva. Aquí está cómo los principales actores se alinean en 2026.

Astro

Astro sigue siendo el estándar de oro para salida zero-JS. Envía HTML y CSS por defecto, y opt-in a JavaScript por componente con directivas client:. Lo usamos extensamente para sitios de marketing, documentación y plataformas ricas en contenido -- mira nuestras capacidades de desarrollo Astro para detalles específicos.

---
// Este componente envía CERO JavaScript
const posts = await fetch('https://api.example.com/posts').then(r => r.json());
---
<ul>
  {posts.map(post => <li><a href={post.url}>{post.title}</a></li>)}
</ul>

Astro 5 (estable desde principios de 2025) añadió server islands y APIs mejoradas de content layer. El modelo mental es simple: todo es pre-renderizado en servidor a menos que explícitamente digas lo contrario.

Eleventy (11ty)

Eleventy 3.0 continúa siendo excelente para sitios zero-JS. Es un generador de sitios estáticos puro -- sin opiniones sobre JavaScript del lado del cliente en absoluto. Si lo quieres, lo añades manualmente. Lo hemos encontrado ideal para sitios más pequeños y blogs donde la simplicidad de build-time importa.

Next.js con Server Components

Next.js es interesante aquí. Los Server Components (el defecto en App Router) no envían JavaScript al cliente. Pero el runtime de Next.js mismo añade una línea base de payload JS para hydration, enrutamiento y prefetching. No puedes llegar a zero-JS verdadero con Next.js, pero puedes llegar notablemente cerca para aplicaciones interactivas. Revisa nuestro trabajo de desarrollo Next.js -- hemos empujado este límite en varios proyectos.

SvelteKit

SvelteKit te permite desabilitar JavaScript por página con export const csr = false. La salida es HTML/CSS puro. Es un gran punto medio -- obtienes la experiencia de desarrollador de componentes Svelte pero puedes desabilitar selectivamente rendering del lado del cliente.

Framework Salida de JS por Defecto ¿Zero-JS Posible? Mejor Para
Astro 5 0 KB Sí (por defecto) Sitios de contenido, marketing
Eleventy 3 0 KB Sí (por defecto) Blogs, docs, sitios simples
Next.js 15 ~85-100 KB No (runtime requerido) Web apps, contenido dinámico
SvelteKit 2 ~15-25 KB Sí (opt-out por página) Sitios híbridos
Fresh (Deno) 0 KB Sí (arquitectura island) Proyectos basados en Deno
Enhance 0 KB Sí (HTML-first) Sitios de web components

Cuándo Zero JavaScript es la Opción Equivocada

Estaría haciéndote un flaco favor si solo hablara sobre cuándo zero-JS funciona. Aquí está cuándo no:

Colaboración en tiempo real. Si estás construyendo algo como Figma, Google Docs, o una aplicación de chat, necesitas WebSockets y gestión de estado del lado del cliente. No hay forma de evitarlo.

Visualización de datos compleja. D3, Observable Plot, o deck.gl para mapas -- estos necesitan JavaScript. Podrías pre-renderizar gráficos estáticos como SVG (y lo hacemos), pero cualquier cosa interactiva necesita código del lado del cliente.

Editores de texto enriquecido. ProseMirror, TipTap, Lexical -- estas son inherentemente aplicaciones del lado del cliente. La mejora progresiva aquí significa proporcionar un fallback <textarea>, lo cual es bastante razonable.

Búsqueda del lado del cliente. Si quieres búsqueda instantánea mientras escribes sin golpear el servidor en cada keystroke, necesitas índices de búsqueda del lado del cliente (Pagefind, Lunr, Fuse.js). Pagefind merece ser llamado específicamente -- es un índice de búsqueda de build-time que solo carga ~5 KB inicialmente.

Flujos de autenticación. Las redirecciones OAuth funcionan sin JS, pero refresco de token, gestión de sesión, y rutas protegidas del lado del cliente típicamente necesitan algo de scripting.

Reproductores de video/audio. Los reproductores personalizados necesitan JavaScript. Pero los elementos <video> y <audio> con controles nativos funcionan perfectamente sin él.

El patrón que recomiendo: comienza con zero-JS y añade quirúrgicamente dónde la experiencia del usuario genuinamente lo demande. Esto es exactamente lo que la arquitectura island de Astro permite -- 95% de la página es HTML estático, y el un widget interactivo obtiene hydratación.

Benchmarks de Rendimiento: JS vs Zero-JS

Hemos estado rastreando rendimiento en todos nuestros proyectos de clientes. Aquí están números reales de sitios en producción que construimos en 2025-2026.

Métrica Típico React SPA Next.js (App Router) Astro (Zero-JS) Mejora
First Contentful Paint 1.8s 0.9s 0.4s 78% más rápido
Largest Contentful Paint 2.5s 1.3s 0.6s 76% más rápido
Time to Interactive 3.2s 1.8s 0.4s 87% más rápido
Total Blocking Time 450ms 180ms 0ms 100% reducción
Tamaño de Transferencia JS 280 KB 105 KB 0 KB 100% reducción
Rendimiento Lighthouse 65-75 85-95 100 --
Tasa de Aprobación Core Web Vitals 55% 82% 99% --

Estos números importan para resultados comerciales reales. Google ha sido cada vez más transparente sobre el impacto de CWV en rankings de búsqueda. Un estudio de 2025 por Searchmetrics encontró que sitios pasando todos los Core Web Vitals tenían 24% mayores posiciones de ranking promedio que aquellos fallando. Y esa brecha se está ampliando.

Para nuestros clientes, hemos visto mejoras medibles: una marca de e-commerce vio un aumento de 15% en tráfico orgánico después de migrar de un React SPA a un escaparate basado en Astro con hydration selectiva. Su arquitectura de CMS headless se mantuvo igual -- solo cambiamos cómo el frontend consumía y renderizaba contenido.

Construyendo una Estrategia de Progressive Enhancement

Aquí está el playbook práctico que seguimos:

Paso 1: Audita tu JavaScript

Antes de construir algo nuevo, mira qué JavaScript estás actualmente enviando y pregúntate: ¿esto necesita ejecutarse en el cliente?

# Forma rápida de revisar uso de JS en Chrome DevTools
# Coverage tab → Reload → Ver cuánto JS realmente se ejecuta

Regularmente encontramos que 40-60% del JavaScript enviado nunca se ejecuta en carga inicial. Es código muerto, polyfills no utilizados, o características que no han sido activadas.

Paso 2: Categoriza tu Interactividad

Pon cada característica interactiva en uno de tres buckets:

  1. Nativa de la plataforma -- Puede hacerse con HTML/CSS solo (usa plataforma)
  2. Mejora -- Funciona sin JS, mejor con ella (mejora progresiva)
  3. Requiere JS -- Genuinamente imposible sin código del lado del cliente (envíalo)

Sé honesto contigo mismo. La mayoría de cosas aterrizan en bucket 1 o 2.

Paso 3: Elige el Framework Correcto

Si estás construyendo un sitio de contenido, documentación, páginas de marketing, o un blog -- recurre a Astro o Eleventy. No elijas Next.js para un sitio de marketing solo porque tu equipo conoce React. El desajuste arquitectónico te cuesta rendimiento.

Si estás construyendo una aplicación con interactividad significativa del lado del cliente, Next.js o SvelteKit con rendering selectivo del servidor tiene más sentido. Usa Server Components dónde sea posible y componentes de cliente solo donde sea necesario.

Ayudamos a los equipos a tomar exactamente estas decisiones -- echa un vistazo a nuestras capacidades o ponte en contacto si quieres hablar de tu situación específica.

Paso 4: Prueba Sin JavaScript

Este es el paso que todos se saltan. Desabilita JavaScript en tu navegador y navega tu sitio. ¿Funciona? ¿Pueden los usuarios:

  • ¿Leer contenido? ✓
  • ¿Navegar entre páginas? ✓
  • ¿Enviar formularios? ✓
  • ¿Acceder a información crítica? ✓

Si no, tu estrategia de mejora tiene agujeros.

Arquitectura del Mundo Real para Sitios Zero-JS

Permíteme compartir una arquitectura concreta que hemos usado para varios proyectos de clientes:

┌─────────────────────────────────────────┐
│              CDN (Cloudflare)            │
│         Static HTML/CSS assets          │
├─────────────────────────────────────────┤
│          Astro SSG / SSR Layer          │
│     Fetches content at build/request    │
├─────────────────────────────────────────┤
│            Headless CMS                 │
│    (Sanity / Storyblok / Payload)       │
├─────────────────────────────────────────┤
│          Form Handler Service           │
│     (Cloudflare Workers / Resend)       │
└─────────────────────────────────────────┘

El contenido vive en un CMS headless. Astro lo jala en tiempo de build (o tiempo de solicitud para contenido frecuentemente actualizado). La salida es HTML y CSS puros, desplegados en un edge de CDN.

Todo el frontend tiene cero JavaScript. El CMS da a los editores de contenido una gran experiencia. Los formularios funcionan sin código del lado del cliente. Las transiciones de página usan cross-document View Transitions. Es rápido, accesible, y resiliente.

Para sitios que necesitan interactividad selectiva -- digamos, un configurador de producto en una página -- usamos la arquitectura island de Astro para hidratar solo ese componente. El resto del sitio se mantiene estático.

Esta es la clase de arquitectura que construimos regularmente. Si te curiosea el pricing para este enfoque, revisa nuestra página de pricing -- sitios zero-JS son típicamente más rápidos de construir y más baratos de alojar.

FAQ

¿Es la mejora progresiva aún relevante en 2026?

Más relevante que nunca. Con soporte 95%+ para características como la Popover API, CSS :has(), View Transitions, y <dialog>, la plataforma web puede manejar interactividad que previamente requerían JavaScript. La mejora progresiva no es una filosofía del pasado -- es una estrategia de ingeniería práctica que resulta en sitios web más rápidos, más resilientes, y más accesibles.

¿Puedes construir un sitio web completo con cero JavaScript?

Absolutamente. Sitios de marketing, blogs, documentación, portafolios, e incluso tiendas de e-commerce pueden ser construidas sin JavaScript del lado del cliente. Los formularios se envían nativamente, la navegación usa enlaces estándar (con View Transitions para pulido), y componentes interactivos como acordeones, modales, y tooltips todos tienen soluciones HTML/CSS-nativas. Los sitios que no puedes construir sin JS son apps en tiempo real, editores de texto enriquecido, y visualizaciones de datos complejas.

¿Cómo afecta zero JavaScript al SEO?

Positivamente, en casi todos los casos. Los motores de búsqueda pueden indexar contenido HTML instantáneamente sin esperar la ejecución de JavaScript. Las puntuaciones de Core Web Vitals mejoran dramáticamente -- especialmente Total Blocking Time, que cae a cero. Los sistemas de ranking de Google recompensan páginas rápidas y accesibles, y los sitios zero-JS consistentemente logran puntuaciones de Lighthouse más altas y mejores tasas de aprobación de CWV.

¿Cuál es el mejor framework para sitios web sin JavaScript en 2026?

Astro es la opción más fuerte para la mayoría de proyectos zero-JS. Produce cero JavaScript por defecto y te permite añadir interactividad del lado del cliente por componente cuando sea necesario. Eleventy es otra opción excelente para sitios más simples. Ambos tienen ecosistemas maduros, buena documentación, y comunidades activas. La elección entre ellos usualmente viene a la autoría basada en componentes (Astro) o simplicidad basada en plantillas (Eleventy).

¿Funcionan los componentes interactivos solo CSS para accesibilidad?

Los elementos HTML nativos como <details>, <dialog>, y la Popover API son accesibles por defecto -- manejan gestión de foco, navegación por teclado, y semántica ARIA automáticamente. Los patrones solo CSS usando checkbox hacks necesitan más cuidado: deberías añadir roles ARIA apropiados y asegurar operabilidad por teclado. En general, las soluciones HTML nativas son más accesibles que implementaciones JavaScript personalizadas porque los vendedores de navegador han hecho el trabajo de accesibilidad para ti.

¿Cómo funcionan View Transitions sin JavaScript?

Cross-document View Transitions (Nivel 2 del spec) funcionan completamente a través de CSS. Añades una regla @view-transition { navigation: auto; }, y el navegador automáticamente crea transiciones animadas entre navegaciones de página. Puedes personalizar las animaciones con pseudo-elementos ::view-transition-old() y ::view-transition-new(). Sin JavaScript requerido. Chrome, Edge, y Safari lo soportan en 2026, con soporte de Firefox esperado pronto.

¿Qué porcentaje de usuarios tienen JavaScript deshabilitado?

Solo alrededor de 1-2% de usuarios deshabilan activamente JavaScript. Pero ese no es el punto. JavaScript falla para muchos más usuarios que eso -- conexiones inestables, firewalls corporativos, extensiones de navegador, cortes de CDN, y errores de parsing todos causan fallas de JS. El UK Government Digital Service encontró que 1.1% de usuarios no estaban obteniendo mejoras de JavaScript a pesar de tener JS habilitado. La mejora progresiva protege a todos estos usuarios.

¿Puedo usar un CMS headless con un frontend sin JavaScript?

Sí, y es una de las mejores combinaciones. El CMS proporciona una gran experiencia de edición para equipos de contenido, mientras que el frontend (construido con Astro o Eleventy) consume contenido en tiempo de build vía API y produce HTML/CSS puro. El JavaScript del CMS se ejecuta en el navegador del editor, no en los navegadores de tus visitantes. Este desacoplamiento te da lo mejor de ambos mundos: gran experiencia de autoría y rendimiento zero-JS para usuarios finales.