Como habréis podido ver, he hecho un menú nuevo para el blog, ya que no era la primera vez que recibía una queja sobre los enlaces flotantes en pantallas pequeñas.

Bien, pues como me disponía a hacer este tipo de menús desplegables, lo primero que hice fue fijarme en uno que vi en CiudadBlogger

Necesitaba personalizarlo mucho más, poner bordes redondeados (tarea que se complicó bastante), sombras, colores de pestañas diferentes, etc. Pero no solo eso:

También quería hacerlo sin imágenes (cosa que he conseguido) y sólo con transiciones CSS en vez de Javascript para los efectos (no se si habría alguna posibilidad de hacerlo con animaciones), cosa que pude hacer al final, como luego explicaré.

Así que me puse a diseñarlo desde cero, siendo este el resultado:

Demo y descarga

El HTML

Usaremos un div con id menu-altern” en el que meteremos una lista ordenada normal “<ul>” (sí, la de las viñetas) con otras listas dentro:


<div id='menu-altern'>
<ul>
<li><a href='#'>Página Principal</a></li>
<li><a href='#'>Opina y sugiere</a>
</li>
<li><a href='#'>Entradas CMC</a></li>
<li class='expandible'>Literatura<div class='flechaabajo'/><ul>
<li><a href='#'>Tema 8</a></li>
<li><a href='#'>Tema 9</a></li>
<li><a href='#'>Tema 10</a></li>
</ul></li>
<li class='destacada'><a href='#'>Sígueme</a></li>
</ul>
</div>

El CSS

Ésta es la parte más difícil y la que me llevó más tiempo. Todas las explicaciones están puestas como comentarios en el CSS.

#menu-altern{
color:#FFFFFF; /*Color del texto*/
width: 589px; /*Ancho del menú--> El número de pestañas principales por el ancho que le demos a cada una(585px) MÁS LOS BORDES (que son 4 de 1px)*/
height:35px; /*Altura del menú*/
box-shadow: 1px 2px rgba(0,0,0,.3); /*La sombra del menú*/
border-radius:4px; /*Bordes redondeados al menú*/
font-family:"Ubuntu",Trebuchet, Arial, Helvetica, sans-serif;/*La tipografía del texto*/
z-index:999;/*Para que sobresalga por encima de cualquier otro elemento de la página*/
text-align:center;/*Para que los links estén centrados*/
}
#menu-altern ul {z-index:999;
}
/*Anchura y altura de cada link*/
#menu-altern ul li{
list-style: none; /*Para quitar la viñeta*/
display:inline;/*Con el menú finalizado podríamos eliminarlo, pero durante la realización sirvió para que los enlaces fueran uno tras otro en vez de en columnas*/
float: left;/*Indispensable, para que se agrupen de derecha a izda*/
width: 117px;/*ancho*/
height:35px; /*la misma que la del menu*/
line-height:35px;/*El mismo valor que la altura, para que aparezca centrado verticalmente*/
background:#666;/*Fondo*/
cursor: pointer;/*Forma del ratón*/
border-right: 1px solid #999;/*Borde derecho*/
}
#menu-altern ul li:first-child{ /*El primer elemento li de una lista---> Esto es lo que nos dará problemas con los bordes redondeados*/
margin-left: -40px; /*Corregimos posición del menú--->NO NECESARIA SI EN NUESTRO CSS TENEMOS "*{margin:0; padding:0;*/
border-bottom-left-radius: 4px;/*bordes redondeados izquierdos*/
border-top-left-radius: 4px;
}
#menu-altern ul li:first-child a{/*Los bordes del enlace del li anterior-->Si este mantuviera bordes cuadrados, no dejaría que se vieran los redondeados*/
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
}
#menu-altern ul li:last-child, #menu-altern ul li:last-child a{/*Los dos pasos anteriores, pero para el último elemento de una lista*/
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
border-right: 0px;/*hacemos que el último elemento no tenga borde derecho*/
}
#menu-altern .flechaabajo{/*Elemento con forma de flecha jugando con los bordes. Por ahora nos tocará ponerla a mano, ya que no me he parado a desarrollar una función Javascript para insertarla después del texto de cada elemento con clase "expandible"*/
display: inline-block;/*Para que se muestre de forma similar a un carácter*/
position: relative; /*Nos permite fijar una posición desde la que debiera ser suya original. Además lo anterior se consigue junto con esto*/
/*Posición de la flecha*/
top: -1px;
left: 10px;
/*Bordes que le dan esa forma*/
border-left: 6px solid transparent;
border-top: 6px solid #fff;
border-right: 6px solid transparent;
border-bottom:0;
}
#menu-altern ul li a {/*Los enlaces dentro de la lista principal*/
display: block;/* Para que mantengan la altura y el ancho de la lista*/
text-decoration: none;/*Para que no nos lo subraye ni nada por el estilo*/
color: #fff;/*Color del link*/
position: relative;/*es prescindible, pero me gusta tenerlo ahí por si después tengo que posicionarlo*/
}
/*Sublista (submenú)*/
#menu-altern ul li ul{/*La lista anidada*/
/*No es imprescindible, pero mejor asegurarse de que no nos aparecen sombras raras*/
box-shadow: none;
border-radius:0px;
/*Corregimos la posición*/
position: relative;
left: -40px;/*corrección de la posición--->NO NECESARIA SI EN NUESTRO CSS TENEMOS "*{margin:0; padding:0;}"*/
width:117px;/*Anchura-->la misma que la del link y el resto de cosas de antes*/
display:none;/*Que no aparezca por defecto*/
z-index:999;/*Que aparezca encima de todo*/
}
#menu-altern ul li ul li{/*Sub-botones*/
display:block;
box-shadow: 1px 2px rgba(0,0,0,.3);/*Para que haga el efecto de sombra de toda la lista*/
float:none;/*Era importante mientras lo desarrollé para que no sigan flotando a la izda. Ahora es prescindible*/
position:relative;
background:#666666;/*Color de fondo*/
z-index:999;/*Que aparezca encima de todo*/
}
#menu-altern ul li ul li a{
color:#ffffff;/*Color de los links*/
border:0px;/*Eliminamos el borde derecho que teníamos puesto*/
}
#menu-altern ul li ul li:first-child, #menu-altern ul li ul li:first-child a{ /*Para que no sea afectado por la primera corrección*/
margin-left:0px;
border-radius:0px;
}
#menu-altern ul li ul li:last-child,#menu-altern ul li ul li:last-child a{/*Estilismo para dar borde redondeado al final de la lista*/
border-radius:0px;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
/*Estilos página(s) destacadas*/
#menu-altern ul li.destacada, #menu-altern ul li.destacada ul li{
background:#C00;
}
/*Efectos hover (cuando pasas el ratón por encima) meramente estilísticos*/
#menu-altern ul li.destacada:hover, #menu-altern ul li.destacada ul li:hover{
background:#FF1A1A;
}

