After you’ve squeezed and merged every element on your page in an ever-decreasing viewport, there’s just two places left to go: outside, or underneath.
Take the fake page above for the very real Japanese energy drink “Blackout God”. As the viewport narrows, the navigation at the top has only a few places to go:
- Shift to the bottom of the page, with a “jump to navigation” link left at the top of the page, using an anchor.
- The navigation could become a drop-down menu.
- The navbar could move underneath or outside the body content, to be revealed with a click.
Broadly speaking, these design decisions are based on the number of links; the first two options are relevant if there are less than a dozen links in the navbar, while the last is better suited to longer navigational elements. For the sake of this exercise, I’ll take on the last option, focussing on the <header>
element in the example:
<div id="container">
<header>
<h1><a href="#"><span>Blackout</span> God</a></h1>
<nav id="headernav">
<a href="#">Home</a>
<a href="#">Products</a>
<a href="#">Order</a>
<a href="#"><span>Legal </span>Disclaimer</a>
</nav>
</header>
...
</div>
The CSS for the example covers the same territory, with the addition of the <body>
; I’ll address the use of SVG backgrounds and blend modes in a future article.
body {
background-image: url(hexgrid.svg), linear-gradient(#111 0%,#111 50%, #555 100%);
background-size: 35.5px 25px, 100% 100%;
background-blend-mode: exclusion;
}
header {
display: flex;
align-items: center;
text-transform: uppercase;
background: rgba(0,0,0,0.2);
}
#headernav a {
color: #fff;
transition: .3s;
text-decoration: none;
padding: .6rem;
}
header h1 a > span {
background: #fff;
color: #000;
padding: 0 1rem;
}
header + * {
margin-left: 7%;
}
#headernav a {
transition: .3s;
}
#headernav a:hover {
background: #000;
}
The navigation moves to the extreme right-hand side side, outside the viewport, when the browser narrows to 850px wide or less. First, we need to identify the elements we want to work with, together with the correct matchMedia
breakpoint. We’ll also initiate the button that will be used in place of the navbar when the latter is displaced:
var headernav = document.getElementById("headernav"),
container = document.getElementById("container"),
tablet = window.matchMedia("screen and (max-width: 850px)"),
header = document.getElementsByTagName("header")[0],
menulink = document.createElement("button");
menulink.id = "menulink";
menulink.innerHTML = "MENU";
Next, I’ll switch the position of the navbar when the breakpoint is met, removing the navbar and substituting in the menu button. This uses the same technique I discussed in a previous article:
function switcheroo(state) {
if (tablet.matches) {
headernav.remove();
header.appendChild(menulink);
container.appendChild(headernav);
} else {
menulink.remove();
header.appendChild(headernav);
}
}
switcheroo(tablet);
tablet.addListener(switcheroo);
When the button is clicked on, the shifted navigation has a slider
class added to it:
menulink.addEventListener("click", function() {
headernav.classList.toggle("slider");
})
That class, and the position of the navbar when the viewport is less than 850px wide, is defined in a @media
query:
@media all and (max-width: 850px) {
#headernav {
position: absolute;
right: -20%; top: 0;
width: 20%; background: #000;
height: 100%; transition: .3s;
}
#headernav a {
display: block;
}
#headernav a:hover {
background: #ccc; color: #000;
}
#headernav a span {
display: none;
}
#headernav.slider {
right: 0;
}
header button {
margin-left: 2rem;
}
}
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/HDjon