Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save queued/145df8b64ac6271581e2 to your computer and use it in GitHub Desktop.
Save queued/145df8b64ac6271581e2 to your computer and use it in GitHub Desktop.

Animate the transformation of a mobile menu toggle into a cross

Animation for a mobile menu toggle. Three horizontal lines transform into a cross and back again. The top and bottom lines fall into the center, transforming into one line. The line(s) rotate clockwise, spawning a line at 45deg and stop at 135 deg, forming a cross. Demo: http://jsfiddle.net/SYYr5/7/

Annotations:

  • the animation uses four additional elements inside the a tag. This is not semantic, but at we can at least use elements without a semantic meaning, like div and span
  • using a div as a second container, we are able to apply a padding to our a tag
  • inTop/outTop, inMiddle/outMiddle and inBottom/outBottom are the same animation. This seemed to be the only way to 'restart' the animation.
  • Adding 180deg looks even better ;) but is a bit laggy sometimes :/
  • We may need to use vendor prefixes :/

The HTML-Snippet:

<a id="toggle-menu">
	<div>
		<span class="top"></span>
		<span class="middle"></span>
		<span class="bottom"></span>
	</div>
</a>

The SCSS-Snippet:

#toggle-menu {
	display: block;
	width: 15px;
	height: 15px;
	padding: 20px;
	cursor: pointer;
	div {
		width: 15px;
		height: 15px;
		position: relative;
	}
	span {
		display: block;
		width: 15px;
		height: 3px;
		background: black;
		position: absolute;
		animation-fill-mode:forwards;
		&.top {
			top: 0px;
		}
		&.middle {
			top: 6px;
		}
		&.bottom {
			top: 12px;
		}
	}
	&.visible {
		span.top {
			animation: inTop 0.8s forwards;
		}
		span.middle {
			animation: inMiddle 0.8s forwards;
		}
		span.bottom {
			animation: inBottom 0.8s forwards;
		}	
	}
	&.hidden {
		span.top {
			animation: outTop 0.8s backwards;
			animation-direction: reverse;
		}
		span.middle {
			animation: outMiddle 0.8s backwards;
			animation-direction: reverse;
		}
		span.bottom {
			animation: outBottom 0.8s backwards;
			animation-direction: reverse;
		}	
	}
}

@keyframes inMiddle {
	25% {
		transform: rotate(0deg);
	}
	100% {
		transform: rotate(45deg);
	}
}

@keyframes outMiddle {
	50% {
		transform: rotate(0deg);
	}
	100% {
		transform: rotate(45deg);
	}
}

@keyframes inTop {
	0% {
		top: 0;
	}
	25% {
		top: 6px;
		transform: rotate(0deg);
	}
	100% {
		top: 6px;
		transform: rotate(135deg);
	}
}

@keyframes outTop {
	0% {
		top: 0;
	}
	50% {
		top: 6px;
		transform: rotate(0deg);
	}
	100% {
		top: 6px;
		transform: rotate(135deg);
	}
}

@keyframes inBottom {
	0% {
		top: 12px;
	}
	25% {
		top: 6px;
		transform: rotate(0deg);
		opacity: 1;
	}
	100% {
		top: 6px;
		transform: rotate(135deg);
		opacity: 0;
	}
}

@keyframes outBottom {
	0% {
		top: 12px;
	}
	50% {
		top: 6px;
		transform: rotate(0deg);
		opacity: 0;
	}
	100% {
		top: 6px;
		transform: rotate(135deg);
		opacity: 1;
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment