Responsive Sidebar in a Modal Window to Avoid Having to Scroll

Many responsive designs push the sidebar (or sidebars) below the main content area at narrower browser window sizes. Nothing wrong with this type of design, it makes sense to have the main content come first. Viewing the content in the sidebar on devices with small screens, however, could mean quite a bit of scrolling. A responsive sidebar in a modal window can solve this.

By having a link positioned at the top of the page that – when clicked – will bring up the sidebar in a modal window (kind of like a lightbox), users browsing on small devices won’t have to scroll down to get to the sidebar content.

Below you can check out the HTML, CSS and jQuery code I’ve used to design this type of responsive sidebar, but perhaps you wanna have a look at the demo first?

Page Structure used in the Demo

<body id="page-top">
   
   <!-- 
   The link for bringing the responsive 
   sidebar up in a modal window,
   also a secondary content skiplink 
   for screen readers
   -->
   <a id="responsive-sidebar-trigger" href="#sidebar">
      Secondary Content
   </a>
   
   <div id="content">

      <div class="inner">
         
         <div id="main">
         
            <div class="inner">
               
               Main content stuff
               
            </div>
            
         </div>
         
         <div id="sidebar">
               
            <div class="inner">
               
               Sidebar stuff...
               
            </div>
      
         </div>
   
         <div id="footer">
         
            <p id="copyright-and-such">
            
               <strong>Footer</strong>
               
            </p>
            
         </div>
      
      </div>
   
   </div>
   
</body>

Javascript Function for Toggling the Responsive Sidebar Effect

/* 
For displaying the sidebar in 
a modal window (kind of a lightbox). 
Uses a skip link to secondary content as a trigger link .
*/
function setupResponsiveSidebar() {
   
   $('body').append('<div id="body_overlay"></div>');
   
   var $body_overlay = $('#body_overlay');
   
   var $responsive_sidebar_trigger = $("#responsive-sidebar-trigger");
   
   var $sidebar = $("#sidebar");
   
   $sidebar.find(".inner").prepend('<a href="#page-top" id="sidebar-close">Close [X]</a>');
   
   var $sidebar_close = $("#sidebar-close");
   
   $sidebar_close.hide();
   
   $(window).bind('hashchange', function() {
      
      var current_hash = window.location.hash.substring(1);
      
      if( !current_hash || current_hash != 'sidebar' ) {
      
         if( $sidebar.hasClass('responsive-sidebar') ) {
            
            $responsive_sidebar_trigger.trigger('click');
               
         }
         
      }
   });
   
   
   /* 
   Toggle the responsive sidebar visibility 
   */
   $responsive_sidebar_trigger.on("click", function( ev ) {
      
      if( !$sidebar.hasClass('responsive-sidebar') ) {
         
         $sidebar_close.show();
         
         var docHeight = $(document).height();
         
         $body_overlay.show().css( 'height' , docHeight + 'px');
         
         $sidebar.addClass('responsive-sidebar');
         
         setTimeout(function(){
            $("html,body").scrollTop($sidebar.offset().top);
         }, 0);
         
      }
      else {
         
         $sidebar_close.hide();
         
         $body_overlay.hide();
         
         $sidebar.removeClass('responsive-sidebar');
         
      }
      
   });
   
   /* 
   Trigger responsive sidebar visibility  change
   */
   $sidebar_close.on("click", function() {
   
      $responsive_sidebar_trigger.trigger('click');
   
   });
}

Style

This is the style I’ve used for the demo. The most relevant selectors are .responsive-sidebar and #responsive-sidebar-trigger. The others are mostly for the full page style.

#content {
   max-width: 60em; 
   margin: 0 auto; 
   padding-top:2%;
   text-shadow:0 1px 0 #fdfdfd;
}

#main {
   float:left;
   width:60%;
   margin-top:2%;
}

#sidebar {
   width:36%;
   float:right;
   margin-top:2%;
}
#sidebar ul {
   list-style:none;
}

#main .inner, #sidebar .inner {
   border:1px dashed #ccc;	
}

#main .inner {
   min-height:4000px;
   position:relative;
}

#main .inner:after {
   content:'[End of main content]';
   position:absolute;
   bottom:0;
   margin-bottom:1em;
   font-weight:bold;
}
.inner {
   padding:2% 4%;
}

