Retina-ready Flipping Accordion Menu with jQuery and CSS3

Retina-ready Flipping Accordion Menu with jQuery and CSS3
File Size: 187 KB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

A cool, themeable, retina-ready, jQuery based accordion menu that opens with an awesome 3D flipping effect using several CSS3 properties.

How to use it:

1. Create a vertical accordion menu with a toggle button as follows:

<div id="viewport">
  <div id="card">
    <div id="front">
      <!-- toggle button -->
      <div class="power"></div>
      <div class="powerdown"></div>
      <!-- toggle button end-->
    </div>
    <div id="back">
      <!-- accordion menu start-->
      <ul class="mainmenu">
        <li><img src="images/palette.png" alt="Palette icon" class="icon"><span>Themes</span></li>
          <ul class="submenu">
            <div class="expand-triangle"><img src="images/expand.png"></div>
            <li id="theme1" class="chosen"><span>Blue</span></li>
            <li id="theme2"><span>Teal</span></li>
          </ul>           
        <li><img src="images/user.png" alt="User icon" class="icon"><span>Account<span></li>
          <ul class="submenu">
            <div class="expand-triangle"><img src="images/expand.png"></div>
            <li><span>About</span></li>
            <li><span>Picture</span></li>
            <li><span>Email</span></li>
            <li><span>Website</span></li>
          </ul>
        <li><img src="images/envelope.png" alt="Envelope icon" class="icon"><span>Messages</span><div class="messages">23</div></li>
          <ul class="submenu">
            <div class="expand-triangle"><img src="images/expand.png"></div>
            <li><span>Inbox</span></li>
            <li><span>Draft</span></li>
            <li><span>Sent</span></li>
            <li><span>Trash</span></li>
          </ul>
        <li><img src="images/cog.png" alt="Cog icon" class="icon"><span>Settings</span></li>
          <ul class="submenu">
            <div class="expand-triangle"><img src="images/expand.png"></div>
            <li><span>Password</span></li>
            <li><span>Notifications</span></li>
            <li><span>Language</span></li>
            <li><span>Privacy</span></li>
            <li><span>Payments</span></li>
          </ul>
        <li><img src="images/key.png" alt="Key icon" class="icon"><span>Logout</span></li>
      </ul>
      <!-- accordion menu end-->
    </div>
  </div>
</div>

2. The main CSS / CSS3 styles.

/*------------ Themes ------------*/

.blue { background-color: #40529B; }

.blue-border { border-top: 1px solid #263A8D; }

.teal { background-color: #008080; }

.teal-border { border-top: 1px solid #006868; }

/*------------ Toggle Button ------------*/

.power {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -46px;
  width: 92px;
  height: 92px;
  margin-top: -46px;
  cursor: pointer;
  background: url('../images/powerup.png') top center no-repeat;
}

.power:hover { background: url('../images/powerdown.png') top center no-repeat; }

.powerdown {
  background: url('../images/powerdown.png') top center no-repeat;
  display: hidden;
}

/*------------ Main Menu ------------*/

.mainmenu {
  font-size: 16px;
  position: relative;
  margin: 0;
  padding: 0;
  box-shadow: 0 5px 10px rgba(0,0,0,.35);
  border-radius: 7px;
}

.mainmenu > li {
  box-sizing: border-box;
  height: 48px;
  color: #f7f1e3;
}

.mainmenu > li:first-child {
  border-top: 0;
  border-radius: 7px 7px 0 0;
}

.mainmenu > li:last-child { border-radius: 0 0 7px 7px; }

.mainmenu > li span {
  line-height: 48px;
  display: block;
}

.mainmenu > li .icon {
  display: block;
  float: left;
  width: 20px;
  height: 20px;
  padding: 14px 20px 0 20px;
}

.mainmenu > li .messages {
  font-size: 11px;
  line-height: 19px;
  display: block;
  float: right;
  width: 34px;
  height: 18px;
  margin-top: -33px;
  margin-right: 19px;
  padding: 0;
  text-align: center;
  background: url("../images/messages.png") no-repeat;
}

.expand-triangle {
  width: 276px;
  height: 10px;
  content: " ";
  margin-left: -40px;
}

.expand-triangle img {
  width: inherit;
  height: inherit;
  vertical-align: top;
}

/*------------ Sub Menu ------------*/

.submenu {
  font-size: 13px;
  box-sizing: border-box;
  content: " ";
  color: #ae9f9f;
}

.submenu li {
  line-height: 20px;
  height: 35px;
  margin-left: -40px;
  padding-top: 11px;
  transition: border-left 220ms ease-in;
  border-left: solid 6px #484141;
  background-color: #484141;
}

.submenu .chosen, .submenu .chosen:hover { border-left: solid 6px #96d145; }

.submenu li:hover { border-left: solid 6px #ae9f9f; }

.submenu li span { margin-left: 30px; }

/*------------ 3D --------------*/

#viewport {
  -webkit-perspective: 1000px;
  -moz-perspective: 1000px;
  perspective: 1000px;
  width: 276px;
  height: 240px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -250px 0 0 -138px;
}

#card {
  -webkit-transform-style: preserve-3D;
  -moz-transform-style: preserve-3D;
  transform-style: preserve-3D;
  width: 100%;
  height: 100%;
  border-radius: 7px;
}

#card > div {
  position: absolute;
  backface-visibility: hidden;
}

#front {
  -webkit-transform: translateZ(1px);
  -moz-transform: translateZ(1px);
  transform: translateZ(1px);
  box-shadow: 0 5px 10px rgba(0,0,0,.35);
}

#back {
  -webkit-transform: translateZ(-1px) rotateY(180deg);
  -moz-transform: translateZ(-1px) rotateY(180deg);
  transform: translateZ(-1px) rotateY(180deg);
}

#front, #back {
  border-radius: 7px;
  width: 100%;
  height: 100%;
  position: relative;
}

