View RSS Feed

Beverleyh

Multi-Level, Off-Canvass Menu with IE7/8 support

Rating: 23 votes, 5.00 average.
Hidden side menus, like the ones used in Facebook and Youtube apps, are a space-saving alternative to traditionally visible desktop menus. This post introduces an upgrade to the earlier CSS-only off-canvass menu, that makes it possible for IE7/8 users to enjoy this menu too.

All the features are the same as the CSS-only version - the difference here is that JavaScript makes it compatible with earlier versions of Internet Explorer (IE7/8).

Demo - CSS3 Multi-Level, Off-Canvass Mobile Menu (with JavaScript IE7/8 support): http://fofwebdesign.co.uk/freebies_f...enu-js-ie8.htm

Now, because this menu builds upon the CSS-only version, it continues to use the checkbox hack, which is what makes functionality possible, without JavaScript, in modern browsers. But, the checkbox hack doesn't work in IE8 and earlier because the ":checked" psuedo class is unsupported in IE before version 9. So, for IE7/8 support, we must do something different - I decided to toggle a class on active menus, styling them open and closed, when needed, with CSS.

Here's the goNav() JavaScript function that toggles the additional class. "sub-nav" is the default class that is always present, and "nav-ie" is an additional class that is added and removed onclick;
Code:
function goNav(nav){
     document.getElementById(nav).className = (document.getElementById(nav).className == 'sub-nav nav-ie') ? 'sub-nav' : 'sub-nav nav-ie';
     }
You can see how this "nav-ie" class is used in the CSS, inside an IE conditional stylesheet. Remember that CSS transforms are not supported in these early versions of IE, so they get a basic left position switch - no slinky slide effect, but at least the menus are made visible (they are initially hidden "off-canvass" with a negative left position of -13.75em);
Code:
<!--[if lt IE 9]>
 <style>
 #menu ul { margin-left:0 }
 #menu.nav-ie, #menu .nav-ie { left:0 }
 #container.nav-ie { position:relative; left:13.75em }
 </style>
 <![endif]-->
So, when the "nav-ie" class is present, the sub-menu is made visible, and when it is removed the sub-menu is hidden again.

The rest of the JavaScript ties the goNav() function to all the sub-menu's "toggle" ◄ and "toggle-sub" ► arrow labels so that the "nav-ie" class is added and removed onclick;
Code:
var sub = document.getElementById('menu').getElementsByTagName('label');
 for(var i = 0; i < sub.length; i++){
     if(sub[i].className == 'toggle-sub'){ // forward '>' arrow label
         sub[i].onclick = function(){
             var chkbox = this.nextSibling;
             while (chkbox.nodeType != 1){ chkbox = chkbox.nextSibling; }
             var subNav = chkbox.nextSibling;
             while (subNav.nodeType != 1){ subNav = subNav.nextSibling; }
             goNav(subNav.id);
             }
         }
     if(sub[i].className == 'toggle'){ // back '<' arrow label
         sub[i].onclick = function(){
             goNav(this.parentNode.parentNode.id);
             }
         }
     }
Finally, the existing uncheckboxes() function that closes all sub-menus in one go in modern browsers, now carries a bit of extra JavaScript to remove all instances of the "nav-ie" class, which again, closes all sub-menu in one go, but for IE7/8;
Code:
function uncheckboxes(nav){
     var navarray = document.getElementsByName(nav);
     for(var i = 0; i < navarray.length; i++){
         navarray[i].checked = false
         }
     var navIE = document.getElementById('menu').getElementsByTagName('ul');
     for(var i = 0; i < navIE.length; i++){
         navIE[i].className = navIE[i].className.replace(/\bnav-ie\b/, '');
         }
    }
That's the sub-menus dealt with. To completely close the menu and return it to it's hidden, "off-canvass" state, I'm going to call the goNav() JavaScript function on the labels - there's one right after the opening #menu div, and another just before the closing #menu div - they'll end up looking something like this;
Code:
    <label class="toggle close-all" onclick="uncheckboxes('nav'); goNav('menu'); goNav('container')">&times;</label>
 </div><!-- closing "#menu" -->
But wait! It's all well and good talking about how to open and close sub-menus in IE7/8 with JavaScript and classes, but I haven't actually yet covered the very first step of opening the menu from its "off-canvass" position! That's very easy to handle when JavaScript is enabled - just put the goNav() function on the ☰ icon;
Code:
<label for="main-nav-check" class="toggle" onclick="goNav('menu'); goNav('container')" title="Menu">&#x2261;</label>
Problems arise when JavaScript is disabled though - those IE7/8 users won't be able to access the menu at all, so I propose this workaround; Use <noscript> tags to serve a static link to your website's sitemap;
Code:
<label for="main-nav-check" class="toggle" onclick="goNav('menu'); goNav('container')" title="Menu">&#x2261;</label>
<!--[if lt IE 9]><noscript><a class="toggle" href="/site-map.php">&#x2261;</a></noscript><![endif]-->
And mimic the existing ☰ icon with this CSS in the IE7/8 conditional styles;
Code:
#header a.toggle { padding:0 0.125em; font:2.875em/1.4375em Arial; text-decoration:none }
Compatibility: Modern browsers and IE9+ both with and without JS, and IE7/8 users with JS enabled (noscript workaround suggested above though).
No slide effect in IE7/8/9.

View the source code of the demo page to grab the JS, CSS and HTML, and use wherever you like (with notices intact in the CSS)

Submit "Multi-Level, Off-Canvass Menu with IE7/8 support" to del.icio.us Submit "Multi-Level, Off-Canvass Menu with IE7/8 support" to StumbleUpon Submit "Multi-Level, Off-Canvass Menu with IE7/8 support" to Google Submit "Multi-Level, Off-Canvass Menu with IE7/8 support" to Digg

Updated 10-29-2014 at 01:09 PM by Beverleyh

Tags: None Add / Edit Tags
Categories
JavaScript & Ajax , CSS related , Web Design issues

Comments