Simple YouTube Menu Effect

A tutorial on how to recreate the effect of YouTube's little left side menu. The idea is to slide a little menu icon to the right side while revealing some menu item list beneath.
Simple YouTube Menu Effect

From our sponsor: Try Mailchimp today.

Today we’ll show you how to recreate the little menu effect that you can see in the left side-menu on YouTube when watching a video (where it says “Guide”). The menu is made of a little menu icon, a label and a list of menu items that appears when the label or menu icon is clicked. Once it’s clicked the menu icon slides to the right and the label moves up while the list items fade in sequentially. We’ll add some more style and effects to it in order to make it a bit more interesting.

So, let’s do it!

The Markup

For the HTML we will use a nav element and inside we’ll add a div that will contain the menu icon and the label. We’ll use an unordered list for the menu items:

<nav id="dr-menu" class="dr-menu">
	<div class="dr-trigger"><span class="dr-icon dr-icon-menu"></span><a class="dr-label">Account</a></div>
		<li><a class="dr-icon dr-icon-user" href="#">Xavier Densmore</a></li>
		<li><a class="dr-icon dr-icon-camera" href="#">Videos</a></li>
		<li><a class="dr-icon dr-icon-heart" href="#">Favorites</a></li>
		<li><a class="dr-icon dr-icon-bullhorn" href="#">Subscriptions</a></li>
		<li><a class="dr-icon dr-icon-download" href="#">Downloads</a></li>
		<li><a class="dr-icon dr-icon-settings" href="#">Settings</a></li>
		<li><a class="dr-icon dr-icon-switch" href="#">Logout</a></li>

Each menu item will have a little icon, so we’ll give them all different classes for that. The icons that we’ll be using are from IcoMoon and we’ve created a custom icon set with their brilliant app.

Let’s take a look at the CSS.


Note that the CSS will not contain any vendor prefixes, but you will find them in the files.

First, we will include our icon font:

