Add basic navigation component

This commit is contained in:
Kyle Gordy 2019-11-12 12:33:21 -05:00
parent 7b9eda4245
commit 8a27a7c1d5
13 changed files with 433 additions and 24 deletions

View File

@ -1,18 +1,43 @@
<header role="banner">
{%- assign default_paths = site.pages | map: "path" -%}
{%- assign page_paths = site.header_pages | default: default_paths -%}
<h2><a rel="author" href="{{ "/" | relative_url }}">{{ site.title | escape }}</a></h2>
<!-- Skip to button -->
<a class="skip-link" href="#main-content">Skip to content</a>
{%- if page_paths -%}
<nav>
<ul>
{%- for path in page_paths -%}
{%- assign my_page = site.pages | where: "path", path | first -%}
{%- if my_page.title -%}
<li><a href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}</a></li>
{%- endif -%}
{%- endfor -%}
</ul>
<header class="nav" role="banner">
<nav class="nav__container container">
{%- assign default_paths = site.pages | map: "path" -%}
{%- assign page_paths = site.header_pages | default: default_paths -%}
<!-- Logo -->
<h1 class="m-0">
<a rel="author" href="{{ "/" | relative_url }}">
{% include logo.html %}
<span class="visually-hidden">{{ site.title | escape }}</span>
</a>
</h1>
<!-- Mobile menu button -->
<button class="nav__menu-trigger" type="button" aria-label="Navigation Menu" aria-expanded="false">
<span class="hamburger">
<span class="hamburger__inner"></span>
</span>
</button>
<!-- Page List -->
{%- if page_paths -%}
<ul class="nav-list list--inline monospace">
{%- for path in page_paths -%}
{%- assign my_page = site.pages | where: "path", path | first -%}
{% assign class = nil %}
{% if page.url == my_page.url %}
{% assign class = 'active' %}
{% endif %}
{%- if my_page.title -%}
<li class="nav-list__item">
<a class="nav-list__link {{ class }}" href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}</a>
</li>
{%- endif -%}
{%- endfor -%}
</ul>
{%- endif -%}
</nav>
{%- endif -%}
</header>

1
_includes/js.html Normal file
View File

@ -0,0 +1 @@
<script type="text/javascript" src="{{ "/assets/js/main.js" | relative_url }}"></script>

10
_includes/logo.html Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -4,15 +4,13 @@
{%- include head.html -%}
<body>
{%- include header.html -%}
<main aria-label="Content">
<main id="main-content" aria-label="Content">
{{ content }}
</main>
{%- include footer.html -%}
{% include js.html %}
</body>
</html>

View File

