Un completo curso de diseño gráfico, ilustración, diseño web y tipografía.

Menús desplegables horizontales con CSS

por Nick Rigby

A cualquiera que haya creado menús desplegables le será familiar la enorme cantidad de script que estos menús requieren. Pero utilizando HTML estructurado y CSS, es posible crear menús desplegables visualmente atractivos que son fáciles de editar y mantener, y que funcionan en un muchos navegadores, incluído Internet Explorer. Mejor aún, para los diseñadores preocupados por el código, ¡no hace falta Javascript! (Realmente, hace falta una minúscula parte de JavaScript is needed, pero no es lo que piensas.)

He aquí una muestra del primera muestra menú en acción.

Crear el menú

La primera parte, y la más importante para crear el menú es la estructura de éste. La mejor manera es construirla como una lista sin numerar, con cada submenú que aparezca como una lista dentro de la lista pariente que la contiene. No es muy complicado:

  <ul> 
    <li><a href="#">Home</a></li> 
    <li><a href="#">About</a> 
      <ul> 
        <li><a href="#">History</a></li> 
        <li><a href="#">Team</a></li> 
        <li><a href="#">Offices</a></li> 
      </ul> 
    </li> 
    <li><a href="#">Services</a> 
      <ul> 
        <li><a href="#">Web Design</a></li> 
        <li><a href="#">Internet 
            Marketing</a></li> 
        <li><a href="#">Hosting</a></li> 
        <li><a href="#">Domain Names</a></li> 
        <li><a href="#">Broadband</a></li> 
      </ul> 
    </li>

    <li><a href="#">Contact Us</a> 
      <ul> 
        <li><a href="#">United Kingdom</a></li> 
        <li><a href="#">France</a></li> 
        <li><a href="#">USA</a></li> 
        <li><a href="#">Australia</a></li> 
      </ul> 
    </li> 
  </ul>

Eso es todo: algo de HTML que es accesible y fácil de editar.

¿Visualmente atractivo?

Si has visto el menú anterior, te habrá parecido una aburrida lista de elementos. Y prometí que sería visualmente atractiva. Añadamos algo de estilo.

El primer paso es suprimir los sangrados y marcadores de la lista y definir el ancho de los elementos del menú.


ul {
	margin: 0;
	padding: 0;
	list-style: none;
	width: 150px;
	}

A contiuación, debemos posicionar los elementos de la lista. Por suerte, se irán colocando en vertical por defecto, que es lo que queremos. Sin embargo, debemos indicar que la posición es relative, porque los submenús se deberán colocar de forma absoluta dentro de ellos.

ul li {
	position: relative;
	}

El siguiente paso son los sub-menús. Queremos que cada uno d ellos aparezca a la derecha del elemento ascendiente cuando pasemos el puntero sobre cada éste.

li ul {
	position: absolute;
	left: 149px;
	top: 0;
	display: none;
	}

Utilizando los atributos “left” y “top”, podemos colocar de manera absoluta cada sub-menú dentro de su ítem del menú ascendiente. Te darás cuenta de que he especificado la propiedad “left” a 149px (1px menos que el ancho de los ítems del menú), lo que permitirá que los sub-menús se superpongan al menú principal y así evitamos que se produzca un borde doble. (Verás a qué me refiero más adelante.)

También hemos hecho que los sub-menús no se muestren, haciendo que la propiedad display sea “none,” ya que al cargar no se van a mostrar, sólo se activarán al pasar el ratón sobre el menú principal.

Ahora ya tenemos lo básico en su lugar correspondiente, pero aún tiene un aspecto algo pobre; vamos a dar algo de estilo a esos enlaces.

ul li a {
	display: block;
	text-decoration: none;
	color: #777;
	background: #fff;
	padding: 5px;
	border: 1px solid #ccc;
	border-bottom: 0;
	}

He asignado estilos a mi gusto, pero puedes cambiarlo según tus propias preferencias, si lo deseas. Es importante que la propiedad display esté como “block,” ya que queremos que cada enlace ocupe todo el espacio posible dentro del ítem de la lista que lo contiene.

