Menú vertical en acordeón con CSS y jquery

menu_acordeonA pesar del buen feedback recibido sobre mi serie de tutoriales de CodeIgniter, los artículos sobre menús animados con CSS y javascript siguen siendo los más populares en este sitio, y parece que son bastante útiles para la gente que está empezando. Por ello hoy me tomo un pequeño respiro de los videotutoriales y voy a enseñaros cómo hacer el clásico menú vertical en acordeón con CSS y jQuery.
El resultado lo puedes ver aquí: Ver demo

HTML

Para el html del menú vamos a emplear la estructura típica de listas anidadas. La última entrada será un enlace directo, sin submenú:

<ul id="menu">
<li><a href="#">Menu 1</a>
	<ul>
		<li><a href="#">Submenu 1</a></li>
		<li><a href="#">Submenu 2</a></li>
		<li><a href="#">Submenu 3</a></li>
		<li><a href="#">Submenu 4</a></li>
	</ul>
</li>
<li><a href="#">Menu 2</a>
	<ul>
		<li><a href="#">Submenu 1</a></li>
		<li><a href="#">Submenu 2</a></li>
		<li><a href="#">Submenu 3</a></li>
		<li><a href="#">Submenu 4</a></li>
	</ul>
</li>
<li><a href="#">Menu 3</a>
	<ul>
		<li><a href="#">Submenu 1</a></li>
		<li><a href="#">Submenu 2</a></li>
		<li><a href="#">Submenu 3</a></li>
		<li><a href="#">Submenu 4</a></li>
	</ul>
</li>
<li><a href="#">Menu sin submenu</a></li>
</ul>

Añadiendo el CSS

Para dar estilo al menú tenemos primero que quitar los estilos por defecto de las listas, eliminar los bullets y márgenes y añadirle display:block para que queden perfectamente alineados los elementos uno debajo de otro. Después tenemos que ocultar con display:none los submenús para que aparezcan todos colapsados por defecto. Vamos a añadir algunas extensiones de CSS3 para mejorar visualmente nuestro menú. Estás extensiones sólo serán visibles en navegadores modernos (Firefox, Chrome y Safari), pero no en Internet Explorer. De esta manera podemos añadir bordes redondeados y sombras al menú y al texto. La propiedad -webkit-transition solo funciona en navegadores basados en webkit (Safari y Chrome), y la utilizaremos para mejor el hover añadiendo un fundido en el color del texto y el background. En los navegadores que no soporten estas propiedades simplemente veremos el menú con esquinas normales, hover típico on-off de CSS y sin sombras.

#menu{
	-moz-border-radius:5px;
	-webkit-border-radius:5px;
	border-radius:5px;
	-webkit-box-shadow:1px 1px 3px #888;
	-moz-box-shadow:1px 1px 3px #888;
}
#menu li{border-bottom:1px solid #FFF;}
#menu ul li, #menu li:last-child{border:none}	
a{
	display:block;
	color:#FFF;
	text-decoration:none;
	font-family:'Helvetica', Arial, sans-serif;
	font-size:13px;
	padding:3px 5px;
	text-shadow:1px 1px 1px #325179;
}
#menu a:hover{
	color:#F9B855;
	-webkit-transition: color 0.2s linear;
}
#menu ul a{background-color:#6594D1;}
#menu ul a:hover{
	background-color:#FFF;
	color:#2961A9;
	text-shadow:none;
	-webkit-transition: color, background-color 0.2s linear;
}
ul{
	display:block;
	background-color:#2961A9;
	margin:0;
	padding:0;
	width:130px;
	list-style:none;
}
#menu ul{background-color:#6594D1;}
#menu li ul {display:none;}

Añadiendo la funcionalidad con jQuery