.flip {
  -webkit-animation: animate 400ms forwards ease-in-out;
  -moz-animation: animate 400ms forwards ease-in-out;
  animation: animate 400ms forwards ease-in-out;
}

@-webkit-keyframes 
animate {  to {
-webkit-transform: rotateY(-180deg);
}

from { -webkit-transform: rotateY(0deg); }
}

@-moz-keyframes 
animate {  to {
-moz-transform: rotateY(-180deg);
}

from { -moz-transform: rotateY(0deg); }
}

@keyframes 
animate {  to {
transform: rotateY(-180deg);
}

from { transform: rotateY(0deg); }
}

.flipback {
  -webkit-animation: animateback 400ms forwards ease-in-out;
  -moz-animation: animateback 400ms forwards ease-in-out;
  animation: animateback 400ms forwards ease-in-out;
}

@-webkit-keyframes 
animateback {  to {
-webkit-transform: rotateY(0deg);
}

from { -webkit-transform: rotateY(-180deg); }
}

@-moz-keyframes 
animateback {  to {
-moz-transform: rotateY(0deg);
}

from { -moz-transform: rotateY(-180deg); }
}

@keyframes 
animateback {  to {
transform: rotateY(0deg);
}

from { transform: rotateY(-180deg); }
}

3. Include the necessary jQuery library on the web page.

<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>

4. Include the retina.js for retina support.

<script src="js/retina.min.js"></script>

5. The core JavaScript to active the accordion menu.

$(document).ready( function() {
  
  // themes
  var $theme1 = 'blue',
    $theme2 = 'teal';
  
  // handlers
  var $card = $('#card'),
    $mainmenu = $card.find('.mainmenu'),
    $submenu = $card.find('.submenu');
  
  // initial setup
  $mainmenu.children('li').addClass($theme1).addClass('blue-border');
  $card.find('#front,#back').addClass($theme1);
  $submenu.find('.expand-triangle').addClass($theme1);
  $submenu.hide();
  
  // clicking on submenu items puts green light on left
  $submenu.on('click','li', function() {
    $submenu.siblings().find('li:not(#theme1,#theme2)').removeClass('chosen');
    $(this).addClass('chosen');
  });
  
  // set theme1
  $submenu.on('click', '#theme1', function() {
    $(this).next('#theme2').removeClass('chosen');
    $mainmenu.children('li')
      .addClass($theme1).addClass('blue-border')
      .removeClass($theme2).removeClass('teal-border');
    $card.find('#front,#back')
      .addClass($theme1)
      .removeClass($theme2);
    $submenu.find('.expand-triangle').addClass($theme1).removeClass($theme2);
  });
  
  // set theme2
  $submenu.on('click', '#theme2', function() {
    $(this).prev('#theme1').removeClass('chosen');
    $mainmenu.children('li')
      .addClass($theme2).addClass('teal-border')
      .removeClass($theme1).removeClass('blue-border');
    $card.find('#front,#back')
      .addClass($theme2)
      .removeClass($theme1);
    $submenu.find('.expand-triangle').addClass($theme2).removeClass($theme1);
  });

  // click on menu expands submenu and closes others' submenu
  $mainmenu.on('click', 'li', function() {
    $(this).next('.submenu').slideToggle().siblings('.submenu').slideUp();
  });
  
  // click logout -> flip to power
  $mainmenu.children('li:last-child').on('click', function() {
    
    // close all submenus before flipping,
    // so height of card is always same at flip time
    $submenu.slideUp(200);
    
    setTimeout(function(){
      $card.addClass('flipback');
    },300);
    
    if($card.hasClass('flip')) {
      setTimeout(function(){
        $card.removeClass('flip');
      },300);
    }
  });
  
  // click on power -> flip to menu
  $('.power').on('click', function() {
    
    setTimeout(function(){
      $card.addClass('flip');
    },300);
    
    if($card.hasClass('flipback')) {
      setTimeout(function(){
        $card.removeClass('flipback');
      },300);
    }
    
    $submenu.first().delay(900).slideDown(400);
  });
});

This awesome jQuery plugin is developed by jpazmino. For more Advanced Usages, please check the demo page or visit the official website.