/* 
For lightbox (modal window) effect 
*/
#body_overlay {
   display:none;
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height:100%;
   background: #777;
   z-index:9999;
   /* IE 8 */
   -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";

   /* IE 5 - 7 */
   filter: alpha(opacity=70);

   /* Safari 1.x */
   -khtml-opacity: 0.7;
   
   /* Netscape */
   -moz-opacity: 0.7;

   /* Others */
   opacity: 0.7;
}


/* 
To view the sidebar as a modal window
(sort of a lightbox)
*/
.responsive-sidebar {
   background:#f0f0f0;
   position:absolute;
   z-index:10000 !important;
   width:86% !important;
   left:7%;
   right:7%;
   top:7%;
   -moz-box-shadow: #111 0.2em 0.2em 0.85em;  
   -webkit-box-shadow: #111 0.2em 0.2em 0.85em;    
    box-shadow: #111 0.2em 0.2em 0.85em;  	
    border:1px solid #aaa;
}

.responsive-sidebar .inner {
   padding-top:3em;
}

/*
The close trigger element within the modal window 
*/
.responsive-sidebar a#sidebar-close {
   position:absolute;
   right:1em;
   top:1em;
   padding:0.25em;
   background:#606060;
   color:#ddd;
   margin-bottom:1em;
   cursor:pointer;
   border:1px solid #999;
   text-decoration:none;
   z-index:10001;
   text-shadow:none !important;
   letter-spacing:2px;
   text-transform:uppercase;
   font-weight:bold;
   font-size:90%;
}

/*
Hide the responsive sidebar trigger link initially, 
but not for screen readers 
*/
#responsive-sidebar-trigger {
   position: absolute !important; 
   top: -9999px !important;
   left: -9999px !important;
}

/*
Make the responsive 
sidebar trigger link look like a button
*/
#responsive-sidebar-trigger {
   background:#ccc;
   color:#777;
   text-align:center;
   padding: 0.6em 2.5%;
   cursor:pointer;
   width:70%;
   max-width:20em;
   font-size:70%;
   font-weight:bold;
   letter-spacing:2px;
   text-shadow:0 1px 0 #f7f7f7;
   text-transform:uppercase;
   text-decoration:none;
   display:inline-block;
   border: 1px solid #ddd;
   -moz-border-radius: 3px;
   -webkit-border-radius: 3px;
   -o-border-radius: 3px;
   -ms-border-radius: 3px;
   -khtml-border-radius: 3px;
   border-radius: 3px;
   background-image: -webkit-linear-gradient(#eee,#ddd);
   background-image: -moz-linear-gradient(#eee,#ddd);
   background-image: -o-linear-gradient(#eee,#ddd);
   background-image: linear-gradient(#eee,#ddd);
   -moz-background-clip: padding;
   -webkit-background-clip: padding;
   -o-background-clip: padding-box;
   -ms-background-clip: padding-box;
   -khtml-background-clip: padding-box;
   background-clip: padding-box;
   -moz-box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.5);
   -webkit-box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.5);
   box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.5);
   margin:1em;
}

/*
Arrow to the right of the link text
*/
#responsive-sidebar-trigger:after {
   display:inline-block;
   content:"";
   border-color: #999 transparent;
   border-style: solid;
   border-width: 0.5em 0.5em 0 0.5em;	
   padding:0;
   height: 0;
   width: 0;
   margin:0 0 0.15em 2.5%;	
}

#responsive-sidebar-trigger:active {
   background-color: #f9f9f9;
}

/* 
   Max-width Media Query
*/
@media screen and (max-width:42em) {
   /* 
   Make everything vertical and unfloated 
   */
   #main, #sidebar {
      float: none !important;
      width: auto !important;
   }
   #responsive-sidebar-trigger {
      position: static !important;
   }
}

4 Responses

  1. tree says:

    It would have been a lot more helpful if you have an area where you show how your codes actually behave, rather than just describing everything in text and codes. Afterall, if your demo works, then we can simply view source to see some (if not all) of your codes. Within seeing the sample, it’s not even clear if your codes actually work or not.

  2. Marta says:

    Works great when I tried in my galaxy nexus!

  3. RMAU says:

    You have full control of what is displayed in popup, align it to any side via CSS, enable or disable scroll on right side of window – whatever.