18F/18f.gsa.gov

View on GitHub
_sass/_libs/uswds/scss/components/_navigation.scss

Summary

Maintainability
Test Coverage
// Navigation helpers
// ---------------------------------

@mixin primary-nav-link {
  line-height: line-height($theme-navigation-font-family, 1);
  padding: units(2);
}

$nav-link-color: "base-dark";
$sliding-panel-width: "card-lg";
$nav-link-accordion-icon-size: 1.5;
$nav-link-arrow-icon-size: 1;

// TODO: Collect animations in a common location?
@keyframes slidein-left {
  from {
    transform: translateX(units($sliding-panel-width));
  }

  to {
    transform: translateX(0);
  }
}

// Header navigation
// ---------------------------------
.usa-nav {
  @include typeset($theme-navigation-font-family, null, 1);
  @include at-media-max($theme-header-min-width) {
    @include u-pin("right");
    @include u-pin("y");
    position: fixed;
    background: color("white");
    border-right: 0;
    display: none;
    flex-direction: column;
    overflow-y: auto;
    padding: units(2);
    width: units($sliding-panel-width);
    z-index: z-index(500);

    &.is-visible {
      animation: slidein-left 0.3s ease-in-out;
      display: flex;
    }
  }

  @include at-media($theme-header-min-width) {
    float: right;
    position: relative;
  }

  .usa-search {
    @include at-media($theme-header-min-width) {
      margin-left: units(2);
    }
  }

  .usa-accordion {
    @include typeset($theme-navigation-font-family, null, 1);
  }
}

// Primary navigation
// ---------------------------------

.usa-nav__primary {
  // Until the $theme-header-width,
  // use the usa-nav-list styles for the slide-in nav
  @include at-media-max($theme-header-min-width) {
    @include nav-list("nav");
    margin-top: units(3);
    order: 2;

    a {
      @include u-padding-y(1.5);
    }
  }

  // At $theme-header-width and wider...
  @include at-media($theme-header-min-width) {
    display: flex;
  }

  // all nav items in the nav
  .usa-nav__primary-item {
    a {
      text-decoration: none;
    }
  }

  // just level 1 nav items...
  > .usa-nav__primary-item {
    line-height: line-height($theme-navigation-font-family, 2);
    @include at-media($theme-header-min-width) {
      font-size: font-size($theme-navigation-font-family, "2xs");
      line-height: line-height($theme-navigation-font-family, 1);
    }

    // ...and their direct links
    > a {
      @include at-media($theme-header-min-width) {
        @include primary-nav-link;
        color: color($nav-link-color);
        display: block;
        font-weight: font-weight("bold");

        &:hover {
          color: color("primary");
        }
      }
    }
  }

  a {
    @include at-media($theme-header-min-width) {
      @include u-padding-y(1);
    }
  }

  button {
    $button-vertical-offset: 53%; // XXX: Magic number

    @include button-unstyled;
    color: color($nav-link-color);
    font-weight: font-weight("normal");
    line-height: line-height($theme-navigation-font-family, 2);
    padding: units(1.5) units(2);
    text-decoration: none;

    @include at-media($theme-header-min-width) {
      @include primary-nav-link;
      font-size: font-size($theme-navigation-font-family, "2xs");
      font-weight: font-weight("bold");
    }

    &:hover {
      color: color("primary");
      background-color: color("base-lightest");
      text-decoration: none;

      @include at-media($theme-header-min-width) {
        background-color: transparent;
      }
    }

    &[aria-expanded="false"] {
      /* stylelint-disable-line selector-no-qualifying-type */
      @include add-background-svg("plus-alt");
      background-position: right 0 center;
      background-size: units($nav-link-accordion-icon-size);

      @include at-media($theme-header-min-width) {
        @include add-background-svg("angle-arrow-down");
        background-size: units($nav-link-arrow-icon-size);
        background-position: right units(2) top $button-vertical-offset;
      }

      &:hover {
        @include at-media($theme-header-min-width) {
          @include add-background-svg("angle-arrow-down-primary");
        }
      }
    }

    &[aria-expanded="true"] {
      /* stylelint-disable-line selector-no-qualifying-type */
      @include add-background-svg("minus-alt");
      background-position: right 0 center;
      background-size: units($nav-link-accordion-icon-size);

      @include at-media($theme-header-min-width) {
        @include add-background-svg("angle-arrow-up-white");
        @include add-knockout-font-smoothing;
        background-size: units($nav-link-arrow-icon-size);
        background-color: color("primary-darker");
        background-position: right units(2) top $button-vertical-offset;
        color: color("white");
      }
    }
  }

  .usa-accordion__button {
    span {
      @include at-media($theme-header-min-width) {
        margin-right: 0;
        padding-right: units(2);
      }
    }
  }
}