Ahora vamos a ver lo sencillo que es hacer funcionar nuestro menú vertical. Primero añadimos el evento click a cada enlace del menú. Después comprobamos si el siguiente elemento tras el enlace es un ul, ya que si es así este contendrá un submenú, si no será un elemento de un submenú o bien un elemento principal que no contiene submenú (en nuestro ejemplo, el último enlace). Si contiene un submenú, al hacer click este se expandirá o colapsará (slideToggle()), a la vez que colapsaremos el submenú que esté visible que no sea el actual. La función event.preventDefault() sirve para evitar que cuando hagamos click el navegador siga el enlace del href tras ejecutar nuestra función javascript.

<script type="text/javascript" charset="utf-8">
$(function(){
	$('#menu li a').click(function(event){
		var elem = $(this).next();
		if(elem.is('ul')){
			event.preventDefault();
			$('#menu ul:visible').not(elem).slideUp();
			elem.slideToggle();
		}
	});
});
</script>

Podéis escribir en los comentarios cualquier duda que tengáis e intentaré responderla, así como sugerencias para próximos tutoriales.

Actualización: Ante la cantidad de peticiones de cómo hacer que el menú sea multinivel, decidí convertirlo en un plugin de jQuery y hacer un pequeño tutorial con screencast incluido: Cómo hacer un plugin jQuery – Menú acordeón multinivel

Compartir:

Enlaces

