En este tutorial aprenderemos a crear nuestro propio menú desplegable basado en jQuery. Lo haremos partiendo de cero y explicándolo como siempre paso a paso, de forma que todos podamos comprender cómo plantear el problema y buscar una solución sencilla y efectiva.

Autor:

Hola! Soy diseñador, programador web y cofundador de la startup Cokidoo, desarrollamos aplicaciones web a gran escala y comercio electrónico, aplicaciones para móviles y advertising. Puedes seguirme através de mi twitter y ver algunos de mis themes en Themeforest. También soy aficionado a la fotografía.
Descarga Demostración

Introducción: ¿Qué vamos a hacer?

Retomamos los tutoriales relacionados con javascript y jQuery de la mano de este control en forma de menú desplegable.

Al contrario que otros controles de este tipo, para desplegar este control, el usuario sólo tendrá que pasar el ratón por encima, en lugar de hacer click. Este será el aspecto final del control a crear:

Vista previa

La idea es que las distintas opciones sean mostradas en formato lista (<ul>), de forma que cada elemento de la lista sea un enlace que te traslade a una nueva sección en la que aparezca marcada la nueva opción seleccionada.

El control no necesitará hacer el cambio entre sección actualmente activa y la seleccionada, ya que eso se controlaría a la hora de generar la salida html en la lógica de programación (PHP, Java, Python… o lo que quiera que uséis).

Actualización: Por cierto… veo que algunas personas no lo han entendido bien: estamos imprimiendo una salida HTML limpia, por tanto los robots y rastreadores de Google y derivados, podrán indexar y seguir perfectamente todas esas opciones de nuestro menú.

¡Vamos a por el primer paso del tutorial!

Paso 1: La estructura HTML

Como acostumbramos a realizar en nuestros tutoriales, mantendremos una estructura sencilla, intentando que sea vistosa pero sobretodo clara a la hora de comprender qué estamos haciendo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="es-ES">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Cómo crear un menú de pestañas elegante en jQuery</title>
    <link rel="stylesheet" href="css/main.css" type="text/css" media="screen" />
</head>
<body>
    <div class="wrapper">
        <h1>Creando un menú desplegable en jQuery</h1>
        <ul class="dropdown">
			<li class="active">Visualizando: <span>Tutoriales</span></li>
			<li class="first"><a href="#">Recursos</a></li>
			<li><a href="#">Inspiración</a></li>
			<li><a href="#">Contacto</a></li>
			<li class="last"><a href="#">Ver más...</a></li>
		</ul>
    </div>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="main.js"></script>
</body>
</html>

Esto es lo que deberíamos tener actualmente:

Vista previa paso 1

Básicamente lo único relevante de este paso es comprender que estamos aplicando la clase de CSS “dropdown” a nuestra lista, con la que estaremos advirtiendo a nuestro futuro código javascript que será un control del tipo desplegable.

Vamos pues a darle un poco de estilo al ejemplo antes de ponernos con la lógica en javascript…

Paso 2: Aplicando estilo con CSS a nuestro menú desplegable

En este caso, el código CSS es muy básico y se centra principalmente en el aspecto visual del control de menú desplegable que estamos creando:

@CHARSET "UTF-8";
/*
Author: Adrian Mato
Author URI: http://web.ontuts.com
*/

