Off-Canvas Menu

Todo

Roadmap

Toggle Nav: Off Canvas Drawer

Component Preview
<div class="o-canvas__drawer o-canvas__menu" aria-labelledby="o-canvas__menulabel">
    <div class="drawer-content">
        <h2 id="o-canvas__menulabel" class="element-invisible">Menu Drawer Options</h2>

    </div>
</div>
  • Content:
    .nav--horizontal {
      padding-top: 10px;
      border-bottom: 1px solid #ccc;
      background: #fff; }
    
    .block-superfish .menu > li:first-child > a {
      padding-left: 0; }
    
    .iowa-bar.iowa-bar--narrow .toggle-nav__bttn {
      display: flex;
      height: 60px; }
      @media (min-width: 980px) {
        .iowa-bar.iowa-bar--narrow .toggle-nav__bttn {
          height: 90px; } }
      @media (min-width: 84.375em) {
        .iowa-bar.iowa-bar--narrow .toggle-nav__bttn {
          top: 50px; } }
    
    .iowa-bar.iowa-bar--narrow .toggle-nav__bttn.inactive {
      background: #f1f1f1; }
    
    .iowa-bar.iowa-bar--narrow .toggle-nav__bttn.active {
      background: #fff; }
    
    .o-canvas--complete .iowa-bar.iowa-bar--narrow .toggle-nav__bttn {
      background: #f1f1f1; }
    
    .o-canvas__group {
      display: flex;
      height: 100%; }
      @media (min-width: 84.375em) {
        .o-canvas__group {
          position: absolute;
          top: 0;
          right: 0; } }
    
    .iowa-bar.iowa-bar--narrow .o-canvas__group {
      position: relative;
      display: flex;
      height: 100%; }
      @media (min-width: 84.375em) {
        .iowa-bar.iowa-bar--narrow .o-canvas__group {
          position: absolute; } }
    
    body.o-canvas--lock::before {
      visibility: visible;
      opacity: 1; }
    
    body.o-canvas--lock {
      overflow: hidden !important; }
    
    body:before {
      position: fixed;
      z-index: 2;
      top: 0;
      left: 0;
      visibility: hidden;
      width: 100%;
      height: 100%;
      content: "";
      transition: opacity .35s;
      pointer-events: none;
      opacity: 0;
      background: rgba(0, 0, 0, 0.55); }
    
    .o-canvas__group {
      flex-basis: 100%; }
      @media (min-width: 980px) {
        .o-canvas__group {
          flex-basis: unset; } }
    
    .o-canvas--complete .toggle-nav__bttn {
      background: #fff; }
    
    .toggle-nav__bttn.active {
      background: #fff; }
    
    .toggle-nav__bttn.inactive {
      background: #fff; }
    
    .toggle-nav__bttn:before {
      margin-right: 10px;
      padding: 0.325rem;
      padding-right: 7px;
      content: "\f0c9";
      color: var(--brand-secondary);
      font-size: 1.5rem;
      -moz-osx-font-smoothing: grayscale;
      -webkit-font-smoothing: antialiased;
      display: inline-block;
      font-style: normal;
      font-variant: normal;
      text-rendering: auto;
      line-height: 1;
      font-family: "Font Awesome 5 Free";
      font-weight: 900; }
      @media (min-width: 980px) {
        .toggle-nav__bttn:before {
          font-size: 1.2rem; } }
    
    .toggle-nav__bttn {
      justify-content: left;
      width: 100%; }
    
    .toggle-nav__bttn.inactive {
      background: #f1f1f1; }
      @media (min-width: 980px) {
        .toggle-nav__bttn.inactive {
          background: #fff; } }
    
    .toggle-nav__bttn.active {
      background: #f1f1f1; }
      @media (min-width: 980px) {
        .toggle-nav__bttn.active {
          background: #fff; } }
    
    .o-canvas__wrapper {
      width: 100%; }
      .o-canvas__wrapper button > * {
        pointer-events: none; }
    
    .toggle-nav__bttn {
      border: none;
      position: relative;
      display: flex;
      align-items: center;
      height: 60px;
      padding: 0 0 0 15px;
      font-weight: 700;
      font-size: 1rem;
      z-index: 2;
      cursor: pointer;
      text-align: center;
      text-decoration: none;
      text-transform: uppercase;
      line-height: 1.4;
      -webkit-font-smoothing: auto;
      -moz-osx-font-smoothing: auto; }
      @media (min-width: 980px) {
        .toggle-nav__bttn {
          height: 80px;
          padding: 14px 35px 0; }
          .iowa-bar--narrow .toggle-nav__bttn {
            padding: 9px 35px 0; } }
      .toggle-nav__bttn:focus span, .toggle-nav__bttn:hover span {
        text-decoration: underline; }
      @media (min-width: 980px) {
        .toggle-nav__bttn span {
          display: inline; } }
      .o-canvas--open .toggle-nav__bttn {
        color: var(--brand-secondary); }
      .toggle-nav__bttn:before {
        margin-right: 0;
        margin-top: -2px;
        padding: 1rem .9rem 1rem .7rem;
        color: var(--brand-secondary);
        font-size: 1rem;
        -moz-osx-font-smoothing: grayscale;
        -webkit-font-smoothing: antialiased;
        display: inline-block;
        font-style: normal;
        font-variant: normal;
        text-rendering: auto;
        line-height: 1;
        font-family: "Font Awesome 5 Free";
        font-weight: 900; }
        @media (min-width: 980px) {
          .toggle-nav__bttn:before {
            margin-right: 5px;
            padding: .8rem 1rem; } }
        .o-canvas--open .toggle-nav__bttn:before {
          width: 25px;
          height: 25px;
          margin-right: 10px;
          padding: 7px;
          content: "\f00d";
          color: #fff;
          border-radius: 50%;
          background: #999;
          font-size: 1rem;
          line-height: .8; }
          @media (min-width: 980px) {
            .o-canvas--open .toggle-nav__bttn:before {
              width: 35px;
              height: 35px;
              font-size: 1.2rem;
              line-height: 1; } }
    
    .o-canvas__drawer {
      position: fixed;
      z-index: 2;
      right: 0;
      display: block;
      visibility: hidden;
      overflow-y: auto;
      width: 100%;
      height: 100%;
      padding: 20px 22px 40px;
      transition: opacity .5s, transform .5s, visibility .5s, -webkit-clip-path 1s;
      transition: clip-path 1s, opacity .5s, transform .5s, visibility .5s;
      transition: clip-path 1s, opacity .5s, transform .5s, visibility .5s, -webkit-clip-path 1s;
      transform: scale(0.925);
      transform-origin: right top;
      opacity: 0;
      background: #fff; }
      @media (min-width: 980px) {
        .o-canvas__drawer {
          padding: 40px 35px;
          max-width: 560px; } }
      .o-canvas--open .o-canvas__drawer {
        visibility: visible;
        height: 100%;
        transition: all .4s ease-in-out;
        transform: scale(1);
        opacity: 1;
        box-shadow: 0 8px 8px 0 rgba(63, 63, 70, 0.25); }
        @media (min-width: 980px) {
          .o-canvas--open .o-canvas__drawer {
            top: 80px; } }
    
    @media (min-width: 980px) {
      .iowa-bar.iowa-bar--narrow .o-canvas--open .o-canvas__drawer {
        top: 146px; } }
    
    @media (min-width: 84.375em) {
      .iowa-bar.iowa-bar--narrow .o-canvas--open .o-canvas__drawer {
        top: 140px; } }
    
    .o-canvas__drawer {
      background-color: white; }
    
    .o-canvas__drawer[aria-hidden="false"]:not(:focus-within) {
      background-color: #fffffe;
      transition: background-color 0.01s; }
    
    .o-canvas--lock .iowa-bar__below {
      background: #f1f1f1; }
    
    @media (min-width: 980px) {
      .header-sticky.scroll-up .iowa-bar__below .o-canvas--open .o-canvas__drawer,
      .header-sticky.scroll-down .iowa-bar__below .o-canvas--open .o-canvas__drawer {
        top: 116px; } }
    
    @media (min-width: 84.375em) {
      .header-sticky.scroll-up .iowa-bar__below .o-canvas--open .o-canvas__drawer,
      .header-sticky.scroll-down .iowa-bar__below .o-canvas--open .o-canvas__drawer {
        top: 110px; } }
    
    @media (min-width: 980px) {
      .header-sticky.scroll-up .iowa-bar__below .toggle-nav__bttn,
      .header-sticky.scroll-down .iowa-bar__below .toggle-nav__bttn {
        height: 60px;
        padding: 3px 35px 0; } }
    
    @media (min-width: 980px) {
      .header-sticky.scroll-down .iowa-bar__below .toggle-nav__bttn {
        top: 0px; } }
    
    @media (min-width: 84.375em) {
      .header-sticky.scroll-down .iowa-bar__below .toggle-nav__bttn {
        top: 30px; } }
    
  • URL: /components/raw/toggle-nav/toggle-nav.css
  • Filesystem Path: src/components/menus/toggle-nav/toggle-nav.css
  • Size: 6.8 KB
  • Content:
    const drawerContainer = document.querySelectorAll(".o-canvas__wrapper");
    const toggleButtons = document.querySelectorAll("button.toggle-nav__bttn");
    const canvasDrawer = document.querySelectorAll(".o-canvas__drawer");
    
    // drawer open/close functionality
    
    document.addEventListener(
      "click",
      function (e) {
        if (!e.target.classList.contains("toggle-nav__bttn")) return;
        // Add the active/open class
        e.target.classList.toggle("active");
        e.target.parentNode.classList.toggle("o-canvas--open");
    
        if (e.target.classList.contains("active")) {
          e.target.setAttribute("aria-expanded", "true");
          e.target.classList.remove("inactive");
          e.target.nextElementSibling.setAttribute("aria-hidden", "false");
          //canvasDrawer[0].querySelector("#superfish-main-accordion li a").focus();
          document.body.classList.remove("o-canvas--complete");
          document.body.classList.add("o-canvas--lock");
        } else {
          e.target.setAttribute("aria-expanded", "false");
          e.target.classList.add("inactive");
          e.target.nextElementSibling.setAttribute("aria-hidden", "true");
          document.body.classList.add("o-canvas--complete");
          document.body.classList.remove("o-canvas--lock");
        }
        // go through each link
        for (var i = 0; i < toggleButtons.length; i++) {
          // skip clicked link
          if (toggleButtons[i] === e.target) continue;
          toggleButtons[i].classList.remove("active");
          toggleButtons[i].classList.remove("inactive");
          toggleButtons[i].setAttribute("aria-expanded", "false");
          toggleButtons[i].parentNode.classList.remove("o-canvas--open");
          toggleButtons[i].nextElementSibling.setAttribute("aria-hidden", "true");
        }
      },
      false
    );
    
    // click outside of menu drawer
    
    document.addEventListener(
      "click",
      function (event) {
        if (!event.target.closest(".o-canvas__group")) {
          document.body.classList.remove("o-canvas--lock");
          document.body.classList.add("o-canvas--complete");
          for (let i = 0; i < drawerContainer.length; i++) {
            drawerContainer[i].classList.remove("o-canvas--open");
          }
          for (let i = 0; i < toggleButtons.length; i++) {
            toggleButtons[i].classList.remove("active");
            toggleButtons[i].setAttribute("aria-expanded", "false");
            toggleButtons[i].nextElementSibling.setAttribute("aria-hidden", "true");
          }
        }
      },
      false
    );
    
    // esc key
    
    window.addEventListener("keydown", function (event) {
      if (event.key === "Escape") {
        document.body.classList.remove("o-canvas--lock");
        document.body.classList.add("o-canvas--complete");
        for (let i = 0; i < drawerContainer.length; i++) {
          drawerContainer[i].classList.remove("o-canvas--open");
        }
        for (let i = 0; i < toggleButtons.length; i++) {
          toggleButtons[i].classList.remove("active");
        }
      }
    });
    
  • URL: /components/raw/toggle-nav/toggle-nav.js
  • Filesystem Path: src/components/menus/toggle-nav/toggle-nav.js
  • Size: 2.8 KB
  • Content:
    @import '../../../assets/scss/variables';
    @import '../../../assets/scss/utilities';
    
    // traditional navigation below logo
    .nav--horizontal {
      padding-top: 10px;
      border-bottom: 1px solid #ccc;
      background: #fff;
    }
    
    .block-superfish .menu>li:first-child>a {
      padding-left: 0;
    }
    
    ////
    .iowa-bar.iowa-bar--narrow {
      .toggle-nav__bttn {
        display: flex;
        height: 60px;
    
        @include breakpoint(md) {
          height: 90px;
        }
    
        @include breakpoint(page-container) {
          top: 50px;
        }
      }
    
      .toggle-nav__bttn.inactive {
        background: #f1f1f1;
      }
    
      .toggle-nav__bttn.active {
        background: #fff;
      }
    
      .toggle-nav__bttn {
        .o-canvas--complete & {
          background: #f1f1f1;
        }
      }
    }
    
    // drawer container
    
    .o-canvas__group {
      display: flex;
      height: 100%;
    
      @include breakpoint(page-container) {
        position: absolute;
        top: 0;
        right: 0;
      }
    }
    
    
    .iowa-bar.iowa-bar--narrow .o-canvas__group {
      position: relative;
      display: flex;
      height: 100%;
    
      @include breakpoint(page-container) {
        position: absolute;
      }
    }
    
    
    
    // transparent overlay
    
    body {
      &.o-canvas--lock::before {
        visibility: visible;
        opacity: 1;
      }
    
      &.o-canvas--lock {
        overflow: hidden !important;
      }
    
      &:before {
        position: fixed;
        z-index: 2;
        top: 0;
        left: 0;
        visibility: hidden;
        width: 100%;
        height: 100%;
        content: "";
        transition: opacity .35s;
        pointer-events: none;
        opacity: 0;
        background: rgba(0, 0, 0, 0.55);
      }
    }
    
    .o-canvas__group {
      flex-basis: 100%;
    
      @include breakpoint(md) {
        flex-basis: unset;
      }
    }
    
    // buttons
    
    
    .toggle-nav__bttn {
      .o-canvas--complete & {
        background: #fff;
      }
    
      &.active {
        background: #fff;
      }
    
      &.inactive {
        background: #fff;
      }
    
      &:before {
        margin-right: 10px;
        padding: $xsm;
        padding-right: 7px;
        content: "\f0c9";
        color: $secondary;
        font-size: 1.5rem;
        @include fas();
        @include breakpoint(md) {
          font-size: 1.2rem;
        }
      }
    }
    
    .toggle-nav__bttn {
      justify-content: left;
      width: 100%;
    }
    
    .toggle-nav__bttn.inactive {
      background: #f1f1f1;
    
      @include breakpoint(md) {
        background: #fff;
      }
    }
    
    .toggle-nav__bttn.active {
      background: #f1f1f1;
    
      @include breakpoint(md) {
        background: #fff;
      }
    }
    
    
    .o-canvas__wrapper {
      width: 100%;
    
      button>* {
        pointer-events: none;
      }
    }
    
    .toggle-nav__bttn {
      border: none;
      position: relative;
      display: flex;
      align-items: center;
      height: 60px;
      padding: 0 0 0 15px;
      font-weight: 700;
      font-size: 1rem;
      z-index: 2;
      cursor: pointer;
      text-align: center;
      text-decoration: none;
      text-transform: uppercase;
      line-height: 1.4;
      -webkit-font-smoothing: auto;
      -moz-osx-font-smoothing: auto;
    
      @include breakpoint(md) {
        height: 80px;
        padding: 14px 35px 0;
        .iowa-bar--narrow & {
          padding: 9px 35px 0;
        }
      }
    
      &:focus,
      &:hover {
        span {
          text-decoration: underline;
        }
      }
    
      &:focus {}
      &:focus:not(:focus-visible) {}
      &:focus-visible {}
    
      span {
        @include breakpoint(md) {
          display: inline;
        }
      }
    
      .o-canvas--open & {
        color: $secondary;
      }
    
      &:before {
        margin-right: 0;
        margin-top: -2px;
        padding: 1rem .9rem 1rem .7rem;
        color: $secondary;
        font-size: $base-font-size;
    
        @include breakpoint(md) {
          margin-right: 5px;
          padding: .8rem 1rem;
        }
    
        @include fas();
    
        .o-canvas--open & {
          width: 25px;
          height: 25px;
          margin-right: 10px;
          padding: 7px;
          content: "\f00d";
          color: $white;
          border-radius: 50%;
          background: #999;
          font-size: 1rem;
          line-height: .8;
    
          @include breakpoint(md) {
            width: 35px;
            height: 35px;
            font-size: 1.2rem;
            line-height: 1;
          }
        }
      }
    }
    
    
    // off canvas drawer
    
    .o-canvas__drawer {
      position: fixed;
      z-index: 2;
      right: 0;
      display: block;
      visibility: hidden;
      overflow-y: auto;
      width: 100%;;
      height: 100%;
      padding: 20px 22px 40px;
      transition: clip-path 1s, opacity .5s, transform .5s, visibility .5s;
      transform: scale(0.925);
      transform-origin: right top;
      opacity: 0;
      background: #fff;
    
      @include breakpoint(md) {
        padding: 40px 35px;
        max-width: 560px;
      }
    
      .o-canvas--open & {
        visibility: visible;
        height: 100%;
        transition: all .4s ease-in-out;
        transform: scale(1);
        opacity: 1;
        box-shadow: 0 8px 8px 0 rgba(63, 63, 70, .25);
    
        @include breakpoint(md) {
          top: 80px;
        }
      }
    }
    
    .iowa-bar.iowa-bar--narrow .o-canvas--open .o-canvas__drawer {
      @include breakpoint(md) {
        top: 146px;
      }
      @include breakpoint(page-container) {
        top: 140px;
      }
    }
    
    .o-canvas__drawer {
      background-color: rgb(255, 255, 255);
    }
    
    .o-canvas__drawer[aria-hidden="false"]:not(:focus-within) {
      background-color: rgb(255, 255, 254);
      transition: background-color 0.01s;
    }
    
    .o-canvas--lock .iowa-bar__below {
      background: #f1f1f1;
    }
    
    // sticky header for Iowa Bar Below
    
    .header-sticky.scroll-up .iowa-bar__below,
    .header-sticky.scroll-down .iowa-bar__below {
      .o-canvas--open .o-canvas__drawer {
        @include breakpoint(md) {
          top: 116px;
        }
    
        @include breakpoint(page-container) {
          top: 110px;
        }
      }
    
      .toggle-nav__bttn {
        @include breakpoint(md) {
          height: 60px;
          padding: 3px 35px 0;
        }
      }
    }
    
    .header-sticky.scroll-down .iowa-bar__below {
      .toggle-nav__bttn {
        @include breakpoint(md) {
          top: 0px;
        }
    
        @include breakpoint(page-container) {
          top: 30px;
        }
      }
    }
    
  • URL: /components/raw/toggle-nav/toggle-nav.scss
  • Filesystem Path: src/components/menus/toggle-nav/toggle-nav.scss
  • Size: 5.5 KB