// Secondary navigation
// ---------------------------------

.usa-nav__secondary {
  margin-top: units(2);

  @include at-media($theme-header-min-width) {
    // Note: Previius calc() couldn't work. don't hardcode rem vals
    bottom: units(8); // XXX magic number
    font-size: font-size($theme-navigation-font-family, "2xs");
    margin-top: units(1);
    min-width: calc(
      #{$theme-search-min-width} + #{units($theme-button-small-width)}
    );
    position: absolute;
    right: units($theme-site-margins-width);
  }

  .usa-search {
    margin-top: units(2);
    width: 100%;

    @include at-media($theme-header-min-width) {
      margin-left: 0;
      margin-top: units(1);
    }
  }
}

.usa-nav__secondary-links {
  @include add-list-reset;
  line-height: line-height($theme-navigation-font-family, 3);
  margin-top: units(3);

  @include at-media($theme-header-min-width) {
    float: right;
    line-height: line-height($theme-navigation-font-family, 1);
    margin-bottom: units(0.5);
    margin-top: 0;
  }

  .usa-nav__secondary-item {
    @include at-media($theme-header-min-width) {
      display: inline;
      padding-left: units(0.5);

      & + .usa-nav__secondary-item::before {
        color: color("base-lighter");
        content: "|";
        padding-right: units(0.5);
      }
    }
  }

  a {
    color: color("base");
    display: inline-block;
    font-size: font-size($theme-navigation-font-family, "2xs");
    text-decoration: none;

    &:hover {
      color: color("primary");
      text-decoration: underline;
    }
  }
}

// Navigation dropdowns
// ---------------------------------

.usa-nav__submenu {
  @include at-media-max($theme-header-min-width) {
    @include nav-sublist;
  }

  @include at-media($theme-header-min-width) {
    @include add-list-reset;
    background-color: color("primary-darker");
    width: units("card-lg");
    padding: units(2);
    position: absolute;
    z-index: z-index(400);
  }

  &[aria-hidden="true"] {
    display: none;
  }

  .usa-nav__submenu-item {
    @include at-media($theme-header-min-width) {
      & + * {
        margin-top: units(1.5);
      }

      a {
        color: color("white");
        padding: 0;
        line-height: line-height($theme-navigation-font-family, 3);

        &:hover {
          background-color: transparent;
          color: color("white");
          padding: 0;
          text-decoration: underline;
        }
      }
    }
  }
}

.usa-nav__submenu-list {
  @include unstyled-list;

  .usa-nav__submenu-list-item {
    margin: 0;
    font-size: font-size($theme-navigation-font-family, "2xs");

    a {
      line-height: line-height($theme-navigation-font-family, 3);
    }
  }
}

// Navigation close button
// ---------------------------------

.usa-nav__close {
  @include button-unstyled;
  @include u-square($size-touch-target);
  color: currentColor;
  flex: none;
  float: right;
  margin: units(-1.5) units(-2) units(2) auto;
  text-align: center;

  &:hover {
    color: currentColor;
    text-decoration: none;
  }

  @include at-media($theme-header-min-width) {
    display: none;
  }

  img {
    width: units(1.5);
  }

  + * {
    clear: both;
  }
}

.usa-js-mobile-nav--active {
  overflow: hidden;
}