Smooth Responsive Accordion Widget With JS and CSS3

Category: Accordion , Javascript | August 31, 2014
Author:chriswrightdesign
Views Total:4,835 views
Official Page:Go to website
Last Update:August 31, 2014
License:MIT

Preview:

Smooth Responsive Accordion Widget With JS and CSS3

Description:

A fully responsive accordion widget which allows you to toggle content sections with smooth sliding animations and text zoom effects. Created by chriswrightdesign.

How to use it:

Create an accordion widget using dl, dt, dd elements as follows.

<div class="accordion">
  <dl>
    <dt><a class="accordionTitle" href="#">First Accordion heading</a></dt>
    <dd class="accordionItem accordionItemCollapsed">
      <p>First Accordion Content</p>
    </dd>
    <dt><a href="#" class="accordionTitle">Second Accordion heading</a></dt>
    <dd class="accordionItem accordionItemCollapsed">
      <p>Second Accordion Content</p>
    </dd>
    <dt><a href="#" class="accordionTitle">Third Accordion heading</a></dt>
    <dd class="accordionItem accordionItemCollapsed">
      <p>Third Accordion Content</p>
    </dd>
  </dl>
</div>

The required CSS to style the accordion.

* {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}
.accordion dl { border: 1px solid #ddd; }
.accordion dl:after {
  content: "";
  display: block;
  height: 1em;
  width: 100%;
  background-color: #c0392b;
}
.accordion dt > a {
  text-align: center;
  font-weight: 700;
  padding: 2em;
  display: block;
  text-decoration: none;
  color: #fff;
  -webkit-transition: background-color 0.5s ease-in-out;
  -moz-transition: background-color 0.5s ease-in-out;
  transition: background-color 0.5s ease-in-out;
}
.accordion dd {
  background-color: #eee;
  font-size: 1em;
  line-height: 1.5em;
}
.accordion dd > p {
  padding: 1em 2em 1em 2em;
  margin: 0;
}
.accordion {
  position: relative;
  background-color: #eee;
}
.container {
  max-width: 960px;
  margin: 0 auto;
  padding: 2em 0 2em 0;
}
.accordionTitle {
  background-color: #e74c3c;
  border-bottom: 1px solid #c0392b;
}
.accordionTitle:before {
  content: "+";
  font-size: 1.5em;
  line-height: 0.5em;
  float: left;
  -moz-transition: -moz-transform 0.3s ease-in-out;
  -o-transition: -o-transform 0.3s ease-in-out;
  -webkit-transition: -webkit-transform 0.3s ease-in-out;
  transition: transform 0.3s ease-in-out;
}
.accordionTitle:hover { background-color: #c0392b; }
.accordionTitleActive { background-color: #c0392b; }
.accordionTitleActive:before {
  -webkit-transform: rotate(-225deg);
  -moz-transform: rotate(-225deg);
  transform: rotate(-225deg);
}
.accordionItem {
  height: auto;
  overflow: hidden;
}

The CSS3 rules to animate the accordion.

.accordionItemCollapsed { max-height: 0; }
.animateIn {
  -webkit-animation-name: accordionIn;
  -webkit-animation-duration: 0.65s;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-direction: normal;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-fill-mode: both;
  -webkit-animation-delay: 0s;
  -moz-animation-name: normal;
  -moz-animation-duration: 0.65s;
  -moz-animation-iteration-count: 1;
  -moz-animation-direction: alternate;
  -moz-animation-timing-function: ease-in-out;
  -moz-animation-fill-mode: both;
  -moz-animation-delay: 0s;
  animation-name: accordionIn;
  animation-duration: 0.65s;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-timing-function: ease-in-out;
  animation-fill-mode: both;
  animation-delay: 0s;
}
.animateOut {
  -webkit-animation-name: accordionOut;
  -webkit-animation-duration: 0.75s;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-direction: alternate;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-fill-mode: both;
  -webkit-animation-delay: 0s;
  -moz-animation-name: accordionOut;
  -moz-animation-duration: 0.75s;
  -moz-animation-iteration-count: 1;
  -moz-animation-direction: alternate;
  -moz-animation-timing-function: ease-in-out;
  -moz-animation-fill-mode: both;
  -moz-animation-delay: 0s;
  animation-name: accordionOut;
  animation-duration: 0.75s;
  animation-iteration-count: 1;
  animation-direction: alternate;
  animation-timing-function: ease-in-out;
  animation-fill-mode: both;
  animation-delay: 0s;
}
 @-webkit-keyframes 
accordionIn {  0% {
 opacity: 0;
 -webkit-transform: scale(0.8);
}
 100% {
 opacity: 1;
 -webkit-transform: scale(1);
}
}
@-moz-keyframes 
accordionIn {  0% {
 opacity: 0;
 -moz-transform: scale(0.8);
}
 100% {
 opacity: 1;
 -moz-transform: scale(1);
}
}
@keyframes 
accordionIn {  0% {
 opacity: 0;
 transform: scale(0.8);
}
 100% {
 opacity: 1;
 transform: scale(1);
}
}
@-webkit-keyframes 
accordionOut {  0% {
 opacity: 1;
 -webkit-transform: scale(1);
}
 100% {
 opacity: 0;
 -webkit-transform: scale(0.8);
}
}
@-moz-keyframes 
accordionOut {  0% {
 opacity: 1;
 -moz-transform: scale(1);
}
 100% {
 opacity: 0;
 -moz-transform: scale(0.8);
}
}
@keyframes 
accordionOut {  0% {
 opacity: 1;
 transform: scale(1);
}
 100% {
 opacity: 0;
 transform: scale(0.8);
}
}

Make the accordion responsive with CSS3 media queries.

 

@media all {
.accordionItem {
  max-height: 50em;
  -moz-transition: max-height 1s;
  -o-transition: max-height 1s;
  -webkit-transition: max-height 1s;
  transition: max-height 1s;
}
}
@media screen and (min-width: 48em) {
.accordionItem {
  max-height: 15em;
  -moz-transition: max-height 0.5s;
  -o-transition: max-height 0.5s;
  -webkit-transition: max-height 0.5s;
  transition: max-height 0.5s;
}
}

The Javascript to enable the accordion.

( function( window ) {
'use strict';
function classReg( className ) {
  return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
var hasClass, addClass, removeClass;
if ( 'classList' in document.documentElement ) {
  hasClass = function( elem, c ) {
    return elem.classList.contains( c );
  };
  addClass = function( elem, c ) {
    elem.classList.add( c );
  };
  removeClass = function( elem, c ) {
    elem.classList.remove( c );
  };
}
else {
  hasClass = function( elem, c ) {
    return classReg( c ).test( elem.className );
  };
  addClass = function( elem, c ) {
    if ( !hasClass( elem, c ) ) {
      elem.className = elem.className + ' ' + c;
    }
  };
  removeClass = function( elem, c ) {
    elem.className = elem.className.replace( classReg( c ), ' ' );
  };
}
function toggleClass( elem, c ) {
  var fn = hasClass( elem, c ) ? removeClass : addClass;
  fn( elem, c );
}
var classie = {
  hasClass: hasClass,
  addClass: addClass,
  removeClass: removeClass,
  toggleClass: toggleClass,
  has: hasClass,
  add: addClass,
  remove: removeClass,
  toggle: toggleClass
};
if ( typeof define === 'function' && define.amd ) {
  define( classie );
} else {
  window.classie = classie;
}
})( window );
var $ = function(selector){
  return document.querySelector(selector);
}
var accordion = $('.accordion');
accordion.addEventListener("click",function(e) {
  e.stopPropagation();
  e.preventDefault();
  if(e.target && e.target.nodeName == "A") {
    var classes = e.target.className.split(" ");
    if(classes) {
      for(var x = 0; x < classes.length; x++) {
        if(classes[x] == "accordionTitle") {
          var title = e.target;
          var content = e.target.parentNode.nextElementSibling;
         
          classie.toggle(title, 'accordionTitleActive');
          if(classie.has(content, 'accordionItemCollapsed')) {
            if(classie.has(content, 'animateOut')){
              classie.remove(content, 'animateOut');
            }
            classie.add(content, 'animateIn');
          }else{
             classie.remove(content, 'animateIn');
             classie.add(content, 'animateOut');
          }
          classie.toggle(content, 'accordionItemCollapsed');
        }
      }
    }
  }
});

You Might Be Interested In:


3 thoughts on “Smooth Responsive Accordion Widget With JS and CSS3

  1. mohamad

    hi good job, i wana use accordion in a element but it doesnt work. can you help me?

    Reply
  2. S.AATHITHYAN

    Hi,

    I have used this and found useful. But I am trying to have a link inside the accordion. When I do it, it is not working. However if I open it in new tab it works. any help?

    Reply

Leave a Reply