
Give your visitors a distraction-free way to read your website’s content without the permanent presence of a menu
As a 25-year-old, you’d expect the World Wide Web to have matured into a fully rounded adult by now; to know how to interact with others properly, to mind its manners and to understand which cutlery to use and when during meals.
As developers we all shape the user’s experience of the World Wide Web. The decisions you make and the effort that you put in will determine whether your particular part of WWW will work properly on a range of devices and whether your code will follow agreed practices and accessibility standards. Providing users with the right tools to use at the right time also has a big impact on usability.
As a core design principle if something isn’t needed, it simply shouldn’t be there. Dine at nearly any restaurant and your waiter will helpfully take away your menu whilst you enjoy your meal, but happily bring it back if you want to consider a dessert. By adding a smart menu to your website, you can tuck your menu discreetly out of the way and let your user concentrate on enjoying the main course. If they need something else, the menu is just a click away.
GET THE CODE FOR THIS TUTORIAL
Set the scene
This tutorial is about adding a smart menu as a refinement to the user experience, but in order for that to be effective you’ll want to provide other user refinements along the way. The right choice of font to suit your content and audience is a must. You should also try adding and removing the font-smoothing code to see the difference it makes.
001 @import url(http://fonts.googleapis.com/css?family=Maven+Pro);
002 * {
003 -webkit-font-smoothing: antialiased;
004 -moz-osx-font-smoothing: grayscale;
005 }
006
007 html {
008 background: url(../img/bg.jpg) no-repeat center center fixed;
009 -webkit-background-size: cover;
010 -moz-background-size: cover;
011 -o-background-size: cover;
012 background-size: cover;
013 }
Tweak that body
Experiment with different font-sizes, line-heights and paragraph spacing until you achieve the best look for your page. Many designers suggest that you avoid using the extremes of black and white to achieve a more aesthetically pleasing result. #eee will give you a nearly white result but just take the edge off any harshness.
001 body {
002 font-family: ‘Maven Pro’, sans-serif;
003 font-size: 25px;
004 line-height: 35px;
005 color: #eee;
006 }
007
008 p {
009 margin-bottom: 50px;
010 text-align: justify;
011 }
012
013 a {
014 color: #efbe5d;
015 text-decoration: none;
016 text-transform: uppercase;
017 }
Room to breath
Use of space is important in usability and also in setting your user’s expectations about the ‘weight’ of the content. Encourage your user to start reading by using plenty of space, especially around headings. Whilst this tutorial doesn’t attempt to provide a fully responsive solution, you should consider how your titles will look if they are forced to wrap in narrower viewports.
001 header {
002 margin: 100px 0 100px;
003 }
004 h1 {
005 font-size: 50px;
006 text-align: center;
007 line-height: 50px;
008 }
009
010 h2 {
011 color: #efbe5d;
012 text-align: center;
013 text-transform: uppercase;
014 border:1px solid #ccc;
015 border-width:0 0 1px 0;
016 margin-bottom: 20px;
017 }
Main menu style
For consistency and economy of code the main and side menu share much of the same styling rules. Border-width: 1px 0; will create a border at the top and bottom but no border to the left or right. If you’re unsure what a particular piece of code does, take it out and see what happens (even the most experienced developer has done this at some point).
001 #nav{
002 border:solid #ccc;
003 border-width:1px 0;
004 list-style:none;
005 margin:0 0 50px;
006 padding:0;
007 text-align:center;
008 }
009
010 #nav a {
011 display:inline-block;
012 }
013
Position the paragraphs
A max-width percentage is applied to avoid excessively long line-lengths on large screens but provide some flexibility to the layout. A reasonably sized margin is needed down the side to accommodate the side menu. Margin: 0 auto; is used to centre the paragraph text horizontally on the page.
001 #wrapper {
002 max-width: 60%;
003 margin: 0 auto;
004 }
005 #cd-nav li {
006 display: inline;
007 }
008 #cd-nav li a {
009 padding: 15px;
010 }
011 #cd-nav li a:hover {
012 color: #eee;
013 }
014
Menu ready
When the user scrolls down the page, the .is-fixed class is added to the #cd-nav div. in readiness for displaying the menu. It’s not needed until the user clicks on the icon though so it is scaled to 0% and waits
until it is called for.
001 #cd-nav.is-fixed ul {
002 position: fixed;
003 max-width: 125px;
004 transform: scale(0);
005 }
006
Now you see me
Steps seven and eight manage the positioning, appearance and disappearance of the side menu.
The menu icon is positioned conveniently half way down the viewport. You’ll want to tweak the top and margin-top settings to suit the height of your own menu and those settings have been adjusted here so that the whole menu is still visible even when the viewport height is significantly reduced.
001 #cd-nav ul.is-visible {
002 2 transform: scale(1);
003 transition: transform 0.3s, visibility 0s 0s;
004 }
005 #cd-nav ul.has-transitions {
006 right: 5%;
007 top:40%;
008 margin-top: -135px;
009 transition: transform 0.3s, visibility 0s 0.3s;
010 }
Now you don’t
ul.is-visible displays the menu when the icon is clicked, ul.has-transitions hides the menu if the icon is clicked whilst the menu is open. ul.is-hidden hides the menu when the page is scrolled past a preset point towards the top of the page.
001 #cd-nav ul.is-hidden {
002 transform: scale(0);
003 transition: transform 0.3s;
004 }
Style and position the menu icon background
It’s easy to change the shape, size and position of this to suit your needs. If you are going to have your icon background flush against the page edge, it makes good visual sense to only put rounded corners on the edges that are not flush.
001 .cd-nav-trigger {
002 position: fixed;
003 top: 50%;
004 right: 0%;
005 width: 60px;
006 height: 60px;
007 border-radius: 25px 0 0 25px;
008 background: #efbe5d;
009 overflow: hidden;
010 text-indent: 100%;
011 white-space: nowrap;
012 z-index: 2;
013 }
Burger and cross
This neat little code forms the central part of the burger icon. Aside from being file-size friendly, this method enables the icon to be easily customisable and easily animated. It’s well worth experimenting with these settings and those in the next two steps to see how the technique works.
001 .cd-nav-trigger span {
002 position: absolute;
003 display: block;
004 width: 20px;
005 height: 3px;
006 background: #eee;
007 top: 50%;
008 margin-top: -1px;
009 left: 50%;
010 margin-left: -10px;
011 transition: background 0.3s;
012 }
Cross bars
These pseudo-elements start to set up the white bars that sit above and below the central bar. When the icon is clicked in its burger state, the central bar fades away and the top and bottom bars rotate to form a cross. It happens quite quickly so slow the animation down if you want to see what is going on more clearly.
001 .cd-nav-trigger span::before, .cd-nav- trigger span::after {
002 content: ‘’;
003 position: absolute;
004 left: 0;
005 background: inherit;
006 width: 100%;
007 height: 100%;
008 transform: translateZ(0);
009 backface-visibility: hidden;
010 transition: transform 0.3s, background 0s;
011 }
012
As above, so below
The -8px for top and bottom are setting the bars in place and their rotation is set to zero in anticipation of them being animated. The RGB setting is a neat way of turning an element invisible. The RGB values could be set to any value and still achieve the same effect, it’s the last 0 that sets the opacity to zero.
001 .cd-nav-trigger span::before {
002 top: -8px;
003 transform: rotate(0);
004 }
005 .cd-nav-trigger span::after {
006 bottom: -8px;
007 transform: rotate(0);
008 }
010 .cd-nav-trigger.menu-is-open span {
011 background: rgba(0, 0, 0, 0);
012 }
013
Create the cross
You can set the cross to any colour you wish here. Rotating bars by 135 degrees and 225 degrees causes them to intersect at 180 degrees to create the cross shape. You can have fun by setting a much higher rotate value and set the cross bars spinning.
001 .cd-nav-trigger.menu-is-open span::before, .cd-nav-trigger.menu-is-open span::after {
002 background: #eee;
003 }
004 .cd-nav-trigger.menu-is-open span::before { top: 0;
005 transform: rotate(135deg);
006 }
007 .cd-nav-trigger.menu-is-open span::after {
008 bottom: 0;
009 transform: rotate(225deg);
010 }
011
Icon animation
The first part above removes the menu icon from the screen when the page is scrolled up. The second part sets up the animation. This is used when the icon’s appearance is triggered by scrolling down the screen.
001 .cd-nav-trigger {
002 visibility: hidden;
003 transform: scale(0);
004 transition: transform 0.3s, visibility 0s 0.3s;
005 }
006 .is-fixed .cd-nav-trigger {
007 visibility: visible;
008 transition: all 0s;
009 transform: scale(1);
010 animation: cd-bounce-in 0.3s linear;
011 }
Animations
Nearly 50 lines of code translate to five when vendor prefixes are removed, so check out the supplied files for the full code. This simple animation creates the bounce effect when it is triggered. The physics of the effect help make the menu seem more real.
001 @keyframes cd-bounce-in {
002 0% { transform: scale(0); }
003 60% { transform: scale(1.2); }
004 100% { transform: scale(1); }
005 }
HTML
Diving straight into the HTML, past the normal links to style sheets and the like, the menu icon is placed in the DOM but rendered invisible until it is required. To work correctly, the anchor link needs to be styled as a page anchor but shouldn’t be a valid link. The empty span tags enable the burger icon to be created.
001 <div id=”wrapper”> 002 <div id=”cd-nav”> 003 <a href=”#0” class=”cd-nav trigger”>Menu<span></span></a> 004 005 <header> 006 <a name=”1”></a><h1>The Star by H G Wells</h1> 007 </header>
An unordered list
The navigation content is all created using the usual unordered html list. The class of “cd-main-nav” is applied to the navigation. This class is not specified in the style sheet, instead it forms part of the small jQuery file and is used to identify that element so that it can be manipulated by the jQuery.
001 <nav id=”cd-main-nav”> 002 <ul id=”nav”> 003 <li><a href=”#1”>ONE</a></li> 004 <li><a href=”#2”>TWO</a></li> 005 <li><a href=”#3”>THREE</a></li> 006 <li><a href=”#4”>FOUR</a></li> 007 <li><a href=”#5”>FIVE</a></li> 008 </ul> 009 </nav> 010 </div>