@font-face {
	font-family: 'icomoon';
	src:url('../fonts/icomoon.eot?#iefix') format('embedded-opentype'),
		url('../fonts/icomoon.woff') format('woff'),
		url('../fonts/icomoon.ttf') format('truetype'),
		url('../fonts/icomoon.svg#icomoon') format('svg');
	font-weight: normal;
	font-style: normal;

The main nav container will have some general styles, like font size, line-height, color and the dimensions. We want it to be flexible but we don’t want it to become too large or too small, so we’ll set a max-width and min-width:

.dr-menu {
	width: 100%;
	max-width: 400px;
	min-width: 300px;
	position: relative;
	font-size: 1.3em;
	line-height: 2.5;
	font-weight: 400;
	color: #fff;
	padding-top: 2em;

The division that contains the menu icon span and the label link will be positioned absolutely and we’ll set the cursor to “pointer”. It needs a high z-index to guarantee that the unordered list does not stay on top of it:

.dr-menu > div  {
	cursor: pointer;
	position: absolute;
	width: 100%;
	z-index: 100;

The menu icon span in our trigger division will also be positioned absolutely and we’ll give it a transition:

.dr-menu > div .dr-icon {
	top: 0;
	left: 0;
	position: absolute;
	font-size: 150%;
	line-height: 1.6;
	padding: 0 10px;
	transition: all 0.4s ease;

When we click on the trigger division, we will give a class called “dr-menu-open” to the nav. The menu icon will then slide to the left and we’ll also translate it for the maount of its own width so that it’s put back nicely into place without spilling over:

.dr-menu.dr-menu-open > div .dr-icon {
	color: #60a773;
	left: 100%;
	transform: translateX(-100%);

In the end of the CSS we will add our icon classes from IcoMoon. The icon in the span for the menu icon will be a bit different, and we’ll use the pseudo class :after to add the little triangle. So, let’s define that as follows:

.dr-menu > div .dr-icon:after {
	content: "e008";
	position: absolute;
	font-size: 50%;
	line-height: 3.25;
	left: -10%;
	opacity: 0;

The icon will be absolute and we’ll pull it into place by giving it a left of -10%. The initial opacity is set to 0 because we don’t want to see it initially when the menu is closed.

Once we open the menu, we will want it to become visible:

.dr-menu.dr-menu-open > div .dr-icon:after {
	opacity: 1;

The label, which is an anchor in our HTML, will get some general styling and we’ll give it a padding so that it’s next to the menu icon. We’ll also add a transition because we want to animate it up, once we open the menu, which we will do by translating it on the Y-axis:

.dr-menu > div .dr-label {
	padding-left: 3em;
	position: relative;
	display: block;
	color: #60a773;
	font-size: 0.9em;
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	line-height: 2.75;
	transition: all 0.2s ease-in;

.dr-menu.dr-menu-open > div .dr-label {
	transform: translateY(-90%);

The unordered list will initially be invisible by having a opacity of 0:

.dr-menu ul {
	padding: 0;
	margin: 0 3em 0 0;
	list-style: none;
	opacity: 0;
	position: relative;
	z-index: 0;
	pointer-events: none;
	transition: opacity 0s linear 205ms;

When we open the menu we want it to get visible and a high z-index so that the trigger div does not cover it:

.dr-menu.dr-menu-open ul {
	opacity: 1;
	z-index: 200;
	pointer-events: auto;
	transition: opacity 0s linear 0s;

The two transitions are for opening and closing the menu. When we open the menu, we want it to appear immediately without a delay and when we close it, i.e. remove the class, we want that it happens with a delay. That delay is defined by the delay of the last item in the list, as we will see shortly.

The list items will also be invisible and we’ll set a transition for the opacity:

.dr-menu ul li {
	display: block;
	margin: 0 0 5px 0;
	opacity: 0;
	transition: opacity 0.3s ease;

.dr-menu.dr-menu-open ul li {
	opacity: 1;

Now, each list item will appear with a different delay: the first item will fade in immediately and the last item will appear in the end:

.dr-menu.dr-menu-open ul li:nth-child(2) {
	transition-delay: 35ms;

.dr-menu.dr-menu-open ul li:nth-child(3) {
	transition-delay: 70ms;

.dr-menu.dr-menu-open ul li:nth-child(4) {
	transition-delay: 105ms;

.dr-menu.dr-menu-open ul li:nth-child(5) {
	transition-delay: 140ms;

.dr-menu.dr-menu-open ul li:nth-child(6) {
	transition-delay: 175ms;

.dr-menu.dr-menu-open ul li:nth-child(7) {
	transition-delay: 205ms;

The links will have some padding and we’ll set them as inline-blocks:

.dr-menu ul li a {
	display: inline-block;
	padding: 0 20px;
	color: #fff;

And we’ll change the color on hover:

.dr-menu ul li a:hover {
	color: #60a773;

Last, but not least, let’s define the icon pseudo-elements:

.dr-icon:after {
	position: relative;
	font-family: 'icomoon';
	speak: none;
	font-style: normal;
	font-weight: normal;
	font-variant: normal;
	text-transform: none;
	-webkit-font-smoothing: antialiased;

.dr-menu ul .dr-icon:before {
	margin-right: 15px;

.dr-icon-bullhorn:before {
	content: "e000";

.dr-icon-camera:before {
	content: "e002";

.dr-icon-heart:before {
	content: "e003";

.dr-icon-settings:before {
	content: "e004";

.dr-icon-switch:before {
	content: "e005";

.dr-icon-download:before {
	content: "e006";

.dr-icon-user:before {
	content: "e001";

.dr-icon-menu:before {
	content: "e007";

And that’s all the style. Let’s take a look at the JavaScript.

The JavaScript

We’ll create a small script that will take care of the menu functionality. When we click on the trigger division, we want the menu wrapper to get the class “dr-menu-open”. Since we will be animating the label out and the menu icon to the right, we want the closing to happen only when we click on the menu icon, just like in the YouTube menu:

var YTMenu = (function() {

	function init() {
		[] document.querySelectorAll( '.dr-menu' ) ).forEach( function( el, i ) {

			var trigger = el.querySelector( 'div.dr-trigger' ),
				icon = trigger.querySelector( 'span.dr-icon-menu' ),
				open = false;

			trigger.addEventListener( 'click', function( event ) {
				if( !open ) {
					el.className += ' dr-menu-open';
					open = true;
			}, false );

			icon.addEventListener( 'click', function( event ) {
				if( open ) {
					open = false;
					el.className = el.className.replace(/bdr-menu-openb/,'');
					return false;
			}, false );

		} );




And that’s it! I hope you enjoyed this tutorial and find it useful!

Tagged with:

Mary Lou

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 35

Comments are closed.
  1. Anyone know how to have it fly out from the other side? I’d like to put it in the right hand corner?

  2. Hi, I love this site and the tutorials! For the people wondering how to change the icons, I just fond out: go to a site like IcoMoon and choose the icons you want from the site or by importing them. Afterwards you’ll be able to change the row in wich they should appear later on. Then you’ll need to download the zip file and in the zip file you’ll have a font file. Exchange this one with the one in the theme and reorganize the U+e00.. in the CSS file and you’re done! Hope it helped

  3. I would like to change the icons but how do u go about that like I know the icon are fonts but how do u place the icon font in the content content :/e003;?

  4. Thanks for the great tutorial! Unfortunately, for some reason I can’t get to make the .dr-label move upwards, while I succeeded making the menu icon move and the ul appear. Is there something particular I should pay attention to?

  5. How would I change the code to keep the menu open instead of closing back up when the user clicks on one of the list items (ie. videos)

  6. Haw should I edit the javasript, if I want to hide menu with other buttons (Videos,Favorities,…)?

  7. Nice, Creative…… I think it is more better when we click on the menu, right area become full width (With responsive feature)..


  8. Hi! Can you give me tips on how to make the drop down list scrollable (since I have a pretty long list)?

    Thank you so much!!