@morsedigital/vanilla-responsive-navigation
v1.4.0
Published
Responsive navigation module written in vanilla JavaScript
Downloads
54
Readme
vanilla-responsive-navigation
Synopsis
A responsive navigation module written in vanilla JavaScript.
Installation
npm install @morsedigital/vanilla-responsive-navigation
Running tests
npm run test
Example Instantiation
const ResponsiveNavigationClass = require('@morsedigital/vanilla-responsive-navigation');
const primaryNavigation = new ResponsiveNavigationClass(
'primary-navigation',
{
list_id: 'primary-navigation-list'
, toggle_id: 'primary-navigation-toggle'
}
);
if (primaryNavigation && primaryNavigation.hasOwnProperty('config')){
primaryNavigation._init();
}
Configuration
A new instance of ResponsiveNavigationClass can contain the following in its configuration object:
new ResponsiveNavigationClass({
dropdownClass: // String. Class for a list item which contains a child ul. Default is "dropdown-parent"
, flyout: // Boolean. Determines whether or not a class is added to the body when the navigation is visible. If you have more than one navigation on the page, make sure you're not setting this to true everywhere. Default is false
, list_id: // String. Id for the main ul in the navigation. Default is "responsive-navigation-list"
, toggle_id: // String. Id for the main toggle. Default is "responsive-navigation-toggle"
, toggle_mobile_id: // String. Id for the mobile toggle. This is only needed if flyout has been set to true. Default is null
});
Example HTML structure (non-flyout)
<nav class="primary-navigation" id="primary-navigation" role="navigation">
<a href="#" id="primary-navigation-toggle" class="primary-navigation-toggle" aria-controls="navigation" aria-expanded="false" aria-hidden="true" aria-label="navigation menu" role="button">
Toggle menu
</a>
<ul id="primary-navigation-list" class="primary-navigation-list">
<li>
<a href="/regular-link">Regular link</a>
</li>
<li class="dropdown-parent">
<a href="#">Parent link</a>
<ul>
<li>
<a href="/child-link-1">Child link 1</a>
</li>
<li>
<a href="/child-link-2">Child link 2</a>
</li>
</ul>
</li>
</ul>
</nav>
Example HTML structure (flyout)
<nav class="primary-navigation" id="primary-navigation" role="navigation">
<a href="#" id="primary-navigation-toggle" class="primary-navigation-toggle" aria-controls="navigation" aria-expanded="false" aria-hidden="true" aria-label="navigation menu" role="button">
Toggle menu
</a>
<ul id="primary-navigation-list" class="primary-navigation-list">
<li class="primary-navigation-header">
<!-- This is the mobile toggle which is used to close the navigation when it's open -->
<a href="#" id="primary-nav-toggle-mobile">
Toggle menu (flyout)
</a>
</li>
<li>
<a href="/regular-link">Regular link</a>
</li>
<li class="dropdown-parent">
<a href="#">Parent link</a>
<ul>
<li>
<a href="/child-link-1">Child link 1</a>
</li>
<li>
<a href="/child-link-2">Child link 2</a>
</li>
</ul>
</li>
</ul>
</nav>
CSS
As a bare minimum, you'll require the following, or similar CSS:
(non-flyout)
.primary-nav-list {
display: none;
&.open {
display: block;
}
}
(Flyout)
Non-responsive
(base styles)
body {
position: relative;
}
Responsive
(styles which are applied at different breakpoints)
@include breakpoint($mobile-breakpoint) {
body {
&.nav-open {
.primary-nav-list {
width: percentage(2/3);
}
}
}
.primary-nav-list {
right: -(percentage(2/3));
width: percentage(2/3);
}
}
@include breakpoint($mobile-and-tablet-breakpoint) {
body {
&.nav-open {
.primary-navigation-list {
right: 0;
}
}
}
.primary-navigation-list {
position: fixed;
top: 0;
@include transition(right 0.2s ease-in-out);
li {
float: left;
width: 100%;
}
.dropdown {
display: none;
}
.dropdown-parent {
& > a {
position: relative;
&:after {
content: "\25b6";
position: absolute;
top: 15px;
right: 10px;
}
&.open {
&:after {
content: "\25bc";
}
}
}
}
}
.primary-navigation-toggle {
display: block;
float: right;
position: relative;
top: 10px;
}
}
@include breakpoint($tablet-breakpoint) {
body {
&.nav-open {
.primary-nav-list {
width: percentage(1/2);
}
}
}
.primary-nav-list {
right: -(percentage(1/2));
width: percentage(1/2);
}
}
@include breakpoint($desktop-breakpoint) {
.primary-navigation-list {
.dropdown {
display: none;
overflow: hidden;
position: absolute;
left: 0;
top: 100%;
li {
clear: both;
white-space: nowrap;
width: 100%;
}
}
.dropdown-parent {
position: relative;
&:hover {
.dropdown {
display: block !important; /* Needs !important to override JS */
}
}
}
}
.primary-navigation-header, .primary-navigation-toggle {
display: none;
}
}