#menu-altern ul li:hover{
background:#888;
}

El Javascript

He hecho dos funciones: La primera (la que estoy usando en el blog) es para que se active si haces click, y la segunda para que lo haga al pasar el ratón por encima (hover). Para poder usarlas tenéis que tener jQuery. Para ello, en el editor de html de blogger pegáis antes de </head>:
//Primera
$(document).ready(function() {
// Muestra y oculta los menús
$('#menu-altern ul li:has(ul)').click( //función al hace click en un "li" que tiene una "ul"
function()
{
$(this).find('ul').slideToggle();
});
});
//Segunda
$(document).ready(function() {
// Muestra y oculta los menús
$('#menu-altern ul li:has(ul)').hover( //función al pasar el ratón por encima de un "li" que tiene una "ul"
function(e) //Primera función-->ratón por encima
{
$(this).find('ul').fadeIn();
},
function(e) //Cuando el ratón deja de estar encima.
{
$(this).find('ul').fadeOut();
}
);
});

Animación por CSS

El mayor problema que me encontré fue que me cegué en hacer aparecer las listas anidadas con css, y no lo conseguí hasta hoy mismo, mientras escribo esta entrada.

Opacidad

Lo había intentado con “opacity:0;” y cambiarla al hacer hover a 1, pero esto tenía (y tiene) un problema, y es que la lista, a pesar de ser transparente, sigue estando ahí.

/*Antes de esto debemos de haber configurado "#menu-altern ul li ul" con "display:block"*/
#menu-altern ul li ul li{
display:block;
box-shadow: 1px 2px 1px rgba(0,0,0,.3);
float:none;
position:relative;
background:#666666;
z-index:999;
overflow: hidden;
-moz-transition:all 1s;/*Firefox*/
-webkit-transition:all 1s;/*Crome/Safari*/
-ms-transition:all 1s;/*IE-->No funciona todavía*/
-o-transition:all 1s;/*Opera*/
transition:all 1s;
opacity:0;
}
#menu-altern ul li:hover ul li{
opacity:1;
}

Altura

