<div class="viewport">
  <header class="header" role="banner">
    
    <nav id="nav" class="nav" role="navigation">
      
      <!-- ACTUAL NAVIGATION MENU -->
      <ul class="nav__menu" id="menu" tabindex="-1" aria-label="main navigation" hidden>
        <li class="nav__item"><a href="#" class="nav__link">Home</a></li>
        <li class="nav__item"><a href="#" class="nav__link">Shop</a></li>
        <li class="nav__item"><a href="#" class="nav__link">Blog</a></li>
        <li class="nav__item"><a href="#" class="nav__link">About</a></li>
        <li class="nav__item"><a href="#" class="nav__link">Contact</a></li>
      </ul>
      
      <!-- MENU TOGGLE BUTTON -->
      <a href="#nav" class="nav__toggle" role="button" aria-expanded="false" aria-controls="menu">
        <svg class="menuicon" xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
          <title>Toggle Menu</title>
          <g>
            <line class="menuicon__bar" x1="13" y1="16.5" x2="37" y2="16.5"/>
            <line class="menuicon__bar" x1="13" y1="24.5" x2="37" y2="24.5"/>
            <line class="menuicon__bar" x1="13" y1="24.5" x2="37" y2="24.5"/>
            <line class="menuicon__bar" x1="13" y1="32.5" x2="37" y2="32.5"/>
            <circle class="menuicon__circle" r="23" cx="25" cy="25" />
          </g>
        </svg>
      </a>
      
      <!-- ANIMATED BACKGROUND ELEMENT -->
      <div class="splash"></div>
      
    </nav>
    
  </header>
  
  <!-- DEMO CONTENT -->
  <main class="main" role="main">
    <div class="gallery" aria-label="gallery">
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
      <a href="#" class="gallery__item"></a>
    </div>
  </main>
</div>
// ---------------------------
// Vars & Helper Functions
// ---------------------------

:root {
  --screen-width:     320px;
  --screen-height:    560px;
  --header-bg-color:  #673AB7;
  --splash-bg-color:  #368887;
}

// calculate a circle's circumference based on radius
@function circumference($r){
  $pi: 3.141592653;
  @return 2*$pi*$r;
}


// ---------------------------
// Main Navigation Menu
// ---------------------------

.nav {
  
  // Toggle Button
  &__toggle {
    display:inline-block;
    position:absolute;
    z-index:10;
    padding:0;
    border:0;
    background:transparent;
    outline:0;
    right:15px;
    top:15px;
    cursor:pointer;
    border-radius:50%;
    transition:background-color .15s linear;
    
    &:hover,
    &:focus {
      background-color:rgba(0,0,0,.5);
    }
  }
  
  &__menu {
    display:flex;
    flex-direction:column;
    justify-content:center;
    height:var(--screen-height);
    position:relative;
    z-index:5;
    visibility:hidden;
  }
  
  &__item {
    opacity:0;
    transition: all .3s cubic-bezier(0.000, 0.995, 0.990, 1.000) .3s;
  }
  @for $i from 1 through 5 {
    &__item:nth-child(#{$i}){
      transform:translateY(-40px * $i);
    }
  }
  
  &__link {
    color:white;
    display:block;
    text-align:center;
    text-transform:uppercase;
    letter-spacing:5px;
    font-size:1.25rem;
    text-decoration:none;
    padding:1rem;
    
    &:hover,
    &:focus {
      outline:0;
      background-color:rgba(0,0,0,0.2);
    }
  }
}


// ---------------------------
// SVG Menu Icon
// ---------------------------

.menuicon {
  display:block;
  cursor:pointer;
  color: white;
  
  transform:rotate(0deg);
  transition: .3s cubic-bezier(0.165, 0.840, 0.440, 1.000); 
  
  &__bar,
  &__circle {
    fill:none;
    stroke: currentColor;
    stroke-width:3;
    stroke-linecap:round;
  }
  &__bar {
    transform: rotate(0deg);
    transform-origin:50% 50%;
    transition: transform .25s ease-in-out;
  }
  &__circle {
    transition: stroke-dashoffset .3s linear .1s;
    stroke-dashoffset:circumference(23); // 23 is the <circle>'s radius
    stroke-dasharray:circumference(23);
  }
}