Ahora las cosas tienen un aspecto algo mejor, aunque los usuarios de Internet Explorer-Windows puede que no esten de acuerdo. IE Win interpreta que los saltos de línea en nuestro HTML con buen formato son un espacio en blanco, de manera que verás que los ítems del menú no se colocan bien en este navegador. Sin ambargo, hay un arreglo para estos fallos de IE:

/* Fix IE. Hide from IE Mac \*/
* html ul li { float: left; }
* html ul li a { height: 1%; }
/* End */

Podemos aplicar el Hack de Holly que figura arriba, que oculta estas reglas de todos los navegadores excepto IE Win. Perfecto. Ahora habrás notado que la regla height: 1% también se ha añadido. Por desgracia, de nuevo, este arreglo hace que aparezca otro bug de IE, el cual requiere un valor de altura para hacer que los enlaces se muestren como elementos de bloque.

Notarás también que es necesario cerrar el menú, cosa que se puede hacer añadiendo el borde que falta al final de la lista. Así que la lista, ul se convierte en:

ul {
	margin: 0;
	padding: 0;
	list-style: none;
	width: 150px;
	border-bottom: 1px solid #ccc;
	}

Con un poco de suerte, todos deberíamos ver ahora el menú no funcional.

Hacer que funcione

Ahora la parte divertida. Queremos que los submenús aparezcan cuando pasamos sobre los ítems del menú.

li:hover ul { display: block; }

Voilà...aquí está el menú básico en acción.

“Woo hoo! ¡Funciona!” Oigo que un 1% de vosotros exclama. “¡Formidable!”

OK, OK, así que ese maldito IE/Win tiene que arruinarlo todo y no hacer lo que se le dice. IE/Win sólo permite que la pseudo-clase :hover se aplique a enlaces — así que ese código, li:hover que hace aparecer los submenús no significa nada para IE.

Una pequeña adición de JavaScript es necesaria para hacer que IE responda (los saltos de línea están marcados como »Ed.):

startList = function() {
if (document.all&&document.getElementById) {
navRoot = document.getElementById("nav");
for (i=0; i<navRoot.childNodes.length; i++) {
node = navRoot.childNodes[i];
if (node.nodeName=="LI") {
node.onmouseover=function() {
this.className+=" over";
  }
  node.onmouseout=function() {
  this.className=this.className.replace»
	(" over", "");
   }
   }
  }
 }
}
window.onload=startList;

Muchas gracias a Patrick Griffiths y Dan Webb, que introdujeron esta técnica en un artículo anterior, Suckerfish Dropdowns. ¡Gracias, chicos!

Ahora, la regla de hover se convierte en:

li:hover ul, li.over ul { 
	display: block; }

Además, podemos asociar el JavaScript con nuestra lista principal ul, así que se convierte en:

<ul id="nav">

Ahora, todo el mundo debería ser capaz de probar una versión básica del menú en acción.

Un fallo en IE5.01

Si alguien usa IE5.01 en Windows notará que el menú parece que salta cuando pasas sobre algunos de los ítems. El problema se puede arreglar fácilmente modificando nuestro código anterior así:

/* Fix IE. Hide from IE Mac \*/
* html ul li { float: left; height: 1%; }
* html ul li a { height: 1%; }
/* End */

Bug misterioso en IE6:

Al desarrollar este artículo, he descubierto un extraño bug que sólo aparece en IE6. Se debe declarar un fondo en el elemento li a, porque si no cuando un sub-menú llega más abajo que el menú principal, los enlaces empiezan a desaparecer antes de que tengas tiempo de hacer clic en ellos. ¡qué extraño! Podéis intentar verlo vosotros mismos.

Adaptaciones

Ya está: un método que cumple los estándares que permite crear menús horizontales desplegables que son visualmente atractivos. Todo lo que necesitas es añadir algunos estilos y adaptarlo a tus gustos. Para muestra, aquí hay uno más bonito que preparé antes. ¡Disfrutadlo!

Nick Rigby en diseñador de Lancaster, UK. promueve los estándares de la web en su lugar de trabajo, Business Serve plc, y su sitio personal, nickrigby.com.

[ Este artículo ha sido traducido con permiso de A List Apart y su autor.]