Going Off Canvas with Zurb Foundation 3.0

The hottest trend in the industry today is almost certainly responsive webdesign (RWD). Every day new approaches appear which redefine the way that we think about websites responding to different devices including desktops, tablets and phones. Today we're going to be diving head first into the newest RWD pattern on the block, off-canvas layouts - a very clever approach from the team at Zurb.
In this tutorial, we're going to be creating a simple homepage that has some very special features when viewed on a smaller viewports. While we're going to be working step by step to create the page, we will be getting Zurb Foundation and the Off-Canvas Layouts to do all the heavy lifting for us.
Ready to get started?
A Few Things Before we Start
As I mentioned, we're going to be building our site based on the hot-off-the-press Zurb Foundation 3.0. Foundation is an advanced responsive front end framework that is often compared to Twitter Bootstrap (Which we have covered here before on Webdesigntuts+). While it's not completely necessary to have used Foundation before, I strongly recommend that you review the Foundation documentation, in particular the Grid section, before you get started on this tutorial.
Secondly, we're not going to be following strict best practices in this tutorial, for the sake of brevity and clarity. For example, we're going to be over-riding the base styles with our own stylesheet, which will have some (very minimal) impacts on performance and an extra HTTP request. I'll be making comments throughout the article whenever another approach may be a better alternative for a production site.
As a quick note on terminology, I'll be referring to the viewport when describing the size of the browser. For example, a 'small viewport' in the context of this tutorial will refer to a browser size (or device) smaller than 768px.
Finally, in the code sections of the tutorial, I'll only be including the -webkit
brower prefix where relevant for the sake of brevity. In the downloadable files, all of the browser prefixes will be included.
With all that said, let's take a look at how we're going to be approaching this project.
The Plan Of Attack
Rather than laying out all of our markup first and then returning to style it via CSS - which would quickly get confusing - we're going to build the page in small chunks, starting with our general markup and then fleshing out and styling each section as we progress.
We're going to be approaching the project like this:
- Download all of the required files and setup our file tree.
- Setup the base HTML and CSS.
- Markup and style the components of the desktop version of the site (i.e. wide viewport size), one by one.
- Hookup the off-canvas components.
- Add and override some media queries to enhance the look of the site for small viewports.
- Look under the hood at what powers the layout.
Step 1: Download the Framework
As we've already discussed, this page is going to be based upon Foundation 3.0 and the off-canvas layouts, both developed by Zurb.
First, head over to the Foundation website and download the latest version. We'll be using the complete download package in this tutorial (but you could also create your own custom build if you prefer).



Next, we'll need to download the off-canvas layouts from the Zurb Playground.