// ---------------------------
// Circular Splash Background
// ---------------------------

.splash {
  position:absolute;
  top:40px;
  right:40px;
  width: 1px;
  height: 1px;
  
  &::after {
    content:"";
    display:block;
    position:absolute;
    border-radius:50%;
    background-color:var(--splash-bg-color);
    
    // screen diameter can be 142vmax at most,
    // circle needs to be twice that size to cover it
    width:284vmax;
    height:284vmax;
    top:-142vmax;
    left:-142vmax;
    
    transform: scale(0);
    transform-origin:50% 50%;
    transition: transform .5s cubic-bezier(0.755, 0.050, 0.855, 0.060);
    
    // will-change tells the browser we plan to 
    // animate this property in the near future
    will-change:transform;
  }
}


// ---------------------------
// Active State
// ---------------------------

.nav:target,
.nav--open {
  
  //scale the background circle to full size
  > .splash::after {
    transform:scale(1);
  }
  
  //animate the menu icon
  .menuicon {
    color:white;
    transform:rotate(180deg);
    
    &__circle {
      stroke-dashoffset:0;
    }
    &__bar:nth-child(1),
    &__bar:nth-child(4) {
      opacity:0;
    }
    &__bar:nth-child(2) {
      transform: rotate(45deg);
    }
    &__bar:nth-child(3) {
      transform: rotate(-45deg);
    }
  }
  
  //show the nav items
  .nav {
    &__menu {
      visibility:visible;
    }
  
    &__item {
      opacity:1;
      transform:translateY(0);
    }
  }
}

// ---------------------------
// Demo Stuff, Ignore
// ---------------------------

body {
  background-color:#D7D7D7;
  font-family: 'Roboto';
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
}

.viewport {
  width:var(--screen-width);
  height:var(--screen-height);
  margin:0 auto;
  position:relative;
  overflow:hidden;
  background-color:white;
}

.header {
  height:5rem;
  background-color:var(--header-bg-color);
}

.main {
  padding:20px;
}

.gallery {
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(130px, 1fr));
  grid-auto-rows: 130px;
  grid-gap:20px;
  
  &__item {
    height:100%;
    background-color:#D8D8D8;
    
    &:hover,
    &:focus {
      background-color:#A4A4A4;
    }
  }
}
View Compiled
const nav = document.querySelector('#nav');
const menu = document.querySelector('#menu');
const menuToggle = document.querySelector('.nav__toggle');
let isMenuOpen = false;


// TOGGLE MENU ACTIVE STATE
menuToggle.addEventListener('click', e => {
  e.preventDefault();
  isMenuOpen = !isMenuOpen;
  
  // toggle a11y attributes and active class
  menuToggle.setAttribute('aria-expanded', String(isMenuOpen));
  menu.hidden = !isMenuOpen;
  nav.classList.toggle('nav--open');
});


// TRAP TAB INSIDE NAV WHEN OPEN
nav.addEventListener('keydown', e => {
  // abort if menu isn't open or modifier keys are pressed
  if (!isMenuOpen || e.ctrlKey || e.metaKey || e.altKey) {
    return;
  }
  
  // listen for tab press and move focus
  // if we're on either end of the navigation
  const menuLinks = menu.querySelectorAll('.nav__link');
  if (e.keyCode === 9) {
    if (e.shiftKey) {
      if (document.activeElement === menuLinks[0]) {
        menuToggle.focus();
        e.preventDefault();
      }
    } else if (document.activeElement === menuToggle) {
      menuLinks[0].focus();
      e.preventDefault();
    }
  }
});
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.