Un menú responsive de navegación que en el celular se esconde tras un botón «Menú» y en pantallas anchas se muestra completo en la cabecera. Sin una línea de JavaScript: el botón abre el menú con el atributo popover de HTML, que ya sabe abrirse, cerrarse con Esc o al tocar fuera, y avisar al lector de pantalla.
También te puede interesar
El código
<header class="cabecera">
<a class="logo" href="#">mi sitio</a>
<button class="abrir" popovertarget="menu">Menú</button>
<nav id="menu" class="enlaces" popover aria-label="Principal">
<a href="#">Inicio</a>
<a href="#">Servicios</a>
<a href="#">Blog</a>
<a href="#">Contacto</a>
</nav>
</header>body { margin: 0; font-family: system-ui, sans-serif; }
.cabecera {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: #0f1f33;
}
.cabecera a { color: white; text-decoration: none; }
.logo { font-weight: 800; }
.abrir {
font: inherit;
color: white;
background: none;
padding: 6px 12px;
border: 1px solid #9aa7b4;
border-radius: 6px;
cursor: pointer;
}
/* Celular: el menú es un popover que se abre con el botón */
.enlaces:popover-open {
display: flex;
flex-direction: column;
gap: 4px;
margin: 56px 12px auto auto; /* arriba a la derecha, bajo el botón */
padding: 12px 16px;
border: 0;
border-radius: 10px;
background: #0f1f33;
box-shadow: 0 8px 24px rgb(0 0 0 / 0.3);
}
/* A partir de 48 rem: el botón sobra y el menú va siempre en la cabecera */
@media (min-width: 48rem) {
.abrir { display: none; }
.enlaces {
display: flex;
gap: 20px;
position: static;
margin: 0;
padding: 0;
border: 0;
background: none;
color: inherit;
width: auto;
height: auto;
overflow: visible;
}
}Pulsa «Menú» en el resultado, o ábrelo en el editor y prueba los botones de Celular y Todo el ancho. Lo comprobamos en los tres navegadores en dos anchos: con la ventana a 375 píxeles se ve el botón, los enlaces están escondidos y aparecen al pulsarlo; a 1,000 píxeles, el botón desaparece y los enlaces están siempre a la vista.
Cómo funciona
popoverconvierte elnaven una capa que el navegador esconde por omisión, ypopovertarget="menu"hace que el botón la abra y la cierre. El navegador se encarga de lo difícil: la muestra por encima de todo, la cierra con Esc o al tocar fuera y le dice al lector de pantalla si el menú está abierto o cerrado. Funciona en Chrome y Edge desde la 114, Firefox desde la 125 y Safari desde la 17.:popover-openes la pseudoclase del menú abierto: ahí se le da forma de panel en columna, arriba a la derecha.- A partir de 48 rem (768 píxeles con la letra normal), la media query esconde el botón y le quita al
navtodo lo que el navegador le pone por ser un popover (posición fija, borde, márgenes) para que quede en fila dentro de la cabecera. Las reglas de la página ganan a las del navegador, así que basta condisplay: flex.
Cada fragmento de HTML de esta página pasó por el Nu Html Checker 26.11.4 (el validador del W3C) y cada resultado se pintó y se midió en Chromium, Firefox y WebKit antes de publicarla. Prueba tus cambios en el editor de HTML y CSS o aprende desde cero con el curso.