6
Ago/09
30
Sencillo menú desplegable – solo con CSS

Sencillo menú desplegable – solo con CSS

En el uso común de usar una barra horizontal como menú de un sitio web es común encontrarse sin suficiente ancho para agregar todas las partes de el sitio. Esto se suele solucionar ordenando el menú en categorías y subcategorías, estas últimas aparecen tan solo cuando pasamos el raton por encima de las categorías principales. Hoy aprenderemos a hacer esto sin necesidad de utilizar Java Script.

Autor: Jack Bach

Bach es el autor principal de este blog. A los 15 años le dio por hacer un juego en flash y eso le llevó a hacer una web para mostrarlo al mundo. Ahora ya han pasado unos años y ha aprendido sobre todo XHTML y CSS para maquetar sus diseños web.

Objetivo

Convertir un menú horizontal de un solo nivel en uno de varios niveles. Queremos que al pasar por encima de un ítem del primer nivel se vea un cuadro con las subcategorías. Tomaremos como base el menú del antiguo tutorial sobre menus con css, aunque no es imprescindible haberlo leído.

preview

El HTML

Recordemos que el código que teníamos era este:

<div id="contenido">
 <div class="menu">
 <div id="menu_i"></div>    <div id="menu_d"></div>
 <ul>
 <li><a href="#">Blog</a></li>
 <li><a href="#">Tutoriales</a></li>
 <li><a href="#">Tips</a></li>
 <li><a href="#">Freebies</a></li>
 <li><a href="#">Foro</a></li>
 </ul>
 </div><!-- fin Menu -->
</div><!--  fin Contenido -->

Vamos a añadir las subcategorías del menú. Para hacerlo, vamos a crear una lista dentro de otra lista. Dentro de las etiquetas <li> y </li> a las que van a pertenecer las subcategorías, después del link que finaliza con </a> insertamos otras etiquetas de <ul> y dentro de ellas los distintos ítems entre etiquetas <li>. Tenemos algo así:

<div id="contenido">
 <div>
 <div id="menu_i"></div>    <div id="menu_d"></div>
 <ul>
 <li><a href="#">Blog</a></li>
 <li><a href="#">Tutoriales</a>
 <ul>
 <li><a href="#">Clasicos</a></li>
 <li><a href="#">Screencasts</a></li>
 <li><a href="#">Tips</a></li>
 </ul>
 </li>
 ...
 </ul>
 </div><!-- fin Menu -->
</div><!--  fin Contenido -->

Para las flechitas que salen encima de cada menu desplegable hemos añadido <span></span> al principio de cada submenu, en el código anterior sería después del <ul> de la línea 7.

El HTML fácil ¿verdad? Vamos a por CSS que es un poco más complicado…

El CSS

Antes de empezar con lo de hoy vamos a modificar dos cositas del ejemplo anterior:

1. En vez de usar display inline para alinear los ítems de la lista (li) usaremos el float left. El resultado es el mismo, pero hace que luego los submenus salgan en su sitio.

.menu li {
 float: left;
}

2. A causa de esto, la altura del menu (.menu) se ve reducida. Se podría solucionar con un clear both, aunque nosotros simplemente definiremos la altura con height.

.menu {
 height: 70px;
}

Dicho lo dicho vamos a por lo importante. La bases de este menú van a ser:

  • La propiedad display que nos va a permitir hacer desaparecer un elemento de la página (none) o hacerlo aparecer (block).
  • Podemos acceder de la siguiente forma a los estilos que hay  dentro de otro estilo cuando pasamos por encima de este último:
.menu ul li:hover ul {...}

El estilo que pongamos entre las dos llaves afectará al último ul cuando el ratón pase por encima del li que lo contiene.

Combinando esto podemos hacer que por defecto el display de .menu ul li ul sea none – es decir, que los submenus por defecto no se vean – pero que cuando pasemos por encima de un ítem de la primera lista aparezca este submenu – el display será block. Nos queda algo así:

.menu ul li ul {
display: none; /* De lo que hablábamos */
background: #cac99e ;
padding: 10px 0;
position: absolute; /* Muy importante */
margin: -12px -20px; /* Lo colocamos donde queremos */
.margin: 69px -170px; /* Hacks para colocarlo bien en ie */
_margin: 69px -170px;
}

.menu ul li:hover ul {
display: block;
}

Como hemos hecho que los li de .menu se alineen con float left, la lista del submenú también se alineeará. Para hacer que cada ítem salga en una línea usaremos float none.

