Convirtiendo Listas en Árboles

25/sep/2007 26

Recontra conocidas ya son los menúes construídos con listas de ítems. Los hay verticales, y muy fácil es transformarlas a horizontales. Gráficamente, existen necesidades que a través de la habilidad del diseñador/desarrollador se pueden solucionar elegantemente con unos trucos de CSS. En este caso, mostraré una manera de crear menúes tipo árboles, utilizando algunos GIF para lograr esos enlaces y nodos.

Bueno, lo primero es el código HTML. Básicamente se compone de una lista con <ul> y algunos <li> tienen sublistas, como verán en el ejemplo a continuación:

<ul id="menu_arbol">
     <li><a href="#" title="Ver las Cervezas">Cervezas</a>
          <ul>
               <li><a href="#" title="Enlace a cerveza Pilsen">Pilsen</a></li>
               <li><a href="#" title="Enlace a cerveza Bock">Bock</a></li>
               <li><a href="#" title="Enlace a cerveza Lager">Lager</a></li>
               <li><a href="#" title="Enlace a cerveza Ale">Ale</a></li>
          </ul>
     </li>
     <li><a href="#" title="Ver los Vinos">Vinos</a>
          <ul>
               <li><a href="#" title="Enlace a Vino Merlot">Merlot</a></li>
               <li><a href="#" title="Enlace a Vino Sirah">Sirah</a></li>
          </ul>
     </li>
     <li><a href="#" title="Ver los Licores">Licores</a>
          <ul>
               <li><a href="#" title="Enlace Licor Ron">Ron</a></li>
               <li><a href="#" title="Enlace a Licor Vodka">Vodka</a></li>
          </ul>
     </li>
</ul>

Ver hasta aquí (1)

Una simple lista de 3 items donde 2 de ellos tienen subitems. En esta caso será un menú, pero puede ser también sólo una lista de elementos (ordenados <ol> o desordenados <ul>) sin enlaces. Bueno, a lo nuestro.

Primero que todo, a través del CSS esconderemos los bullets, ya que los reemplazaremos por una imagen de una línea vertical.

ul#menu_arbol, ul#menu_arbol ul {
     list-style-type: none;
     background: url(imagenes/linea_vertical.gif) repeat-y;
}
ul#menu_arbol li {
     padding: 0 10px;
}
ul#menu_arbol ul {
     margin-left: 5px;
}

Ver hasta aquí (2)

Ahora, conectamos los nodos:

 ul#menu_arbol li {
     padding: 0 10px;
     background: url(imagenes/nodo.gif) no-repeat;
}

Ver hasta aquí (3)

Finalmente, nos queda poner otra imagen donde las listas se cierren. Esto lo tendremos que hacer agregando una class manualmente a los últimos ítems de cada lista:

 ul#menu_arbol li.cierre {
     background: #FFF url(imagenes/cierre.gif) left top no-repeat;
}

Importante fijarse que en este punto se agregó un color de background (blanco) lo que se hizo necesario para tapar la línea vertical que pasa por debajo (dado que esta imagen es un GIF transparente).

Ver hasta aquí (4)

Con eso estaríamos, pero hagamos esto bien de una. Podemos automatizar tarea de agregar las class, a través de Javascript:

 window.onload = function () {
     var tree = document.getElementById("menu_arbol");
     var lists = [ menu_arbol ];
     for (var i = 0; i < tree.getElementsByTagName("ul").length; i++)
          lists[lists.length] = tree.getElementsByTagName("ul")[i];
     for (var i = 0; i < lists.length; i++) {
          var item = lists[i].lastChild;
          while (!item.tagName || item.tagName.toLowerCase() != "li")
          item = item.previousSibling;
          item.className += " cierre";
     }
};

Esto lo que hará será primero buscar en todos los <ul> (getElementsByTagName) su último nodo (lastChild) y le agregará la class="cierre" que creamos (className +).

Ver hasta aquí (5)

Podemos también agregarle movimiento, un toggle() por ejemplo. Utilicen el framework que más les acomode, en este caso aprovecharé lo liviano de Mootools:

window.addEvent(’domready’, function(){
     var mySlide = new Fx.Slide(’cervezas’);
     mySlide.hide()
     $(’toggle_c’).addEvent(’click’, function(e){
          e = new Event(e);
          mySlide.toggle();
          e.stop();
     });
});

Primero, tomamos el #cervezas y lo escondemos (mySlide.hide()); luego, tomamos el #toggle_c (que se lo dí al <ul> del subítem) y le damos la instrucción de mostrarlo o esconderlo cuando le haga un click ($(’toggle_c’).addEvent(’click’) y mySlide.toggle();). Luego, se repite con los otros elementos de la lista.