Lo había intentado antes, pero no ha sido hasta hoy cuando se me han abierto los ojos. Cambié la altura de los item de la lista anidada a 0, y puse al hacer hover la altura a 35px (la altura del menú):
/*Antes de esto debemos de haber configurado "#menu-altern ul li ul" con "display:block"*/
#menu-altern ul li ul li{
display:block;
box-shadow: 1px 2px 1px rgba(0,0,0,.3);
float:none;
position:relative;
background:#666666;
z-index:999;
height:0px;
overflow: hidden;
-moz-transition:all 1s;/*Firefox*/
-webkit-transition:all 1s;/*Crome/Safari*/
-ms-transition:all 1s;/*IE-->No funciona todavía*/
-o-transition:all 1s;/*Opera*/
transition:all 1s;
}
#menu-altern ul li:hover ul li{
height:35px;
}

El resultado

Os dejo con los cuatro resultados diferentes, y un link de descarga de todos los archivos:

DemoDescarga

Conclusión

Espero que os haya sido útil ya que, la verdad, no encontré ningún menú como este animado solamente con CSS3.

Actualizo: Acabo de ver algunos en script-tutorials (1|2|3|4), aunque sigo sin haber encontrado ninguno en español.

Ah! y feliz Año Nuevo, que es la primera entrada de 2012!

18 pensamientos en “Menú horizontal desplegable animado

  1. Imagen de Clara el dijo:

    Una pregunta: ¿Hay opción a que lo expliques todo otra vez, pero esta vez en un idioma prehistórico o algo parecido? Ja, ja, ja. Es que no me he enterado de nada, y soy yo la que estudio TIC (tendré que pedirle a Alipio una hoja de reclamaciones). Eso sí, la próxima vez que haga algo, averiguaré como se llama cada una de las partes… :(

  2. Imagen de Clara el dijo:

    He visto el resultado: cómo mola. Increíble. Maravilloso. El vocabulario de mi diccionario se agota, vamos a dejarlo aquí. En serio, está muy bien, pero ¿cuándo lo vas a colocar? … ;)

    • Imagen de Emilio Cobos Álvarez el dijo:

      Había un problema con el archivo, pero ya debería de estar solucionado.

      No obstante, y siendo sincero, ahora soy capaz de hacer algo más consistente, sin tener que andar cambiando anchos para redondear los bordes.

      Estáte atento, porque creo que pronto publicaré éste menú, pero más consistente.

  3. Imagen de Félix Redondo Casado el dijo:

    ESTIMADO Emilio:

    Te escribo acerca del menú desplegable estilo botón que lo tengo mucho veces en mi blog arqueocinema.

    Puedes verlo en la siguiente página: PÁGINA ELIMINADA

    La pregunta que te quería hacer es la de cómo es posible hacer que cada una de las páginas enlazadas se abra en otra página distinta a la de mi blog, así como poner el atributo no follow.

    He estado probando más de dos horas pero no lo consigo. Si me puedes echar una mano te lo agradecería.

    • Imagen de Emilio Cobos Álvarez el dijo:

      Siento la tardanza en contestar:

      Si te refieres a los menús select, no son un link directamente, así que no son indexados de ninguna de las maneras. La única manera de conseguir que se valla a la página enlazada es con el evento onchange.

      <select onchange='if(this.options[this.selectedIndex].value) location.href = this.options[this.selectedIndex].value'>
      <option value="http://url">Ir a mi página</option>
      </select>
  4. Imagen de Félix Redondo Casado el dijo:

    Hola Emilio. Te escribo porque he eliminado la página que te citaba en el Link del comentario anterior y las herramientas de webmaster de Google me avisan de que el link sigue activo porque lo publiqué en tu blog. Dime si algún modo de quitar el link o el comentario. Quizás podrías suprimirlo tú. Un cordial saludo.

    • Imagen de Emilio Cobos Álvarez el dijo:

      Sí, sin problemas, dalo por hecho. No obstante, yo no me preocuparía demasiado por los 404 de google webmasters, no afectan en nada al posicionamiento y simplemente son una ayuda para que el webmaster tenga más “feliz” a los usuarios ;)

      Saludos

  5. Imagen de MiguelMiguel el dijo:

    Buenos dias Emilio

    Ante todo muchisimas gracias por el Menu desplegable, me ha encantado.

    Una preguntita:
    Como puedo hacer para que dentro de Literatura>Tema 8>
    De Tema 8 salta otro menú hacia la derecha igual que el otro con otras opciones.
    ¿Cual sería el código?

    Muchisimas gracias de antemano.

    Miguel A.

    • Imagen de Emilio Cobos Álvarez el dijo:

      Actualmente no se puede :( Sólo lo hice con dos niveles de profundidad, y cambiarlo requeriría una gran cantidad de código. Uno de las cosas en mi lista de cosas para hacer es rehacer completamente el menú, pero por ahora no se puede… :S lo siento

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes usar las siguientes etiquetas y atributos HTML:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre data-language=""> <ul> <ol> <li>
Para poner código usa <pre data-language="[lenguaje]"><code>[código]</code></pre>, y no olvides escapar el HTMl.