.menu ul li ul li {
display: block;
float: none;
position: relative;
color: #fff;
padding: 0 20px;
line-height: 30px;
}

Para la flecha de arriba emos usado <span></span> en el html. El código css es realmente sencillo: le damos un alto, un ancho, un fondo y posicionamos.

.menu ul li ul span {
background: url('img/flecha.png');
margin: -20px 50px;
width: 20px;
height: 10px;
position: absolute;
}

Y esto es más o menos todo. Lo demás son detalles que podéis ver descargandos el código. Cualquier duda o comentario, abajo tenéis un formulario, ¡Animaros! Si os ha gustado el tutorial acordaros de suscribiros al feed o seguirme en twitter.

Demo y Descarga

Filed under: Tutoriales
Comentarios (30) Trackbacks (1)
  1. randich
    21:41 on Agosto 18th, 2009

    hola jackbach, está bueno el ejemplo justo tenía problemas con algo parecido :P

  2. beleita
    9:35 on Agosto 19th, 2009

    Gracias a la explicación he entendido bien como funciona,

    muy buena y sencilla, Gracias.

  3. Jesus
    6:18 on Agosto 21st, 2009

    hola que tal! me gusta tu blog!

    soy nuevo en esto tengo una pregunta, esto funciona para wordpress y solo se modifica el codigo que dices de los thems y gracias por contestar?

  4. Jack Bach
    15:42 on Agosto 21st, 2009

    Hola Jesus!
    Para aplicar esto a Wordpress tienes que ir a wp_content>Themes>Nombredeltheme. Hay encontraras un archivo llamado header.php que seguramente es donde estará el menú. Ahí es donde irá el html. También encontraras otro archivo llamado style.css que es donde irá el css.
    En breve escribiré una serie de tutoriales para aprender a hacer themes en WP en los que se tratará este tema.

    Hasta pronto!

  5. Jesus
    6:00 on Agosto 27th, 2009

    Hola como estas?
    gracias por tu ayuda me sirvio bastante,
    ahora tengo otra duda. como puedo coloar o hacer en wordpress este cuadro donde puedo dejar cometarios o enviar sugerencias a un correo como lo tienes tu?
    te doy las gracias por contestar¡

  6. Naturaleza insólita
    8:11 on Diciembre 20th, 2009

    Hola, muchas gracias por compartir la idea, estaba usando el botón AddThis en las entradas pero me daba problemas, y con esto pude crear mi propio menú de marcadores sociales. :)

  7. irudiz
    14:11 on Enero 25th, 2010

    No me funciona y no se que puede ser. Me sale la lista de arriba abajo. He metido en el html tanto en el css el codigo que pones tu y me sale la subcategoria desplegada y la lista de arriba abajo.

  8. axel
    2:45 on Marzo 20th, 2010

    oe tio esta muy bien lo he probado en mozilla pero en internet explorer no funciona men
    en otros navegadores aun no lo he probado,,, pero k ago para k funcione tambien en IE.
    ya k la mayoria de usuarios tienen IE en su casa algunos incluso IE antiguos…

  9. ivan dario
    0:10 on Abril 1st, 2010

    hola jack queria hacerte dos preguntas
    1. como hago para q la flechita salga en el lugar correcto en cada uno de los submenis si al definirlo toma un solo valor?
    2. como puedo crear un submenu dentro de otro submenu?

    te agradeceria mucho tu ayuda lo mas pronto posible

    • Jack Bach
      13:48 on Abril 2nd, 2010

      La flechita toma un solo valor porque no hay una, sino tantas como submenus, y el valor que toma es la posición que tiene respecto el submenu al que está relacionada.
      Es decir… Fijate que hay un span dentro de cada ul de submenú. Ese span es la flechita, y los margenes que se le dan son respecto al ul.
      Para hacer un submenú dentro de un menú añades otro ul dentro del ul que tenias en la lista principal y sigues con el procedimiento que ves en este tutorial. Pero creo que es mejor plantearse si son necesarios tantos niveles, la usabilidad del sitio se puede ver resentida.

      Hasta pronto!

  10. echeva
    0:07 on Abril 12th, 2010

    hola.
    me estoy iniciando en esto por un poryecto que tengo de fin de curso y me han gustado mucho tus explicaciones.
    Solo tengo una duda, podrias decirme como hacer un submenu(por ejemplo dentrod de clasicos D.Quijote).
    Muchas graicas.

  11. victor
    14:56 on Abril 12th, 2010

    graciaspor esto me sera de util

  12. Yllelder
    22:55 on Abril 14th, 2010

    En el CSS haces das atributos a un objeto .menu, pero en el HTML no hay ningún “id=menu”, sólo hay “menu_i” y “menu_d”.

    No lo entiendo.

    • Jack Bach
      20:45 on Abril 15th, 2010

      Verdad! el primer div tiene que ser class=”menu” (no id), ahora lo corrijo.

      Muchas grácias por hacermelo saber, espero haberte ayudado de todas formas! Espero ver publicadas tus creaciones!

      Suerte!

  13. Santiago,r.a
    4:39 on Mayo 2nd, 2010

    Fantástico el tutorial, buen trabajo.

  14. Yllelder
    23:25 on Mayo 2nd, 2010

    Por supuesto que me ayudaste, ¡muchas gracias socio!

  15. jesuli
    17:58 on Mayo 27th, 2010

    podrias dejar todos los códigos en un solo paso y enviarmelo a mi e-mail? Gracias

    • Jack Bach
      21:14 on Mayo 28th, 2010

      Hola jesuli!
      fijate que hay un link de descarga. Si clickas en él podrás descargarte todo el código “en un solo paso” directamente. Así no hace falta que te lo envíe por email.

      Espero que te sirva el código! Suerte!

  16. Elias
    2:20 on Junio 11th, 2010

    Voy a emplear estos conocimiento en mi blog estan muy bien detallado mucha gracias por la explicacion

  17. Juan Martin
    20:40 on Noviembre 2nd, 2010

    Muy bueno el turorial. Lo usé y quedó muy bien! El único problema es que no se ve bien en IE7 y no funciona el desplegable.

  18. Luciano
    17:55 on Noviembre 5th, 2010

    hola, buenas tardes, tengo una duda, tengo un menu similar, en el div del menu esta tdo en orden, y funciona perfecto, mi problema es, que en el div que le viene abajo, cuando el menu se despliega, me mueve todo el contenido, intente ponerle un index-z 10 al menu ( a los otros no los categoricé o le puse index-z 2 pero sigo teniendo el problema, hay alguna otra opcion que no sea dejar el espacio en blanco ? saludos y desde ya muchas gracias!
    Luciano

    • Jack Bach
      18:41 on Noviembre 5th, 2010

      Hola Luciano,
      z-index solo te determina que elemento te queda delante y que elemento detràs. Si el submenú que se despliega ya está tapando lo que hay abajo no tienes por que modificar su valor.
      Tu problema viene de el atributo “position”. Tienes que asegurarte de que el submenú que se despliega tiene “position: absolute” y el “li” que lo contiene “position: relative” como ves en el ejemplo que hay en el tutorial.
      ¿Lo tienes así? Si me pasas un enlace a tu trabajo puedo ayudarte mejor ;)
      Suerte!

  19. Cristian
    19:36 on Noviembre 13th, 2010

    Buenisimo, muchas gracias, lo he probado todo y no conseguía uno que funcione en IE tambien,
    Gracias nuevamente

  20. chuster
    8:52 on Diciembre 17th, 2010

    Hola, tengo una pregunta, ¿dónde habría que editar el código para que el menú no esté en horizontal sino en vertical?
    Gracias

  21. Edward
    2:01 on Enero 30th, 2011

    …. Friend, Great Work …. Thanks for sharing.

  22. ElSad
    10:26 on Abril 1st, 2011

    Hola muy buenas,
    resulta que instale un menu diferente a este en mi blog. Exactamente uno de purecssmenu. En principio todo funciona perfecto, pero ayer probe en IE8 y el menu despegable se despliega por debajo de los elemento que hay por debajo del menu.
    He estado buscando una posible solucion, y me encontre con la solucion del z-index. Se supone que hay que darle un valor alto para que sobreponga por encima de todos los elementos. Hasta ahi bien, pero el problema es que no encuentro ese parametro en el div de mi menu. Unicamente me salen dos z-index uno dentro de /* Tabs y otro dentro de /* Content. Y ahora no se cual es que hay que modificar. O si esos no tienen nada que ver con el menu, no lo se.

    Te dejo mi enlace por si me pudieras echar una mano por favor.

    http://elsadsphoto.blogspot.com/

    Un saludo y mil gracias de antemano

  23. nelson
    2:21 on Noviembre 15th, 2011

    hola me parece muy bien el menu gracias por compartir los archivos

  24. SirOne
    18:24 on Noviembre 16th, 2011

    Excelente aporte!

    Sencillo, claro y preciso. Lo probaré en alguno de mis diseños a ver que tal me va…

    Gracias.

Deja un comentario