2013-08-02
A sample pattern for responsive "footer anchor" navigation.
A Pen by Oliver Pattison on CodePen.
<header> | |
<nav id="top"><a href="#menu">Menu ↓</a></nav> | |
<h1>Content-first responsive nav</h1> | |
<p class="responsive-alert">Hint: try narrowing this viewport to less than 40em (typically 640px).</p> | |
</header> | |
<article> | |
<p>This is a sample pattern for responsive "footer anchor" navigation. Try making your viewport width greater than 40em to see a large inline nav. Then try making your viewport width less than 40em to see a vertical nav at the bottom of the page.</p> | |
<p>"Footer anchor" is a content-first pattern that places content ahead of navigation on smaller screens. This uses no JavaScript and is entirely CSS-based.</p> | |
<h2>Why?</h2> | |
<p>This sort of pattern is really useful if you want to have navigation items clearly visible at the end of a long article, while also easily accessible on larger screen views in a standard horizontal list at the top of the page.</p> | |
<ul> | |
<li>Without this pattern, single-column layouts at the end of a long page will be so far from the site nav at the top that the user will not easily be able to get back to the top, especially on smaller devices.</li> | |
<li>On smaller viewports, fitting lots of nav items can be really difficult at the top of the page.</li> | |
<li>On larger viewports, there is often so much room for visible navigation items that you would not often want to hide it in a collapsed menu or push it to the bottom of the page.</li> | |
</ul> | |
<h2>Unresolved issues</h2> | |
<p>On larger viewports, there is no navigation at the bottom of the page! This might be an issue if users are expecting additional navigation at the bottom of a longer article (like you would find on a smaller viewport in this same pattern). One solution to this would involve having a redundant navigation <em>only</em> for larger viewports, but to me, this feels like a hack and may not be an ideal solution. Other solutions may involve having two separate navigations (one for large screens, one for smaller screens; exclusive and hidden from view when not needed) but this is also a hack and could lead to maintainability issues.</p> | |
<p>Even on small screens, this method doesn't feel like conventional navigation patterns, and therefore might surprise or confuse some people. However, I think this can be designed around a bit, especially if the nav options have high contrast against other elements, as well as a convenient "back to top" option. Even so, I can imagine some people would dislike this pattern. Figuring out whether it is appropriate for a project might require significant prototyping, research and user testing.</p> | |
<h2>Other people working on this pattern</h2> | |
<ul> | |
<li><a href="http://jasonweaver.name/lab/touchnav/v2/">Jason Weaver</li></a></li> | |
<li><a href="http://adactio.com/journal/6338/">Jeremy Keith</a></li> | |
<li><a href="http://codepen.io/bradfrost/full/mlyvu">Brad Frost</a></li> | |
<li><a href="http://www.lukew.com/ff/entry.asp?1649">Luke Wroblewski</a></li> | |
<li><a href="http://responsivenavigation.net/examples/footer-list/">Erick Arbé</a></li> | |
</ul> | |
<p>Thanks to the above for a bit of inspiration and some helpful examples.</p> | |
<h2>Let's go further down the page</h2> | |
<p>I have intentionally pushed smaller screens further down the page, as if this were a longer article.</p> | |
<hr> | |
</article> | |
<nav id="menu"> | |
<ul> | |
<li><a href="#menu">Home</a></li> | |
<li><a href="#menu">Archive</a></li> | |
<li><a href="#menu">About</a></li> | |
<li><a href="#menu">Contact</a></li> | |
<li><a href="#top">Back to top ↑</a></li> | |
</ul> | |
</nav> | |
<footer>An example footer. This is a pen by <a href="http://oliverpattison.org">Oliver Pattison</a>.</footer> |
/* Colors are Solarized http://ethanschoonover.com/solarized */ | |
html { | |
background: #fdf6e3; | |
color: #586e75; | |
font: normal 400 1rem/1.5 'Open Sans', Calibri, sans-serif; | |
} | |
body { | |
height: 100%; | |
margin: 0 auto; | |
max-width: 100%; | |
} | |
header, | |
article, | |
footer, | |
nav { | |
margin: 0 auto; | |
max-width: 40em; | |
padding: 0 1em; | |
} | |
a { | |
color: #b58900; | |
} | |
a:hover { | |
color: #268bd2; | |
} | |
header h1 { | |
line-height: 1.25; | |
margin: 0; | |
padding: .25em 0 0; | |
} | |
#top a, | |
#menu a { | |
background: #eee8d5; | |
border-left: #b58900 .5em solid; | |
display: block; | |
font-family: 'Calluna Sans', 'Open Sans', Calibri, sans-serif; | |
padding: 1em; | |
text-decoration: none; | |
} | |
#top a { | |
float: right; | |
margin: 0; | |
} | |
#menu ul { | |
padding: 0; | |
list-style: none; | |
} | |
#menu li { | |
margin: 1em; | |
} | |
#menu li:last-child a { | |
background: #eee8d5; | |
border-left: #93a1a1 .5em solid; | |
} | |
#menu li:last-child a { | |
color: #93a1a1; | |
} | |
article { | |
padding: .5em 1em 0; | |
} | |
hr { | |
border: #cb4b16 .5em solid; | |
margin: 2em; | |
} | |
footer { | |
background: #eee8d5; | |
padding: 2em 1em; | |
} | |
.responsive-alert { | |
background: #002b36; | |
color: #d75f00; | |
display: none; | |
font-size: .875em; | |
font-weight: bold; | |
padding: 1em; | |
} | |
/* Mobile-first media query! */ | |
@media screen and (min-width: 40em) { | |
.responsive-alert { | |
display: block; | |
} | |
header nav { | |
display: none; | |
} | |
header h1 { | |
margin: 0; | |
padding: 2.5em 0 0; | |
z-index: 4; | |
} | |
#menu { | |
font-size: 1em; | |
left: 50%; | |
margin: 0 0 0 -20em; | |
padding: 0; | |
position: absolute; | |
top: 0; | |
width: 40em; | |
} | |
#menu ul { | |
margin: 0; | |
} | |
#menu li { | |
display: inline-block; | |
margin: 0 1em; | |
} | |
#menu a { | |
margin: 0; | |
padding: .75em 2em; | |
} | |
#menu li:last-child { | |
display: none; | |
} | |
} |