Maquetación Web Dinámica / Responsive Design profesional
El menú hamburguesa: checkbox hack y la versión correcta
El menú hamburguesa (☰) es EL componente del responsive móvil — y también una lección de criterio: se puede hacer sin JavaScript con un truco ingenioso, y ENTENDERLO te enseña mucho CSS... pero la versión profesional lleva JS por razones de accesibilidad. Hoy aprendes ambas y por qué cada una existe.
El checkbox hack: CSS con memoria
CSS no tiene variables de estado ("menú abierto/cerrado")... pero un
checkbox SÍ recuerda si está marcado, y CSS puede leerlo con :checked y
el hermano general ~ (módulo 3, ¡los combinadores!):
<nav class="menu">
<input type="checkbox" id="toggle" class="toggle">
<label for="toggle" class="hamburguesa">☰ Menú</label>
<ul class="enlaces">
<li><a href="#">Inicio</a></li>
<li><a href="#">Cursos</a></li>
<li><a href="#">Contacto</a></li>
</ul>
</nav>body { font-family: system-ui; padding: 16px; }
.menu { background: white; border: 1px solid #e2e8f0; border-radius: 10px; padding: 12px 16px; max-width: 300px; }
.toggle { position: absolute; opacity: 0; pointer-events: none; }
.hamburguesa { cursor: pointer; font-weight: 700; color: #1e293b; user-select: none; }
.enlaces { list-style: none; margin: 0; padding: 0; max-height: 0; overflow: hidden; }
.toggle:checked ~ .enlaces { max-height: 200px; padding-top: 10px; }
.enlaces a { display: block; padding: 8px 4px; color: #475569; text-decoration: none; border-radius: 6px; }
.enlaces a:hover { background: #f1f5f9; }El mecanismo: el label con for marca/desmarca el checkbox invisible
(módulo 2 — la pareja label+input), y el selector :checked ~ enciende
los estilos del menú. Un bit de memoria + un selector = interactividad sin
JS. Ingenioso de verdad.
Por qué NO es la versión final
El hack funciona con mouse y tacto, pero suspende el examen de accesibilidad: un lector de pantalla anuncia "casilla de verificación, no marcada" (¿¡qué!?) en vez de "botón, menú, contraído"; no comunica el estado abierto/cerrado; y el manejo de teclado es errático. Para un usuario de tecnologías de asistencia, el menú simplemente no existe como menú.
La versión correcta: button + aria-expanded
<nav>
<button class="hamburguesa" aria-expanded="false" aria-controls="enlaces">
☰ <span class="sr-only">Menú</span>
</button>
<ul id="enlaces" class="enlaces">
<li><a href="#">Inicio</a></li>
<li><a href="#">Cursos</a></li>
</ul>
</nav>const boton = document.querySelector(".hamburguesa");
boton.addEventListener("click", () => {
const abierto = boton.getAttribute("aria-expanded") === "true";
boton.setAttribute("aria-expanded", String(!abierto));
});Cinco líneas de JS — tu primer JavaScript real del curso, y mira qué hace:
NO abre el menú; solo actualiza el ATRIBUTO. El CSS sigue haciendo el
trabajo visual, ahora leyendo [aria-expanded] (selector de atributo,
módulo 3). El button da teclado gratis (Enter/Espacio), y el lector de
pantalla anuncia "botón, Menú, expandido/contraído". Todos ganan.
¿Cuál es el problema de accesibilidad central del checkbox hack?
Mini-reto
Ponle a tu periódico el menú correcto: en móvil (base), hamburguesa con
button+aria; desde >= 768px, el menú horizontal de siempre (la
hamburguesa se oculta con display: none en la query). Ambas versiones
conviven en el mismo HTML.
Qué sigue
Tienes TODO el responsive: mentalidad, queries, contenedores, imágenes, fluidez, viewport y navegación. El proyecto del módulo lo junta: una landing completa de 5 secciones, mobile-first de verdad, construida desde 375px hasta 1440px.