Menú acordeón CSS desplegable con hover o con clic | Oloblogger Los menús del tipo "acordeón" son aquellos cuyos elementos se disponen -normalmente- en ve...

14 de noviembre de 2016

Menú acordeón CSS desplegable con hover o con clic

Los menús del tipo "acordeón" son aquellos cuyos elementos se disponen -normalmente- en vertical y cuyas correspondientes opciones se despliegan y quedan visibles al seleccionar el elemento principal que los engloba.

Son especialmente útiles para barras laterales aunque el efecto para ciertos diseños a veces no es el óptimo. Hay que valorar por tanto su conveniencia o no de usarlos, teniendo en cuenta que el menú plegado ocupa evidentemente menos altura que cuando está desplegado y por tanto, cuando se hacen visibles las opciones secundarias todos los elementos (otros gadgets, por ejemplo) que pudiera haber debajo de él, se desplazarán hacia abajo tanto como el menú se despliegue.

Dicho esto lo que veremos será un esquema básico de cómo construirlos sin necesidad de JavaScript (eso otro ya vimos cómo hacerlo), para que reaccionen tanto cuando se pase el puntero por encima (hover) como cuando se haga clic sobre ellos.


Menú acordeón CSS


Desplegable con hover


El marcado HTML será el habitual de una lista, usando ul para delimitar la propia lista y li para cada uno de sus elementos. Para las distintas opciones de cada elemento de la lista simplemente anidaremos dentro de cada cual una nueva lista.

Será suficiente con que marquemos la lista principal con una clase específica para que luego el CSS haga el resto. En el siguiente ejemplo usaremos acorh.

<ul class="acorh">
  <li><a href="#">OPCIÓN 1</a>
    <ul>
      <li><a href="URL11">Opción 1.1</a></li>
      <li><a href="URL12">Opción 1.2</a></li>
    </ul>
  </li>
  <li><a href="#">OPCIÓN 2</a>
    <ul>
      <li><a href="URL21">Opción 2.1</a></li>
      <li><a href="URL22">Opción 2.2</a></li>
      <li><a href="URL23">Opción 2.3</a></li>
    </ul>
  </li>
  <li><a href="#">OPCIÓN 3</a>
    <ul>
      <li><a href="URL31">Opción 3.1</a></li>
      <li><a href="URL32">Opción 3.2</a></li>
    </ul>
  </li>
</ul>

(*) Los URLXX que puse en otro color, los tendréis que cambiar por las direcciones de destino de cada uno de los enlaces que incluya el menú.


Una vez tenemos una estructura HTML como esa, sólo será cuestión de añadir el siguiente CSS para que el menú funcione con el estilo acordeón:

ul.acorh,
ul.acorh * {
margin: 0;
padding: 0;
border: 0;
}
ul.acorh {
margin: 10px auto;
padding: 0;
list-style: none;
width: 100%;
font-size: 18px;
}
ul.acorh li {
list-style: none;
}
ul.acorh li a {
display: block;
padding: 10px 10px 10px 20px;
background: #333;
color: #eee;
border-bottom: 1px solid #000;
border-top: 1px solid #666;
text-decoration: none;
box-sizing: border-box;
}
ul.acorh li ul {
max-height: 0;
margin: 0;
padding: 0;
list-style: none;
overflow: hidden;
transition: .3s all ease-in;
}
ul.acorh li li a {
padding: 10px 10px 10px 40px;
background: #999;
color: #000;
font-size: 16px;
border: 0;
border-bottom: 1px solid #ccc;
box-sizing: border-box;
}
ul.acorc li li:last-child a {
border-bottom: 0;
}
ul.acorh li:hover ul {
max-height: 300px;
transition: .3s all ease-in;
}
ul.acorh li a:hover {
background: #666;
color: #fff;
}

Tal que así:




Casi todo lo que veis en el CSS es formato de colores y demás, pero hay algo que que quiero destacar porque es precisamente lo que hace visibles o invisibles las subopciones.

Ese algo es la propiedad max-height del selector correspondiente a las listas anidadas o secundarias (ul.acorh li ul) que como podéis comprobar inicialmente tiene el valor cero. Luego para el mismo selector pero una vez hecho hover sobre su inmediatamente superior li (ul.acorh li:hover ul), ya ponemos un valor para max-height lo suficientemente alto (sin pasarnos) como para que quepan en esa altura el número máximo de subopciones que usemos para cualquier elemento principal.

De esta manera inicialmente la lista no se ve por tener altura cero y al pasar el puntero es cuando se expande ocupando la altura que necesite.

Podíamos haber usado height de la misma manera, pero en ese caso la transición que hemos incorporado para que el desplegado sea suave y no brusco, no hubiera funcionado. Cosas del CSS.


Desplegable con click: dispositivos táctiles


Para que la cosa funcione con un clic ya tenemos que echar mano de la pseudo-clase :target. En un principio sería sólo cuestión de cambiar el anteriormente mencionado selector ul.acorh li:hover ul por ul.acorh li:target ul, pero CSS es un poco puñetero y para que funcione como queremos es necesario que los elementos "clicables" tengan una id única y que además sus enlaces apunten a sí mismos.