@ -2,14 +2,13 @@ html {
scroll-behavior: smooth; // smooth anchor link scrolling
}
body {
overflow-x: hidden; // for animation transforms
}
img {
max-width: 100%;
height: auto;
max-width: 100%;
height: auto;
}
// Global box-sizing
@ -23,6 +22,5 @@ img {
// Remove tap highlight on mobile
a {
-webkit-tap-highlight-color: transparent;
-webkit-tap-highlight-color: transparent; /* For some Androids */
-webkit-tap-highlight-color: transparent;
}

View File

@ -0,0 +1,65 @@
////////////////////
// List
////////////////////
.list--inline {
list-style-type: none;
margin: 0;
padding: 0;
> li {
display: inline;
}
}
.list--plain {
list-style: none;
margin: 0;
padding: 0;
}
////////////////////
// Visibility
////////////////////
// Hide visually and from screen readers
.hidden {
display: none !important;
}
// Hide only visually, but have it available for screen readers:
// https://a11yproject.com/posts/how-to-hide-content/
.visually-hidden:not(:focus):not(:active) {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
white-space: nowrap; /* added line */
}
////////////////////
// Spacing
////////////////////
.m-0 {
margin: 0 !important;
}
////////////////////
// Logo
////////////////////
.logo {
vertical-align: middle;
width: 100%;
max-width: 130px;
}
// Dark version of logo
.logo.dark {
.logo__icon { fill: $seafoam-light; }
.logo__wordmark { fill: $white; }
.logo__subhead { fill: rgba($white, .70) }
}

View File

@ -0,0 +1,39 @@
////////////////////
// Layout Variables
////////////////////
// Container padding
$cp-sm: 15px;
$cp-md: 5%;
$cp-lg: 75px;
// Max site width
$max-width: 1440px;
// Breakpoints
$bp-sm: 600px;
$bp-md: 800px;
$bp-lg: 1000px;
$bp-xl: $max-width;
////////////////////
// Container
////////////////////
.container {
width: 100%;
max-width: $max-width;
margin: auto;
padding-left: $cp-sm;
padding-right: $cp-sm;
@media screen and (min-width: $bp-md) {
padding-left: $cp-md;
padding-right: $cp-md;
}
@media screen and (min-width: $bp-xl) {
padding-left: $cp-lg;
padding-right: $cp-lg;
}
}

View File

@ -0,0 +1,56 @@
////////////////////
// Font Imports
////////////////////
// Source Sans Pro + Source Code Pro
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700|Source+Sans+Pro:400,400i,700&display=swap');
////////////////////
// Available Weights
////////////////////
// Source Sans Pro
// Regular: 400
// Regular Italic: 400i
// Bold: 700
// Source Code Pro
// Regular: 400
// Bold: 700
.sans-serif {
font-family: 'Source Sans Pro', sans-serif;
}
.monospace {
font-family: 'Source Code Pro', monospace;
}
////////////////////
// Body
////////////////////
body {
@extend .sans-serif;
font-size: 100%;
font-weight: 400;
color: $slate-800;
}
////////////////////
// Links
////////////////////
a {
color: $teal;
text-decoration: underline;
text-underline-offset: 2px;
text-decoration-color: transparent;
transition: 0.2s all ease-in-out;
transition-property: color, text-decoration;
}
a:hover,
a:focus {
text-decoration-color: currentColor;
}

View File

@ -0,0 +1,8 @@
.btn-reset {
padding: 0;
border: none;
font: inherit;
color: inherit;
background-color: transparent;
cursor: pointer;
}

View File

@ -0,0 +1,55 @@
////////////////////
// Variables
////////////////////
$width: 20px;
$height: 2px;
////////////////////
// Hamburger Button
////////////////////
.hamburger {
position: relative;
width: $width;
}
.hamburger:before,
.hamburger:after,
.hamburger__inner {
content: '';
position: absolute;
display: block;
right: 0;
width: $width - 3px;
height: $height;
background-color: $teal;
border-radius: $height;
transition: all 0.2s ease-in-out;
}
.hamburger:before,
.hamburger:after {
width: 100%;
transform-origin: left;
}
.hamburger:before {
top: -7px;
}
.hamburger:after {
top: 7px;
}
.active .hamburger:before {
transform: translateX(3px) rotate(45deg);
}
.active .hamburger__inner {
opacity: 0;
}
.active .hamburger:after {
transform: translateX(3px) rotate(-45deg);
}

View File

@ -0,0 +1,140 @@
////////////////////
// Variables
////////////////////
$nav-height-sm: 60px;
$nav-height-lg: 80px;
$nav-zindex: 10;
////////////////////
// Navigation
////////////////////
.nav {
position: relative;
width: 100%;
background-color: $white;
border-bottom: 1px solid $slate-300;
z-index: $nav-zindex;
}
.nav__container {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
height: $nav-height-sm;
background-color: $white;
@media (min-width: $bp-md) {
height: $nav-height-lg;
}
}
.nav .logo {
@media(max-width: $bp-md) {
max-width: 105px;
}
}
.nav__menu-trigger {
@extend .btn-reset;
width: $nav-height-sm;
height: $nav-height-sm;
margin-right: -$cp-sm;
display: flex;
justify-content: center;
align-items: center;
outline: none;
@media (min-width: $bp-md) {
display: none;
}
}
.nav-list {
@media (max-width: $bp-md) {
position: absolute;
top: $nav-height-sm;
right: 0;
bottom: 0;
left: 0;
height: calc(100vh - #{$nav-height-sm});
padding: 20px $cp-sm;
background-color: $teal;
display: flex;
flex-direction: column;
overflow: auto;
opacity: 0;
visibility: hidden;
transition-duration: 0.2s;
transition-property: opacity, visibility, transform;
transition-timing-function: ease-in-out;
}
}
.menu-active .nav-list{
opacity: 1;
visibility: visible;
}
.nav-list__item {
border-bottom: 1px solid $teal-dark;
@media (min-width: $bp-md) {
border-bottom: none;
}
&:not(:last-of-type) {
@media (min-width: $bp-md) {
margin-right: 20px;
}
@media (min-width: $bp-lg) {
margin-right: 40px;
}
}
}
.nav-list__link {
display: block;
padding: 20px 10px;
color: $white;
@media (min-width: $bp-md) {
display: inline;
padding: 10px 0;
color: $slate-600;
&:hover,
&:focus,
&.active {
color: $teal;
text-decoration: underline;
}
}
}
////////////////////
// Skip Nav Link
////////////////////
.skip-link {
position: absolute;
top: -$nav-height-lg;
padding: 1rem;
font-size: 1rem;
line-height: 1;
color: $white;
text-decoration: none;
background: $teal-dark;
transition: top .2s ease-in-out;
z-index: $nav-zindex + 1;
&:focus {
top: 0;
}
}

View File

@ -9,3 +9,10 @@
@import "base/colors";
@import "base/normalize";
@import "base/additional-defaults";
@import "base/typography";
@import "base/layout";
@import "base/helpers";
@import "component/buttons";
@import "component/navigation";
@import "component/hamburger-button";

7
assets/js/main.js Normal file
View File

@ -0,0 +1,7 @@
// Mobile Menu Toggle
var menuBtn = document.querySelector(".nav__menu-trigger");
menuBtn.onclick = function () {
menuBtn.classList.toggle("active");
document.body.classList.toggle("menu-active");
};