/******* GENERAL RESET *******/
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td {
    border:0pt none;
    font-family:inherit;
    font-size:100%;
    font-style:inherit;
    font-weight:inherit;
    margin:0pt;
    padding:0pt;
    vertical-align:baseline;
}
body{
    line-height: 1em;
    font-size: 14px;
    font-family: Arial, Helvetica, sans-serif;
    margin: 0pt;
    cursor: default;
    color: #fff;    
    background: #262626 url("bg.png") repeat scroll 0 0;
}
table{
    border-collapse: separate;
    border-spacing: 0pt;
}
strong{
    font-weight: 700;
}
caption, th, td{
    font-weight:normal;
    text-align:left;
}
blockquote:before, blockquote:after, q:before, q:after{
    content:"";
}
blockquote, q{
    quotes:"" "";
}
pre{
    font-family: Arial, Helvetica, sans-serif;
}
input{
    border: 0;
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
}
textarea{
    font-family: Arial, Helvetica, sans-serif;
    color: #888888;
    padding: 7px 3px 0 4px;
    font-size: 11px;
}
select{
    font-size: 11px;
    color: #888888;
    background: #fff;
    font-family: Arial, Helvetica, sans-serif;
    border: 1px solid #CAD2CE;
}
ul{
    list-style: none;
    list-style-type: none;
    list-style-position: outside;
}
a{
    cursor: pointer;
    color: #ece6bd;
    text-decoration: underline;
    outline: none !Important;
}
html,body{
    height:100%;
}
.clear{
    clear: both;
    height: 0;
    visibility: hidden;
    display: block;
    line-height: 0;
}
.clearfix{
    overflow: hidden;
}
.italic{
    font-style: italic;
}
/******* /GENERAL RESET *******/

/******* GENERAL *******/
h1{
    color: #fff;
    font-size: 26px;
    line-height: 3em;
}
h2{
    line-height: 2em;
    margin-top: 30px;
    margin-bottom: 20px;
    color: #e4e1cd;
}
.wrapper{
    width: 982px;
    margin: 0pt auto;
    padding-top: 10px;
}
/******* /GENERAL *******/

/******* CONTENT *******/
h3{
    line-height:1em;
    vertical-align:middle;
    height:48px;
    padding:10px 10px 10px 52px;
    font-size:32px;
    color:#E4E1CD;
}
/******* /CONTENT *******/

/******* MENU *******/
ul.dropdown{
	width: 200px;
	border: 1px solid #000;
	border-radius: 5px;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	background: #1a1a1a;
	margin-top: 2em;
}
ul.dropdown li{
	display: none;
	font-size: 12px;
}
ul.dropdown li.active{
	display: block;
	color: #8c8c8c;
	font-size: 14px;
	padding: 12px;
	color: #555;
	border-top: 1px solid #313131;
	border-radius: 4px;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
}
ul.dropdown li.active span{
	background: transparent url("dropdown.png") no-repeat scroll right center;
	padding-right: 24px;
	color: #8c8c8c;
}
ul.dropdown li a{
	display: block;
	text-decoration: none;
	padding: 8px 8px 8px 10px;
	background: #1e1e1e;
	border-bottom: 1px solid #171717;
}
ul.dropdown li.last a{
	border:0;
}
ul.dropdown li.first a{
	border-top: 3px solid #131313;
}
ul.dropdown li a:hover{
	background: #232323;
	color: #fff;
	padding-left: 11px;
}
/******* /MENU *******/

La clase dropdown será con la que identificaremos el control y sobre la cual aplicaremos el resto de propiedades a los distintos elementos.

Así pues todos los elementos de la lista compartirán estilo excepto la clase active la cual aparecerá siempre en el primer puesto de la lista, y será la que identifique el elemento actualmente seleccionado / activo.

Este es el aspecto que presentará ahora nuestro control:

Vista previa paso 2

Como habréis podido comprobar, ahora no se están mostrando los elementos de la lista, salvo el elemento activo. Sólo necesitamos crear la lógica para que se muestren / oculten a nuestro antojo via javascript…

¡Vamos a ello!

Paso 3: Añadiendo interacción con javascript mediante jQuery

Repasemos qué es lo que queremos de nuestro control en forma de menú despegable antes de aplicar la interacción:

  • Mostrar opciones al pasar el ratón por encima.
  • Ocultar opciones al mover el ratón de encima.
  • Reutilizable para tener múltiples controles en una misma página.

Con esto en mente, necesitaremos identificar (mediante selectores de jQuery) los elementos de clase “dropdown” para reconocerlos como controles de menú desplegable.

Antes de explicar la parte de los eventos, echemos un vistazo al código final:

//variable global para controles dropdown
var menu = $("ul.dropdown");

