En este pequeño tutorial vamos a ver cómo crear el típico menú lateral vertical desplegable. Seguro que lo has visto en mil sitios porque es muy útil, sobre todo cuando necesitas maquetar una web responsive que tiene un menú de primer nivel demasiado grande.
En principio, este menú permanece oculto y, al mostrarse, empuja al div
del contenido principal. Primero lo veremos usando JavaScript y luego solo con HTML y CSS. Que conste que hay muchas formas de hacerlo, estas dos solo son un par de ellas.
En este sencillo ejemplo (que puedes ver en directo aquí) tenemos simplemente dos divs. El que envuelve al menu (id="sidebar"
) y el del contenido principal.
Cuando el menú está abierto, el sidebar tiene un ancho fijo y está posicionado como fixed
, por si hay que hacer scroll en el contenido. Así que, al div del contenido le damos un margin-left
igual al ancho del sidebar.
La clave está en que, al hacer clic en "Abrir menu", hacemos 3 cosas a través de JavaScript:
- Al div lateral le asignamos un ancho fijo
- Al div del contenido le asignamos un margen por la izquierda igual al ancho de la columna lateral
- Ocultamos el link de "Abrir menú" y mostramos el de "Cerrar menú"
Las animaciones son CSS3, no hay JavaScript involucrado.
Y al hacer clic en cerrar, simplemente recorremos el camino inverso.
Este sería el html de los enlaces para abrir y cerrar:
<a id="abrir" class="abrir-cerrar" href="javascript:void(0)" onclick="mostrar()">
Abrir menu
</a>
<a id="cerrar" class="abrir-cerrar" href="javascript:void(0)" onclick="ocultar()">
Cerrar menu
</a>
Y estas las funciones de JavaScript que llamamos:
<script>
function mostrar() {
document.getElementById("sidebar").style.width = "300px";
document.getElementById("contenido").style.marginLeft = "300px";
document.getElementById("abrir").style.display = "none";
document.getElementById("cerrar").style.display = "inline";
}
function ocultar() {
document.getElementById("sidebar").style.width = "0";
document.getElementById("contenido").style.marginLeft = "0";
document.getElementById("abrir").style.display = "inline";
document.getElementById("cerrar").style.display = "none";
}
</script>
¿Y si pudiéramos hacer un menú muy parecido pero sin JavaScript?
Pues sí, se puede. El menú sin JavaScript se basa en lo mismo en lo que se refiere a las propiedades de los divs del menú y de los contenidos. Lo único que varía es la forma de controlar este comportamiento.
Descargo de responsabilidad y aviso a navegantes:
Lo que vamos a hacer con HTML y CSS en este ejemplo es una chapuza de proporciones bíblicas que se salta las buenas prácticas del marcado de HTML semántico y del desarrollo web front end en general. Es interesante hacerlo como ejercicio experimental para ser conscientes de que, conociendo bien CSS y echándole imaginación, se pueden hacer cosas muy interesantes, pero la capa de comportamiento se debería manejar siempre a través de JavaScript.
Bien, una vez dicho esto, ¿cómo controlaremos si el menú está abierto o cerrado? Pues usando un input
del tipo checkbox
, a través de la pseudoclase :checked
, que comprueba si el campo está marcado o no. En la práctica es como si almacenásemos un valor booleano en una variable de JavaScript, pero en CSS.
<input id="abrir-cerrar" name="abrir-cerrar" type="checkbox" value="" />
<label for="abrir-cerrar">
☰ <span class="abrir">Abrir</span><span class="cerrar">Cerrar</span>
</label>
El input lo ocultaremos con CSS, porque es suficiente con tener visible el placeholder para hacer clic sobre él:
input#abrir-cerrar { visibility:hidden; position: absolute; top: -9999px; }
Podríamos ocultarlo también con display:none;
pero recuerdo haber leído en algún lado (lo siento, no recuerdo dónde) que puede dar problemas en algunos móviles. Siendo sincero, nunca me he encontrado este caso pero más vale prevenir, así que lo he ocultado con visibility:hidden;
y luego lo posiciono en absoluto para llevármelo bien lejos, así no me molesta ocupando sitio al renderizar en el navegador.
Dentro del placeholder he colocado dos <span>
que me servirán para mostrar u ocultar la palabra "abrir" o "cerrar" a conveniencia.
Ahora, simplemente nos queda escribir los estilos en los que se mostrará el menú cuando el input
esté activo:
input#abrir-cerrar:checked ~ #sidebar {
width:300px;
}
input#abrir-cerrar:checked + label[for="abrir-cerrar"], input#abrir-cerrar:checked ~ #contenido {
margin-left:300px;
transition: margin-left .4s;
}
input#abrir-cerrar:checked + label[for="abrir-cerrar"] .cerrar {
display:inline;
}
input#abrir-cerrar:checked + label[for="abrir-cerrar"] .abrir {
display:none;
}
Si te estás preguntando qué hace el símbolo "~", pues bien, es un selector de CSS parecido a "+" pero con una sutil diferencia:
- El selector "+" selecciona el elemento que esté inmediatamente a continuación en el marcado html
- En cambio, el selector "~" selecciona el elemento que esté a continuación pero no es necesario que esté inmediatamente a continuación
Y esto es todo, ya tendríamos nuestro menú funcionando que puedes ver aquí. Por cierto, puedes descargarte los dos ejemplos juntos haciendo clic aquí (ZIP 6,7 KB).
¿A que es sencillo? Ahora ya sólo faltaría poner el resto del diseño de nuestra página a nuestro gusto, y quizá hacer algún ajuste menor del tamaño del menú para alguna resolución de móviles.
Pero eso ya te toca a ti. Pruébalo y me cuentas en los comentarios.
Fecha de publicación: