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

Enlaces

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

  1. Lucas dice:

    Ya lo logré! jejeje

    no si es la solucion optima pero paso a comentarles como lo hice por si a alguien le sirve:

    1) puse id=»primero» en el elemento q quiero desplegar
    2) en el document ready agregue esta linea:
    $(‘#primero’).slideDown();

    3) listo!

    Saludos!

  2. Junior dice:

    Muy bueno man justo lo que buscaba se le agradece mucho 😉

  3. Renee dice:

    Gracias hermanito esto era justamente lo que queria aplicar a mi web… thanks. Apenas estoy empezando con esto de lo css. Sigue publicando más

  4. anRoswell dice:

    amigo excelente te agradesco mucho justo lo q estaba buscando, q tal si el submenu permitiera otro submenu, osea otro nivel????

  5. BAdutllak dice:

    Gracias por el tutorial esta putamente currado, y funciona eexceeleente, pero seria posible añadir un subitem al submenu??y de ser asi como se hace?? porque he probado mil historias y no logro que funcione bien (soy un novato), gracias de antemano y sigue publicando que a la gente como yo le van de p*ta madre estos tutoriales!!

  6. David Rojas dice:

    @BAdutlak y @anRoswell Esta pregunta me la hacen mucho, así que aproveché para hacer convertirlo en un plugin de jquery y hacer un screencast:
    http://www.davidrojas.net/index.php/jquery/screencast-como-hacer-un-plugin-jquery-menu-acordeon-multinivel/

  7. Melisa dice:

    Hola, sabes tu codigo me funciona muy bien pero cuando lo quiero poner dentro de mi página, no me carga estoy trabajando con div y ajax.

  8. Alvaro dice:

    David muy buena la web y los articulos.

    Pregunta: como se hace para elegir como submenu abierto por defecto uno del ultimo nivel, le pongo el ul id=»open» pero no lo toma en el ultimo escalon de submenus. y aparte como se puede hacer para que cargue todo cerrado el acordeon y despues se despliegue solo?

    gracias sos un capo

  9. Alejandro dice:

    Muchisimas gracias por el aporte, lo he puesto en funcionamiento y me ha ahorrado un tiempo valioso

  10. David Rojas dice:

    @Alvaro Para que se abra por defecto en el último escalón habría que modificar el script, por ejemplo en esta parte:

    if(settings.startingOpen){
    $(settings.startingOpen).show();
    }

    habría que decirle que ademas de mostrar el div con id startingOpen, mostrara su padre que está oculto. Sobre lo de que cargue todo cerrado y después se despliegue no sé a que te refieres, supongo a que se despliegue en tiempo de carga. Esto lo puedes hacer manualmente con jQuery colocando un script al final de la página (para asegurarte que se ha cargado), pero no lo veo demasiado útil.

    @Melisa Si no me das más detalles que «no me carga» me temo que no puedo hacer nada. ¿Has mirado qué error te da con Firebug?

  11. Emmanuel dice:

    Hola, este menu es justo lo que buscaba!! es muy bueno!

    Te comento que soy muy nuevo por lo que tuve un problema al cargarlo en mi página. Yo coloqué todas las partes en los lugares que especificas y la parte del HTML la puse dentro del div de menu. El problema es que al hacer click en, por ejemplo menu2 en ves de deplegarse el submenu se pierde el div completo.

    Desde ya, muchas gracias

  12. Jose Tabeayo dice:

    David… una pregunta… en la empresa donde trabajo… estoy intentando implementar estos menus para una intranet que se esta creando… pero por mas que lo intento en la parte coorporativa no me funciona… ¿Porque puede ser? ¿Alguna restriccion interna de la empresa?

  13. David Rojas dice:

    @Jose Te he contestado al comentario en el otro post 🙂

  14. Alvaro dice:

    Costo pero puse con eso de los subsubmenu desplegados al inicio.

    Gracias David!!

  15. Silvi dice:

    muy chulo… y como estoy un poco pez con javascript pregunto. Si quiero que el menu quede desplegado donde lo hubiera desplegado al navegar (no se si me explico) como hago? En php crearia una cookie donde almacenaria que menu esta abierto para cargarlo asi, pero como digo, en js estoy pez total… gracias 🙂

  16. David Rojas dice:

    @Silvi Para qué necesitas una cookie? Si lo que quieres es que se despliegue cada sección según en la página que estés navegando, lo que tienes es con php añadir una clase a ese submenú con un echo, y en el CSS poner que esa clase sea visible (o más sencillo, imprimir un style=»display:block» en ese elemento).

  17. RG dice:

    Hola, muy bueno este script.
    Tengo una pregunta: ¿es posible que al hacer click en la opción el menú quede desplegado?. Supongo que se hará con una clase o algo así, estoy haciendo mi primera página en php y aún no lo manejo tan bien. ¿Alguna ayuda?
    ¡Gracias por todo!

  18. Raul dice:

    Buenas.
    Aqui con un problema, implemente un menu jQuery dentro de mi aplicación y todo salio bien, el problema es que el CSS de los ul li solo lo hace la primera vez que se pasa sobre ellos, la segunda vez no toma en cuenta el menu_hover y aunque conservan su funcionalidad no los cambia de color ni abre sus submenus hasta que se le da click sobre ellos, alguien sabe cual puede ser la solución…?

  19. David Rojas dice:

    @RG Revisa los comentarios de este artículo, más gente ha preguntado lo mismo o algo parecido. Tendrías que usar PHP para leer una cookie que habrías guardado con javascript al hacer click (sí necesitas una cookie, @Silvi, entendí mal tu pregunta).

  20. Fran dice:

    Gracias David, muy buen script.. lo estaba buscando… y lo he implementado en un sitio web que estoy creando… he reemplazado un link principal del menu por una imagen y va bien tb… lo que me gustaría saber es como puedo lograr que esta imagen cambie… o sea: imagen1 cuando esta expandido o desplegado e imagen2 cuando esta cerrado… asi puedo crear una especie de efecto Toggle On/Off… no se si soy claro.. y muchas gracias… 🙂

  21. Jose dice:

    Misma pregunta que Fran … hay alguna manera de hacer eso? Felicitaciones por el script, muy bueno.

  22. Marcelo dice:

    Hola, mi consulta es si puedo dejar seleccionada la opcion que elegi del menu,asi puedo saber mediante el menu en que pagina me encuentro, y gracias por el menu me funciona sin problemas

  23. Silvi dice:

    pues tambien es verdad… a veces como me complico la vida! 😀

  24. kekoso dice:

    Y el codigo Fuente???

  25. David Rojas dice:

    @kekoso No tienes mas que cargar la demo y hacer botón derecho -> ver código fuente. De todas formas está todo el código importante pegado y explicado en el artículo.

  26. pato dice:

    Muchisimas gracias!!Justo lo que necesitaba. Funciona perfecto. Un saludo, pato

  27. Valdehornos dice:

    Me parece un gran aporte, muchas gracias. Mi pregunta es: Si yo implanto el mismo menú en bastantes páginas de mi sitio web, a la hora de actualizar los contenidos o items del mismo, tendría que editar todas ellas ¿no? Existe alguna manera de que el contenido del menú lo tome de un fichero externo? De esa forma, actualizando ese fichero, el contenido se actualizaría en todas las páginas. Muchas gracias de nuevo.

  28. Vcnt dice:

    Hola! El menu me funciona perfectamente, pero me deja de funcionar la funcion cufón, y es por jquery, se habia dado este problema?

  29. David Rojas dice:

    @Vcnt No utilizo cufón, así que no sé decirte. Para empotrar fuentes de todas formas te recomiendo que le eches un vistazo a esto, a mi gusto bastante mejor que usar cufón: http://www.davidrojas.net/index.php/diseno-web/fuentes-en-la-web-con-font-face/

  30. David dice:

    Gracias x enseñarnos como hacer el tipico menu, muchas gracias x tomarte tu tiempo.

  31. Hola david, gracias por tus aportes. el menu funciona perfectamente. quisiera pedirte por favor, me ayudes con lo siguiente, quisiera que cuando el menu se despliega, no desplace hacia abajo, los demas contenidos de mi pagina web. muchas gracias por tu interes en mis inquietudes

  32. Hola david, gracias por tus aportes, el menu funciona perfecto, pero quisiera que al desplegar el menu, el contenido de la pagina no se desplegara hacia abajo, puedes checar esto en el siguiente link: http://danielantioquia.info/sitios/multigym/aliados/aliados_principal_html.php

    Gracias por tu ayuda

  33. joan dice:

    tengo un problema, cuando cargo la pagina de prueba para ver si me funciona el menú al hacer clic en cualquiera de los menús no despliega ninguno no se por que ?? ayuda por favor, lo estoy trabajando en visual studio 2008

  34. David Rojas dice:

    @joan ¿Has mirado si te da algún error en Firebug?

  35. Mariana dice:

    Hola! Gracias por compartir el menú, està muy bueno!!!
    pero tengo un problema (y soy extremadamente nueva en esto) necesito poner 2 menús en mi pàgina pero no puedo porque parece q se mezclan los estilos cuando pongo el segundo, los 2 funcionan muy bien por separado, pero juntos no. Muchas gracias de antemano, saludos!

  36. Monica dice:

    HOla, soy nueva en esto y quiero hacer un menu desplegable, todo sale bien hasta que hago el añado el css, pero cuando trato de añadir el jquery, no me funciona el menu. Yo lo he incluido en el codigo Html en head. No se si lo estoy haciendo bien, o que otra cosa deberia hacer para que me funcione.

  37. tito dice:

    no olvidéis poner en el head:

    sino no funciona

  38. Bfam dice:

    Una pregunta, como se puede hacer para hacer mas ancho el menu? ya que si pones nombres de submenu o menus mas largos, te hace salto de linea, y otra cosa, para hacer que los nombres del submenu salgan alineados a la izquierda, se podria haceR? tal y cm pasa en el acordeaon multimenu, asiasssssssssssssss

  39. Bfam dice:

    Otra pregunta, y se puede hacer, que cuando desplegas un submenu, que la palabra del submenu que as desplegado quede por ejemplo de otro color?

    asiasssssssssssss

  40. Leandro dice:

    Hola hace ya un tiempo que instalé este menú en mi web y funciona correctamente, lo que estoy necesitando si alguien sabe es hacer que funcione el boton que despliega el menú. Es decir que este botón en lugar de solo desplegar el menú también abra una página. (si ven mi web para eliminar los links que dicen introduccion).
    He probado de varias maneras pero no lo he logrado.

  41. Richard dice:

    Excelente aporte muchas gracias

  42. Richard dice:

    Hola, tengo un problema, el menu no me funciona con IE5.5 ni con IE9, hay algo que se deba modificar?.
    Saludos cordiales

  43. emiliano dice:

    hola david, hace dias que venia probando el codigo del menu y finalmente luego de ver el codigo fuente del demo pude hacerlo funcionar.
    lo unico malo es que me desconfiguro ciertas cosas, por ejemplo la hora de posteo en las entradas me la subio mas arriba, los iconos de compartir estan medio desfigurados, y unos links que tenia en otro gadget de entradas mas visitadas me los encuadro de color azul tal cual al formato de este menu acordeon, como puedo corregir eso y que funciones todo normalmente,
    desde ya muchas gracias por la atencion y estaré a la espera de una respuesta.
    +saludos !

  44. Tony dice:

    Excelente Menú.
    Por favor, una pregunta. Como podría tener este mismo menú pero de forma horizontal ?.
    Ya he aplicado uno de forma vertical, pero desarrollo una intranet y necesito los dos.
    Muchas Gracias.

  45. jhon dice:

    hola, implemente el codigo aqui descrito en mi web, lo modifique pero las paginas que no tienen subpaginas no las lleva al mainframe, en cambio las otras si, pueden ver el sitio , como corrijo ese problema?

    un eje, Nosotros la pagina de «quienes» deberia aparecer en el marco principal y al dar clic abre otra ventana, como lo corrijo, por fa gracias..

  46. Fernando dice:

    Hola. Lo primero felicitarle por este magnìfico aporte y que a mì personalmente me esta sirviendo en la renovaciòn de mi web pues buscaba algo asì pues yo no tengo ni idea de programaciòn y le agradezco enormemente este aporte.
    Por otro lado decirle que funciona perfectamente en Crhome y firefox, pero en explorer de windows 7 aunque abre bien el menù, los enlaces al clicarlos no redirigen y no se por que. Decirle que estoy haciendo la nueva web con dos marcos, uno donde va el menu, siempre presente y el otro, el principal donde deben ir saliendo el resto de paginas segun se cliquee en el menù, y esto es lo que no funciona en explorer de windows 7. La version del explorer instalado en mi pc es la 9. Le ruego si es tan amable me ayude a solucionarlo con el fin de que mi web pueda ser visualizada desde cualquier navegador y poder dejar este magnìfico menù ofrecido por usted.
    Un saludo y mi agradecimiento de antemano.
    Fernando Muñoz

  47. Alejandro dice:

    Magnifico aporte,, agradecido me funciona ala perfeccion, eso si con ganas de hacer algunas modificaciones,, eso si soy neofito en este tema no he podido usar imagenes como botones,, tanto para los botones principales como para los submenu,, se podrá??,, muchas gracias

  48. jose dice:

    Excelente menu me servira mucho , gracias por ayudarme con este script, sigue asi

Deja un comentario

Time limit is exhausted. Please reload the CAPTCHA.

RSS iTunes podcast Twitter

Categorías

Enlaces

Archivos