//control de eventos
$(this.document).ready(function(){
	menu.mouseover(function(){
		displayOptions($(this).find("li"));
	});
	menu.mouseout(function(){
		hideOptions($(this));
	});	
})

//funcion que MUESTRA todos los elementos del menu
function displayOptions(e){
	e.show();
}
//funcion que OCULTA los elementos del menu
function hideOptions(e){
	e.find("li").hide();
	e.find("li.active").show();
}

El código como podéis comprobar es relativamente sencillo, y en el podemos ver la asignación de los eventos “al pasar por encima” y “al quitar el ratón de encima”, los cuales llaman a las funciones:

  • displayOptions(): Muestra todos los elementos de la lista inicialmente ocultos al pasar el ratón por encima.
  • hideOptions(): Oculta todos los elementos de la lista, y luego vuelve a mostrar el elemento activo.

La razón por la que mostramos nuevamente el elemento activo es porque el selector de jQuery que estamos empleando está ocultando todos los elementos de la lista, entre los que se incluye el activo, pero deseamos que se mantenga visible.

Antes de dar por finalizado el tutorial, me gustaría resaltar otro detalle del código anterior: la función find(), mediante la cual localizamos los elementos del control que está recibiendo los eventos.

Siempre que programes controles reutilizables, trata de trabajar con referencias al objeto activo, de esta forma podrás reutilizarlos o crear plugins de forma realmente sencilla.

Podríamos estar utilizando selectores de jQuery genéricos pero recordad: queremos que nuestro control pueda aparecer en más de una ocasión en una misma página, por tanto trabajamos con referencias al objeto activo, en lugar de a todos los objetos que contengan la clase de CSS dropdown.

Con todo ello, generar un plugin apartir de este planteamiento sería realmente trivial. Si bien no lo hemos hecho en este tutorial, sí que hemos explicado anteriormente cómo crear plugins en jQuery, echadle un vistazo que es realmente útil.

Reflexión final

Una vez más vuelvo a insistir en lo de siempre: con un poco de curiosidad y ganas por profundizar en lo que nos interesa podemos -en este caso- crear controles dinámicos en javascript de forma realmente sencilla.

Lo más importante es tener claro qué es lo que queremos que haga nuestro control (sus eventos, etc…) y luego buscar la mejor solución posible a cada uno de esos requisitos ya sea con jQuery u otras librerías javascript que manejemos.

Espero que os haya resultado útil y… ¡Nos vemos en el próximo artículo!

¿Necesitas desarrollar un proyecto web o para móviles? ¡Estamos disponibles!

Visitar Cokidoo

Cokidoo, los creadores de Ontuts, desarrollamos proyectos tecnológicos centrados en redes sociales y aplicaciones web, aplicaciones móviles y consultoría web y bases de datos.

Somos jóvenes, inquietos, versátiles, apasionados por la innovación y enfocados en las nuevas tecnologías. Con Ontuts tratamos de compartir nuestro conocimiento adquirido en los distintos proyectos, ayudando a la comunidad y mostrando nuestra capacidad tecnológica.

Si necesitas un presupuesto sin compromiso, estamos disponibles, no dudes en contactar con nosotros.

Comentarios en esta publicación (38 comentarios)

¿Te ha gustado esta publicación? ¡Puedes compartir tu opinión con todos nosotros! Simplemente pincha aquí mismo.

Se habían hecho esperar… pero vuelven los tutoriales de javascript and company ^__^

Adrián, te juro que no es mi intención trollear :-) , pero, aunque el artículo está muy bien, no me convence nada esta solución en si porque no es nada accesible y los spiders no pueden seguir los enlaces.

Me parece mucha mejor solución esta, que es prácticamente CSS y con casi nada de javascript (de hecho si desactivas javascript con el web developer sigue funcionando):

http://www.htmldog.com/articles/suckerfish/dropdowns/example/bones3.html

Simplemente es mi intención aportar otras soluciones al mismo problema. :-)

@Pablo ya sabes que no molestan nunca los comentarios constructivos ;)

