Monday, August 12, 2013

How to make aside menu with nice effect on showing.


In this tutorial I will show You how create aside menu with interesting flip effect for main content of page. It uses CSS3 transition and transform. Javascript is used for manipulate classes.

On this screenshoot below you can find how it looks like:

Aside menu in use
Aside menu in use

To see this in action just scroll to end of post and watch demo.

Main content:

As a example content I used sample page from Bootstrap 3 RC1 (more about news from Bootstrap 3 you can read here). Whole content is wrapped by div with id content which is also wrapped by div with id main.

For aside menu we need create new container. For me it's div with id asideMenu. There I put example navigation founded on twitter bootstrap.

Style time:

Ok, we created content but now we need add style for this. To do this I used Sass, which I also want to learn in the middle of doing this aside menu demo. We need hide menu on start, so I set position absolute and move menu -40% in right side. Exaclty this same dimension need to be set also for width of menu.

Second step is settings for aside menu when it is showed. For this I using class moved. It's simple, You need just move position from right -40% to 0. To make this move smoothly I add CSS transition property. Here are CSS rules for aside menu:

  #asideMenu
    @include posAbsolute(right, top, -40%)
    width: 40%
    height: 100%
    padding-left: 10px
    background-color: #eee
    @include transition(all, .2s)
      
    &.moved
      background-color: #fff
      width: 40%
      right: 0
      
    #buttonOpen
      @include posAbsolute(left, top, -100px, 15px)
      
    #buttonClose
      @include posAbsolute(right, top, 10px, 10px)

Rest of rules for page content you can find here:
body
  background-color: #222 !important
  font: 15px Tahoma
  height: 100%
  width: 100%
  
  #main
    overflow: hidden
    @include posAbsolute
    @include maxSize
    @include transition(all, .2s)
  
  #content
    text-align: center
    background-color: #fff
    box-shadow: 0 0 20px 30px #ccc
    @include transform
    @inclide posAbsolute
    @include maxSize
    @include transition(all, .4s)
      
    &.moved
      background-color: #ccc
      @include transform(-45deg, -40%)

I use mixins because it's supports DRY. You don't need repeat each time whole properties, like transition, for each browser. Definition for transition, transform, maxSize, posAbsolute mixins you can find below:

@mixin transition($property: all, $time: .2s)
  transition-duration: $time
  -o-transition-duration: $time
  -ms-transition-duration: $time
  -moz-transition-duration: $time
  -webkit-transition-duration: $time
  
  transition-property: $property
  -o-transition-property: $property
  -ms-transition-property: $property
  -moz-transition-property: $property
  -webkit-transition-property: $property
  
  transition-timing-function: ease-in-out
  -o-transition-timing-function: ease-in-out
  -ms-transition-timing-function: ease-in-out
  -moz-transition-timing-function: ease-in-out
  -webkit-transition-timing-function: ease-in-out

@mixin transform($rotateY: 0deg, $translateX: 0%, $perspective: 900px)  
  -webkit-transform: perspective(900px) rotateY($rotateY) translateX($translateX)
  -moz-transform: perspective(900px) rotateY($rotateY) translateX($translateX)
  -ms-transform: perspective(900px) rotateY($rotateY) translateX($translateX)
  -o-transform: perspective(900px) rotateY($rotateY) translateX($translateX)
  transform: perspective(900px) rotateY($rotateY) translateX($translateX)
  
  -webkit-transform-style: preserve-3d
  -moz-transform-style: preserve-3d
  -ms-transform-style: preserve-3d
  -o-transform-style: preserve-3d
  
@mixin maxSize
  width: 100%
  height: 100%
  
@mixin posAbsolute($side: left, $level: top, $sideVal: 0, $levelVal: 0)
  position: absolute
  #{$side}: $sideVal
  #{$level}: $levelVal

...and some Javascript for end

Because I need add class to some DOM elements on page, when button "Options" is pressed, I included some javascript. Otherwise I make it working on mobile devices. To open aside menu You need swipe your finger from right to left side. To close the menu just move your finger from left to right.

Javascript code:

(function(document, undefined){
  var asideMenu = document.getElementById('asideMenu'),
      content = document.getElementById('content'),
      buttonOpen = document.getElementById('buttonOpen'),
      buttonClose = document.getElementById('buttonClose'),
      startTouchPos = 0, endTouchPos  = 0,
      openMenu = function(){
        content.className = asideMenu.className = 'moved';
        buttonOpen.style.visibility = 'hidden'
      },
      closeMenu = function(){
        content.className =  asideMenu.className ='';      
        setTimeout(function(){
          buttonOpen.style.visibility = ''
        }, 200);
      };
  
  document.addEventListener('touchstart', function(e){
    startTouchPos = parseInt(e.touches[0].clientX,10);
  });
  
  document.addEventListener('touchmove', function(e){
    e.preventDefault();
    endTouchPos = parseInt(e.touches[0].clientX, 10);
  });
  
  document.addEventListener('touchend', function(e){    
    if(endTouchPos < startTouchPos && (startTouchPos - endTouchPos > 50) ){ openMenu() }
    else if(endTouchPos > startTouchPos && (endTouchPos - startTouchPos > 50)){ closeMenu() }
    startTouchPos = endTouchPos = 0;
  });
  
  buttonClose.addEventListener('click', function(){ closeMenu() });
  buttonOpen.addEventListener('click', function(){ openMenu() });
  
})(document)

Demo:

Enjoy: http://codepen.io/lukasz-zak/full/hioAy

No comments :

Post a Comment