Making CSS transitions alternate by manipulating browser's history

Making CSS transitions alternate by manipulating browser's history

How to revert and alternate a CSS transition with the aid of JavaScript.

Interesting things happen when we use CSS transitions together with the :target pseudo-element. As you probably know, once the target is reached by adding an hash to the current's page URL, the transition is complete. But if you manipulate the browser's history with JavaScript you can revert this process.

We have the following menu which features a button:


<div id="navigation">
	<ul id="nav">
	  <li><a href="#">Home</a></li>
	  <li><a href="#">About</a></li>
	  <li><a href="#">Contact</a></li>
	</ul>
	<div id="opener">
		<a href="#navigation" class="icon-gear"></a>
	</div>
</div>

The relevant CSS styles are the following:


#navigation {
	height: 3em;
	width: 18em;
	color: #fff;
	position: fixed;
	top: 50%;
	margin-top: -1.5em;
	left: -18em;
	-moz-transition: all 500ms ease-out;
	-webkit-transition: all 500ms ease-out;
	-ms-transition: all 500ms ease-out;
		transition: all 500ms ease-out;
	
}

#navigation:target {
	left: 0;
}

When you click on the button the attached transition will fire due to the :target pseudo-element. Here's how we can revert this process with JavaScript:


var handleMenu = function() {
	var menu = document.getElementById('navigation'),
		opener = document.getElementById('opener'),
		button = opener.getElementsByTagName('a')[0];
	button.addEventListener('click', function() {
		var left = window.getComputedStyle(menu, null).getPropertyValue('left');
		if(parseInt(left) == 0) {
			history.back(); // remove hash
		} else {
			history.forward(); // add hash
		}
	}, false);
};

document.addEventListener('DOMContentLoaded', function() {
	handleMenu();
}, false);

When you add or remove the hash from the current's page URL, the CSS transition fires again with an alternate effect. That's exactly what we want.

[view-example url="http://codepen.io/gabrieleromanato/full/HwusL"]