Pero te estás equivocando, realmente esos enlaces sí que son “cliqueables” por los spiders y bots rastreadores, estamos generando una salida HTML totalmente limpia: una lista con enlaces. La muestra más clara la tienes en la primera imagen que mostramos en el paso 1 :)

Por cierto, el ejemplo que has mostrado está genial pero eso es un menú para secciones y subsecciones, realmente este está planteado como un dropdown a modo de “select”, no con intención de barra de navegación al uso.

@adri, cuando te refieres a un “select”, ¿hablas de por ejemplo en las futuras Experiencias traducidas de Erasmusu.com el desplegable para cambiar de idioma? Jejeje…

Y sí, claro que es crawleable, sólo que en el ejemplo no ha puesto links a ningún sitio. Pero se ve claro que el html generado lleva los links, que es lo que verá el crawler.

Los valores href=”#˝ no dejan de ser valores y enlaces, tenedlo en cuenta. Supongo que de ahí ha surgido la duda de Pablo.

Reyvolsam

Pues muy interesante el articulo, no se programar en JQuery y este ejemplo esta muy bien ademas de que el resultado queda super bien.
Desde hoy sigo este blog amigo, espero mas sobre JQuery o relacionados…

¡¡¡SAludos!!

Cierto, me lié yo solito por no pararme a verlo con calma. :-)

Un fallo de usabilidad de este tipo de menús es que el menú debe permanecer en pantalla hasta que se hace clic fuera de él.

Si el menú desaparece simplemente por mover el ratón fuera, puede hacerse muy complicado hacer clic en una opción…

También recomendaría que el menú no se desplegase hasta no hacer clic en él.

En fin, espero que no te tomes a mal mi critica. :)

Saludos

@Daniel, también puedes asignarle un delay al desplegable, para que desaparezca después de un tiempo si el usuario lo abandona.

Ejemplo (deplegable de idiomas): http://www.cafebabel.es/article/33863/pompidou-arte-contemporaneo-europa-este-historia.html

Sobre lo del click, depende. Por ejemplo en algunos Menús, como el de http://www.erasmusu.com, si cliqueas encima, te lleva a una sección distinta que las del resto del desplegable, por lo que no tendría sentido.

Para el resto de casos, como el de Cafe Babel, personalmente, también prefiero el click. No hay nada que moleste más que mover el ratón por la pantalla y que “algo salte”.

@Daniel No te preocupes por las críticas, faltaría más!

Personalmente no estoy de acuerdo en que sea un fallo de seguridad, es una opción tan o más válida que el desplegarlos con click. A mí personalmente para este tipo de controles me gusta más que se autodesplieguen, sin hacer pensar al usuario… y además si te fijas hemos dejado un padding lo suficientemente grande como para que el usuario oculte el menú sin querer o sin llegar a ser tedioso.

Pero como todas estas cosas, hasta que no lo pruebas con usuarios en tiempo real, no sabrás si realmente estás en lo cierto o no :)

Excelente, lo vamos a aplicar en nuestro sitio, espero y publiquen pronto la actualizacion.
Saludos desde CANCUN, MEXICO

Nicolas

Hola amigo, excelente menu, tengo una consulta, yo al utilizar el menu, cuando se despliega se me tira para abajo todos los contenidos que tengo. Te paso el ejemplo del site que te estoy comentando..
http://www.ppiova.com/
Saludos
Nicolas.

Joseph

Hola, me gusta este tutorial. Pero pienso q deberias limitar el estilo css para los elementos especificos del dropdown. Por medio de un id o clases, para q al implementarlo en algun sitio no estropee los estilos que ya se tienen. SALU2

sickboy

bueno con un show(‘fast’) creo que queda fantástico, me dio varias buenas ideas, muchas gracias por este muy buen tutorial

Davo

Hola amigo, soy nuevo en esto, weno, estoy en clases de desarrollo web, y pues nuestra profesora nos mando a maquetizar y crear un sitio web, estuve viendo tu menu desplegable, lo agregue a una pagina, pero no logro crear mas menus como ese horizontalmente, para usarlo como mi menu principal, quiciera usar mas menues desplegables para mi pagina pero no lo logro. por ejemplo, kisiera ponerlo donde va: inicio, somos, etc…. porfas, disculpa por mi ignorancia, pero apenas estoy empezando en el mundo web.

