Categories:

Using JavaScript to toggle the menu on demand, create IE8 compatibility

So far our off-canvas menu is controlled using label elements that toggle the #togglebox checkbox element, in turn opening/ closing the menu. As flexible as it is already, wouldn't it be nice to take that one step further, by having the ability to toggle the menu inside regular links, images, or on demand inside another script, for example? With our choice of using CSS and CSS's checkbox sibling selector as the mechanism for toggling the menu, the aforementioned versatility can easily be gained by creating a JavaScript function that simply checks or unchecks the target checkbox element on demand, in turn toggling the menu on demand. So simple, and yet, so simple! Such a JavaScript function looks like this:

<script>

// Extra function to control menu state from anywhere on your page/ inside your script
function expandoffcanvasmenu(action){ //param: 'open', 'close', or empty to toggle menu state
	var togglebox = document.getElementById("togglebox")
	var newstate = (action == 'open')? true : (action == 'close')? false : !togglebox.checked
	togglebox.checked = newstate
}

</script>

The function accepts 3 possible values for its lone parameter- "open", "close", and empty (no parameter) to control the state of the #togglebox checkbox. In the last case, it toggles the menu state between checked and unchecked. In any case, as soon as the checkbox's state changes, our off-canvas menu state automatically changes as well. The following uses ordinary links to call the expandoffcanvasmenu() via onClick using each of the 3 possible parameter values as illustration:

Arbitrary Open Menu link
Arbitrary Close Menu link
Arbitrary Toggle Menu link

Making our off-canvas menu IE8 compatible

IE8 doesn't support the checkbox sibling selector (~) we've used as the basis for opening/closing the off canvas menu based on the checked state of our hidden checkbox. Nor does it support CSS3's translate3d() for shifting the menu and page contents horizontally (like in IE9). For those of you that care about IE8 compatibility, with JavaScript, we can make the menu at least functional in the way the menu already is in IE9 with just a few more lines of code. All we have to do is to create an alternate version of expandoffcanvasmenu() above that explicitly shows and hides the menu by setting its visibility property, and furthermore, attach that function to the label elements of the menu to simulate their functionality in IE8. All this can be done elegantly and cleanly by defining the code inside IE comments:

<!--[if lte IE 8]>

<style>

/* IE8 specific CSS */

label#navtoggler{
	border-width: 0.6em;
}

nav#offcanvas-menu label#closex{
	text-indent: 0;
}

</style>


<script>
document.createElement("nav") // create "nav" element so CSS styles get properly applied to the menu's nav element

function expandoffcanvasmenu(action){
	var nav = document.getElementById("offcanvas-menu")
	var newstate = (action == 'open')? 'visible' : (action == 'close')? 'hidden' : nav.style.visibility == 'hidden'? 'visible' : 'hidden'
	nav.style.visibility = newstate
}

window.attachEvent("onload", function(){
	document.getElementById("navtoggler").onclick = function(){
		expandoffcanvasmenu('open')
	}
	document.getElementById("closex").onclick = function(){
		expandoffcanvasmenu('close')
	}
})
</script>
<![endif]-->

Everything defined inside the conditional comments are only applied in IE8 and below. We've altered the CSS slightly for those browsers so the label and "x" close button show up correctly. Following the CSS is the modified expandoffcanvasmenu() function that merely toggles the menu's NAV element visibility, plus calls the function whenever the label and close buttons of the menu are clicked on.

Final off-canvas menu version

Conclusion

In this tutorial we've deconstructed the making of the quintessential menu of the mobile era, the off-canvas menu, using the checkbox sibling selector (~) for menu state control, plus CSS3 transform to shift the page contents horizontally. We also saw how to transition the "visibility" property properly for our purpose, by setting a delay before the property is applied when the menu is transitioning from open to close. And last but not least, we see how easy it is to enhance the menu's accessibility using a touch of JavaScript, so the final version is polished enough for the uncompromising real world.

End of tutorial