Unzip both files, but don't combine them just yet - we will need to tweak the document tree, which we'll be covering in Step 3 in a few moments.
Step 2: Download Page Assets
We'll be using a few images and assets in our project. Download and extract the source files to use what you see in the demo. The images for the slides are just placeholders however, so you might think about something a little more dynamic to spice things up.
- Images
- slide1.jpg (alternatively: Orb (#79688) by Marc Sebastian)
- slide2.jpg (alternatively: Old Dusty Radio (#48791) by Marc Sebastian)
- slide3.jpg (alternatively: IMG_5720 by Marc Sebastian)
- logo.jpg
- featured_project.png
- Custom Icon Font (Credit IcoMoon)
- IcoMoon.eot
- IcoMoon.svg
- IcoMoon.ttf
- IcoMoon.woff
- index.html
Step 3: Setup the File Tree
Now that we have all of the required files, stylesheets and scripts, let's combine these into a single folder so that we can start getting our hands dirty.
We have to do a little renaming and tweaking here, so be careful to follow these next steps closely:
1. Create a new folder on your desktop and move across the contents of the extracted Foundation 3.0 folder.



2. Rename the index.html file to 'default.html'.
Create a new folder called 'misc' and move the license, robots and humans text files (just to keep everything neat and tidy).



3. From the offcanvas folder that you have downloaded and extracted, move the following files into your main project folder:
- offcanvas-2.html → root
- css/offcanvas.css → /stylesheets/
- js/jquery.offcanvas.js → /javascripts/



4. Create a new folder under 'images' and name it 'site_assets'. Copy across the image files downloaded from the resources (see Step Two.)



5. Create a new folder called 'fonts' and move across the custom font files downloaded in Step Two.



6. Finally, create the following new files:
- index.html
- /stylesheets/style.css



Note: there are several files in the javascripts folder that we won't be using in this project. I've left them in, in case you want to build upon our base and explore the other features of Foundation. For the record, this tutorial requires the following .js files - feel free to delete the remaining scripts:
- app.js
- jquery.min.js
- jquery.offcanvas.js
- jquery.orbit-1.4.0.js
- modernizer.foundation.js
Step 4: Lay Down the HTML Markup
As mentioned already, we're going to be building our page piece by piece, but I do want to make sure that we have a plan to build upon. As such, let's markup our index.html page so we know where we are headed in the following steps.
First, let's setup our <head>
and <body>
and link up all of the required stylesheets and scripts:
index.html
1 |
<!DOCTYPE html>
|
2 |
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
|
3 |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
4 |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
|
5 |
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
|
6 |
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> |
7 |
<head>
|
8 |
<meta charset="utf-8" /> |
9 |
|
10 |
<!-- Set the viewport width to device width for mobile -->
|
11 |
<meta name="viewport" content="width=device-width" /> |
12 |
|
13 |
<title>Off Canvas Layout With Zurb Foundation</title> |
14 |
|
15 |
<!-- Included Foundations CSS Files -->
|
16 |
<link rel="stylesheet" href="stylesheets/foundation.css"> |
17 |
<link rel="stylesheet" href="stylesheets/offcanvas.css"> |
18 |
|
19 |
<!-- Included Custom CSS Files -->
|
20 |
<link rel="stylesheet" href="stylesheets/style.css"> |
21 |
|
22 |
<!--[if lt IE 9]>
|
23 |
<link rel="stylesheet" href="stylesheets/ie.css">
|
24 |
<![endif]-->
|
25 |
|
26 |
<!-- Include Gooogle Webfonts -->
|
27 |
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600' rel='stylesheet' type='text/css'> |
28 |
|
29 |
<script src="javascripts/modernizr.foundation.js"></script> |
30 |
|
31 |
<!-- IE Fix for HTML5 Tags -->
|
32 |
<!--[if lt IE 9]>
|
33 |
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
34 |
<![endif]-->
|
35 |
|
36 |
</head>
|
37 |
|
38 |
<body id="page"> |
39 |
|
40 |
<!-- HEADER -->
|
41 |
|
42 |
<!-- SLIDER -->
|
43 |
|
44 |
<!-- CALLOUT -->
|
45 |
|
46 |
<!-- SERVICES -->
|
47 |
|
48 |
<!-- FEATURED PROJECT -->
|
49 |
|
50 |
<!-- CONTACT US -->
|
51 |
|
52 |
<!-- FOOTER -->
|
53 |
|
54 |
|
55 |
<!-- Include JS Files -->
|
56 |
|
57 |
<script src="javascripts/jquery.min.js"></script> |
58 |
<script src="javascripts/foundation.js"></script> |
59 |
<script src="javascripts/apps.js"></script> |
60 |
<script src="javascripts/jquery.orbit-1.4.0.js"></script> |
61 |
<script type="text/javascript" src="javascripts/jquery.offcanvas.js"></script> |
62 |
|
63 |
|
64 |
</body>
|
While everything here should be fairly self explanatory, let's quickly run through the code:
- The HTML5 doctype has been set.
- Added some conditional rules for older versions of Internet Explorer.
- Changed the viewport width (i.e. the width of the browser window) to the width of the device for phones.
- We've linked up the stylesheets that we'll be using during this project, including an 'IE8 and under only' stylesheet Note, you'd ideally want to combine and minify these stylesheets for a production site.
- We'll be using the 'Open Sans' webfont from Google Webfonts in this project. We've included a call to this font in three different weights (300, 400 and 600). View the Open Sans font family.
- We've included a link to the modernizer script and the HTML5 shiv for IE8.
- In the body of the document I've added in some comments to indicate the final structure of the markup.
- Finally, we've linked to our javascript files, including jQuery, Foundation, Orbit (the Foundation slider that we'll be using in this project), and of course, our off-canvas script that will help with the final effects that we're trying to achieve.
Easy peasy so far, right? Let's set up our CSS stylesheet and add a few base styles.
Step 5: Set Up the CSS
Before creating our own style.css stylesheet, we want the ability to read the foundation.css stylesheet (even though we won't be making any changes to it). As the downloaded foundation.css file is served to us minified (i.e. no white space, no trailing semi-colons and no line breaks), it's not very readable at the moment.
To solve this problem, we need to 'unminify' the CSS:
- Open up the foundation.css stylesheet in your code editor of choice and copy the entire contents to your clipboard.
- Head over to Peter Coles' Online CSS Unminifier.
- Paste the copied text into the first window on the site and click the 'Unminify' button.
- In the second window that appears, copy all the text to your clipboard.
- Return to the foundation.css file, and copy the clipboard text over the top of the file.
- Save the document with the same filename and location (/stylesheets/foundation.css)
As the unminified foundation.css is around 2800 lines, we're not going to waste time by navigating the entire file to make changes and insert new styles. Instead, we've already created our own stylesheet called 'style.css' that we will be including new styles and over-riding the base styles set out by foundation.css.
Open up style.css from your stylesheets folder and add the following code:
1 |
@charset "UTF-8"; |
2 |
|
3 |
/* `Main Styles and Grid Overrides
|
4 |
----------------------------------------------------------------------------------------------------*/
|
5 |
/* Set some colors that will be used in the layout */
|
6 |
body {background-color:#201A16;} |
7 |
|
8 |
.color-one {background-color: #4A456C;} /* light purple */ |
9 |
.color-two {background-color:#353153 ;} /* dark purple */ |
10 |
.color-three {background-color: #201A16;} /* brown */ |
11 |
.color-four {background-color:#755F4F ;} /*light brown*/ |
12 |
.color-five {background-color:#dddddd;} /*dark gray */ |
13 |
|
14 |
section { |
15 |
padding:0; |
16 |
margin:0; |
17 |
/* Prevents horizontal scrollling for off-canvas elements */
|
18 |
overflow-x: hidden; |
19 |
}
|
20 |
|
21 |
/* Set the width of the site rows */
|
22 |
.row { |
23 |
width:1024px; |
24 |
}
|
25 |
|
26 |
/* Make sure that the bands stretch to 100% width */
|
27 |
.full-width, .site-footer { |
28 |
min-width:100%; |
29 |
position: relative; |
30 |
z-index:9999; |
31 |
}
|
32 |
|
33 |
|
34 |
/* `PRIMARY NAVBAR
|
35 |
----------------------------------------------------------------------------------------------------*/
|
36 |
|
37 |
/* `TYPOGRAPHY
|
38 |
----------------------------------------------------------------------------------------------------*/
|
39 |
|
40 |
h2, h3 { |
41 |
font-family:'Open Sans', sans-serif; |
42 |
text-align:center; |
43 |
color:white; |
44 |
font-size:2em; |
45 |
font-weight:600; |
46 |
}
|
47 |
|
48 |
h3 { |
49 |
font-size:1.7em; |
50 |
position: relative;} |
51 |
|
52 |
p { |
53 |
color:white; |
54 |
font-size: 1.3em; |
55 |
font-family: 'Open Sans', sans-serif; |
56 |
font-weight: 300; |
57 |
}
|
58 |
|
59 |
|
60 |
/* `BUTTONS
|
61 |
----------------------------------------------------------------------------------------------------*/
|
62 |
|
63 |
/* `FORMS
|
64 |
----------------------------------------------------------------------------------------------------*/
|
65 |
|
66 |
/* `LAYOUT
|
67 |
----------------------------------------------------------------------------------------------------*/
|
68 |
|
69 |
/* `OFF CANVAS
|
70 |
----------------------------------------------------------------------------------------------------*/
|
71 |
|
72 |
|
73 |
/* `MEDIA QUERIES
|
74 |
----------------------------------------------------------------------------------------------------*/
|
At this stage, all we have done is created some structure to the stylesheet to help us keep everything organized and logical in the later steps (as defined by the CSS comments), and added a selection of style overrides and some color classes that we will be using in the initial steps.
You'll note that color classes have been added (e.g. .color-one) to our styles. While we could build the colors directly into the page section selectors as we go, this approach allows us to easily modify colors in a single place, as well as giving us a reusable class that can be used to style any elements background anywhere in the page.
Another thing to note is that instead of describing the color classes with their color (e.g. .dark-purple), they are completely non-presentational, allowing us to change the colors at any time or even reuse the code in another project without being locked in to presentational class names.
I've also removed the default padding from the section
elements as we'll be creating a full width layout.
The default .row
class set in foundation.css is 1000px, which is a tad too narrow for our layout. We've changed this to 1024px.
Next, I've added a .full-width
class that will allow us to create our 100% width section 'bands' in our layout.
Finally, under the 'Typography' section, I've also set some base styles for our header and paragraph elements.
Columns? Rows? Full Width classes? Confused? Don't be. Let's take a flyby review of how Foundation works.
Step 6: A Five Minute Review of Foundation
You have read the Foundation documentation, and have an understanding of how a Foundation page is structured, right?
No? Let's get you up to speed.
A webpage built with Foundation follows a set format that allows you to create a multi columned, responsive layout very quickly and very easily.
The following diagram gives you an overview of the general structure that we'll be using today:



This is a very simplified overview, but it will serve our purposes to explain the Foundation grid system.
Firstly, Foundation 2 requires a container div to wrap all of its child content within. This requirement has been removed in the latest code base of Foundation 3.0, meaning that row divs can be included directly under the <body>
tags.
Secondly, to achieve our colored 'bands', each section is wrapped in a div with a class of .fullwidth
. The background color will be added in with an additional class (.color-one, .color-two, etc.), which we added in the previous step.
Next, each part of the site is wrapped in a div with a class of .row
In the last step, we set the width of the row div at 1024px. In fact, we could set this width at any width to suit our needs and the Foundation grid adapts to the width without us needing to change any other CSS.
Contained in each .row
div are up to twelve divs with a class of .column
, depending on the layout you want to achieve. So, for example, for content that stretches the full width of the row, we would use apply the classes of .twelve .columns
. In the second example (which is representative of a page with a main content area and a side bar), inside our row you would have two divs, one with a classes of .eight .columns
and another with classes of .four .columns
.
When the browser window is resized to a smaller viewport (or a small device is used to view the site), the columns automatically stack on top of one other as per the rules set out in foundation.css stylesheet - that's right… with just a little bit of markup, your site is automatically responsive (cool, huh?).
Finally, in the last example in the above image, we can center a column horizontally within the row by applying the additional class .centered
(note, this only centers the div, not the content inside it).
To make these concepts clearer, let's code the three examples in the image:
1 |
|
2 |
<!-- example one -->
|
3 |
<div class="full-width color-one"> |
4 |
<div class="row"> |
5 |
<div class="twelve columns"> |
6 |
|
7 |
<!-- ...content goes here... -->
|
8 |
|
9 |
</div><!-- end twelve columns --> |
10 |
</div><!-- end row --> |
11 |
</div><!-- end full-width --> |
12 |
|
13 |
<!-- example two -->
|
14 |
<div class="full-width color-two"> |
15 |
<div class="row"> |
16 |
<div class="eight columns"> |
17 |
|
18 |
<!-- ...content goes here... -->
|
19 |
|
20 |
</div><!-- end eight columns --> |
21 |
|
22 |
<div class="four columns"> |
23 |
|
24 |
<!-- ...content goes here... -->
|
25 |
|
26 |
</div><!-- end four columns --> |
27 |
</div><!-- end row --> |
28 |
</div><!-- end full-width --> |
29 |
|
30 |
<!-- example three -->
|
31 |
<div class="full-width color-three"> |
32 |
<div class="row"> |
33 |
<div class="eight columns centered"> |
34 |
|
35 |
<!-- ...content goes here... -->
|
36 |
|
37 |
</div><!-- end eight columns --> |
38 |
</div><!-- end row --> |
39 |
</div><!-- end full-width --> |
An important concept to understand about the Foundation grid system is that column widths are measured in percentages, meaning that they automatically adjust to fill the row (or nested row) that they are children of.
Another thing that is very important to note is that columns stretch to 100% of the width of the row - in fact, the Foundation grid system uses box-sizing on all elements, so there is no padding or margins between columns (the spacing in the image above is only representational to illustrate the broad concepts of the grid system).
It should also be noted that you are able to nest infinite rows within columns (well, within reason, anyway). While we won't be doing much nesting of rows within columns in this tutorial, this is a very powerful layout technique and gives the ability to create extremely sophisticated layout patterns.
Still confused, or you'd like to delve into the grid system some more? I highly recommend that you review the extensive documentation on the Foundation site.
And with that whistlestop tour of the basics of the Foundation grid system, let's get into some code!
Step 7: Markup the Header Section
For our header, we want a logo to the left of the page and a simple navigation bar that will float to the right side of the page. When the viewport of the browser or the device reaches a width of 768px and under, we want a number of things to happen:
- The logo will be the topmost element of the site, and will remain aligned left to the browser window.
- The navigation bar will become hidden.
- Two buttons will appear that will give access to the small-viewport navigation menu and the off-canvas elements of the site.
- When the menu button is pressed, a mobile navigation menu will dropdown from the top of the screen.
- When the 'off-canvas' button (as we will call it for now) is pressed, the main screen will move to the right and a supplemental panel will slide out from the left of the panel.
We will be tackling steps four and five later on in the tutorial, but we have everything that we need baked right into Foundation to achieve steps one to three.
First, since we know that our logo and our navigation bar will occupy two ends of the same row, we can easily lay this out with the .row
and .column
classes discussed in the last step.
In your index.html file, add the following code directly under the header comment (underneath the <body>
) tag:
1 |
|
2 |
<div class="first full-width color-three"> |
3 |
|
4 |
<header id="header" class="row"> |
5 |
|
6 |
<!-- LOGO -->
|
7 |
<div class="five columns"> |
8 |
<a href="#" class="logo"><img src="images/site_assets/logo.png" /> |
9 |
<h1 class="hide-for-small">Off Canvas</h1></a> |
10 |
</div> <!-- end five columns --> |
11 |
|
12 |
<!-- LARGE VIEWPORT NAVIGATION -->
|
13 |
<div class="seven columns"> |
14 |
<nav id="menu" class="hide-for-small"> |
15 |
<ul id="mainNav" class="nav-bar"> |
16 |
<li><a href="" class="main">Home</a></li> |
17 |
<li><a href="" class="main">About</a></li> |
18 |
<li><a href="" class="main">Services</a></li> |
19 |
<li><a href="" class="main">Blog</a></li> |
20 |
<li><a href="" class="main">Contact</a></li> |
21 |
</ul>
|
22 |
</nav>
|
23 |
|
24 |
<!-- SMALL SCREEN EXTRAS BUTTONS -->
|
25 |
<p class="show-for-small"> |
26 |
<a class='menu-button button' id="menuButton" href="#menu">Menu</a><!-- link goes to named anchor --> |
27 |
<a class='sidebar-button button' id="sidebarButton" href="#contact" >Contact Us</a> |
28 |
</p>
|
29 |
|
30 |
<!-- link goes to named anchor -->
|
31 |
</div><!-- end seven columns --> |
32 |
|
33 |
</header>
|
34 |
</div><!-- end full width --> |
35 |
|
36 |
<!-- All other site components
|
37 |
...
|
38 |
...
|
39 |
... -->
|
There are a few things to comment on in this code block - including the utilization of a number of Foundation's features.
First, you'll notice that we have wrapped our logo in a div with a class of .five .columns
and our navigation bar (and the extras) in a .seven .columns
div, as per our introduction to the grid system in Step Six.
As I mentioned, at smaller screen sizes, we want the main navigation to be hidden from view. Using Foundation, this is as simple as adding the class .hide-for-small
, which effectively sets display: block;
in viewports greater than 767px sets display: none;
for the element in smaller viewports (take a look at the unminified foundation.css code from line 547 – 565 for a better understanding of this).
In the opposite way, the two buttons in the 'small screen extras' section are hidden from view on large screens (>767px) and displayed on smaller screens by adding the .show-for-small
class to the <p>
element.
We've also added some ids to the small screen buttons that will help us in the later stages of the tutorial.
Make sure that the the footer
tag is closed right above our javascripts and <body&rt;
tag at the bottom of the page - all of the markup for the remaining site components will be wrapped in this div.
Now that we have established the markup, let's style the individual components.
In your style.css file, under the 'Layout' section, add the following code:
1 |
/* HEADER */
|
2 |
|
3 |
.logo { |
4 |
position: relative; |
5 |
top:20px; |
6 |
}
|
7 |
|
8 |
|
9 |
.logo img { |
10 |
/* Remove border in ie */
|
11 |
border:none; |
12 |
}
|
13 |
|
14 |
.first { |
15 |
/* add the border under the header */
|
16 |
border-bottom: 5px solid #755F4F; |
17 |
}
|
18 |
|
19 |
header { |
20 |
min-height: 100px; |
21 |
}
|
You'll see that there is nothing too groundbreaking here. We've simply set a minimum height for the <header>
, added a 5px border to the full width div with the inclusion of the .first
class and set some basic positioning for the logo.
Currently, the <h1>
element sits on top of the logo image. We'll want to remove the this header from view but still include it in the markup for SEO and accessibility purposes.
Under the 'Typography' section of style.css, add in the following code:
1 |
h1 { |
2 |
/* remove h1 text from the viewport */
|
3 |
font: 0/0 a; |
4 |
text-shadow: none; |
5 |
color: transparent; |
6 |
}
|
Here, we've set the h1 to a font size and line height of 0%, removed any legacy text shadow and removed any text color.
Next, we'll style our navigation menu.
Step 8: Style the Navigation Menu
Under the 'Primary Navbar' section of the style.css stylesheet, add in the following code:
1 |
/* nav bar floats to the right of the row */
|
2 |
#mainNav {float:right;} |
3 |
|
4 |
|
5 |
.nav-bar { |
6 |
/* override foundation styles */
|
7 |
background-color:transparent; |
8 |
border:none; |
9 |
}
|
10 |
|
11 |
.nav-bar > li { |
12 |
/* removes borders */
|
13 |
box-shadow:0 0 0 0; |
14 |
border:none; |
15 |
/*centers nav bar to the logo */
|
16 |
line-height: 60px; |
17 |
background-color:#201a16; |
18 |
-webkit-transition:all .2s ease-in-out; |
19 |
}
|
20 |
|
21 |
.nav-bar>li:last-child { |
22 |
border:none; |
23 |
/* removes borders */
|
24 |
box-shadow:0 0 0 0; |
25 |
}
|
26 |
|
27 |
.nav-bar > li:hover { |
28 |
border-bottom: 4px white solid; |
29 |
-webkit-transition:all .2s ease-in-out; |
30 |
box-shadow: 0 1px 3px rgba(0, 0, 0, .4) inset; /* Opera 10.5, IE9, FF4+, Chrome 6+, iOS 5 */ |
31 |
background-color:#110E0C; |
32 |
}
|
33 |
|
34 |
.nav-bar > li a { |
35 |
border:none; |
36 |
font-family: 'Open Sans', sans-serif; |
37 |
font-weight: 400; |
38 |
/* px used instead of em to ensure nav bar doesn't break into multiple lines */
|
39 |
font-size: 15px !important; |
40 |
}
|
In this CSS, we are taking the base styles from foundation and applying style more suited to our design.
The default styles in Foundation create borders for the navigation <li>
elements in two ways, first by applying a 'border-left' attribute and secondly by applying a 1px box shadow. Since we don't want any borders, both the border and box-shadow attributes need to be set to 0.
In addition to the base styling, I've also added a simple transition to the hover state of the <li>
items that adds a little polish to the menu. It's also worth pointing out that as well as applying the transition to the hover state, I've also applied the same transition to the normal state, so when the mouse hovers off the element, the effect 'rewinds'.
The only other thing of note in this code block is the use of pixels instead of ems for the link elements. While it's often a good idea to use ems (or rems) for text elements in your projects to allow users to define their own text size, in this case we want to ensure that users can't resize their text so as not to break the layout of the navigation bar (of course we can't do anything about zooming, however!).
We also need to style the small-screen-extras buttons.
In the 'Buttons' section of your style.css stylesheets, apply the following code:
1 |
.button { |
2 |
background-color:#dddddd; |
3 |
border-color: #cccccc; |
4 |
color:#222222; |
5 |
}
|
6 |
|
7 |
.button:hover { |
8 |
background-color: #bbb; |
9 |
box-shadow: 0px 0px 10px rgba(0, 0, 0, .8) inset; /* Opera 10.5, IE9, FF4+, Chrome 6+, iOS 5 */ |
10 |
border-color: #444444; |
11 |
color:#222222; |
12 |
}
|
13 |
|
14 |
.button:focus { |
15 |
-webkit-box-shadow: 0 0 4px #ffffff, 0 1px 0 rgba(255, 255, 255, 0.5) inset; |
16 |
-moz-box-shadow: 0 0 4px #ffffff, 0 1px 0 rgba(255, 255, 255, 0.5) inset; |
17 |
box-shadow: 0 0 4px #2ba6cb, 0 1px 0 rgba(255, 255, 255, 0.5) inset; |
18 |
color: #222; |
19 |
}
|
All we are doing here is building upon the existing styling from foundation.css. What that means is that we need to change some colors and we can still take advantage of all of Foundation's sweet transitions.
Note: these changes will flow on to any other buttons in the page. If we wanted a button of a different color later on (for example a submit button), we could easily target it with an additional class name.
Great! That's our header finished (for the moment). If you resize your browser window, you'll be able to see Foundation in action. Of course, our small-screen-extra buttons don't do anything (yet).
Step 9: The Slider
For the next section of the site, we'll be adding a simple slider that will scroll through three full-width images. In addition, the slider width will resize to the width of the border, and will also become hidden on screens smaller than 767px.
Sounds complicated? Actually, it's quite simple. We'll be using Foundation's built in slider "Orbit" plugin which is extremely easy to hook up and customize to meet our needs.
Under the 'Slider' section in your index.html file, add in the following code:
1 |
<div class="full-width"> |
2 |
<div class="hide-for-small"> |
3 |
<div id="featured"> |
4 |
<img src="images/site_assets/slide1.jpg" alt="" /> |
5 |
<img src="images/site_assets/slide2.jpg" alt="" /> |
6 |
<img src="images/site_assets/slide3.jpg" alt="" /> |
7 |
</div>
|
8 |
</div> <!-- end hide-for-small --> |
9 |
</div><!-- end full width --> |
You'll see here that we've wrapped the slider (with an id of "featured") in a div with a class of .hide-for-small
that will change the slider to display: none;
for screen sizes <767px. Both of these divs are wrapped in a .full-width
div.
Styling the slide show couldn't be easier. In your style.css stylesheet, add the following CSS under the 'Layout' section:
1 |
/* SLIDER */
|
2 |
#featured > img {width:100%;} |
Finally, we need to call the Orbit jQuery script. At the bottom of your document before the </body>
tag, add the following script:
1 |
<!-- Call Slideshow --> |
2 |
<script type="text/javascript"> |
3 |
$(window).load(function() { |
4 |
$('#featured').orbit(); |
5 |
}); |
6 |
</script> |
Before we move on, there's just a couple of quick things that I'd like to mention.
Firstly, depending on your Foundation build, you may need to change the file path of the Orbit images (arrows, timers, bullets, etc.) to the correct location in your file tree (../images/foundation/orbit/..). You can do this quite simply by completing a find / replace in your foundation.css stylesheet, or update them manually between lines 2448 and 2659 of the unminified foundation.css file.
Secondly, we won't be customizing the slider past the base styles. There are a bunch of different options, transitions and more that you can apply to the slider. To learn more about extending the Orbit slider, refer to the Foundation Orbit Documentation.
Thirdly, I'd like to point out that there would be performance issues with this solution for small screens if put into the wild. The .hide-for-small
class simply sets display: none;
, and does not actually stop the device from downloading the images. This means that a mobile phone on cellular data would be downloading three sizable images for - essentially - nothing.
This is a tricky topic and is out of scope for this tutorial, however a possible solution may be to use AJAX to load in the images for large screen sizes.
Step 10: The Callout Section
The next step is to add a simple callout or slogan to the site underneath the slider.
Under the 'Callout' section in the index.html, add the following code:
1 |
<div class="full-width color-five"> |
2 |
<div class="row callout"> |
3 |
<div class="twelve columns"> |
4 |
<p>We make incredible websites for incredible companies.</p> |
5 |
</div><!-- end columns --> |
6 |
</div><!-- end row --> |
7 |
</div><!-- end full width color five --> |
In this HTML we've set up a full width column div .twelve .columns
, and added a class of .callout
to the row that will allow us to style the callout text.
Next step is to add some styling for the </code>
element.
Under the 'Typography' section of the style.css stylesheet, add the following code:
1 |
/* CALLOUT PANEL */
|
2 |
|
3 |
.callout p { |
4 |
font-family:'Open Sans', sans-serif; |
5 |
text-align:center; |
6 |
font-size:2em; |
7 |
font-weight:600; |
8 |
color:#222222; |
9 |
margin-bottom: 0; |
10 |
}
|
Note: all of these attributes except for color and margin-bottom are identical to the h1, h2 & h3 selectors that we have already defined. While it's fine to add the .callout p
selector to this stack, I've chosen to define it separately in case we would want to either change the style of any of these elements or reuse the code for a future project. As always, there's pros and cons to both approaches and I'll leave the final choice with you.
Next, add the following CSS to the 'Layout' section of the stylesheet:
1 |
.callout {padding:20px 0;} |
Step 11: Markup the Services Section
In the services section of the site we want three side-by-side panels that will stack on top of one another on small viewports.
First, let's start with the general markup.
Under the 'Services' section in your index.html, add in the following markup:
1 |
<div class="full-width color-two"> |
2 |
<div class="row"> |
3 |
<div class="eight columns centered"> |
4 |
<h2>Our Services</h2> |
5 |
</div>
|
6 |
</div>
|
7 |
|
8 |
<div class="row"> |
9 |
<div class="four columns service"> |
10 |
|
11 |
<!-- Content will go here -->
|
12 |
|
13 |
</div> <!-- end four columns --> |
14 |
|
15 |
<div class="four columns service"> |
16 |
|
17 |
<!-- Content will go here -->
|
18 |
|
19 |
</div> <!-- end four columns --> |
20 |
|
21 |
<div class="four columns service"> |
22 |
|
23 |
<!-- Content will go here -->
|
24 |
|
25 |
</div> <!-- end four columns --> |
26 |
|
27 |
</div><!-- end row --> |
28 |
|
29 |
</div><!-- end full-width --> |
You'll see that we've created a single .row
div wrapped in a .full-width
div. In the row, we've created three .four .columns
div and added in an additional class of .service
to each.
We'll add a little padding to the .service
class in the 'Layout' section of the style.css stylesheet:
1 |
/* SERVICES AREA */
|
2 |
.service {padding-bottom: 30px;} |
Step 12: Add Content and Style the Service Panels
For the content of each service panel we'll be including an icon font (downloaded from IcoMoon to add a visual representation of the relevant service, a header, some lorem ipsum text and a 'read more' button:
1 |
<!-- SERVICES -->
|
2 |
<div class="full-width color-two"> |
3 |
<div class="row"> |
4 |
<div class="eight columns centered"> |
5 |
<h2>Our Services</h2> |
6 |
</div>
|
7 |
</div>
|
8 |
|
9 |
<div class="row"> |
10 |
<div class="four columns service"> |
11 |
<!-- data-icon attribute sets the correct icon font. See line #140 style.css -->
|
12 |
<h3 class="service-icon"><span aria-hidden="true" data-icon="&#x6e;"></span> Webdesign</h3> |
13 |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
14 |
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, |
15 |
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo |
16 |
consequat. </p>
|
17 |
|
18 |
<span><a href="#" class="radius button">Learn More &rarr;</a></span> |
19 |
</div>
|
20 |
|
21 |
<div class="four columns service"> |
22 |
<h3 class="service-icon"><span aria-hidden="true" data-icon="&#x21;"></span>Copywriting</h3> |
23 |
|
24 |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
25 |
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, |
26 |
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo |
27 |
consequat. </p>
|
28 |
<span><a href="#" class="radius button">Learn More &rarr;</a></span> |
29 |
</div>
|
30 |
|
31 |
<div class="four columns service"> |
32 |
<h3 class="service-icon"><span aria-hidden="true" data-icon="&#x22;"></span>Marketing</h3> |
33 |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
34 |
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, |
35 |
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo |
36 |
consequat. </p>
|
37 |
<span><a href="#" class="radius button">Learn More &rarr;</a></span> |
38 |
</div>
|
39 |
</div><!-- end row --> |
40 |
</div><!-- end full-width --> |
You'll note that we are using the data-icon
selector along with the relevant unicode for each heading to include the icon in our page. I don't want us to lose momentum, so I won't go into this in much detail. Having said that, if you want to read more about why data-icon
is a preferred method for this application, Chris Coyier has a good overview of HTML for Icon Font Usage over on CSS Tricks.
For your reference, the unicode pairings for our icon font are as follows:
- n = Screen Icon
- ! = Pencil Icon
- " = Graph Icon
Next, we will style the <h3>
element, hookup the IcoMoon <@font-face>
and style the icons.
In the 'Typography' section of your stylesheet, add in the following code:
1 |
@font-face { |
2 |
font-family: 'IcoMoon'; |
3 |
src: url('../fonts/IcoMoon.eot'); |
4 |
src: url('../fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), |
5 |
url('../fonts/IcoMoon.svg#IcoMoon') format('svg'), |
6 |
url('../fonts/IcoMoon.woff') format('woff'), |
7 |
url('../fonts/IcoMoon.ttf') format('truetype'); |
8 |
font-weight: normal; |
9 |
font-style: normal; |
10 |
}
|
In this code block, we are referencing the IcoMoon fontface with preferred formats for the various browsers.
Next, in the 'Layout' section of the stylesheet, add the following code:
1 |
/* Use Data-icon in the HTML to use the icon font */
|
2 |
[data-icon]:before { |
3 |
/* providing a fallback bg color for browsers that don't support rgba*/
|
4 |
background-color:#000000; |
5 |
background-color: rgba(0,0,0,.4); |
6 |
/* Sets the background disc and shadow */
|
7 |
box-shadow: 0 1px 1px rgba(255,255,255,0.3), 0 1px 0 rgba(0, 0, 0, 0.33) inset; |
8 |
border-radius: 60px; |
9 |
/* inserts the icon font as pseudo-content */
|
10 |
content: attr(data-icon); |
11 |
display: block; |
12 |
font-family: 'IcoMoon'; |
13 |
|
14 |
/* We want the icons to be fixed size (like an image), so we use px instead of em */
|
15 |
font-size: 60px; |
16 |
height: 120px; |
17 |
|
18 |
/* Centers the icon in the disc */
|
19 |
line-height:120px; |
20 |
}
|
21 |
|
22 |
h3.service-icon span { |
23 |
/* give the span width */
|
24 |
display: block; |
25 |
/* centers the icon and its background */
|
26 |
margin: 0 auto; |
27 |
width: 120px; |
28 |
margin-bottom:20px; |
29 |
}
|
30 |
|
31 |
.service > span { |
32 |
padding: 20px 0 30px 0; |
33 |
width:100%; |
34 |
display:block; |
35 |
/* Centers the button, since the button fills its parent with 100% width */
|
36 |
text-align:center; |
37 |
}
|
The comments here should be fairly self explanatory, but in essence this block of CSS creates a 60px high white icon centered in the middle of a circular disc with a diameter of 120px. A chained set of box-shadows gives the disc a subtle 'letterpress' effect. We've also defined the height of all elements in pixels (instead of ems) to give us control over users that resize their default text size in their browsers.
The span that wraps the button is set to width: 100%;
and text-align: center;
to ensure that the button aligns itself to the horizontal center of the service column.
Great! We're making excellent progress. Let's move on to the featured project section of the site.
Step 13: Markup the Featured Project Section
In this section of the site, we're aiming to add an image of a featured project that is aligned to the center of the page. When we scale down the browser size, we also want this image to respond to the new viewport width and automatically scale down to an appropriate size.
The markup for this section of the site is fairly straight forward:
1 |
<!-- FEATURED PROJECT --> |
2 |
<div class="full-width color-one"> |
3 |
<div class ="row featured"> |
4 |
<div class="twelve columns"> |
5 |
<h2>Featured Project</h2> |
6 |
<a href="#" class="featured"><img src="images/site_assets/featured_project.png" alt="Featured Project Screenshot"></a> |
7 |
</div> |
8 |
</div> |
9 |
</div> <!-- end full-width --> |
Styling our featured project is nice and easy, too.
Under the 'Layout' section in your stylesheet, add the following code:
1 |
/* Featured Project */
|
2 |
.featured { |
3 |
padding-bottom: 30px; |
4 |
}
|
5 |
|
6 |
.featured img { |
7 |
/* centers the image to the middle of the .columns div */
|
8 |
position: relative; |
9 |
left: 50%; |
10 |
margin-left:-300px; |
11 |
border: none; |
12 |
}
|
The way that we've positioned the image is worth talking about briefly. Since we know that the width of the image is 600px, we can accurately center the image to its parent by adding position:relative
, setting the left position to 50% and then giving it a negative left margin of 300px (half the width of the image).
Step 14: Markup The Contact Section
Creating forms for any website is never a fun job, but luckily for us, Foundation makes the job about as painless as possible. Not only can we use and build upon the default styling from the foundation.css stylesheet (which is quite nice in itself), we can also use rows and columns to control the widths of our input and text area fields.
Let's add in the following code underneath the featured image section of our page and then we'll discuss the way that we have controlled the layout of the form:
1 |
<div class="full-width"> |
2 |
<div class="row"> |
3 |
<div class="ten columns centered"> |
4 |
<h2>Get In Contact</h2> |
5 |
|
6 |
We'd love to hear from you about your next project. Fill in the form below and we'll be in touch with you as soon as we can. |
7 |
|
8 |
<form>
|
9 |
<div class="row"> |
10 |
<div class="six columns"> <!-- this controls the width of the inputs --> |
11 |
<label>Name</label> |
12 |
<input type="text" class="oversize" /> |
13 |
<label>Email</label> |
14 |
<input type="text" class="oversize" /> |
15 |
</div>
|
16 |
</div>
|
17 |
|
18 |
<div class="row"> |
19 |
<div class="twelve columns"> <!-- this controls the width of the textarea --> |
20 |
<label>Tell Us About Your Project</label> |
21 |
<textarea></textarea>
|
22 |
<a href="#" class="button" id="submit">Submit</a> |
23 |
</div>
|
24 |
</div>
|
25 |
</form>
|
26 |
</div>
|
27 |
</div> <!-- end row --> |
28 |
</div><!-- end full width --> |
The first thing that you will notice is that we have taken advantage of the .centered
class to align the ten columns div to the center of the row. Doing this will ensure that the form remains neat and the input elements do not stretch too wide.
Next, you'll see that we have nested a row and a six-column div inside the form to control the width of the input fields. Remember, that because our columns are all measured in percentage widths, the width of a nested column is relative to its parent (in this case the .ten .columns
div), and not the 1024px that we have set for all <div class="row">
elements. In other words, a .six .columns
div will always be half the width of its parent.
Next, we have closed the row housing the .six .columns
div and created a new row that has a child div with classes of .twelve .columns
that give the textarea
a width of 100% of its parent (which is still the ten column div).
As I mentioned before, the default styles of the Foundation forms are perfectly acceptable as they are, but with that said, we'll tweak a few of the styles so that they fit will with our overall design.
Under the 'Forms' section of your stylesheet, add in the following CSS:
1 |
label { |
2 |
font-family: 'Open Sans', sans-serif; |
3 |
font-size:1.3em; |
4 |
color:white; |
5 |
font-weight: 300; |
6 |
padding: 15px 0 5px 0; |
7 |
}
|
8 |
|
9 |
input[type="text"], textarea { |
10 |
border-radius:5px; |
11 |
background-color:#110E0C; |
12 |
border:1px solid #0A0807; |
13 |
box-shadow: 0 2px 7px rgba(0, 0, 0, .5) inset; |
14 |
height: 45px; |
15 |
color:white; |
16 |
}
|
17 |
|
18 |
input[type="text"]:focus, textarea:focus { |
19 |
/* change the font color on focus */
|
20 |
color:black; |
21 |
}
|
22 |
|
23 |
textarea { |
24 |
min-height:200px; |
25 |
font-family: sans-serif; |
26 |
font-size: 18px; |
27 |
overflow-y: hidden; |
28 |
}
|
Step 15: Create the Footer
The final step for our basic page is to add a (very) simple footer.
Add in the following code underneath the 'Footer' section of the index.html file:
1 |
<!-- FOOTER -->
|
2 |
<footer class=" color-four site-footer row" role="contentinfo"> |
3 |
<div class="twelve columns"> |
4 |
<p>Chris Brown for Webdesign Tuts+ Using Zurb Foundation 3.0 &amp; based on code from Jason Weaver and Luke Wroblewski</p> |
5 |
</div>
|
6 |
</footer>
|
Also add in the following CSS to the 'Layout' section of your style.css stylesheet:
1 |
.site-footer {text-align: center; padding: 40px 0} |
2 |
.site-footer p {font-size: 1.2em;} |
Step 16: Hook Everything up with Off-Canvas
You've done really well to get this far. Take a break and give yourself a well deserved pat on the back. Just don't rest for too long... the exciting stuff is still to come.
Our next step is to hookup our markup into the off-canvas syntax to achieve the desired effects at small viewport sizes.
Let's just step back for a moment and review what we want to happen when the page is accessed on small viewports:
- The main navigation will become hidden, and when the 'Menu' button is pressed a navigation menu will slide into view from the top of the page.
- When the 'Contact Us' button is pressed, the main content will slide to the right, being 'pushed' out of the way by the contact form.
We'll add these functions to our HTML, style the elements as required and then return to take a peek under the hood and learn how the off-canvas layout do their magic.
Let's start by setting up the page for off-canvas.
Step 17: Add an Additional Class to the Body to Call Off-Canvas
As our very first baby step, add a class of "off-canvas" to the <body>
tag of your index.html:
1 |
<body id="page" class="off-canvas"> |
Next, we'll set up our slide-navigation for small viewports.
Step 18: Small Viewport Navigation Menu
To include a small viewport navigation menu, we'll need to replicate our main navigation.
Return towards the top of your index.html file and add in the following code between the <div class="bpdy">
tag and the <div class="first full-width color-three">
tag:
1 |
<!-- SMALL SCREEN NAVIGATION -->
|
2 |
<nav id="topMenu" role="navigation"> |
3 |
<ul id="nav" class="nav-bar"> |
4 |
<li><a href="" class="main">Home</a></li> |
5 |
<li><a href="" class="main">About</a></li> |
6 |
<li><a href="" class="main">Services</a></li> |
7 |
<li><a href="" class="main">Blog</a></li> |
8 |
<li><a href="" class="main">Contact</a></li> |
9 |
</ul>
|
10 |
</nav>
|
The most important thing to note here is the <nav>
element. You'll see that we've given it an id of "topMenu" which will trigger the menu when the menu button is pressed and we've also assigned a role="navigation"
to the element. It's the latter that the offcanvas.css stylesheet will pickup and apply the result.
It's important to note that we've essentially repeated ourselves here by duplicating our main navigation menu. Not only have we repeated code that goes against the principles of DRY (don't repeat yourself), it also means that if we want to change the navigation menu in any way (e.g. add extra items or include a drop-down menu), we'd need to also change the small viewport navigation menu too... not a great solution for a dynamic site.
A better solution would be to use the jQuery clone() element and append it to the small viewport menu, something along the lines of:
1 |
var $clonenav = $('#mainNav').clone(); |
2 |
|
3 |
$("#topMenu").append($clonenav); |
Check out the codepen to see this solution in action.
With all that said, to keep things simple, we'll acknowledge the problems with the duplicate menu solution and run with it for the sake of simplicity.
Next, let's add a little styling to our newly created small viewport navigation menu.
In the 'Media Queries' section of your style.css stylesheet, add in the following:
1 |
@media only screen and (max-width: 767px) { |
2 |
|
3 |
.nav-bar > li:hover { |
4 |
border-bottom: none; |
5 |
}
|
6 |
|
7 |
.nav-bar > li > a.main { |
8 |
border:none; |
9 |
}
|
10 |
|
11 |
.menu-button { |
12 |
/* Add a margin betwen the logo and the 'Menu' button */
|
13 |
margin-top:30px;} |
14 |
} /* end media query */ |
In this small piece of CSS, we've added instructions for the browser to remove the borders for the <li>
and a.main
elements on viewports 767px and smaller.
If you've followed along closely, you'll be able to see the small viewport navigation menu in action. Save your changes, hop over to your browser, refresh the page and resize the window to a small size. When the 'Menu' button is pressed, you should see our new navigation menu slide into view.
Step 19: Send the 'Contact Us' Section Off-Canvas
The next step is to alter our markup to let offcanvas.css and offcanvas.js know that we want to send the contact form section of the site off-canvas and slide it into view when only the 'Contact Us' button is pressed on small viewports.
To do this, we'll need to wrap our markup in two separate <section>
elements and assign roles to these elements.
Return to your index.html file and wrap the markup in section elements like so:
1 |
<section role="main"> <!-- Main Section For OffCanvas --> |
2 |
|
3 |
<!-- CALLOUT TEXT
|
4 |
...
|
5 |
...
|
6 |
-->
|
7 |
|
8 |
|
9 |
<!-- SERVICES
|
10 |
...
|
11 |
...
|
12 |
-->
|
13 |
|
14 |
|
15 |
<!-- FEATURED PROJECT
|
16 |
...
|
17 |
...
|
18 |
-->
|
19 |
|
20 |
</section> <!-- end of main section --> |
21 |
|
22 |
<section id="contact" role="complementary"> <!-- This tells the javascript to take this content out of the main page and into the sidebar on small screens --> |
23 |
|
24 |
<!-- CONTACT US
|
25 |
...
|
26 |
...
|
27 |
-->
|
28 |
|
29 |
</section> <!-- end off-canvas sidebar --> |
Just in case that isn't clear, you'll want to start the <section role="main">
directly under the <header>
and close it directly under the 'Featured Project' code. Next, you'll want to wrap all of the 'Contact Us' code in the <section id="contact" role="complementary">
element. The site footer continues as normal underneath the closing <section>
.
Next, we'll need to override some of the offcanvas.css base styles to ensure that our layout doesn't break with our new <section>
elements.
In your style.css stylesheet under 'Off Canvas', add in the following code:
1 |
|
2 |
[role="complementary"], [role="main"] { |
3 |
/* remove the default padding */
|
4 |
padding:0; |
5 |
}
|
6 |
|
7 |
@media all and (min-width: 768px) { |
8 |
|
9 |
.js [role="complementary"] { |
10 |
/* Sets both the complementary and main sections at 100% width instead of main content / sidebar layout */
|
11 |
width: 100%; |
12 |
}
|
13 |
.js [role="main"] { |
14 |
width: 100%; padding: 0 0; |
15 |
}
|
16 |
} /* end media query */ |
17 |
|
18 |
[role="main"]:before { |
19 |
content:""; |
20 |
/* Changes the bg color of the flyout panel */
|
21 |
background-color: #322820; |
22 |
}
|
The most important thing to note here is the setting of the .js [role="complementary"]
and .js [role="main"]
widths to 100%. In the default styling of the off-canvas layout, these elements are set to a main content / sidebar layout. Changing the widths to 100% ensures that the linear layout that we've created is maintained.
With those changes, we are now very close to completing our project. At this stage, you can resize your browser down to a small size, click the 'Menu' and 'Contact Us' buttons and see all of the off-canvas functionality in action.
All that remains at this stage is to tidy up some loose ends and style some of our elements for small viewports.
Step 20: Style the Page for Small Device Widths
As it is, the page is perfectly acceptable in terms of design, but a few elements of the site need a little polishing for small viewports.
In your style.css stylesheet, add the following CSS to the 'Media Queries' section, before the closing curly bracket of the media query that we've already created. I've included all of our media query in the following code block, but remember that we've already created the first three selectors in Step 15:
1 |
@media only screen and (max-width: 767px) { |
2 |
|
3 |
.nav-bar > li:hover { |
4 |
border-bottom: none;} |
5 |
|
6 |
.nav-bar > li > a.main { |
7 |
border:none;} |
8 |
|
9 |
.menu-button { |
10 |
/* Add a margin betwen the logo and the 'Menu' button */
|
11 |
margin-top:30px;} |
12 |
|
13 |
.first { |
14 |
padding-bottom:0 !important; |
15 |
border-bottom: none;} |
16 |
|
17 |
.full-width {padding-bottom: 10px;} |
18 |
|
19 |
.service { |
20 |
/* add a 1px bottom border between the service panels */
|
21 |
padding: 15px 15px 30px 15px; |
22 |
border-bottom: 1px solid rgba(0,0,0,.2);} |
23 |
|
24 |
.service:last-child { |
25 |
/* Removes the bottom border on the last service panel */
|
26 |
border:none;} |
27 |
|
28 |
/* ensures that the featured project div fills 100% of its parent */
|
29 |
.featured {width:100%;} |
30 |
|
31 |
/* Removes the centering of the featured image and resizes the image as the viewport is scaled down */
|
32 |
.featured img {width:100%; left:0; margin-left:0;} |
33 |
|
34 |
} /* end media query */ |
And with that, we've finished! Great work!
Step 21: Looking Under the Hood
I'm sure that by now you are looking forward to a coffee (or perhaps something stronger!) and a well deserved break.
I won't be going through each line of code with you, but I did want to take this opportunity to take a quick look behind the scenes at the off-canvas code to show you in simple terms how we've achieved what we've achieved today.
To start off with, as I'm sure that you've already picked up, the most important hooks in our code are the role
attributes given to each of the two <section>
elements in our markup. While the use of roles is not the only way to accomplish the off-canvas effect, they do add an extra layer of elegance and accessibility to the code.
Accessible Rich Internet Application (ARIA) roles are a small part of the Web Accessibility Initiative and allow website developers to add additional information to elements that can add extra context for visitors to the site that are using screen readers. While the list of available roles is extensive, we've used the two navigation roles of 'main' and 'complementary', which when you think of it is quite appropriate for our purposes today. While it's a slow read, you can read more about roles from the W3C.
In terms of functionality, the first thing that the off-canvas layout does is to position the small viewport navigation menu off of screen on large viewport sizes with the following javascript:
1 |
// jquery.offcanvas.js line 1-5 |
2 |
// Set the negative margin on the top menu for slide-menu pages |
3 |
var $selector = $('#topMenu'); |
4 |
if ($selector.length > 0) { |
5 |
$selector.css("margin-top", $selector.height() * -1); |
6 |
} |
And with the CSS, the default display type is set to display: none;
on wide viewports:
1 |
/* offcanvas.css line 46 */
|
2 |
@media all and (min-width: 768px) { .js menu-button, .js .sidebar-button { display: none; } |
Next, the jquery.offcanvas.js javascript applies a class of 'active' to the body element when either of the small viewport panels is selected:
1 |
//jquery.offcanvas.js lines 7-23 |
2 |
|
3 |
// Watch for clicks to show the sidebar |
4 |
$selector = $('#sidebarButton'); |
5 |
if ($selector.length > 0) { |
6 |
$('#sidebarButton').click(function(e){ |
7 |
e.preventDefault(); |
8 |
$('body').toggleClass('active'); |
9 |
}); |
10 |
} |
11 |
|
12 |
// Watch for clicks to show the menu for slide-menu pages |
13 |
$selector = $('#menuButton'); |
14 |
if ($selector.length > 0) { |
15 |
$('#menuButton').click(function(e){ |
16 |
e.preventDefault(); |
17 |
$('body').toggleClass('active-menu'); |
18 |
}); |
19 |
} |
When the 'active' class is applied to the body, the offcanvas.css stylesheet repositions the section with role=[main]
80% to the right and sets the role=[complementary]
section to a margin: 0;
:
1 |
/* offcanvas.css lines 40-42 */
|
2 |
.active [role="complementary"] { margin-left: 0; } |
3 |
|
4 |
.active [role="main"] { margin-right: -80%; } |
This is a pretty simplistic view of the workings of off-canvas, but serves to give you a high-level overview of how the layout works. I highly recommend digging into offcanvas.css and jquery.offcanvas.js to bring yourself up to speed with the intricacies of the code.
Conclusion and Review
If you've followed along to this point, congratulations! Today we've jumped straight into the the deep end with Foundation and off-canvas to produce a functional, practical home page layout that has real-world applications that is bound to impress your next client.
This is only one of the off-canvas configurations that we could have used today. In fact, in the offcanvas downloads are three additional layouts for you to play with. Just open up the .html files and insert your own code to experiment and customize your own off-canvas pages.
If you have any questions, please leave them in the comments and I'll try my best to answer them for you.
Did you enjoy working with Foundation? Would you like to see more tutorials in the future exploring this framework? If so, please let us know!
Changelog: 22 October 2012
Since the publication of this tutorial Foundation has altered in a few subtle ways. Other best practices in web design have also emerged, so I've updated the tutorial to reflect these changes.
- edited instructions within step 6 re: containers in foundation 3.0
- removed <div class="container"> tags, rules and references throughout the tutorial, index.html and style.css files
- changed the hidden h1 method from position: absolute; left:-9999px to font:0/0 a; etc.
- removed extra <div class="row"> x2 from step 11
- changed the footer to include links