Elementos interactivos sin JavaScript
Cómo lograr UI rica y accesible usando solo HTML5 y CSS3.
1. ¿Por qué evitar JavaScript?
Eliminar dependencias de scripts aporta rendimiento, seguridad y accesibilidad. Los navegadores pueden renderizar el contenido de forma inmediata, los crawlers de SEO indexan sin bloqueos y los usuarios con limitaciones de red obtienen una experiencia más fluida.
- Performance: menos bytes descargados y menos tiempo de ejecución.
- Seguridad: elimina vectores de XSS comunes en código JS.
- Accesibilidad: los elementos nativos ya están optimizados para lectores de pantalla.
2. Elementos HTML5 que son interactivos por naturaleza
Detalles y resumen
<details>
<summary>¿Qué es el checkbox‑hack?</summary>
<p>Una técnica CSS que usa un input type="checkbox" oculto para
controlar la visibilidad de elementos sin JS.</p>
</details>
El elemento <details> permite crear secciones colapsables con <summary> como disparador. Es totalmente accesible y soportado desde Chrome 12, Firefox 49 y Safari 10.
Input y atributos de validación
<form novalidate>
<label for="email">Correo electrónico:</label>
<input type="email" id="email" name="email" required
pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$">
<button type="submit">Enviar</button>
</form>
HTML5 ofrece validación nativa (required, pattern, type="email", etc.) que muestra mensajes de error sin necesidad de scripts.
3. Técnicas CSS para interacción avanzada
Checkbox‑hack (toggle)
<input type="checkbox" id="nav-toggle" class="d-none">
<label for="nav-toggle" class="btn btn-primary">Menú</label>
<nav class="mt-3">
<ul class="list-unstyled">
<li><a href="#">Inicio</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Contacto</a></li>
</ul>
</nav>
<style>
#nav‑toggle:checked + label + nav { display: block; }
#nav‑toggle:not(:checked) + label + nav { display: none; }
</style>
Al marcar el checkbox oculto, el selector :checked controla la visibilidad de cualquier elemento hermano.
Radio‑hack (pestañas)
<div class="tabs">
<input type="radio" name="tab" id="tab‑1" checked class="d-none">
<label for="tab‑1" class="btn btn-outline-primary">Tab 1</label>
<input type="radio" name="tab" id="tab‑2" class="d-none">
<label for="tab‑2" class="btn btn-outline-primary">Tab 2</label>
<div class="content mt-3">
<section id="c‑1">Contenido del Tab 1</section>
<section id="c‑2">Contenido del Tab 2</section>
</div>
</div>
<style>
#tab‑1:checked ~ .content #c‑1,
#tab‑2:checked ~ .content #c‑2 { display: block; }
#tab‑1:checked ~ .content #c‑2,
#tab‑2:checked ~ .content #c‑1 { display: none; }
</style>
Los radio garantizan exclusividad: sólo una pestaña está visible a la vez.
4. Comparativa: Soluciones nativas vs. JavaScript
Ventajas de la solución nativa
- Sin carga de archivos
.js(menos KB). - Mejor SEO: los crawlers pueden seguir enlaces y leer contenido colapsado.
- Mayor compatibilidad con lectores de pantalla.
- Menor superficie de ataque (XSS).
Cuándo todavía usar JavaScript
- Interacciones complejas que requieren estado persistente.
- Animaciones avanzadas (canvas, WebGL).
- Comunicación en tiempo real (WebSocket, SSE).
- Integración con APIs externas.
5. Buenas prácticas y consideraciones de seguridad
- Usar siempre etiquetas semánticas:
<nav>,<section>,<button>garantizan accesibilidad. - Escapar contenido dinámico en el servidor: aunque no haya JS, la inyección de HTML sigue siendo una amenaza.
- Validar formularios del lado del servidor: la validación HTML es una ayuda, no un sustituto.
- Probar en navegadores antiguos: el
checkbox‑hackfunciona desde IE9 con:checkedsoportado parcialmente; si se necesita soporte total, considerar un polyfill CSS.
6. Casos de uso del mundo real
- FAQ sin JavaScript:
<details>permite respuestas colapsables y mejora la indexación. - Menú hamburguesa en sitios estáticos: checkbox‑hack con CSS para abrir/cerrar.
- Tabs de documentación: radio‑hack para secciones de código.
- Formularios con validación nativa:
required,type,patterny mensajes de error personalizados con::placeholdery:invalid.
Elementos interactivos sin JavaScript: conceptos y ejemplos en HTML