ZeusAlfred

Wey no mames gracias… buen aporte…. le gusto a mi jefe… gracias…. me salvaste el trabajo ok sigue asi……..

Oscar

Hola, posiblemente sobrevole el tutorial rapidamente, pero el archivo main.css, esta incluido en algun lugar ? O es parte de JQuery?

Blanca

Hola

Esta genial el ejemplo. Tengo una pregunta y es como puedo cambiar que el menú al desplegarse se vea por encima de la tabla con lo que contenga un flash, imagenes,,, y no me desplace lo demás hacia abajo.

Gracias.

Gabriel
Emanuel

¿Por que al incluir el archivo Javascript y Jquery arriba dentro de las etiquetas (Precisamente debajo de la deja de funcionar?

Alexander

Hola.
Gracias por este aporte del menu, pero como podriamos hacer para que este menu quede encima de otro elemento?, es decir el menu lo tengo encima de una imagen, pero cuando lo despliego en vez de quedar encima de la imagen, lo que hace es bajar la imagen.
Muchas gracias por tu atención.

Adriana

Muchisimas gracias en serio eres muy amable en poner estos tutoriales además con el código tan bien organizado

muy buen post, me ayudo mucho con un proyecto

Dolly

Hola, intento adaptar tu ejemplo a algo que necesito, quiero un menu de 3 o 4 niveles, pero que al hacer click recien se vaya mostrando el submenu de adentro y asi sucesivamente… Sera solo cambiar en la propiedad del javascript “mouseover” por la de “click (no estoy segura como se llama este funcion del click)” o habra q cambiar algo mas, no estoy segura… Help!

nefrali

gracias por el material
se puede por que en bes de abajo salgan para derecha o izquierda
y en donde lo puedo modificar
gracias

Sería aplicar este menú desplegable a una adaptación web móvil (WAP)? porque estaba pensando en no tener una ul dentro de un li con display none y al pulsarlo (:hover) dispaly:block, pero el problema es que no podría cerrarlo, así que no sé si tendré que meter jquery. ¿alguna recomendación?

Hola, muchas gracias por el aporte, esta muy bueno.

Slds..

Mauro

Hola,
Una pregunta ¿ como puedo crear sub-menus en este trabajo ?

Gracias.

Nacho

Me pasa lo mismo que a los demás: si coloco el menú en un cuando se ejecuta empuja a los demás divs para abajo.

Adi

orale mui buenas aportaciones io apenas stoi empezando a programar en html i me gusto eso de query pero aun no comprendo mui bien ji pero sta interesante hace mas dinamica la pagina web

Eduardo

Si deseo que lo desplegable sea hacia un lado, lado derecho por ejemplo en linea recta, cual seria la solución? Gracias. Como siempre buenos aportes.

ozmar

hola el codigo css del segundo paso donde lo pongo? y el 3 codigo en el 3 paso donde lo pongo y en el primer codigo usas 3 archivos son dos .js y un .css espero no se mucha molestia de antemano muchas gracias

Ned

Muy bueno el menú!! pero tengo una duda.. como hago para ponerlo y que cuando desplega la lista no se me agrande la tabla en donde lo tengo puesto o si es en div ponerlo arriba de todo y que no me modifique lo que sigue? Gracias!

Maria

Hola!!!
con la duda como Davo me gustaría saber como agregar mas ítems!!!

Juan Carlos

gracias por el dato aqui les paso tambien un dato http://cafezzito.com/ en esa pagina encuentras algunos menus interesantes

Juan Carlos

El tutorial está muy bueno; sin embargo tengo una pregunta, he puesto dos botones uno debajo del otro pero hay un espacio entre ellos, cómo haría para que aparezcan juntos? Ayuda por favor!!!!!!!

Muchas Gracias!

Esaú

Como todo el mundo, desplaza lo que tenga debajo… ¿alguna idea?. Gracias!