Esto se traduce en un HTML como este, en el que la diferencia con el anterior son precisamente las id de los elementos de la lista principal y el contenido de sus enlaces, que en lugar de estar vacíos (#) llevan un marcador con el mismo id. Los cambios que habría que hacer sobre lo visto los he vuelto a marcar también con otro color.

<ul class="acorh">
  <li id="opcion1"><a href="#opcion1">OPCIÓN 1</a>
    <ul>
      <li><a href="URL11">Opción 1.1</a></li>
      <li><a href="URL12">Opción 1.2</a></li>
    </ul>
  </li>
  <li id="opcion2"><a href="#opcion2">OPCIÓN 2</a>
    <ul>
      <li><a href="URL21">Opción 2.1</a></li>
      <li><a href="URL22">Opción 2.2</a></li>
      <li><a href="URL23">Opción 2.3</a></li>
    </ul>
  </li>
  <li id="opcion3"><a href="#opcion3">OPCIÓN 3</a>
    <ul>
      <li><a href="URL31">Opción 3.1</a></li>
      <li><a href="URL32">Opción 3.2</a></li>
    </ul>
  </li>
</ul>

(*) Los URLXX de nuevo los tendréis que cambiar por las direcciones de destino de cada uno de los enlaces que incluya el menú.

Una vez hecho esto, el código CSS será exactamente el mismo que vimos antes salvo el selector ul.acorh li:hover ul, que como comenté antes pasará a ser ul.acorh li:target ul y que quedaría así:

ul.acorh li:target ul {
max-height: 300px;
transition: .3s all ease-in;
}

La demo con clic a continuación.



Para hacer que con un nuevo clic se plegara el último elemento desplegado ya tendríamos que recurrir a otro sistema con un CSS más complejo y no tan genérico, a la utilización de input o usar JavaScript.


Desplegable con hover y click


Esto es sencillo y además recomendable si queremos usar el hover, pero que en dispositivos táctiles el desplegable funcione también.

Para ello simplemente hemos de combinar los dos selectores vistos como alternativas e incluir en el CSS ambos:

ul.acorh li:hover ul,
ul.acorh li:target ul
{
max-height: 300px;
transition: .3s all ease-in;
}

¿Vemos otro post al azar por si le encuentras utilidad o quizás prefieres ser más metódico y suscribirte a nuestras entradas por correo? También puedes imprimir este artículo y por supuesto compartirlo en redes sociales si fue de tu agrado.

Compartir
Copy URL

Y muchos más artículos interesantes si nos sigues en...

follow us in feedly

6 comentarios :

  1. Hola Oloman, mira quisiera ponerle a un div position fixed cuando el scroll va por x altura, ahora mismo estoy probando este script

    $(function() {
    if ($('#sidebar-right-1').length) {
    var columna = $('#sidebar-right-1');
    var columnaHeight = $('#sidebar-right-1').height();
    var columnaTop = $('#sidebar-right-1').offset().top;
    var boleano = false;
    if(window.innerWidth < "920") {
    boleano = true;
    }
    $(window).scroll(function() {
    if(window.innerWidth > "900") {
    var columanMainOuterHeight = $('.main-oute').height();
    if(columanMainOuterHeight > "500") {
    if(boleano === true) {
    boleano = false;
    columnaTop = $('#sidebar-right-1').offset().top;
    }
    var limit = $('#caja-populares').offset().top - columnaHeight - 20;
    var windowTop = $(window).scrollTop();
    if (columnaTop < windowTop) {
    columna.css({position: "fixed", top: 20});
    } else {
    columna.css(&#39;position&#39;, &#39;static&#39;);
    }
    if (limit < windowTop) {
    var diff = limit - windowTop;
    columna.css({ top: diff });
    }
    }
    }else {
    columna.css('position', 'static');
    }
    });
    }
    });

    el script funciona (por el momento xD) pero quería preguntarte si ¿tienes algún script similar? uno que se adapte mejor al caso especial de blogger. Bueno eso es todo. saludos...

    ResponderEliminar
    Respuestas
    1. ¿El caso especial de Blogger? Si pones los selectores CSS de cada caja correctamente, da igual que sea Blogger que otro.

      Sobre tu pregunta, no tengo ninguno publicado, pero puedes buscar en Google "Portamento" un JavasScript prefabricado que creo hace lo que quieres.

      Eliminar
    2. "Portamento" ok, y sobre el selector css he agregado #sidebar-right-1 pero veo que también se puede usar .sidebar o el id del mismo gadget. Al inicio probé con las clases column-right-inner y column-right-outer pero nose, creo que será mejor usar el id del gadget. bueno si alguna vez veo que tengo muchos problemas con ese script probaré el "Portamento". Gracias nuevamente por tú ayuda

      Eliminar
  2. una pregunta que no viene al caso, pero estoy casi loco por no poder enviar mis twitter a mi pagina de facebook ya fui en twitter a configuracion, aplicaicones y si aparece facebokk pero no aparece conectar, dime que tengoque hacer para que mis twitter se publiquen solos en mi facebook

    ResponderEliminar
  3. Espera un poco porque tarda unos segundos en aparecer. Si no lo hace ya no tengo ni idea, así que lo mejor es que consultes el soporte de Twitter.

    ResponderEliminar