- var menuLinks = ['Home', 'Features', 'Tutorial', 'Docs', 'News', 'Blog', 'About', 'Contact', 'Community'];

#app.container
	.zz-menu(v-bind:class="{ 'zz-menu-shown': zzMenuShown }" v-bind:style="zzMenuStyle" v-on:scroll="zzMenuScroll" ref="zzMenu")
		ul
			- for (var i = 0; i < menuLinks.length; i++)
				li
					a(href="#") #{menuLinks[i]}
	.zz-menu-btn(v-on:click="zzMenuToggle" v-bind:style="zzMenuBtn")
		span
		span
		span
	h1 Example Cover
	p Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
	a(href="#") Start Now
View Compiled
$red-1: #8d0a0a;
$red-2: #ff6242;

@import url("https://fonts.googleapis.com/css?family=Montserrat:400,400i,700");
@import url("https://fonts.googleapis.com/css?family=Fugaz+One&display=swap");
@import url("https://fonts.googleapis.com/css?family=Overlock&display=swap");

@mixin button($font-size, $padding) {
	color: $red-2;
	font-family: Montserrat, sans-serif;
	font-weight: bold;
	text-align: center;
	text-decoration: none;
	font-size: $font-size;
	background-color: #1a1a1a;
	padding: $padding;
	outline: 0;
	box-sizing: border-box;
	transition: transform 200ms ease-out, background-color 200ms ease-out;
	&:hover {
		color: $red-1;
		background-color: #f2f2f2;
	}
	&:active {
		transform: scale(1.2);
	}
}

.zz-menu {
	background-image: linear-gradient(to bottom right, $red-1 10%, $red-2 50%, $red-1 80%);
	background-size: 100% 100%;
	background-position: 0px 0px;
	width: 100vw;
	height: 100vh;
	padding: 80px 8vw;
	overflow: auto;
	box-sizing: border-box;
	position: fixed;
	top: 0;
	left: 0;
	transform-origin: calc(100vw - 80px) 60px;
	transform: scale(0);
	transition: all 500ms cubic-bezier(0.6, -0.3, 0.75, 0.05);
	ul {
		padding: 0;
		margin: 0;
		display: flex;
		flex-direction: column;
		align-items: center;
		list-style-type: none;
		li {
			width: 100%;
			max-width: 360px;
			opacity: 0;
			transform: translateX(-10%);
			transition: all 500ms linear 0ms;
			a {
				@include button(10vw, 4vw 2vw);;
				width: 100%;
				margin-bottom: 6vw;
				display: block;
				overflow: hidden;
			}
			&:last-child {
				a {
					margin-bottom: 0;
				}
			}
		}
	}
	&.zz-menu-shown {
		transform: scale(1);
		transition: transform 500ms cubic-bezier(0.2, 0.9, 0.3, 1.3);
		+ .zz-menu-btn span {
			&:nth-child(1) {
				transform: rotate(-45deg) translateX(-25%) translateY(125%);
			}
			&:nth-child(2) {
				opacity: 0;
				transform: scaleY(0) translateX(100%);
			}
			&:nth-child(3) {
				transform: rotate(45deg) translateX(-25%) translateY(-125%);
			}
		}
		ul li {
			opacity: 1;
			transform-origin: top center;
			transform: translateX(0%);
			@for $i from 0 through 6 {
				&:nth-child(#{$i + 1}) {
					transition: all 500ms cubic-bezier(0.2, 0.9, 0.3, 1.5) 500ms + ($i * 100ms);
				}
			}
		}
	}
}

.zz-menu-btn {
	@include button(0, 15px);
	width: 80px;
	height: 80px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	position: fixed;
	top: 20px;
	right: 40px;
	&:hover {
		span {
			background-color: $red-1;
		}
	}
	span {
		background-color: $red-2;
		width: 100%;
		height: 16px;
		margin-bottom: 8px;
		transform-origin: center;
		transition: all 650ms cubic-bezier(0.7, -0.5, 0.3, 1.5), background-color 200ms ease-out;
		&:last-child {
			margin-bottom: 0;
		}
	}
}

@media (min-width: 400px) {
	.zz-menu {
		padding: 150px 40px 120px;
		ul li a {
			@include button(40px, 20px 10px);
			margin-bottom: 30px;
		}
	}
}

html, body, .container {
	width: 100%;
	height: 100%;
	padding: 0;
	margin: 0;
}

.container {
	background-color: #303030;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	h1, p {
		color: #ffffff;
		text-align: center;
		padding: 0 40px;
	}
	h1 {
		font-family: "Fugaz One", cursive;
		font-size: 64px;
		font-weight: normal;
		margin: 0;
	}
	p {
		font-family: "Overlock", cursive;
		font-size: 24px;
		max-width: 320px;
		margin: 30px;
	}
	a {
		@include button(24px, 20px);
	}
}
View Compiled
var app = new Vue({
	el: '#app',
	data: {
		zzMenuShown: false,
		zzMenuStyle: {
			backgroundSize: '100% 100%',
			backgroundPosition: '0px 0px'
		},
		zzMenuBtn: {
			top: 20
		}
	},
	methods: {
		zzMenuToggle: function(evt) {
			evt.preventDefault();

			let zzMenu  = this.$refs.zzMenu;
			let scrollH = zzMenu.scrollHeight;
			let offsetH = zzMenu.offsetHeight;
			let height  = offsetH + ((scrollH - offsetH) / 2);

			this.zzMenuStyle.backgroundSize = '100% ' + height + 'px';
			
			this.zzMenuShown = (!this.zzMenuShown) ? true : false;
			
			if (this.zzMenuShown) {
				this.$refs.zzMenu.scrollTop = 0;
			}
		},
		zzMenuScroll: function(evt) {
			let el      = evt.target;
			let zzMenu  = this.$refs.zzMenu;
			let scroll  = -(el.scrollTop / 2);
			
			this.zzMenuStyle.backgroundPosition = '0px ' + scroll + 'px';
			
			this.zzMenuBtn.top = (20 - el.scrollTop) + 'px';
		}
	}
});
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js