Ver ejemplo final

Por supuesto, todo el código a través de un view source de los ejemplos.

Comentarios

  1. Claudio [#]

    Hola, disculpa por el doble post, estube viendo wordlingo.com y hay que pagar tu te suscribiste?, o hay otra forma de traducir sin pagar saludos y gracias por tu pronta respuesta.

  2. Cristian Ocampo [#]

    Buen trabajo!
    Un consejo… cuando haces enlaces a los ejemplos y todos los enlaces internos dentro del post, deberías agregar la url completa con el dominio para quienes leemos desde el lector de feeds, podamos acceder a esos enlaces.
    Muy buen sitio, siempre muy útil…

  3. fearlex [#]

    Muy bueno, como siempre en espera de tus maravillosos articulos, esta es una muy buenisima idea, a ver si la implemento y te digo 😀

  4. Pablo [#]

    Excelente caso, me gustó mucho.
    Pero una consulta, el ejemplo final no funciona bien en firefox. El menú jamas se “cierra”.
    En IE7 funciona perfectamente.

  5. Enrique [#]

    Respondiendo a pablo, a mí me funciona bien en firefox…

  6. Pablo [#]

    A lo que me refiero es que en firefox, el ejemplo final, no aplica la class “cierre”.
    Y el árbol jamás se cierra… a mi sólo me pasa?

  7. CSSLab Admin [#]

    Toda la razon Pablo, con algo de tiempo revisare el JS y tratare de usar Mootools para ello. Saludos y gracias.

  8. mcarmen [#]

    Hola, una duda para centrar los submenús como podemos hacer?.

    Gracias

  9. CSSLab Admin [#]

    mcarmen: text-align: center; te bastara

  10. mcarmen [#]

    Gracias, solucionado pero ahora no se ve bien en Firefox, alguna idea del motivo?.

    mc

  11. CSSLab » Alto mínimos para IE6 (y el resto, claro) [#]

    […] Convirtiendo Listas en Árboles […]

  12. Jordi [#]

    hola , he encontrado algo que igual te puede servir , en el momento del cierre de la lista en lugar de esto :

    ul#menu_arbol li.cierre {
    background: #FFF url(imagenes/cierre.gif) left top no-repeat;
    }

    podrias utilizar esto :

    ul#menu_arbol li li:last-child{
    background: #FFF url(‘../images/cierre.gif’) left top no-repeat;
    }
    la funcion last-child permite cambiar la imagen en el ultimo elemento de la lista.

  13. Cmacias [#]

    @Jordi.

    Eso solo funcionaría con Firefox. Explorer en cualquiera de sus versiones no reconoce last-child

  14. Alejandro [#]

    ¿Es posible aumentar la velocidad al despliegue de los subvalores?

  15. CSSLab Admin [#]

    Claro Alejandro, en la web de mootools hay algunas referencias al uso de FX.Slide. Puedes variar la duracion (en ms), por ejemplo:
    var mySlider = new Fx.Slide('myElement', {duration: 500});
    mySlider.toggle()

  16. www.minicatalogo.cl [#]

    me gustaria verlo en mas de un nivel.
    Saludos

  17. Manuel A [#]

    Al anidar mas niveles el tamaño del div falla y se traslapan, es decir, no se ven.

    Podrian ayudarme con eso

  18. Dani [#]

    Alguien modifico el codigo para no incluir tantas lineas de los addevent en cada pagina?
    Me refiero a hacerlo mas modular, como cololar alguna funcion generica en el .js y llamarlas con los parametros, ej ‘cervezas’, ‘toggle_c’… porque aun no lo logro

  19. adree [#]

    donde encuentro las imagenes que utilizaste como linea vertical y nodo

  20. Guest [#]

    por ke no me funciona con el de la pagina pero si con el q vos tienes ?

  21. Julio [#]

    Dani:

    podrias agregar el codigo JS
    “window.addEvent(’domready’, function(){
    ……
    });”

    dentro de codigo php , antes capturando la ID de las UL LI q imprimiras, obvio sto tb en una variable en PHP

  22. miguel [#]

    como hago para agregar un subitem a un subitem?
    que codigo utilizo?
    bacana la web
    gracias

  23. Enlaces vacíos y semánticos ↝ CSSLab [#]

    […] en un caso de ejemplo. Supongamos que se agrega una función para ejecutar un slideToggle a un enlace; por lo que he visto generalmente esto se hace de 2 […]

  24. matias [#]

    hola donde encuentro las imagenes de el nodo y la linea vertical?

Deja tu Comentario

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

CSSLab