<div class="hamburger">
<div class="hamburger__container">
<span class="hamburger__top"></span>
<span class="hamburger__middle"></span>
<span class="hamburger__bottom"></span>
</div>
</div>
<div class="menu">
<div class="menu__container bg-white">
<nav class="menu__nav">
<ul class="menu__list">
<li class="menu__item js-span">Links</li>
<li class="menu__item">
<a class="menu__link" href="#">Link #1</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#">Link #2</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#">Link #3</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#>">Link #4</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#">Link #5</a>
</li>
</ul>
</nav>
<nav class="menu__nav">
<ul class="menu__list">
<li class="menu__item js-span">More Links</li>
<li class="menu__item">
<a class="menu__link" href="#">More Link #1</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#">More Link #2</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#">More Link #3</a>
</li>
<li class="menu__item menu__item--contact">
<span>Contact</span>
<div class="menu__info">
<span>Seattle, WA</span>
<span>
<a class="menu__external" href="mailto:thomas.vaeth@gmail.com">thomas.vaeth@gmail.com</a>
</span>
</div>
</li>
</ul>
</nav>
<div class="menu__sidebar">
<div class="menu__flip">
<div class="menu__copy">
<span>All content & images ©2020 Thomas Vaeth.</span>
<span>Website by <a class="menu__external" href="https://thomasvaeth.com/" target="_blank" rel="noopener noreferrer">Thomas Vaeth</a>.</span>
</div>
</div>
</div>
</div>
<div class="menu__img bg-black">
<figure class="absolute-bg" style="background-image: url('https://source.unsplash.com/t2Sai-AqIpI/900x1600');"></figure>
</div>
</div>
<section class="demo">
<p class="demo__text">
#CodePenChallenge<br/>
Full-Page Navigation
</p>
</section>
$mq-xsmall: 22rem;
$mq-sm: 32rem;
$mq-med: 54rem;
$mq-lg: 65rem;
$mq-xl: 91rem;
$mq-xxl: 115rem;
$mq-xxxl: 130rem;
$color-white: #fff;
$color-lightgrey: #d8d8d8;
$color-darkgrey: #231f20;
$color-black: #000;
@mixin nth-transition-delay($items: 12, $baseTime: 0s, $delayTime: 100ms) {
@for $i from 1 through $items {
&:nth-child(#{$i}) {
transition-delay: $baseTime + ($delayTime * $i);
}
}
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
font-family: "Poppins", sans-serif;
font-weight: 300;
font-size: 100%;
line-height: 1.5;
color: $color-black;
@media (min-width: $mq-sm) {
font-size: 102.5%;
}
@media (min-width: $mq-med) {
font-size: 105%;
}
@media (min-width: $mq-lg) {
font-size: 107.5%;
}
@media (min-width: 75em) {
font-size: 110%;
}
@media (min-width: $mq-xl) {
font-size: 115%;
}
@media (min-width: $mq-xxl) {
font-size: 120%;
}
@media (min-width: $mq-xxxl) {
font-size: 125%;
}
}
a {
text-decoration: none;
}
ul {
margin: 0;
padding: 0;
list-style-type: none;
}
figure {
max-width: 100%;
height: auto;
margin: 0;
}
.hamburger {
position: fixed;
top: 1em;
right: 1em;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
height: 3.5em;
width: 3.5em;
background-color: transparent;
border: 1px solid $color-darkgrey;
border-radius: 100%;
cursor: pointer;
transition: border-color 300ms ease-in-out;
@media (min-width: $mq-med) {
top: 2em;
right: 2em;
}
@media (min-width: $mq-xl) {
top: 3em;
right: 3em;
}
&:before {
content: "";
position: absolute;
top: 3px;
left: 3px;
height: calc(3.5em - 8px);
width: calc(3.5em - 8px);
border: 1px solid $color-darkgrey;
border-radius: 100%;
transition: border-color 300ms ease-in-out;
}
.js-menu-open & {
border-color: $color-darkgrey;
transition-delay: 300ms;
@media (min-width: $mq-med) {
border-color: $color-white;
}
&:before {
border-color: $color-darkgrey;
transition-delay: 300ms;
@media (min-width: $mq-med) {
border-color: $color-white;
}
}
}
.js-menu-closing & {
cursor: wait;
}
&__container {
transition: transform 300ms ease-in-out;
.js-hamburger & {
transform: rotate(90deg);
transition-delay: 300ms;
}
}
&__top,
&__middle,
&__bottom {
display: block;
height: 1px;
width: 1.85em;
background-color: $color-darkgrey;
.js-menu-open & {
background-color: $color-darkgrey;
@media (min-width: $mq-med) {
background-color: $color-white;
}
}
}
&__middle {
margin: {
top: 6px;
bottom: 6px;
}
opacity: 1;
transition: margin 300ms ease-in-out 300ms, opacity 0s ease-in-out 300ms;
.js-menu-open & {
margin: {
top: -2px;
bottom: -2px;
}
opacity: 0;
transition: margin 300ms ease-in-out, opacity 0s ease-in-out;
}
}
&__top,
&__bottom {
transform: rotate(0);
transition: transform 300ms ease-in-out, background-color 300ms ease-in-out;
.js-menu-open & {
transition-delay: 300ms;
}
}
&__top {
.js-menu-open & {
transform: rotate(45deg);
}
}
&__bottom {
.js-menu-open & {
transform: rotate(-45deg);
}
}
}
.menu {
position: fixed;
top: 0;
left: 0;
z-index: -9;
height: 100%;
width: 100%;
visibility: hidden;
opacity: 0;
@media (min-width: $mq-med) {
min-height: 40em;
}
.js-menu-visible & {
z-index: 998;
visibility: visible;
opacity: 1;
}
&__container,
&__img {
position: absolute;
top: 0;
height: 100%;
}
&__container {
left: 0;
display: flex;
width: 100%;
overflow: hidden;
}
&__img {
position: relative;
display: none;
@media (min-width: $mq-med) {
display: block;
}
.absolute-bg {
opacity: 0;
transition: opacity 450ms cubic-bezier(0.25, 0.1, 0.25, 1) 300ms;
.js-menu-open & {
opacity: 1;
}
}
}
&__nav {
display: flex;
justify-content: center;
margin: {
top: 2em;
bottom: 2em;
}
padding: {
top: 3em;
bottom: 3em;
}
&:first-of-type {
flex-basis: 45%;
max-width: 45%;
border-right: 1px solid $color-black;
}
&:last-of-type {
flex-basis: 55%;
max-width: 55%;
@media (min-width: $mq-lg) {
flex-basis: 45%;
max-width: 45%;
border-right: 1px solid $color-black;
}
}
}
&__list {
display: flex;
flex-direction: column;
}
&__item {
overflow: hidden;
&:first-child {
margin-bottom: 2em;
font-weight: 500;
font-size: 0.9em;
text-transform: uppercase;
letter-spacing: 0.1em;
}
&:not(:first-child):not(:last-child) {
margin-bottom: 0.25em;
}
@for $i from 2 through 6 {
&:nth-child(#{$i}) {
.menu__link {
transition-delay: 100ms * $i;
}
}
}
&--contact {
margin-top: auto;
font-weight: 500;
font-size: 0.8em;
text-transform: uppercase;
letter-spacing: 0.1em;
}
span {
@include nth-transition-delay(3);
opacity: 0;
transition: opacity 600ms cubic-bezier(0.25, 0.1, 0.25, 1);
.js-menu-open & {
opacity: 1;
}
}
}
&__link {
position: relative;
display: inline-block;
font-size: 1.5em;
color: $color-black;
opacity: 0;
transform: translate3d(0, 100%, 0);
transition: all 600ms cubic-bezier(0.25, 0.1, 0.25, 1);
&:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
height: 1px;
width: 0;
background-color: $color-black;
transition: width 400ms ease;
}
&:hover {
&:after {
width: 100%;
}
}
.js-menu-open & {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
&__sidebar {
position: relative;
display: none;
@media (min-width: $mq-lg) {
display: block;
flex-basis: 10%;
max-width: 10%;
}
}
&__flip {
position: absolute;
top: 0;
left: 50%;
transform: rotate(90deg) translateY(-50%);
transform-origin: left top;
}
&__copy {
display: inline-flex;
justify-content: space-between;
width: 100vh;
padding: {
right: 2em;
left: 2em;
}
& > span {
@include nth-transition-delay(3);
font-size: 0.8em;
opacity: 0;
transition: opacity 600ms cubic-bezier(0.25, 0.1, 0.25, 1) 100ms;
.js-menu-open & {
opacity: 1;
transition: opacity 600ms cubic-bezier(0.25, 0.1, 0.25, 1) 200ms;
}
}
}
&__external {
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.1em;
color: $color-black;
}
&__info {
display: flex;
flex-direction: column;
margin-top: 2em;
}
}
.js-overflow {
overflow: hidden;
}
.bg-white {
background-color: $color-white;
}
.bg-black {
background-color: $color-black;
}
.absolute-bg {
position: absolute;
top: 0;
left: 0;
z-index: 0;
height: 100%;
width: 100%;
background-position: 50%;
background-repeat: no-repeat;
background-size: cover;
}
.demo {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: $color-lightgrey;
&__text {
margin: {
top: 0;
bottom: 0;
}
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.1em;
text-align: center;
}
}
View Compiled
const Menu = (() => {
let s;
return {
settings() {
return {
body: $('body'),
hamburger: $('.hamburger'),
open: 'js-menu-open',
visible: 'js-menu-visible',
overflow: 'js-overflow',
width: $(window).width(),
prevWidth: $(window).width(),
};
},
init() {
s = this.settings();
this.bindEvents();
},
bindEvents() {
let menuContainerWidth;
if (s.width < 864) {
menuContainerWidth = 100;
} else if (s.width < 1456) {
menuContainerWidth = 50;
} else {
menuContainerWidth = 45;
}
$(window).on('resize', () => {
s.width = $(window).width();
if (s.width < 864) {
menuContainerWidth = 100;
} else if (s.width < 1456) {
menuContainerWidth = 50;
} else {
menuContainerWidth = 45;
}
});
s.hamburger.on('click', () => {
Menu.toggleMenu(menuContainerWidth);
});
s.body.on('keyup', e => {
if (s.body.hasClass(s.open) && e.which === 27) {
Menu.toggleMenu(menuContainerWidth);
}
});
},
toggleMenu(width) {
s.hamburger.toggleClass('js-hamburger');
s.body.toggleClass(s.open);
s.body.toggleClass(s.overflow);
if (s.body.hasClass(s.open)) {
s.prevWidth = width;
anime.timeline({
easing: 'easeOutQuart',
duration: 600,
begin() {
$('.menu__img').css('left', `${width}%`);
s.body.addClass(s.visible);
}
})
.add({
targets: '.menu__container',
width: [0, `${width}%`]
})
.add({
targets: '.menu__img',
width: [0, `${100 - width}%`]
}, 0);
}
if (!s.body.hasClass(s.open)) {
anime.timeline({
easing: 'easeInQuart',
duration: 600,
delay: 200,
complete() {
s.body.removeClass(s.visible);
}
})
.add({
targets: '.menu__container',
width: [`${s.prevWidth}%`, 0]
})
.add({
targets: '.menu__img',
width: [`${100 - s.prevWidth}%`, 0]
}, 0);
}
}
};
})();
$(() => {
const span = $('.js-span');
let $ele, words;
for (let i = 0; i < span.length; i++) {
$ele = $(span).eq(i);
words = $ele.html();
$ele.html(words.replace(/([A-z0-9'@+-<>.,'"“”‘’?!*&/]+)/g, '<span>$&</span>'));
}
Menu.init();
});
View Compiled