Cómo hacer un menú vertical desplegable con HTML y CSS (con y sin JavaScript)
Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

Cómo hacer un menú vertical desplegable con HTML y CSS (con y sin JavaScript)

Menu vertical desplecagble con HTML5 y CSS3 (con y sin JavaScript)

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. De entrada, el 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 checkboxa 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">
        &#9776; <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.

Pablo Iglesias Pablo Iglesias es diseñador y responsable de Marketing en campusMVP. Cuenta la leyenda que, anidando listas HTML en busca de la página semánticamente perfecta, provocó un agujero espacio-temporal en IE tan grande, que en Redmond tuvieron que llamar al comando SG1 de Stargate para evitar una invasión alienígena. Puedes seguirlo en twitter ( @piglesias). Ver todos los posts de Pablo Iglesias

No te pierdas ningún post

Únete gratis a nuestro canal en Telegram y te avisaremos en el momento en el que publiquemos uno nuevo.

Archivado en: Desarrollo Web | Trucos

Comentarios (3) -

hey amigo, si bien el codigo no es el mejor me ayudaste a entender como hacer esa transición, gracias, en verdad te lo agradezco

Responder

Pablo Iglesias
Pablo Iglesias

Muchas gracias Christian :-)

Responder

Jorge Durán
Jorge Durán

Me ayudo bastante el código. El único problema que tengo, es que cuando hago scroll hacia abajo y uso el menú, la página se sube y no se queda donde se quedó.

Responder

Agregar comentario