CodeForge

Maquetación Web Dinámica / JavaScript para maquetadores: darle vida al DOM

Patrones de UI: modal, tabs, acordeón y dark mode

Teoría22 min20 XP

Hay un puñado de componentes que te van a pedir en CADA proyecto: un modal, pestañas, un acordeón, un interruptor de tema oscuro. Son tan comunes que conviene tenerlos como recetas mentales, hechos bien —accesibles— de una vez. Esta lección es tu recetario: los patrones clásicos con todo lo que aprendiste en el módulo, y con la accesibilidad que separa un componente profesional de uno a medias.

El reflector: un modal que se comporta

Ábrelo y ciérralo de las tres formas, y prueba con el teclado (Tab, Escape). Lo que lo hace accesible: el foco ENTRA al modal al abrir (cerrar.focus()), VUELVE al botón original al cerrar (previo.focus()), Escape y el clic en el fondo lo cierran, y los aria describen su rol. (Un modal de producción además ATRAPA el foco en un ciclo dentro del diálogo; el <dialog> nativo de HTML te da varias de estas gratis y vale la pena conocerlo.)

Las otras tres recetas

tabs.js
// TABS: un botón por pestaña (role="tab"), un panel por contenido
tabs.forEach((tab) => {
tab.addEventListener("click", () => {
  tabs.forEach((t) => t.setAttribute("aria-selected", "false"));
  paneles.forEach((p) => (p.hidden = true));
  tab.setAttribute("aria-selected", "true");           // marca la activa
  document.querySelector(tab.dataset.panel).hidden = false;  // muestra su panel
});
});
acordeon-y-tema.js
// ACORDEÓN: un botón con aria-expanded que muestra/oculta su contenido
boton.addEventListener("click", () => {
const abierto = boton.getAttribute("aria-expanded") === "true";
boton.setAttribute("aria-expanded", String(!abierto));
contenido.hidden = abierto;
});
// (o el nativo: <details><summary>Título</summary>...</details>, sin JS)

// DARK MODE persistente: la clase + localStorage (persistencia del módulo 7)
const guardado = localStorage.getItem("tema");        // "oscuro" o null
if (guardado === "oscuro") document.body.classList.add("oscuro");
toggle.addEventListener("click", () => {
const oscuro = document.body.classList.toggle("oscuro");
localStorage.setItem("tema", oscuro ? "oscuro" : "claro");   // recuerda la elección
});

Fíjate en el hilo común de las cuatro recetas: JavaScript cambia un estado (una clase o un aria), el CSS pinta, y la accesibilidad se sincroniza — exactamente la regla de oro de la lección 2, aplicada una y otra vez. Los patrones cambian; el principio no.

Tu modal se ve perfecto, pero un usuario que navega con teclado se queja: al abrirlo, sigue 'atrapado' navegando la página de atrás, y al cerrarlo no sabe dónde quedó. ¿Qué falta?

Mini-reto

Elige UNA receta y móntala en "El Observador" con accesibilidad completa: un modal de "suscríbete" (con foco y Escape), o pestañas para las secciones (Portada / Opinión / Deportes con aria-selected), o el dark mode persistente. Pruébalo SOLO con teclado, sin tocar el mouse: si puedes abrir, usar y cerrar todo con Tab, Enter y Escape, tu componente está a nivel profesional.

Qué sigue

Tienes el recetario completo. El reto del módulo los combina en una página real: scroll reveals que aparecen al bajar, un navbar inteligente que se transforma, y un modal accesible — los tres patrones que definen una landing moderna, integrados por ti. El examen de "darle vida al DOM".