Navigation
Responsive navigation menus.
Demos
Toggle
The handle shows and hides the navigation in place. These demos set maxWidth: Infinity so they're always enabled; by default navigation is only enabled below 980px.
<div class="demo_page">
<button type="button" class="demo_button" id="toggle-handle">Menu</button>
<nav class="demo_nav js-navigation" data-navigation-handle="#toggle-handle">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
<p>Page content.</p>
</div>
import { Navigation, Utils } from 'formstone';
Utils.ready(() => {
Navigation.construct('.js-navigation', {
type: 'toggle',
maxWidth: Infinity, // Always enabled in this demo (default: below 980px)
});
});
body {
margin: 0;
}
.demo_button {
background: var(--color-yellow);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
cursor: pointer;
display: inline-block;
font: inherit;
padding: 10px 20px;
text-decoration: none;
}
/* Theme off-canvas navigation; set on both the navigation and the content */
.demo_nav,
.demo_page {
--fs-navigation-offscreen-width: 260px;
--fs-navigation-offscreen-background: var(--color-white);
}
.demo_page {
background: var(--color-gray-10);
min-height: 100vh;
padding: 5vh 5vw;
}
.demo_nav {
box-sizing: border-box;
padding: 20px;
}
.demo_nav a {
background: var(--color-blue);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
display: block;
margin-bottom: 10px;
padding: 10px 15px;
text-decoration: none;
}
.fs-navigation-handle.fs-navigation-open {
background: var(--color-red);
}
Overlay
The navigation slides in over the page content. While open, the rest of the page is inert; click outside or press Escape to close.
<div class="demo_page" id="overlay-content">
<button type="button" class="demo_button" id="overlay-left-handle">Menu Left</button>
<button type="button" class="demo_button" id="overlay-right-handle">Menu Right</button>
<p>Page content.</p>
</div>
<nav class="demo_nav js-navigation" data-navigation-handle="#overlay-left-handle" data-navigation-content="#overlay-content" data-navigation-options='{"gravity":"left"}'>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
<nav class="demo_nav js-navigation" data-navigation-handle="#overlay-right-handle" data-navigation-content="#overlay-content" data-navigation-options='{"gravity":"right"}'>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
import { Navigation, Utils } from 'formstone';
Utils.ready(() => {
Navigation.construct('.js-navigation', {
type: 'overlay',
maxWidth: Infinity, // Always enabled in this demo (default: below 980px)
});
});
body {
margin: 0;
}
.demo_button {
background: var(--color-yellow);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
cursor: pointer;
display: inline-block;
font: inherit;
padding: 10px 20px;
text-decoration: none;
}
/* Theme off-canvas navigation; set on both the navigation and the content */
.demo_nav,
.demo_page {
--fs-navigation-offscreen-width: 260px;
--fs-navigation-offscreen-background: var(--color-white);
}
.demo_page {
background: var(--color-gray-10);
min-height: 100vh;
padding: 5vh 5vw;
}
.demo_nav {
box-sizing: border-box;
padding: 20px;
}
.demo_nav a {
background: var(--color-blue);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
display: block;
margin-bottom: 10px;
padding: 10px 15px;
text-decoration: none;
}
.fs-navigation-handle.fs-navigation-open {
background: var(--color-red);
}
Push
The navigation slides in and pushes the page content aside.
<div class="demo_page" id="push-content">
<button type="button" class="demo_button" id="push-left-handle">Menu Left</button>
<button type="button" class="demo_button" id="push-right-handle">Menu Right</button>
<p>Page content.</p>
</div>
<nav class="demo_nav js-navigation" data-navigation-handle="#push-left-handle" data-navigation-content="#push-content" data-navigation-options='{"gravity":"left"}'>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
<nav class="demo_nav js-navigation" data-navigation-handle="#push-right-handle" data-navigation-content="#push-content" data-navigation-options='{"gravity":"right"}'>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
import { Navigation, Utils } from 'formstone';
Utils.ready(() => {
Navigation.construct('.js-navigation', {
type: 'push',
maxWidth: Infinity, // Always enabled in this demo (default: below 980px)
});
});
body {
margin: 0;
}
.demo_button {
background: var(--color-yellow);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
cursor: pointer;
display: inline-block;
font: inherit;
padding: 10px 20px;
text-decoration: none;
}
/* Theme off-canvas navigation; set on both the navigation and the content */
.demo_nav,
.demo_page {
--fs-navigation-offscreen-width: 260px;
--fs-navigation-offscreen-background: var(--color-white);
}
.demo_page {
background: var(--color-gray-10);
min-height: 100vh;
padding: 5vh 5vw;
}
.demo_nav {
box-sizing: border-box;
padding: 20px;
}
.demo_nav a {
background: var(--color-blue);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
display: block;
margin-bottom: 10px;
padding: 10px 15px;
text-decoration: none;
}
.fs-navigation-handle.fs-navigation-open {
background: var(--color-red);
}
Reveal
The page content slides aside to reveal the navigation underneath.
<div class="demo_page" id="reveal-content">
<button type="button" class="demo_button" id="reveal-left-handle">Menu Left</button>
<button type="button" class="demo_button" id="reveal-right-handle">Menu Right</button>
<p>Page content.</p>
</div>
<nav class="demo_nav js-navigation" data-navigation-handle="#reveal-left-handle" data-navigation-content="#reveal-content" data-navigation-options='{"gravity":"left"}'>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
<nav class="demo_nav js-navigation" data-navigation-handle="#reveal-right-handle" data-navigation-content="#reveal-content" data-navigation-options='{"gravity":"right"}'>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
import { Navigation, Utils } from 'formstone';
Utils.ready(() => {
Navigation.construct('.js-navigation', {
type: 'reveal',
maxWidth: Infinity, // Always enabled in this demo (default: below 980px)
});
});
body {
margin: 0;
}
.demo_button {
background: var(--color-yellow);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
cursor: pointer;
display: inline-block;
font: inherit;
padding: 10px 20px;
text-decoration: none;
}
/* Theme off-canvas navigation; set on both the navigation and the content */
.demo_nav,
.demo_page {
--fs-navigation-offscreen-width: 260px;
--fs-navigation-offscreen-background: var(--color-white);
}
.demo_page {
background: var(--color-gray-10);
min-height: 100vh;
padding: 5vh 5vw;
}
.demo_nav {
box-sizing: border-box;
padding: 20px;
}
.demo_nav a {
background: var(--color-blue);
border: var(--border-size) solid var(--color-black);
border-radius: var(--border-size);
color: var(--color-black);
display: block;
margin-bottom: 10px;
padding: 10px 15px;
text-decoration: none;
}
.fs-navigation-handle.fs-navigation-open {
background: var(--color-red);
}
Options
Set instance options by passing a valid object at initialization, or to the public .defaults() method. Custom options for a specific instance can also be set by attaching a data-navigation-options attribute containing a properly formatted JSON object to the target element.
| Name | Type | Default | Description |
|---|---|---|---|
gravity |
string |
'left' |
Navigation gravity (left, right) |
label |
string |
'Menu' |
Accessibility label |
maxWidth |
string |
'980px' |
Width to auto-disable instance |
type |
string |
'toggle' |
Navigation type (toggle, push, reveal, overlay) |
focusables |
string |
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' |
Focusable elements |
Data attributes provide configuration options and can be set directly on the target element.
| Name | Type | Description |
|---|---|---|
data-navigation-options |
string (JSON) |
JSON encoded object containing instance options |
data-navigation-handle |
string |
Selector for navigation handle element (required; a console warning is logged when missing) |
data-navigation-content |
string |
Selector for content element (required for push and reveal) |
While a push, reveal or overlay navigation is open it behaves as a modal dialog: the rest of the page is made inert, which hides it from assistive technologies and keeps focus inside the navigation. Clicking outside or pressing Escape closes it and returns focus to the handle. Handles get aria-expanded for every type and aria-haspopup="dialog" for modal types.
Methods
Methods are publicly available to all active instances, unless otherwise stated.
| Name | Description |
|---|---|
.close() |
Closes navigation instance |
.construct() |
Initializes Navigation on target elements |
.defaults() |
Sets default options for future instances |
.destroy() |
Removes instance and all related data |
.disable() |
Disables navigation instance |
.enable() |
Enables navigation instance |
.open() |
Opens navigation instance |
.close()
Closes instance.
Examples
el.Navigation.close();
.construct()
Initializes Navigation on target elements.
Returns
| Type | Description |
|---|---|
NodeList |
NodeList of target elements |
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
selector |
string (required) |
'' |
Selector string to target |
options |
object (optional) |
{} |
Object containing instance options |
Examples
let targets = Navigation.construct('.js-navigation');
Navigation.construct('.js-navigation', { type: 'overlay' });
.defaults()
Sets default options for future initialization.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
options |
object (required) |
{} |
Object containing default options |
Examples
Navigation.defaults({
type: 'push'
});
.destroy()
Removes instance and all related data.
Examples
el.Navigation.destroy();
.disable()
Disables instance.
Examples
el.Navigation.disable();
.enable()
Enables instance.
Examples
el.Navigation.enable();
.open()
Opens instance.
Examples
el.Navigation.open();
Events
Events are triggered on the target instance's element, unless otherwise stated.
| Name | Description |
|---|---|
navigation:open |
Instance opened |
navigation:close |
Instance closed |
Styles
CSS custom properties are used to modify default styles. Set the --fs-navigation-offscreen-* properties on both the navigation and the content element, since the content uses the same width to move aside.
| Property | Default | Description |
|---|---|---|
--fs-navigation-offscreen-background |
#fff |
Offscreen menu background |
--fs-navigation-offscreen-width |
80vw |
Offscreen menu width |
--fs-navigation-offscreen-zindex |
0 |
Offscreen menu z-index |
--fs-navigation-offscreen-duration |
0.2s |
Offscreen transition duration |
--fs-navigation-offscreen-timing |
ease |
Offscreen transition timing |
--fs-navigation-overlay-zindex |
3 |
Overlay navigation z-index |
--fs-navigation-overlay-content-background |
rgba(0, 0, 0, 0.8) |
Overlay content background |
--fs-navigation-overlay-content-zindex |
2 |
Overlay content z-index |
--fs-navigation-push-zindex |
0 |
Push navigation z-index |
--fs-navigation-push-content-zindex |
1 |
Push content z-index |
Classes allow deeper customization and indicate the current state of a specific instance.
| Classname | Type | Description |
|---|---|---|
.fs-navigation |
element |
Target element |
.fs-navigation-handle |
element |
Handle element |
.fs-navigation-content |
element |
Content element |
.fs-navigation-enabled |
modifier |
Indicates enabled state |
.fs-navigation-open |
modifier |
Indicates open state |
.fs-navigation-closed |
modifier |
Indicates closed state |
.fs-navigation-animated |
modifier |
Indicates animated state |
.fs-navigation-{type}-nav |
modifier |
Navigation type on the navigation element (toggle, push, reveal or overlay) |
.fs-navigation-{type}-handle |
modifier |
Navigation type on the handle |
.fs-navigation-{type}-content |
modifier |
Navigation type on the content element |
.fs-navigation-{type}-{gravity}-nav |
modifier |
Gravity (left or right) on the navigation element; not added for toggle |
.fs-navigation-{type}-{gravity}-handle |
modifier |
Gravity on the handle; not added for toggle |
.fs-navigation-{type}-{gravity}-content |
modifier |
Gravity on the content element while open; not added for toggle |
For example, type: 'push', gravity: 'right' adds .fs-navigation-push-nav and .fs-navigation-push-right-nav to the navigation, .fs-navigation-push-handle and .fs-navigation-push-right-handle to the handle, .fs-navigation-push-content to the content, and .fs-navigation-push-right-content to the content while open.