177 comentarios para “Menú vertical en acordeón con CSS y jquery”

  1. fdfpdsf dice:

    Donde puedo consegir el codigo del enlace del script , esque cuando no estoy conectado a internet no funciona, necesito este script…..

    donde lo puedo descargar

  2. V. Mejía dice:

    muchas gracias… fácil de manipular y simple de entender…

  3. Jose Luis dice:

    Muy bueno !!!!

  4. carlos dice:

    Hola, me ha gustado tu menu, pero me gustaría saber si sabrías indicarme como hacer para que cuando piques en el segundo botón que se despliega, el que pone menu dos, se cierre el primer botón del desplegable el que se llama menu uno

  5. Mikel dice:

    Hola,

    muy bueno!!! lo unico que no entiendo… (tambien si me funciona bien) ¿cual es la funcion javascript que al clicar una pestaña, antes de abrirse el submenu, vuelve a subir el submenu ya abierto?

  6. Iñaki dice:

    Muy buen script, tan sólo comentar que en el ejemplo se os ha olvidado comentar que en los tiene que aparecer la url de GOogle:

  7. mario dice:

    necesito que tenga un siguiente nivel de submenú… excelente menú

  8. miguelUnefa dice:

    hola hermano, epale como hago para que funcione sin internet? trate de descargar el archivo jquery.min.js desde http://jqueryui.com/download pero no encontre el archivo.Gracias.

  9. Uthanien dice:

    Hola!

    El menu esta genial, pero tengo problemas al integrarlo en otros lados, porque los “ul” y “a” no son únicos dentro del menu, por lo que entra en conflicto con los otros estilos.

    Hay forma de dejar ese estilo 100% para este menu, y evitar otros conflictos???

    saludos!!

  10. daniel dice:

    Hola David, gracias por tus aportes, esta muy sencillo y facil de entender…mira, tengo una duda y he estado buscado la rpta. en muchos lados, ahi va:
    ¿Como hago para que, al momento de hacer click en un submenu, este quede seleccionado? Es decir que no se cierre automaticamente el acordeon sino quede abierto en la pagina actual? Espero entiendas mi pregunta, gracias por todo!!!

  11. samuel dice:

    Daniel lo que debes hacer es quitar del css la línea de display:none y luego, en la página poner una condición if (sea que uses php, asp o javascript) para que reconozca que si está en la página le agregue esa linea de display:none a la etiqueta que deseas.

    Buen aporte, gracias!

  12. Raúl dice:

    Muy buen aporte David.
    Saludos desde Bs. As.Argentina.

    Por cierto:
    A los que no les funciona sin estar conectados a internet les digo…
    NO sean flojos y lean el codigo fuente del demo y sedaran cuenta que es tan simple como abrir el archivo jquery.min.js y guardarlo con extención .js en el directorio que quieran de su web o localhost. Luego modifican la URL en el head del HTML y listo.
    ¿Saben que hay que incluir el framework jQuery verdad?

    Si solo copian y pegan no aprenderán nada!

  13. Pedro dice:

    Hola.

    Tu menú me parece una pasada, simple y directo. Mi problema es que estoy empezando con el tema de javascript y jquery y todavía ando un poco perdido.

    me gustaría saber que tendría que modificar del código para que cuando hago clic sobre el menú sin submenú (el último de la lista) se cierre el menú desplegado con anterioridad. Es decir que si el menú dos estaba abierto y hago clic sobre el menú sin submenú el menú 2 se cierre.

    Espero que puedas echarme un cable. Gracias.

  14. Hermoso! me salvó de una…

  15. Yesenia Fuentes dice:

    David excelente ejemplo para un menu vertical con jquery. Me funciono enseguida. Ahora estoy tratando de que cuando se haga clic en un submenu y se actualice una pagina al lado me quede abierto y seleccionado el mismo submenu para que el usuario sepa donde esta ubicado (es decir que no se contraiga el submenu). No le he agarrado la onda todavia a lo que dice samuel de quitar el estilo display:none y colocarlo en cada pagina. Si alguien me puede dar una idea con un ejemplo. Tengan Muy Buen dia!

  16. sega dice:

    Mira, hola! lo que pasa es que tengo la misma duda de Daniel o por lo menos es lo que pienso, que al hacer click en un submenú y se actualize la pagina para cargar otra, no se me ‘reinicie’ el estado del MENÚ ACORDEON…… tu le explicaste pero no te entiendo. si me hicieras el favor de hacer un ejemplo y me publicaras la pagina te estaria muy agradecido….. mmm y de paso si huebiera una forma de señalar el menú en el cual esta situado o ubicación….
    GRACIAS DE ANTEMANO y espero tu pronto respuesta….

  17. Andres dice:

    Hola Daniel ya sé como eliminar Display:none; del CSS pero no se como agregar la Condición en PHP le agradeceria mucho si nos explicará como se hace

  18. tere dice:

    hola yo tengo un acordion pero quisiera reiniciar su estado,saben como seria??

  19. Neko dice:

    MUCHÍSIMAS GRACIAS!! no sabes cómo fue de ayuda este tutorial… gracias a ésto pude salir de un apuro. En verdad GRACIAS

  20. arcanisgk dice:

    me gustaría ver si esto se puede hacer pero utilizando clases en ves de ID…

  21. Irmo dice:

    Hola buenos dias,coloque el proyecto en vb 2010 y no me habre los submenu, que puedo hacer para que me funcione bien?

  22. Dulce dice:

    Hola! miro que en tu demo si funciona el despligue con los submenu a mi no me funciona el jquery en mi pagina

  23. Dulce dice:

    Hola soy yo, otra vez…
    Mi pregunta es la siguiente:
    Al hacer clic en una opcion, cuando se despliega hacia abajo, quiero meter un submenu en una de las opciones del submenu que ya se despliega, solo que no he conseguido hacerlo.

    Espero y puedan hecharme una mano y que me hayan entendido xD

    Saludos…

  24. DA dice:

    Hola una consulta, me gustaría saber como hago para hacer un submenu del submenu porque intento hacerlo y no me sale.

    espero puedan ayudarme .. saludos

  25. Geojoo dice:

    Muy buena pagina, gracias

  26. Hillel dice:

    Gracis por el ejemplo. Pero hay que hacerlo compatible con Internet Explorer tambien, no?
    Aun tengo clientes que usan esa cosa.

  27. Marcelo Ulloa Lagos dice:

    Buenísimo, muchas gracias.

Deja un comentario

Introduce tu información personal en el formulario, regístrate o identifícate usando twitter con el siguiente botón.

Time limit is exhausted. Please reload the CAPTCHA.

RSS iTunes podcast Twitter

Categorías

Enlaces

Archivos