• Como

    Como hacer un Acordeón (accordion) con jQuery y CSS

    En este tutorial haremos un acordeón vertical usando jQuery con un código bastante minimalista y facil de entender, usaremos CSS para darle decoración y mejorar la experiencia de usuario.

    Estructura HTML

    Usaremos con una lista de definición o definition list (dl) para manejar la estructura de los contenidos, una vez comprendas el funcionamiento del código podrás adaptarlo a cualquier otra estructura:

    <dl>
        <dt>Titulo 1</dt>
        <dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur maxime cupiditate nesciunt molestias itaque vel reiciendis officiis explicabo cum impedit dolorem quod minus beatae architecto necessitatibus sed exercitationem aliquam omnis!</dd>
    
        <dt>Titulo 2</dt>
        <dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates mollitia quos! Dolor cum vitae aperiam deserunt hic quas quidem qui excepturi minima repudiandae pariatur id sit dignissimos laborum provident velit!</dd>
    
        <dt>Titulo 3</dt>
        <dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Optio voluptatum expedita sunt voluptatibus ratione assumenda quo animi numquam blanditiis asperiores illo laudantium et quae itaque reiciendis nam ducimus officiis officia?</dd>
    
        <dt>Titulo 4</dt>
        <dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto obcaecati numquam nemo quasi omnis accusamus illo distinctio doloribus architecto culpa maiores blanditiis laborum accusantium assumenda vero necessitatibus optio? Ipsa perferendis.</dd>
    
        <dt>Titulo 5</dt>
        <dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto obcaecati numquam nemo quasi omnis accusamus illo distinctio doloribus architecto culpa maiores blanditiis laborum accusantium assumenda vero necessitatibus optio? Ipsa perferendis.</dd>
      </dl>

    jQuery

    Luego procedemos a incluir a jQuery y ademas creamos un script en el cual ira nuestro código, si deseas puedes manejarlo en un JS aparte, pero para el ejemplo lo haremos todo junto:

    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
    
    </script>

    Lo primero que haremos sera ocultar todos los ‘dd’, pero no los dd que esten posteriores a un dt con clase .activo, esto nos va a permitir dejar un item abierto por defecto, luego procedemos a detectar cuando ‘dt’ sea presionado:

    $('dl dd').not('dt.activo + dd').hide(); 
    $('dl dt').click(function(){
    
    });

    Dentro del evento de click le pondremos una condición:

     $('dl dt').click(function(){
       if ($(this).hasClass('activo')) {
            $(this).removeClass('activo');
            $(this).next().slideUp();
       } else {
            $('dl dt').removeClass('activo');
            $(this).addClass('activo');
            $('dl dd').slideUp();
            $(this).next().slideDown();
       }
    });

    (Linea 23) Si es que este ‘dt’ que acabamos de cliquear tiene la clase .activo (osea si esta abierto) le quitamos la clase .activo (linea 24) y hacemos que el elemento que le sigue, que vendría a ser el ‘dd’ adyacente (que esta mostrandose), se oculte (linea 25).

    En caso contrario (que muy probablemente vendría a ser el estado por defecto) al hacerle clic, lo primero que hará es quitarle .activo a todos los demás ‘dt’ (linea 27), pero le asignamos .activo al que acabamos de cliquear (linea 28), luego ocultamos todos los ‘dd’ (linea 29) y por ultimo mostramos solo el ‘dd’ que le sigue a este ‘dt’ (linea 30), de esta forma solo se muestra uno a la vez.

    CSS

    Hasta allí lo tendríamos completamente funcional, sin embargo la experiencia no es tan agradable, para mejorar esto usaremos algo de CSS:

    *{ font-family: sans-serif; margin: 0;}
    dl{ margin: 60px auto; width: 600px; }
    dt, dd{ padding: 20px; }
    dt{ background: #333333; color: white; border-bottom: 1px solid #141414; border-top: 1px solid #4E4E4E; cursor: pointer; }
    dd{ background: #F5F5F5; line-height: 1.6em; }
    dt.activo, dt:hover{ background: #424242; }

    Va quedado mejor, pero podemos hacer mas aun, le vamos a añadir unas flechitas con la ayuda de la pseudo-clase :after.

    dt:before{ content: "▸"; margin-right: 10px; }
    dt.activo:before{ content: "▾"; }

    Lo que estamos haciendo aqui es que, por defecto antes de todo dt haya una ‘▸’, pero si este dt esta .activo que esta cambie a ‘▾’.

    Dejar un item activado por defecto

    Si queremos dejar un item abierto por defecto, simplemente le ponemos al dt la clase activo, ya que al cargar la pagina no va a ocultar los dd que esten posteriores a un dt con clase activo:

    <dt class="activo">Titulo 3</dt>
    <dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Optio voluptatum expedita sunt voluptatibus ratione assumenda quo animi numquam blanditiis asperiores illo laudantium et quae itaque reiciendis nam ducimus officiis officia?</dd>

    Código Final

    <!DOCTYPE HTML>
    <html lang="en-US">
    <head>
    	<meta charset="UTF-8">
    	<title></title>
    	<style type="text/css">
    		*{ font-family: sans-serif; margin: 0;}
    		dl{ margin: 60px auto; width: 600px; }
    		dt, dd{ padding: 20px; }
    		dt{ background: #333333; color: white; border-bottom: 1px solid #141414; border-top: 1px solid #4E4E4E; cursor: pointer; }
    		dd{ background: #F5F5F5; line-height: 1.6em; }
    		dt.activo, dt:hover{ background: #424242; }
    
    		dt:before{ content: "▸"; margin-right: 10px; }
    		dt.activo:before{ content: "▾"; }
    	</style>
    </head>
    <body>
    	<dl>
    		<dt>Titulo 1</dt>
    		<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur maxime cupiditate nesciunt molestias itaque vel reiciendis officiis explicabo cum impedit dolorem quod minus beatae architecto necessitatibus sed exercitationem aliquam omnis!</dd>
    
    		<dt>Titulo 2</dt>
    		<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates mollitia quos! Dolor cum vitae aperiam deserunt hic quas quidem qui excepturi minima repudiandae pariatur id sit dignissimos laborum provident velit!</dd>
    
    		<dt>Titulo 3</dt>
    		<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Optio voluptatum expedita sunt voluptatibus ratione assumenda quo animi numquam blanditiis asperiores illo laudantium et quae itaque reiciendis nam ducimus officiis officia?</dd>
    
    		<dt>Titulo 4</dt>
    		<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto obcaecati numquam nemo quasi omnis accusamus illo distinctio doloribus architecto culpa maiores blanditiis laborum accusantium assumenda vero necessitatibus optio? Ipsa perferendis.</dd>
    
    		<dt>Titulo 5</dt>
    		<dd>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto obcaecati numquam nemo quasi omnis accusamus illo distinctio doloribus architecto culpa maiores blanditiis laborum accusantium assumenda vero necessitatibus optio? Ipsa perferendis.</dd>
    	</dl>
    	<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    	<script type="text/javascript">
    	  $('dl dd').not('dt.activo + dd').hide();
           $('dl dt').click(function(){
              if ($(this).hasClass('activo')) {
                   $(this).removeClass('activo');
                   $(this).next().slideUp();
              } else {
                   $('dl dt').removeClass('activo');
                   $(this).addClass('activo');
                   $('dl dd').slideUp();
                   $(this).next().slideDown();
              }
           });
    	</script>
    </body>
    </html>

    Si tienes alguna duda ponla en los comentarios, puedes ver el resultado final en este enlace y/o descargar el código fuente desde aquí.

  • Josue Ochoa

    Hola, soy el editor de este blog, trabajo como desarrollador web freelance, sígueme en Twitter.

  • Tal vez te interese
Acerca de

WebTursos es un blog de tutoriales, articulos y recursos para diseñadores y desarrolladores web. mas...

Suscribete

Suscríbete para recibir los últimos posts directamente en tu bandeja de entrada: