You are on page 1of 180

W

E
N

9 HOURS OF FREE VIDEO

Improve your websites with


our expert advice

unlock the
potential
of web design
HTML5
 CSS3 RWD
JavaScript
 WordPress

Welcome to

The complexity of modern websites is a far cry from the early days of the Web.
Current trends for interactivity, animation and responsive design have expanded
the arsenal of skills needed to build exciting, cutting-edge sites. New frameworks
and JavaScript libraries are springing up everywhere, and it can be challenging at
times to keep pace with the industry. Thats where this book comes in. Throughout
each section youll find guides on how best to harness modern tools, add
excitement to pages, and enhance the efficiency of your workflow. For everything
from designing for mobile devices to building your first online shop, read on.

Imagine Publishing Ltd


Richmond House
33 Richmond Hill
Bournemouth
Dorset BH2 6EZ
 +44 (0) 1202 586200
Website: www.imagine-publishing.co.uk
Twitter: @Books_Imagine
Facebook: www.facebook.com/ImagineBookazines

Publishing Director
Aaron Asadi
Head of Design
Ross Andrews
Edited by
Dan Collins
Senior Art Editor
Greg Whitaker
Designer
Abbi Denney
Printed by
William Gibbons, 26 Planetary Road, Willenhall, West Midlands, WV13 3XT
Distributed in the UK, Eire & the Rest of the World by:
Marketforce, Blue Fin Building, 110 Southwark Street, London, SE1 0SU
Tel 0203 148 3300 www.marketforce.co.uk
Distributed in Australia by:
Network Services (a division of Bauer Media Group), Level 21 Civic Tower, 66-68 Goulburn Street,
Sydney, New South Wales 2000, Australia Tel +61 2 8667 5288
Disclaimer
The publisher cannot accept responsibility for any unsolicited material lost or damaged in the
post. All text and layout is the copyright of Imagine Publishing Ltd. Nothing in this bookazine may
be reproduced in whole or part without the written permission of the publisher. All copyrights are
recognised and used specifically for the purpose of criticism and review. Although the bookazine has
endeavoured to ensure all information is correct at time of print, prices and availability may change.
This bookazine is fully independent and not affiliated in any way with the companies mentioned herein.

Web Design Tips, Tricks & Fixes Volume 3 Revised Edition 2015 Imagine Publishing Ltd
ISBN 978-1910439784

Part of the

bookazine series

Contents

Is your content king?

Tricks

Tips

64

Animate CSS

16

New adventures in responsive design

72

Build an online shop

24

Design and develop in the browser

78

Scroll horizontally using jInvertScroll

30

Code the web with open-source


editor Brackets

82

Create a scroll-triggered animation

34

Build a responsive WordPress theme

86

Make an animated SVG header


with Snap.svg

38

Build a responsive slider using bxSlider

90

Create an animated infographic with SVG

42

Code a stunning mobile app with Ionic

94

46

Create animated buttons with CSS3

Streamline your workflow with Bower


and Grunt

50

Add angled page designs with CSS


and jQuery

97

Manipulate the DOM with AngularJS

102

Create a scaling hover effect

104

Produce a 3D direction-aware hover effect

108

Create a shake effect using CSS3


animation

54

Make a responsive menu for a


retina screen

58

Create data-driven interfaces


with KnockoutJS

82
Scrolltriggered
animation

34
Build a
responsive
theme

6 Web Design Tips, Tricks, & Fixes

110

Construct 3D customised cubes

112

Use overlay effects on background video

116

Build an HTML5 platform game

166

Automatically test your JavaScript


with Jasmine

170

Automate development processes


with Grunt.js

Fixes
122

Supercharge your CSS

128

The theory of text and type

134

Modernizr masterclass

138

Create sticky table headers using CSS


and jQuery

142

Speed up responsive sites


with Foundation

146

Build a custom Foundation template

150

Get faster, smarter code with RequireJS

154

Create responsive sites with intention.js

158

Make an eCommerce web element


with CSS3

162

Customise a map with the Google


Maps API

16
Responsive
design
GET IN TOUCH
facebook.com/ImagineBookazines
twitter.com/Books_Imagine

8
How to
tailor your
content

128
Learn about
text and
type

Web Design Tips, Tricks, & Fixes 7

Is your content king?

IS
YOUR
CONTENT
KING?
10 MOVES TO PERFECT
YOUR STRATEGY

8 Web Design Tips, Tricks, & Fixes

Is your content king?

CONTENT IS EVERYTHING
A

n empty house can be strong in its


foundations, and well maintained, but without
furniture, fittings and family it is still only an
empty house. Content makes it a home. Content is
everything as it is with a website. It is a fact of online
life that a well-produced website with poor content
will always fall behind a badly produced website with
excellent content. Browsers are online for a reason, and
that reason is content.
Good content engages the audience. While delivering
a message is paramount, it is just as important to
consider the way in which that message is delivered.
This can start with such basic considerations as
grammar and spelling. If your site is designed to present
you as an expert in your field, how much negative
impact on your prowess do you think the spelling

mistakes and missed punctuation will have? Illiteracy is


not a desirable skill and it doesnt pay to underestimate
your audience and assume they wont pick up on it.
Nor should your content outstay its welcome. In this
age of diminished attention spans, nothing sends a user
fleeing for the hills like a great wall of insurmountable
text, with nothing to break it up. The user experience
(UX) is essential to the success of your site. If you have
a point to make, dont waste time getting to it. This will
only serve to test your audiences patience.
The web is constantly changing, and with it the way
in which content should be prepared. This is the age
of social media and sharing, and content which can
be easily shared between users will always have the
biggest impact. It is time to view content as something
that can live beyond the confines of your site.

CREATE A PLAN
When it comes to the creation of websites, there are
endless tutorials that can be found online dedicated
to designing and building the perfect site structure.
Web design and web development practices are being
constantly perfected, updated and refined. However,
there is one area of web creation that too often remains illconsidered and badly planned the content itself. Content
is the driving force behind any website. It doesnt matter
how well-built and functional your site structure is, if
the content it houses is sub-standard and fails to do
the job for which it is intended, then youve wasted
your time.
Creation and analysis of web content should be as
important a primary stage of the development of a
website as determining the technology in which the site
will be built, but quite often the content is treated as a
secondary concern. When you think about it, this really
makes no sense at all. The content is the reason that the
site exists in the first place. People have come to your site
for a reason, and its not to click those perfectly scripted
button animations or simply sit and watch the expertly
executed page transitions you spent time on.
Your site only exists to deliver your content, so you
have to question whether your content is the best it can
be. For example, have you actually considered who your
target audience is? This may well be one of the most
overlooked and yet essential factors of content strategy.
How can you design a site that will appeal to a group of

Find out why you should care about content and its
place in the users experience of your site

QContent plays a big role in how a user experiences

your site and whether they decide to come back

Planning your content strategy is essential but it is


worth considering certain factors before diving in

people if you dont know which people you are trying to


attract? While you may be hoping to appeal to everyone,
this will only make for an ineffective content strategy. Even
if you are going for a more broad appeal, there are still
ways of narrowing it down to a more manageable group
consider age range, for example.
Having identified the audience, you need to work
out what would be the best way to communicate your
message to them. Different audiences respond to different
voices, ideas and media and this can have a huge
impact on the way your site eventually looks.
Following on from how you address your site visitors,
the next step is determining exactly what the core
message is that you are trying to get across to them.
When the audience leaves your site, what should they
take away from the experience? With a strong message,
you can make a real impact on people.
Finally, you need to ensure that every item of content
on your website has a defined purpose, otherwise there is
no point in having it there. Every piece of content on your
site should serve to reinforce your message and resonate
with the target audience for maximum effect.
These are the main principles of content strategy,
a series of best practices for creation, publishing and
maintenance of web content. In this overview, well go
over these basics in a little more detail and demonstrate
how you can prepare your content. Not just for your site,
but for the benefit of your sites audience.

Your site exists only to deliver your


content, so you have to question whether
your content is the best it can be

WHAT QUESTIONS
SHOULD YOUR
STRATEGY ADDRESS?
A basic content
strategy plan
s%FUFSNJOFZPVSBVEJFODF
This is the most important starting
point. Who is the content for? Who are
you trying to attract to your site, service
or product?
s'JOEZPVSUIFNFBOENFTTBHF
What is the message that you want
to communicate to site visitors? What
do you want to tell or show to the
audience you have identified?
s%FWFMPQUIFBQQSPQSJBUFWPJDF
What tone of voice will best deliver the
message and resonate with the chosen
audience, to bridge the gap between
need and solution?
s#FVTFGVM
Does your content serve the purpose
for which it is intended? Is it actually
useful to those for whom you have
identified a need?

s.BJOUBJODPOTJTUFODZ
Is your content consistent in tone of
voice throughout the site? Does your
site communicate with one voice?

Web Design Tips, Tricks, & Fixes 9

Is your content king?

WHO IS THIS CONTENT FOR, ANYWAY?


Before you do anything else, it is vital that you understand who you are trying to reach
Understanding your audience is so vital, and so obvious
a need for any business, that it may seem strange to
even mention it. And yet, it is often skipped over by
those who would rather assume that the site is there
for the good of everybody who visits. While this may be
a pleasing ideal, almost every business has a majority
demographic they should be targeting.
The approach to identifying your key demographic
depends a great deal on your business and available
assets. If you already have a website and wish to
improve on the content, then using Google Analytics
and Webmaster Tools to track and measure your sites
visitors is an excellent way to build a profile. This can tell
you where your site hits are coming from, and which
parts of your site are proving the most popular.

However, those who are starting out on their first


website will probably need a different approach.
Customer surveys can be extremely useful for finding
out data, if possible, either on the business premises or
by an email campaign. Creating a social media presence
for your business, such as on Facebook and Twitter, can
give you access to your customer base, although this
can take some time to build up. Larger businesses can
go a step further and organise focus groups or engage
the services of canvassing companies.
The main aim is to build a profile of the target
customer. Create a character with likes and dislikes,
habits and traits, budgetary constraints and needs. The
more detail you are able to fill in, the easier it is to tailor
your content to fit them perfectly.

QFocus groups can help you find your target audience

CONTENT WITH A PURPOSE


Your content is not an aimless idea, waiting to be noticed it exists for a reason
Now that you have a good idea who your target
audience is, you can start to think about how you
are going to communicate with them and what it is
you want to communicate. Usually, there is a service
or product that is being promoted by the site. Your
message must exist in the gap between your service
and the customers need. That is the bridge your
content needs to build, and finding the correct tone of
voice is key to building it.
Tone of voice is determined by the target customer
profile. The key point to nail is that you communicate
in a way that they understand. For example, does he/
she respond better to an informal, conversational
approach? Or would a reserved, professorial persona
be more appealing? Is there a target age group in your
demographic? If so, does that have some bearing
on your tone of voice? If youre targeting a younger
audience, can you make your content more bite-size
without dumbing down? It is absolutely vital that you
get this right, so you dont alienate your site visitors.
Once you have this tone of voice, it is important that
you stick to it. Make sure that it is employed throughout
the site even down to the 404 Not Found page. This
means that, if you have more than one or two people
working on your content, there should be a style guide
of some sort. Perhaps even a tone of voice persona,
that matches well with the target audience.
Think about the different types of content you can
make available. Would your target audience be more
inclined to watch videos than read text? If you have
a lot of text, is it easily readable? Would interactive
elements, such as a forum or review facility, be a major

10 Web Design Tips, Tricks, & Fixes

advantage to your demographic or be deemed a


tedious distraction? Add share buttons for social media
and encourage users to pass your content on by all
means, but avoid cluttering the page.
Above all, ensure that your content is useful. Better
still, instructive. Every word, every image, every video,
must be able to justify itself and contribute to the overall
message. Theres absolutely no room for repetitive
content, or useless content that is included by the
business director for sentimental reasons.

QThe Innocent smoothie brand has perfected its

tone of voice, using an informal tone combined with


bright colours to strengthen the core message

Once you have a tone of voice, make sure


that it is employed throughout the site

EXPERT INSIGHT FROM THE INDUSTRY

RIK BARWICK
Creativitea.co.uk

The first engagement with a brand is through content,


whether an ad, video or website. Taking the time to
plan a good content strategy is imperative
to brand success. When preparing your UX you
must remember the target market and deliver
excellent content.
Content strategy can be the difference between
lighter or heavier pages, depending on your
audiences location and wealth. Fast and focused sites
may not be as enticing on their own, but can make a
huge difference to your bounce rates and returning
visitors stats.
A pet-hate of mine is keyword-stuffed content,
written for bots. Yes, content needs to be optimised for
search engines, but it needs to engage humans too!

Is your content king?

THE DIFFERENT APPROACHES


TO CONTENT STRATEGY

Content strategies can be as varied as the websites


and audiences that they are intended for

There is no such thing as a one-size-fits-all content


strategy. Certain rules and procedures can be applied
throughout, but a good content strategy must be
tailored precisely to what the website it is focused on,
be it a new site in production or an old site that is simply
looking to refresh itself. Just as the Natural History
Museum will prepare and display dinosaur bones and
ancient mummies in completely different environments,

so too should your marketing strategy meet the needs


of the content and audience it is dealing with.
An eCommerce site selling bikes will target a vastly
different audience to that of a showroom site for a
prestigious auction house. Even if both sites are built
using the same template or content management
system, the end user, and therefore the digital marketing
strategy, must be marked in its differences. This is

why understanding your audience is so vital. The


outdoor-loving biker will respond to approaches and
digital outlets that would not work with the avid antique
collector and each will seek different ideals from the
sites they frequent. The content strategist, then, must
understand what makes each site singular and tailor the
method from there. Below we look at two examples of
different content strategy approaches.

CASE STUDIES: THE GUARDIAN AND ADOBE


These organisations both took different, but equally effective, approaches to their content strategies tobring success

www.theguardian.com

adobe.ly/19x04z8

WHO The Guardian


WHAT Expanding news content
and amalgamating several of
their sites into one
WHY To respond to the growing
international user base

WHO Adobe
WHAT Devising a content
strategy using Marketing Cloud
WHY To promote and
demonstrate the effectiveness
of the new software

News sites can be tricky.


Naturally, they have the fastest
turnover of content on the
web, and reporting factual
QThe Guardian is the ideal example of a
events leaves you with the same
successful news site
content as your competitors.
There is also the problem of generating revenue from sites which, for many,
replace the need to purchase a newspaper. Many news sites have adopted a
paywall approach, charging consumers for premium content, while others
rely on advertising revenue to keep content free, such as The Guardian.
The Guardian website is a great example of well-presented and wellorganised news content. The initial landing page is tidy and user-friendly,
handling the varied content with ease. The Guardian recently underwent a
major shift in its content strategy analysis of web traffic revealed it had a
growing international user base. As a result, The Guardian took a number
of steps to meet this opportunity, including a change of domain from .co.
uk to .com; the expansion of news content on both the site and app to allow
country-specific filtering; and the amalgamation of several sites into one.
Since these changes, The Guardian website has continued to grow into a
successful entity all on its own, catering to its own specific audience, rather
than simply existing as a digital version of the print newspaper.

Media giant Adobe took a


singular route to develop a
content strategy for their new
marketing tool, Adobe Marketing
QAdobe created the perfect marketing
Cloud. In essence, they spent a
circle for their new product
year using the product to devise
a content strategy for itself. It seems obvious in retrospect, yet still has a
ring of genius about it. Adobe also decided to promote the research and
development process of the strategy as a public debate on the effectiveness
of digital marketing. This proved to be an inspired move, resulting in good
exposure for the new product on social media channels and print media.
Adobe then ran a series of video campaigns which resulted in the highest
return as did a live debate, viewable through a Facebook app. However,
the apps return dwindled significantly once it was limited only to replays
of the debates, but a followup targeted Twitter campaign boosted the apps
performance yet again. Adobe also discovered that organic traffic to the
website had higher rates of engagement with the audience than paid traffic
from ads and as a result decided to discontinue the paid traffic approach.
In the end, the whole exercise not only provided Adobe with all the
metrics they needed to target their content, but it did the job of successfully
promoting their Marketing Cloud product. A definite win-win approach.

DIFFERENT DIRECTIONS, SAME OUTCOME


The Guardian understood that knowing the
audience is vital. Once they had become aware of
the huge international interest in their site, they
reacted immediately. Change can be a good thing;
move with the times and keep up with the needs

of your audience. Simply changing the portal may


seem passive, but it worked for the consumer.
Adobes decision to make the creation of
their content strategy a marketing tool of itself
maximised all the elements at their disposal. Direct

engagement with their audience created more


buzz, and led to more converted traffic, than simply
buying ad space. By making the consumer part of
the process, you can utilise the singular nature of the
web, tailoring engagement directly to the user.

Web Design Tips, Tricks, & Fixes 11

Is your content king?

3 STEPS TO A KILLER HEADLINE

Follow these tips to really make sure


your headline is selling your content

GET THE LENGTH RIGHT

UNLEASH ITS FULL POWER

INCLUDE A SUB-HEADLINE

Make your headline engaging for the


audience and youll reap the rewards

Your headline isnt just a title, but an


introduction to you and your site

Your headline need not stand alone add a


little detail to entice your site visitors

There is some difference of opinion on the length of


the perfect headline. A short headline can be catchy
and to the point, but make it too short and youre
probably not revealing the right amount of information
to draw your readers in. A longer headline will give
enough information, and include some useful keywords
for SEO purposes, but make it too long and you not
only risk falling victim to that limited attention span
of web surfers nowadays, but revealing so much that
you render the content beneath it pointless. The best
approach is to keep it as short as possible, but do not
neglect the following points in doing so.

Too often the headline is put together as an


afterthought to the content, but in many ways it is the
most important part of all. If it doesnt entice, the content
will never be seen. Use your headline to its full potential.
Dont undersell your content. Describe what it is to
come. It may even help to make it seem like the reader
will be losing out if they dont read on. For example, if
your content is all about your range of kitchen utensils,
then try How our range of kitchen utensils can save you
time. Now readers know that there is an advantage to
reading on. Dont be afraid of using a little hyperbole
this can help grab the audiences attention.

A useful practice is to give your headline a sub-headline,


an H2 tag to your headlines H1. This can be used to offer
a little more information or enticement without having
to extend the length of the main headline. It can take
the form of a short sentence or even a brief, bulleted,
rundown of major points from the content. For example,
you can follow How our range of kitchen utensils
can save you time with And they last a lifetime. Or
perhaps something simple and appealing like: quicker
to clean or fully guaranteed. Youve now provided more
enticements for the reader to stick with your content
rather than click off somewhere else.

SEO AND GOOD CONTENT ARE


MORE LINKED THAN EVER

Refreshing your content and updating regularly could


see you ranked much higher in Googles search results

SEO has moved on quite considerably over the last


few years. Googles quick-fire updates, with their
endearing animal names, have left many once-solid SEO
techniques either dead in the water or at the very least
far less buoyant than they used to be. Blog comments,
paid links, directory listings and link exchanges have all
been rendered useless by Googles algorithm updates.
While keywords and link-building still retain their
importance, it
is content that
appears to be
Googles primary
focus now. For
this reason, it
is absolutely
imperative that your content is primed and prepared to
appear relevant and informative in Googles eyes.
These days the search engines are emphasising
quality over quantity. They are looking for wellproduced, useful content that adheres to the topics it
claims to be catering for. This is why relevance is vital.
Good spelling and grammar are also more important
than ever as is the variety of content types, such as
images, video and infographics.
Google also favours content that is updated or added
to on a regular basis, which is why so many business
sites have now started to incorporate blogs into their
web presence. This can be an especially helpful tool

for those that struggle to update the core content of


their website. Maintenance of a blog allows for regularly
published content. Providing fresh content, combined
with smart integration of keywords and social media
networking, is one of the best SEO methods currently
available to us. A Facebook, Twitter and Google+
extension of a brand is also invaluable.
But it is natural optimisation that seems to be the
SEO route for
the future.
This new
direction by
Google may
have made life
more difficult
for SEO agencies in the short term, but it does make
it much easier for site owners to include good SEO
techniques in their own websites, without the need
for external services. Plus, raising the quality of all web
content ensures that the end user gets what they are
looking for (as opposed to irrelevant content stuffed full
of keywords) and a good experience, while your content
is protected from future algorithm updates.
Well-written, relevant content that can be easily
shared across social networks can get your site higher
up the search rankings and seen by more prospective
clients. It is well worth refreshing and regularly updating
your site in order to finish higher up the search results.

Providing fresh content is


one of the best SEO methods
currently available to us

12 Web Design Tips, Tricks, & Fixes

HARNESS THE POWER


OF SOCIAL SEO
Unlock the potential that social
networks can offer you
SEO is no longer about cramming several
keywords into your sites content and hoping
to be found. Now, its about SMO Social Media
Optimisation. By making use of social networks
such as Facebook and Twitter, you open up
other channels that allow people surfing the
web to find you. In doing so, youre enabling
them to interact directly with you as well as
increasing the breadth of your presence online.

Is your content king?

CASE STUDY:
VIRGIN.COM
How Virgin streamlined their main site to
better appeal to their customers
WHO Virgin.com
WHAT A major relaunch and content strategy for
Virgins main website
WHY To expand on the purpose of the parent site
and unite all Virgin businesses
Media, travel and banking giant Virgin brought in
digital agency Beyond to overhaul their website
and online brand strategy. Virgin.com had
functioned as a portal site to the various branches.
The goal was to boost the already successful
business model by giving the parent site a content
purpose, incorporating Virgins companies and
values into one strategy and theme, aligning that
strategy with current social trends, and increasing
the amount of time users spend on the page.
Working with Virgins digital manager Bob
Fear, Beyond analysed metrics and analytics from
Google, Hootsuite and social media channels to
ascertain the digital marketing approaches yielding
the best responses. They researched Virgins
core audience, deciding which customers had the

QVirgin is keen to cater to its core audience by updating its main website

potential for increased growth, the importance of


Richard Bransons presence in brand marketing,
and what people love about the brand. Beyond
analysed social media conversations about Virgin
to determine what matters to users, and where
these conversations were happening.
The content strategy Beyond and Fear
formulated highlighted a number of tactics. Focus

USEFUL RESOURCES

on social media platforms, popular with Virgins


core customer, scored high. Increasing content
focus on travel and reducing it on fitness was
important, since fitness discussions were too
brief. Key topics should also target music,
entrepreneurship and sustainability. This
research allowed Virgin to fine-tune their
activity to better suit their audience.

From content curation to scheduling your social media updates, this


broad range of services will have you covered on all bases

SEO GADGETS CONTENT


IDEAS GENERATOR
seogadget.com/tools/
content-strategy-generator
Stuck for new content to put out there?
SEO Gadget has produced a simple but
remarkably effective tool for finding
inspiration in your search for content ideas. Just open the generator as a Google doc,
place your keyword of choice into the B3 field, hit return, and it will provide you with
a list of up-to-date articles and posts on that topic from various sources around the
web. Use these as a guide to what is currently trending, and you will have a valuable
starting point for keeping your own content up-to-the-minute relevant. To use this
service you will require a Google account.

GOOGLE TRENDS
www.google.co.uk/trends
Google provides a mighty armada of tools and
resources that can help you tailor your content.
Webmaster Tools and Analytics give you
everything you could possibly need to monitor
your sites traffic, while Trends gives you up-todate information on the popularity of particular
keywords and search terms, allowing you to fine-tune the keywords that you end up
using in your content. You can also make use of Hot Searches to see which topics are
currently trending and make sure you ride that wave with some focused content and
social media links. Measure your service or product against a competitors and alter
your marketing approach accordingly.

LISTLY

HOOTSUITE

list.ly

hootsuite.com

Content curation appears to have become


the term of the moment in content strategy.
Curation is the process of sharing meaningful
third-party content with your brand followers
on an ongoing basis, which in turn increases
your presence as a brand expert. There is a
range of tools emerging for improving your content curation, and among the best is
Listly. Everyone loves compiling lists, and Listly allows you to build a variety of topicdriven lists, as well as sharing posts and articles on the lists of other users. There is also
a handy export function to Excel.

Hootsuite was voted the best social media


management tool of 2013 by industry experts,
and its not difficult to see why. The vast array
of features gives you full control of your social
media presence in one place. Post across
several social media accounts simultaneously,
or at scheduled intervals. Monitor those social media sites for current trends and make
use of Hootsuites own analytics options. There is also The HootLet, a Google Chrome
plug-in that allows you to share content from any page on the web (as well as a few
other monitoring features) through your Hootsuite account.

Web Design Tips, Tricks, & Fixes 13

Tips

Get to grips with


tools, techniques
and frameworks

16

New adventures in responsive design

24

Design and develop in the browser

30

Code the web with open-source


editor Brackets

34

Build a responsive WordPress theme

38

Build a responsive slider using bxSlider

42

Code a stunning mobile app with Ionic

Discover the processes that go into building a


successful responsive project

Prototype, test and optimise your site using browser


development tools

Increase your design efficiency with these tips

Zurbs Foundation is ideal for your latest


WordPress project

Join the growing trend for responsive sliders by


harnessing the bxSlider jQuery plug-in

Build feature-rich HTML or mobile apps using the


Ionic framework

14 Web Design Tips, Tricks, & Fixes

46

Create animated buttons in CSS3

50

Add angled page designs with CSS


and jQuery

54

Make a responsive menu for a


retina screen

58

Create data-driven interfaces


with KnockoutJS

Create some cool-looking 3D buttons that will add


that extra polish to your site

Use angled backgrounds and add images

Work with custom fonts to build a responsive menu

Make a modular app with real-time UI updates

Rather than designing


pages, were now designing
complete systems

24

30

Design sites
in your
browser

Learn to
code with
Brackets

38

50

Build a
responsive
slider

Add angled
page
designs

16
Discover key
RWD tips
and tools

Web Design Tips, Tricks, & Fixes 15

Discover the process behind a successful responsive


project, from creative conception and design, through
to building and testing
16 Web Design Tips, Tricks, & Fixes

New adventures in responsive design

THE BIG IDEA!


O

ver the past 12 months we have


seen one the fastest and most
significant developments in the web
design industry. The influx of highly
capable mobile devices with powerful
processors, modern browsers and
excellent displays, has opened the floodgates for
much greater creativity in responsive web design.
Where we were previously only concerned with screen
widths, now we also find ourselves considering user
interactions, device connection speeds and even the
users location.
Clients expectations have also increased, which
means that careful consideration as well as effective
communication is paramount in absolutely every aspect
of a responsive design project.
Before diving in, as with any project, a solid
understanding of the brief is vital. Make sure there are
no areas left open to interpretation between you and
your client. It helps to ask the client for anything, both

visually and functionally, that has inspired them when


creating the brief. From this you will have a good grasp
of the clients expectations for the end product.
Next, align these expectations with those of the end
users, this can be achieved by asking users what they
would expect from the product and make sure that
these expectations are prioritised.
Agree the devices and browsers to be supported.
If you can access analytics data from an existing site,
use this to help in deciding the testing approach. As a
minimum you will need to be testing with an iPad and
iPhone as well as an Android phone and tablet.
Now that you have a sound idea of the scale and
scope of the whole project, take a step back and
consider any future developments. These could be low
priority requirements or even just ideas that you have
had through the process so far.
Working your way through all of this should give you
a clear idea of what you are aiming to achieve and give
you a much greater chance of doing so.

EXPERT INSIGHT
Nearly every brief I see asks
for support for mobile and, with
the proliferation of devices over
recent years, this cannot be ignored.
Responsive design takes focus away
from which handset or what system,
allowing teams to focus on crafting
great experiences and how they can be
enhanced by available technology.
Damian Proctor
Executive creative director
Q Redweb

START PLANNING
The standard next step in any
website project would be to map out
the IA, but with a responsive build it
helps to take this a little further. Once
the site structure is mapped out
and key content elements defined,
these content elements need to be
prioritised. This will be really beneficial
when you get to the build, as it helps define the markup structure and content flow for small screens.
You can now start sketching out the page layouts;
start with the global elements like the header, footer
and site navigation and cover small, medium and

With good
planning and
RS \WbW]\Wbya
[cQVSOaWS`
b]Q`SObS
a][SbVW\U
W[^`SaaWdS

large screens. Then you can move onto the main


content layouts for each page, again covering a
range of screen width the order of the content
elements on small screens can be taken from their
priority in the architecture.
This is a really good stage to get the client
involved, running through your sketches or
wireframes and iterating on them with the client.
This helps the client to get involved and gain a sense
of ownership of the solution.
Next, identify all functional components
throughout, these may be simple interactive
elements like tabs and carousels or much more

complex functionality like data handling, filtering


and rendering. As these elements will be relying on
JavaScript, the flexibility required across all screen
sizes may not be achievable through CSS alone. This
means additional time and consideration may be
required to ensure a rich user experience of these
components across all devices.

TOOLS YOU CAN TRUST


xMind

Balsamiq

Chalkmark

www.xmind.net
A great application for mapping out site and
content structure using a drag-and-drop
interface, allowing quick and easy iteration.

balsamiq.com
A rapid wireframing tool with a wide range of predefined
common components to choose from. This makes it easy
to lay out ideas as if you are sketching on paper.

www.optimalworkshop.com/chalkmark.htm
An online tool thats great for sharing your
wireframes and setting up quick click testing
and feedback for users.

Web Design Tips, Tricks, & Fixes 17

BUILD CONSIDERATIONS

Before designing the final site and


getting into the code build, there
are a few areas to make sure you
have a clear idea on. If you are
planning on using a responsive
grid, either from a framework or
your own, the design will have to
fit within this. You need to know
what devices the end users will
be using to help define your build
and testing strategy. You also
need to have confidence that site you build will
perform as the client and users expect.

From using
the right
responsive
framework
to ensuring
ST QWS\b^OUS
load times
eWbVQ]\QWaS
8OdOAQ`W^b
Q]RS

Page performance
In terms of performance, todays browsers are a far
cry from the days of IE8 and below. Its important to
remember that, although a browser can run JavaScript
and render complex designs efficiently, not all devices
will have the best connection speeds. It is paramount
that the page load times are kept as low as possible,
there are a few simple things to consider that ensure
your site build performs for all screens.
Using CSS3 shapes instead of images
It is standard practice to use image sprites to save on
the number of images loaded within a page. For simple
icons and shapes you can replace these images with
CSS3 shapes. A great resource to check out is css-tricks.

18 Web Design Tips, Tricks, & Fixes

com/examples/ShapesOfCSS, by combining these


techniques with :before and :after selectors you can
really speed up your icon rendering.
Compiling your CSS and JavaScript files
Make sure that on the live server your CSS and
JavaScript files are minified and compiled to as few
http requests as possible. There are many resources
available for this and many CMS platforms make this
available out of the box.
Be careful when making reference to DOM
elements in JavaScript
When manipulating DOM elements with JavaScript,
especially if using jQuery, be sure to reference DOM
elements as few times as possible store them as
variables and use them throughout your script. Also,
consider how you target these elements, try to use IDs
whenever possible. When targeting by an ID, JavaScript
will stop looking for the element once it has been found,
whereas if youre using a class, every DOM element will
be checked and all matched items returned.

Adapting functional
components
Run through your list of functional components,
created during the planning phase, and ascertain what
is possible for each screen size and/or device to be
supported. Try not to restrict functionality for all users

just to cater for a small proportion. Have a good idea, not


only of what different solutions will be built, but how you
will transition between them technically.

Should You Use a


Responsive Framework?
There are a wealth of frameworks available to kick start
a responsive build. They not only save time but also
provide solutions to problems often encountered. This
is much more than simply adjusting and reflowing page
layouts, but can also include responsive navigation and
interactive components. All these things have been well
tested across devices which reduces the risk of timeconsuming bug fixing later in the project.
Although using a framework may seem like the way
to go, there are some instances when they may not
be suitable. If the page layouts are simple or there are
only a small range of layouts, you may be able to build
these with much less CSS code using flexible widths
and CSS media queries. Also if the site is at the other
end of the scale and has a high level of complexity, such
frameworks can be difficult to extend and adapt
to provide the desired solution.
So it is important to align any framework with the
defined layouts and functionality, as well as the scale
of the project. If you are working within a development
team, it also makes sense to canvas opinion across the
team, as everyone will have to understand and be able
to work with any chosen framework.

New adventures in responsive design

WHICH FRAMEWORK TO USE?

BOOTSTRAP

FOUNDATION

SKELETON

getbootstrap.com
Probably the most popular and longest-standing
framework available, with extensive input from
the open source community.

foundation.zurb.com
A powerful and well-structured framework with
some very impressive plug-ins.

www.getskeleton.com
An easy and lightweight grid framework with
simple styles to get working quickly.

PROS This framework is set up to allow easy

Very lightweight its in the name! as


this is not bloated with any component types or
functionality you just wont use.

PROS Really easy to set up and get started with

PROS

a range of themes and functional extensions.

extension and adaptation with your own bespoke


code, providing good flexibility for your project.

PROS There are lots of good examples

PROS The documentation for this is

and demonstrations as well as a large, active


development community.

excellent, full of code examples covering most


requirements you will need.

CONS

A steeper learning curve than Bootstrap


and does require more customisation to
implement functional elements.

CONS

Skeleton doesnt include any functional


plug-ins, so anything outside of the CSS
framework will need to be created bespoke.

CONS

There isnt a prevalent development


community to ask for support, or very much in
the way of available documentation.

Can be difficult to extend and adapt to


suit more complex interfaces and functionality.

PROS

Its simple structure makes it easy to


extend for any project and really make the
framework your own.

CONS

CONS

The full code is large so will affect page


performance, although you can choose which
components you need when downloading the
resources, which helps eradicate this issue.

Not as large a development community


as Bootstrap but it is growing.

CONS

MOBILE OR DESKTOP FIRST?


It is difficult to say that either mobile- or desktop-first
approaches are the right way to go. Although the
trends in mobile usage do suggest that users on
mobile devices will far surpass those on desktop
machines, if the key differentiator is screen size then
we would have to take into account higher resolution
devices as if they were desktop. Either approach has
its benefits and restrictions.

;]PWZS `ab
When taking this approach you can be sure that you
will not be building complex page layouts that are
difficult to adapt when the screen width is reduced. It
also will ensure that the mark-up structure you write
will follow the content prioritisation defined as part of
the IA. As you will be primarily focused on touchscreen
devices you will inevitably cater for touchscreen events
from the outset, creating a more efficient and tailored
solution for these devices. You may find, however, that
when viewed on desktop or larger screens, the layouts
seem very simple and not that creative or interesting.

You may also have discounted certain functionality that


wasnt feasible or was particularly difficult on smaller
screens, therefore impacting on the experience for
users with larger screens.

2SaYb]^4W`ab
When catering for larger screens first you will not
be restricted in terms of creative page layouts and
functionality. You can be confident that those users
with larger screens will have the best experience of
your site as possible. It is easy, however, to not cater
for touch interactions and have to code these in later,
which is more difficult. It is also common to cause
yourself problems when reducing the screen size
as the mark-up may not be ordered by the correct
prioritisation, which means a certain amount of DOM
manipulation is required to cater for these particular
sizes. Some of the functional components will not
work on smaller screens and, if you havent accounted
for these in your planning, this can severely increase
the time the site takes to build.

BVS@WUVb
/^^`]OQV

be aware of the
dO`W]caPS\S ba
and pitfalls in
taking either
approach and
decide which
works best for
your project

The best way to approach


any build is not restrict
yourself to one or the other. As you can see,
both have their merits and really, they can be
used in conjunction to produce great results.
You must order your mark-up by prioritisation to
reduce the amount of DOM manipulation needed to
cater for all screen sizes. You should have identified
those functional components that may require
alternative implementations for different screen sizes,
that way you will not be delivering a lesser experience
for one or the other. The capabilities of devices
are used whenever possible, for example touch
interactions and gestures or geolocation look-ups.
The final thing to remember is the end user, if they are
predominantly using an iPad to use the site you must
consider medium screen sizes as the benchmark
from the clients perspective.

Web Design Tips, Tricks, & Fixes 19

THE ANATOMY OF RWD

Key elements that make up an


W\bcWbWdSO\RST QWS\b`Sa^]\aWdSaWbS

Fullsize screens
offer the option to
add all the relevant
navigation elements
including search.
Think how to include
on the small screen

All interactions
are bound using
touch events to
reduce perceived
lag and provide a
smooth interface

Images are
loaded when
needed to
ensure page
load speeds
are maintained.
The amount of
images in each
section of this
gallery layout
is adjusted for
mobile devices

0]bVbVS ZbS`
and navigation
elements are
toggled from
view on smaller
devices, allowing
more room for
the core site
content but still
providing clear
site controls to
the user

MAKING YOUR SITE LOOK GOOD


When designing a
responsive site you
cannot rely on using
a desktop screen. The
use of devices in the
project should start
now; view static JPEGs
of your designs on devices as you create
them and run through them with clients in
this way. By doing this you will find that it is much
easier to get the proportions correct across the
devices. When changing the layout for mobile
screens it is not just a case of reflowing all of the
content, you may want to make buttons and links
larger so that they are easier to interact with, or
adjust font sizes in order to cater for the fact that
the user is holding the screen closer to them.
You cant cater for these aspects of design when
looking at the layouts on a desktop screen.
We are all used to designing for desktop but
most of the problems occur when considering the
smaller screens. It helps to take inspiration from the
interfaces we all use on devices every day, and the
Android and iOS interfaces have been developed
over the years and give us a good indication of the
behaviours of users. One of the biggest challenges
is site navigation fortunately, there are three clear
solutions to this design challenge.

Collapsible menus

With responsive
sites the design
process can be
daunting, but it
doesnt have to be

20 Web Design Tips, Tricks, & Fixes

For smaller screens, collapse the list of links


into an open and close menu, this more
often than not uses the three bar icon to
indicate the functionality to the user (taken
from iOS and Android interfaces).

Slide-out menus
This particular approach has been made
popular by the Facebook application on
many devices. The menu is displayed off
the screen and with a swipe or button tap,
it slides into view. This is really useful for
nested links, as tapping a menu item can
slide a list of child pages into view.

Anchor linking

There are various tricks that can be


used to save space and look good
while maintaining functionality

By rendering a second navigation block


at the base of the page layout, you can
set this only to display on smaller screens
simply in CSS. Then, an anchor link can
replace the navigation at the top of the
page, taking the user to the menu at the
bottom. This solution requires very little
JavaScript and therefore performs very
well across devices. You can make the
experience much smoother by animating
the scroll to the menu.

New adventures in responsive design

SETTING UP A FRAMEWORK

TOUCH

How to get the bootstrap framework up and running in simple steps


once set up, you can take advantage of the great tools on offer

CONSIDERATIONS

01

Get the resources

Download the compiled and minified files


from getbootstrap.com/getting-started
and add these to your project solution. Alternatively, you
can access these files from a CDN as shown. Include
the default theme provided, you can edit/replace or
overrule this CSS file when implementing your design.

001 <!-- Latest compiled and minified


CSS -->
002 <link rel=stylesheet href=http:
//netdna.bootstrapcdn.com/bootstrap/
3.1.1/css/bootstrap.min.css>
003 <!-- Base Bootstrap theme -->
004 <link rel=stylesheet href=http:
//netdna.bootstrapcdn.com/bootstrap/
3.1.1/css/bootstrap-theme.min.css>
005 <!-- Latest compiled and minified
JavaScript -->
006 <script src=http://netdna.
bootstrapcdn.com/bootstrap/3.1.1/js/
bootstrap.min.js></script>
007

02

Set up your base


HTML structure

Reference the resource files in your base


HTML structure and add your own stylesheet to start
to implement your styles. If you are planning on using
any of Bootstraps functional plug-ins make sure you
remember to include jQuery as well.

001 <!DOCTYPE html><html lang=en>


002 <head>
003
<meta charset=utf-8>
004
<meta name=viewport content=
width=device-width, initial-scale=1>
005
<title>Getting Bootstrap up and
running</title>
006
<!-- jQuery is needed for
Bootstrap JavaScript plugins -->
007
<script src=http://ajax.
googleapis.com/ajax/libs/jquery/1.11.0/
jquery.min.js></script>
008
<!-- Latest compiled and
minified CSS -->
009
<link rel=stylesheet
href=http://netdna.bootstrapcdn.com/
bootstrap/3.1.1/css/bootstrap.min.css>
010
<!-- Base Bootstrap theme -->
011
<link rel=stylesheet
href=http://netdna.bootstrapcdn.com/
bootstrap/3.1.1/css/bootstrap-theme.
min.css>
012
<!-- Add you CSS file after the

Bootstrap CSS -->


013
<link href=css/styles.css
rel=stylesheet>
014 </head>
015 <body>
016
<h1>The start of my site
build!</h1>
017
<!-- Bootstrap Plugins
-->
<script src=http://netdna.
bootstrapcdn.com/bootstrap/3.1.1/js/
bootstrap.min.js></script>
018 </body>
019 </html>

03

Add core structure


and navigation

This is an example of a simple horizontal


navigation bar which switches to a collapsible list for
small screens. We also have a primary large button with
some intro text. The class container can be used to
wrap any section in a centred wrapper.

04

Now add some


columns

Now we have added a row containing


three columns. At medium screens the first column
spans all 12 columns and the remaining two only 6.
On small screens they all span 12 columns. This is
implemented by wrapping the floated elements in
a class row and then using the column classes, for
example col-lg-4 will make the element span 4 columns
on large screens, whereas col-md-6 will make the
element span 6 columns on medium screens.

05

get creating

From this point on, you should be able to


quickly create the page layouts you need
and then start delving into the range of CSS options
that Bootstrap has to offer. The
documentation for the
CSS and JavaScript
plugins are well
Full code
detailed and
found on
available from
the website
webdesignermag.co.uk/
getbootstrap.com.
bcb]`WOZ ZSa
Enjoy creating!

Getting used to touch events is


vital to the user experience of a
site on devices
If we use a click event across all devices
it will create a slight lag effect that can be
really frustrating for users. This is due to how
touchscreen devices handle the click event
it in fact triggers a range of events as follows;
Touchstart, Touchmove (an event for every
pixel move), Touchend and finally Click. The
amount of time between the Touchend and
Click events can be up to 0.5 a second. This
delay makes the interaction feel sluggish but
is not long enough for it to seem broken. The
solution for this is to bind all click events with
a Touchend or Touchstart and fallback to click
when necessary. All of this is handled out of
the box by both Bootstrap and Foundation
Responsive frameworks.

ADAPTIVE
JAVASCRIPT
Use Matchmedia and window.
onresize events to adjust your
JavaScript functionality
Inevitably you will need to change either
some markup based on the screen size eg,
you may have a sliding carousel of images
and on smaller screens not want it to slide
automatically. You could achieve this by
checking the window width on page load and
then setting up the functionality to match.
This, however, wont run again when the
window is resized, so will only implement
the functionality based on the initial window
size. To achieve this youll have to update the
functionality on either a window.onresize
or Matchmedia event. The window.onresize
event is triggered for every pixel change in
window size, so itll be intensive to run checks
every time it fires. This makes the Matchmedia
event a more efficient solution. These events
are only triggered when the window is resized
to the matching rules set, the same event that
CSS media queries listen to.
This technique gives the added benefit of
matching your CSS media queries, so aligning
JavaScript adaptations with your layout
changes is easy to manage. If you use window.
innerWidth the value returned doesnt match
the value that triggers the CSS media queries.

Web Design Tips, Tricks, & Fixes 21

TIME TO TEST
How to be
Q]\ RS\b
that your
PcWZReWZZ
work across
RSdWQSa
without
costing too
much time

The sheer range of devices in use today


means that it is increasingly difficult to
test across a wide enough range and to
still be confident in the final product. If it
takes an hour to run through a test on
one device, it will take the same amount
of time for each device thereafter. This
means that to stop increasing our time
and cost in testing we need to find
some smarter ways to do it.

Use the browser


Both Chrome and Firefox have excellent tools and extensions
for testing responsive sites. As you build, check all screen widths

in the browser from 320px and up. If you just catered for the
screen widths of specific devices, the final solution will not be
future-proof. Devices with new screen widths are coming out
all the time, so we cant assume that the most popular devices
now will remain so. In these browsers you can also emulate
touch events, but this doesnt really give you the tangible
feedback that using a touchscreen does.

Test as you go
This is a simple approach, just as relevant for desktop browsers,
you test each layout and component on a tablet and phone
as you create them. Make sure that with both devices you are
covering the Android and iOS platforms this way when you get
to the end of the build you shouldnt have any bugs that affect all
devices or are linked to a specific platform.

Use four core devices


When you have finished the build and come to formal testing,
use at least a tablet and phone each, for both Android and
iOS. If you do not have access to four devices you can use
emulators, but you will find discrepancies in behaviour when
comparing to the actual devices. To speed up this process you
can use a tool to synchronise the interactions on a site across
multiple devices. Both Adobe Edge Inspect (html.adobe.com/
edge/inspect) and GhostLab (vanamco.com/ghostlab) not
only provide this flexibility but also include a host of helpful
debugging tools. These give you DOM, CSS and Console access
to the devices that you have connected. Its easy enough
finding bugs when testing, but to figure out exactly what is
happening these debug tools really are indispensable.

Rapid wide range testing


Once you have completed testing with actual devices and fixed
any issues that you stumbled upon, you can use emulators to
check across a wider range of devices.

EM ULATORS VS DEVICES
There is
a host of
emulators
OdOWZOPZST]`
testing, but
can they be
`SZWSRc^]\-

emulators

PROS

CONS

You cannot be certain as to


exactly how accurate the emulators are,
unless you decide to spot check your
builds on actual devices.

CONS

PROS You can do it all from your


desktop when working on a local
environment, no need to connect a
range of devices to the same network

22 Web Design Tips, Tricks, & Fixes

With the right tools


`Sa^]\aWdSbSabW\UQO\
PS[cQVSOaWS`O\RUWdS
g]cQ]\ RS\QSW\bVS
\OZa]ZcbW]\

Adobe Edge
Inspect
html.adobe.com/edge/inspect
If you already use Adobe software
you will probably have a license
for this application. It allows you
to connect multiple devices to
your Chrome browser and then
synchronise page loads across
them from your desktop. A range
of debugging tools are provided,
giving you access to the DOM, CSS
and Console for each device.

Ghost Lab
vanamco.com/ghostlab
This application was initially only
available on Mac OS, but is now
available for Windows users too. It
not only synchronises page loads,
but also page interactions. This
tool also provides some really
useful debugging tools, making
the process of fixing your bugs
that much quicker.

devices

Both Chrome, Firefox and IE11 have some level of device


emulation available now. In addition, there is a wide range
of more sophisticated emulator apps and sites available,
including Mobile Phone Emulator (www.mobilephoneemulator.
com), Screenfly (quirktools.com/screenfly) and Blackberry
Ripple Emulator (bit.ly/1tUY3DZ) to name a few. Some simply
demonstrate layout changes for devices, while others have
Geolocation and Accelerometer overrides to test more complex functionality.

You can test a wide variety of


devices relatively quickly without the
cost of purchasing each device yourself
just to be able to test. Your clients can
also use the same tools.

TOOLS
TO TEST

It is difficult to test touch


interactions and gestures using a
desktop screen. A device is held in
the hand so emulators are not a true
representation of the full user experience.

Its really satisfying to see something you are building running seamlessly
across a range of devices. Whether you have a range on hand to build with
or use devices from an open device lab, you can be confident that users will
have a great experience when visiting a site you have built.

PROS You can be confident that

CONS

no issue will be left undiscovered


across the range of devices you test
with. You will find all bugs even
those that stem from hardware or
operating systems.

It can be costly to purchase


enough devices to cover your
testing strategy and, worse still, they
tend to go out of date very quickly.
The average user will upgrade their
device once a year.

PROS

CONS

Being able to actually use


the touch interactions as intended
ensures a smooth user experience.
You can also test multiple browsers
on the same device it is common
for Android users to use Chrome as
well as the native browser.

It is a much more timeconsuming process to test on


actual devices. They all need to be
connected to the correct network
and set up or integrated with a
separate application in order to
allow debugging.

New adventures in responsive design

CASE
STUDY

RESOURCES
Useful tools that will make
the RWD process easier

Survs

FARROW & BALL

This was a fully


`Sa^]\aWdSRSdWQS `ab
application build that
was designed to provide
inspiration and curation for
a large customer base

inspiration.farrow-ball.com
Farrow & Ball creates unparalleled paints and
handcrafted wallpapers, distributing them
around the world. Known for the quality of its products Farrow
& Ball has a large and varied customer base, from the home
decorator to interior design and corporate clients.

WHO

Farrow & Ball wanted to provide an


inspirational site for its customers to explore
ideas for their decorating projects, curate and share images
within the platform and in turn drive business across all sectors.

WHAT

The products available from Farrow & Ball


speak for themselves, but generating a social
environment for sharing and exploring creative ideas for their
customers was something completely new.

WHY

Due to the majority of customers


visiting the Farrow & Ball website
from iPads, this site was actually designed
and built with medium-sized tablets at
the forefront. It works seamlessly across
screen sizes from 320px wide and up, as
well as using touch events to provide a
smooth interface throughout. The site also
uses KnockoutJS, an MVVM JavaScript
framework for binding complex data to
DOM elements. The end product has met
the clients expectations from the outset
and has had huge take up from their
customer base since launch.

THE FUTURE OF RESPONSIVE DESIGN


Responsive and adaptive
websites are now expected
as standard by clients and the
tools that we use are always
developing and making things
quicker and easier. This trend is
bound to continue as there are a
lot of areas, such as testing, that
are not really efficient enough just yet.
Perhaps we can expect the differences
between native device applications and responsive
sites to disappear as the browsers gain access to more
and more device-specific functionality. It will also not
be long before responsive not only covers differing
screen sizes but also screen shape from circular watch
interfaces to real-world overlays on glasses or contact
lenses. Connection speeds for devices are also bound

The industry
is always
changing what can we
expect from
the future
of RWD?

to increase, meaning the scale and complexity of the


platforms we design and build are all set to increase.
The way we interact with the internet is always
changing, and the rate of technology development
is not looking like it will slow down. It is imperative, as
web designers and developers, that we keep up to
speed with new possibilities and always take time out
to think a little differently. There is so much more on
the horizon for us to consider currently we are only
concerned about what is happening in the browser.
What if we think bigger? We could adjust the contrast in
dimly lit surroundings, change layout when the user is
further away and even adjust functionality and content
depending on other nearby devices.
It is down to us to share experiences and approaches
in order to help the exciting ideas become the standard
expectations of both clients and end users alike.

www.survs.com
Provides the ability to create online surveys
and add them to a clients existing site. You
can then gather vital information from their
current users, without the cost and time of
holding focus groups with users.

PlaceIt
placeit.net
Upload your site designs or scrape straight from
an existing URL and then have your image placed
within a range of screens and devices. Excellent
for visualising the final product to clients.

Window Resizer
for Chrome
chrome.google.com/webstore/detail/
window-resizer
Test your CSS layouts quickly with this simple,
but very useful, free extension for Google
Chrome. There is a range of quick links to
resize the browser to specific device sizes and
also the ability to extend with your own sizes.

JS Console
jsconsole.com
Not the most exciting-looking tool but one of
the most useful. This gives you access to the
JavaScript console of a device with a simple
script injection. There are straightforward
instructions and demonstrative videos on how
to use it included on the site.

Web Design Tips, Tricks, & Fixes 23

Discover the web browser development tools that will help you to
prototype, test and optimise your website to perfection

hortly after Mozilla introduced Firefox,


a powerful in-browser diagnostics and
monitoring tool was released as an extension.
This marked the beginning of a shift in how web
designers and developers approach the problem of
prototyping, optimising and designing in the browser.
More recently, the wide-spread adoption of a
responsive design workflow has meant that the oldfashioned concept of a fixed-width window has been
replaced with an understanding that the only way to
fully test a website is in the browser itself, pushing and
pulling the window into different proportions to check
and adapt the way content reflows.

24 Web Design Tips, Tricks, & Fixes

Designing and developing within the browser


required a shift in the way we approach problems.
Rather than designing pages, were now designing
complete systems that automatically respond to
different conditions, generating more of a style guide
than a single page layout.
While the shift was led by Firebug, which well look
at shortly, this is no longer the only option available to
designers and developers. In fact, all the major browsers
now have either built-in developer tools, or a rich set
of extensions available to help users test, optimise
and even develop directly within the browser. Even
Internet Explorer is a real option, as it has a useful set

of debugging and inspection tools built right into the


browser, which may come as quite a surprise to some.
Over the next few pages we take a look at each of the
main browsers, and reveal the must-use development
tools that can help you work smarter and faster without
ever having to leave the browser environment. No
matter what your own browser preference is, youll
find a useful set of tools that can help you design and
develop directly in the browser, making the process of
testing and optimising smoother and less strenuous.
While these tools wont do the work for you, they
provide such an integral part of the process that youll
soon consider them an essential part of your toolkit.

Design and develop in the browser

START DEVELOPING IN FIREFOX


WITH FIREBUG

The browser extension that started it all, Firebug


has a lot to offer in todays developer-rich toolset

TOP TOOLS

Qgetfirebug.com
The Firebug extension allows you
to inspect HTML elements directly
within the DOM, including procedurally
generated nodes.

FireFTP

Q

mzl.la/1cArbIa
A simple debugging tool is built in,
allowing you to create JavaScript
breakpoints and check whats going on
as your code executes.

The DOM tab allows you to quickly and


easily reposition and restyle elements
within the DOM, without ever having to
leave your browser.

Firebug is a must-have extension for Firefox if youre a designer


or developer. It allows you to quickly target any element within
a page and view the underlying markup, CSS properties, layout
and Document Object Model (DOM) instantly even where
some of this is generated procedurally.
On top of that, it also allows you to directly edit any of these
elements and instantly preview the resulting change directly
inside Firefox, making it a superb way to quickly prototype
changes to an existing design within your browser.
Once you move beyond the basic features, you can also use
Firebug to create breakpoints in your JavaScript code, analyse
network access and loading times, and query collections within.
Of course, youre not purely limited to your own pages and
apps. Firebug doesnt save changes to the server, instead
editing your locally downloaded copy of a page and its assets,

so you can also use


it to inspect and
CONDITIONAL
learn from other
BREAKPOINTS
website designs.
If youd like to stop your
JavaScript running when a
All this makes
certain condition is met, right
Firebug (and the
click on the line number of
other similar tools
your script within Firebugs
youll see) an
Script panel, and type in a
essential tool both
condition such as x=10. The
for new designers
script will now pause when
and developers, and
and if that condition
is met.
seasoned pros alike.
Quite simply, once
you start developing using Firebug, youll never want to go
back to the old-fashioned approach of edit, refresh, test!

FireFTP turns your installation of


Firefox into a fully functional File
Transfer Protocol (FTP) client for
uploading and downloading files
to and from remote servers. It also
includes advanced functionality
such as directory analysis and
comparison, automatic syncing
of files and folders, support for
secure FTP (sFTP), SSL, remote
editing and much more.
Perhaps most importantly,
FireFTP allows you to create and
manage multiple sites, so its easy
to work across different servers
without having to manually
remember and rekey your login
credentials each time you access.

Fireshot

Q

mzl.la/1hM6cWU

GET TO GRIPS WITH FIREBUG

01

Inspect the DOM

Open any website youd like to


inspect using Firefox. Make sure you
have FireBug installed, and right-click
on any element within the page. From
the resulting pop-up menu, select the
Inspect Element with Firebug option.

02

Firebug may be the grandfather of modern in-browser


development tools, but it certainly still packs a punch

Edit HTML

The main window displays the


HTML markup, while the right column
allows you to tweak styles. When you
inspect an element, youll get the HTML
tab in the main window so you can edit
the HTML. Double-click it to edit.

03

Edit the CSS

Once youve found a style to


add to, double-click beneath one of the
existing rules and type your new rule into
Firebug. Rules will take effect immediately,
so you can quickly prototype different
styles interactively in the browser!

FireShot is am extension that


performs one task well. Its a
screen capture tool that records
the visible output of a webpage
as a screenshot from Firefox, but
rather than being limited to the
visible area, FireShot grabs the
entire rendered page.
The extension will save in
PDF, PNG, JPEG, GIF or even
BMP format, and captures can
be annotated within FireShot,
making it a great choice for
highlighting features in a page,
developing user manuals, or
helping to identify areas in a
page that need attention. Great if
youre working as part of a team.

Web Design Tips, Tricks, & Fixes 25

EXPERIMENT WITH GOOGLE CHROME


Chrome ships with an extensive set of developer tools as part of the package for
users to get started with
Qbit.ly/IENotW
Like Firebug, Chromes developer tools
provide a range of different options
including a DOM inspector, JavaScript
console and Resources view.

The styles tab offers a handy layout


diagram that illustrates the box model
being applied to the selected element.

EASILY EDIT A
PAGE IN CHROME
Editing HTML markup and
styles is straightforward in
Chrome using the built-in
developer tools provided

01

Open Developer
Tools panel

HTML is editable via Chromes


developer tools. Right-click on the page
you want to edit, and choose Inspect
Element. This will open the Developer
Tools panel. Now double-click on any
element in the Elements tab to edit it,
as the browser updates in real-time.

The DOM and HTML source code can


be directly edited, making it easy to
adapt an existing page to incorporate
new elements.

Taking its cue from Firebug, Chrome offers a suite of tools


that largely mirrors the functionality found in the Firefox
extension. Youll find a handy Elements/DOM viewer, which
also incorporates some nice features such as pop-up previews
of embedded media elements. In addition, the Resources tab
shows all of the individual elements that are downloaded as
part of the page request, including any JavaScript, CSS, favicon,
image, video, font and Flash files.
The standout features of Chromes developer tools are the
Timeline, Profiles and Audits tabs. The Timeline tab simply
shows how long each individual resource takes to load and
render in the browser. This feature allows you to quickly identify
any bottlenecks that are caused either by the server, your files
sizes, or complex rendering code.
The Profiles tab allows you to perform unit testing of your
JavaScript, analysing the extent to which each individual

TOP TOOLS

call puts stress on the processor. This can be particularly


useful when youre looking to squeeze every last ounce of
performance out of your webpage or app.
Finally, the Audits tab offers a handy set of actions to help
ensure that your page
is (largely) standards
SAVE YOUR
compliant. Its not
CHANGES
limited to picking
When youve been working
you up on missing
inside Chromes developer
alt tags and invalid
tools, creating new markup
nesting though also
or styles, you can quickly
available are handy
save a copy of the revised
page by right-clicking and
hints and tips on
choosing Save As from the
how to optimise your
pop-up menu.
code for even better
performance.

Pendule

Q

02

Style it up

03

Delete elements

Just as with Firefoxs Firebug


extension, Google Chromes Developer
Tools allow you to make on-the-fly
stylesheet updates to your page.
Select an element on the page as per
the previous step, then use the Style
tab to insert a new style declaration
within an existing rule.

bit.ly/1f6nXMu

MeasureIt!

Q

bit.ly/1bvfNZv
When youre converting
a mockup from a static
Photoshop comp into a
working HTML page or
deconstructing a design, it can be tricky to get everything
perfect. MeasureIt! simplifies this with a measuring ruler.
The process is simple: draw out a ruler across the browser
window, and MeasureIt! will feed back the width and height
of any elements on the page. By using this in combination
with the built-in developer tools, you can quickly resize and
reposition elements to achieve a perfect representation of
the mockup. Its also handy for getting an at-a-glance reading
on the dimensions of a particular element within the page.

26 Web Design Tips, Tricks, & Fixes

Pendule extends the


built-in developer
tools within Chrome
to offer advanced
functionality.
A handy set of features includes being able to
automatically beautify CSS and quickly disable all
styles; inline styles only, or embedded styles only. As
well as the prettifying of source code (making it easier
to see whats happening in a page), you can override
any built-in form restrictions and alter a forms method.
One of the best features available is the ability to
view generated source with changes highlighted,
which is particularly useful when youre loading
content using AJAX, or updating the DOM by inserting
nodes at runtime using JavaScript.

You can delete elements from


your HTML source code using Chromes
developer tools. Select the element
youd like to remove using the Elements
tab, and hit Delete on your keyboard.
This doesnt remove the markup from
the server, just from the current render
of the page. If youd like to save your
changes, right-click and choose Save.

Design and develop in the browser

SHAPE YOUR SITE WITH SAFARI


Safari has a complete set of developer tools at its
disposal but you need to enable them first!

LEARN THE
SHORTCUTS

Qbit.ly/1d7Livt

To make the most of Safaris


Web Developer tools, its
worth learning the keyboard
shortcuts to save time
switching between different
tabs. You can find a complete
list of these in the online
documentation at
developer.apple.com.

Like Firebug, Safaris developer tools


offer a range of ways to interrogate the
pages DOM, styles and resources.

The built-in console allows you to


query objects and collections directly
from the Web Developer panel.

As both Chrome and Safari share their roots in the open


source WebKit project, you might expect to find a similar set
of developer tools in both browsers. If that is the case, you
shouldnt be disappointed! Safari boasts largely the same
excellent toolset that Chrome offers, albeit with only a few
minor differences in functionality or finesse.
Just as with the other tools weve looked at in this feature,
Safaris developer tools allow you to inspect and edit HTML
elements directly, viewing the updated page rendering as it
changes in response to your edits. You can also access and
alter the styles, and use the JavaScript console to test variables,

MAKE ALTERATIONS IN SAFARI

Inspect an
element

Safari allows you to right-click on


an element and inspect it using the
developer tools. You do, however, need
to enable the Developer menu before
this will work. Choose Safari>Preferences,
select the Advanced tab and ensure
Show Develop in the menu bar is checked.

Inspect devices

Q

bit.ly/1d7LSJK

The Resources view provides access


to all the individual elements that make
up the page, including cookies, local
storage and any extension scripts.

01

TOP TOOLS

02

methods and actions. Naturally, you can also set breakpoints


for your code to help you debug, and theres a useful timeline
mode that allows you to track the way a page is loaded and
rendered within the browser window.
The debugger facility makes it significantly easier for
designers and developers to find problem code and identify
the precise issue, whether thats an unescaped string or an
unnecessarily resource-hungry loop.
Other nice features include the ability to switch between
different colour models when editing CSS, making it easy to use
a combination of different approaches (such as hex and rgba).

Safaris web developer tools are extremely capable


and very easy to learn. Here we show you the basics

Edit HTML
and CSS

Once enabled, you can edit the HTML


and CSS of a page just as with all the
other tools weve featured. Highlight
the content youd like to alter, right-click
and choose Inspect element, then make
changes in the Developer Tools window.
Changes are rendered in real-time.

03

Use the console

The console allows you to interact


with scripts that are already included on
your page, as well as create new scripts.
This can be especially useful when it
comes to debugging, but there is no real
limitation with what you can run in the
console. Try a simple alert(); method to
see this in action.

One of the major benefits of


Safaris built-in developer toolset;
by enabling the option on your
iPhone or iPad, you can access
the entire toolset on your desktop
while referring to a page loaded
on your mobile device.
This is a powerful capability
that makes it much easier to
conduct on-device testing of your
pages, and is especially useful
when optimising JavaScript or
CSS3 code to work well on these
less powerful devices. You can
find full instructions on how to
set up your iOS devices to use
the Safari developer tools at
developer.apple.com.

ySlow

Q

yhoo.it/1kyCH7W
The ySlow extension, developed
by Yahoo!, is available for all the
common browsers, so youre
not limited to using Safari. ySlow
allows you to inspect a pages
performance, marking it against
a series of tests and making
recommendations to improve
page performance.
There are a core 20-plus rules
to ensuring the best performance
of your page, and each time the
extension runs it checks the page
against these criteria. These are
techniques that many developers
employ, but if youve overlooked
one or more, ySlow will alert you.

Web Design Tips, Tricks, & Fixes 27

REDISCOVER INTERNET EXPLORER


In the past Internet Explorer was the worst option for in-browser development, but
with the introduction of IE11 this has changed

TOP TOOLS

Qbit.ly/IENotW
Just as with all the other tools available,
the newly refreshed Internet Explorer
F12 developer tools offers a full web
inspector and console.

UI Responsiveness

Q

Styles applicable to the currently


selected element are pulled out into
this area, allowing you to edit and
preview the results in real-time.

bit.ly/1golD73

A range of profiling tools are also


provided under the Profiler tab,
which enable you to analyse and test
JavaScript and page performance.

If youre a web developer with more than a few years


experience behind you, youll probably be quite familiar with
the limitations of the Internet Explorer debugging environment.
In Internet Explorer 6, meaningless pop-up script error alerts
would tell you something was wrong, but the facility to analyse
and actually decipher what was causing the issues was
unfortunately beyond the majority of designers.
Thankfully this has all changed with the more recent versions
of Microsofts browser, and Internet Explorer 11 sees the arrival
of a completely re-architected set of developer tools known
as F12 Developer Tools, given its name since the keyboard
shortcut to launch the suite is F12.

Present and correct are a DOM/HTML node editor and


inspector, JavaScript console, profiling suite and network
analysis tool. The same core features weve seen across all the
other browsers are all present and correct here, so if youre
either limiting yourself to using Internet Explorer, or simply
want to analyse performance in this browser, you now have the
complete toolset to allow you to do so.
There is still the odd cryptic error message that pops up, but
with quick reference to the developer tools documentation at
bit.ly/1gZ1v92 you can decipher these with relative ease. Its
difficult to overestimate the importance of having these tools
available, so web designers across the globe should rejoice!

EDIT AND IMPROVE YOUR SITE WITH F12

Editing in-browser is now perfectly


viable with IEs improvements

Thanks to Microsofts own


efforts, there are a number of
additional tools available within
the F12 suite. One example is
the excellent UI Responsiveness
testing tool. This testing
suite graphically represents
the loading and animation
performance of individual
elements within the page,
allowing you to analyse where
bottlenecks are causing your
page to respond sluggishly.
You can access the UI
Responsiveness tool from the F12
toolset youve already seen just
click on the Speedo icon to open
the suite and get started.

Emulation tools

Q

bit.ly/18lF9P4

01

Open the tool

Opening the Developer Tools


within Internet Explorer is really easy:
simply press the F12 key on your
keyboard. If youre using a tablet such as
the Microsoft Surface, or your keyboard
doesnt have a set of function keys,
you can also access it under the
Tools menu.

28 Web Design Tips, Tricks, & Fixes

02

Edit a node

You can quickly and easily update


the DOM by selecting a node directly
inside the F12 Developer Tools window,
or right-clicking on a page element and
choosing Inspect Element from the popup menu. Once selected, you can edit
and delete nodes by double-clicking or
pressing the Delete key as appropriate.

03

Update the styles

This follows a similar user


interface pattern to the other developer
tools; to edit a style, first select the DOM
node youd like to interact with. F12 Tools
will show you all the applicable styles for
that node. Double-click inside an existing
rule to add an additional style, or create
an entirely new one.

Now you can emulate different


browsers using Internet Explorer
11. Found within the main F12
window, as with the other tools
featured here, the Emulation
options are underneath the
icon that looks like a monitor
and mobile phone. This area
allows you to simulate different
rendering models and screen
sizes, so you can pretend that
youre viewing a website with a
Windows Phone instead.
You can also make IE pretend
to be elsewhere on the globe,
which is handy if youre serving
location-aware content.

Design and develop in the browser

DESIGN AND CREATE IN OPERA


Opera is one of the oldest browsers still available today, but how does it compare to
the market leaders when it comes to developing in the browser?
Qwww.opera.com/developer

USE OPERAS
DRAGONFLY TOOLS
Use our quick-start guide to get
going with Opera

Opera ships with a complete set of


developer tools Dragonfly that
allow you to interact with and query
a page with ease.
The console allows you to interact
with the scripting engine on the
page, querying elements and loading
content as necessary.

01

Inspect an
element

Opening up Dragonfly, Operas


developer tools suite, is really easy.
Simply press Ctrl+Shift+I on a PC, or
Cmd+Opt+I on a Mac. Or, you can
select a single part of a page, right-click
on it and choose Inspect Element from
the pop-up menu to launch Dragonfly.

Styles can be updated directly using


the built-in styles browser, which also
works in combination with the HTML
DOM viewer to report on active styles
for the selected element.

Opera has always


threatened to be a
USE CHROME
powerful force on the
EXTENSIONS
desktop, but has never
Because Opera now shares
really achieved the
the same rendering engine
market share it perhaps
as Google Chrome, youll find
that many of the extensions
deserves. Away from the
available for Chrome will also
desktop, however, it has
now work on Opera!
significant support. This
is reflected in the team
behind Operas decision
to move away from the Presto engine to use Chromium instead.
Immediately following this move, Opera was temporarily left
without a set of developer tools. This caused developers to cry

shame, as Operas solution Dragonfly was a well-realised


set of developer tools that offered an excellent cross-platform
solution to developing not just for the desktop, but also for
devices unsupported by other browsers.
Thankfully, things have changed and the developer tools
are back and as good as ever in the latest version of Opera. So
once again designers and developers have full access to a suite
of tools that allow them to inspect and interrogate pages, as
well as develop directly within the browser.
As is similar to the other tools weve already covered in this
feature, Operas Dragonfly allows you to edit, insert and delete
HTML directly within the DOM. You can also edit the CSS and
scripts used on a page. And, as you might expect, theres a full
set of analysis tools available here too!

TOP TOOLS

Chromiumbased
extensions

Q

QCross-platform
development

www.opera.com/dragonfly
Opera is a big player
in the mobile world. If
youre targeting devices
outside desktop, it makes
a lot of sense to test and develop your site using Opera.
Happily, Dragonfly works across all devices, so you can use
the same toolset to inspect and query your page whether
youre testing against a tablet, smartphone, or desktop.
This is especially useful when it comes to older phones or
embedded devices such as TV set-top boxes. The former are
especially prevalent across the developing world, where the
latest versions of Android or iOS arent nearly as relevant or
universal as they are in the UK.

02

Edit the CSS

03

Use the console

Just like with Chromes


Developer Tools, Dragonfly allows
you to interactively update the CSS
of individual elements on your page.
This makes it a fantastic option for
iteratively designing directly within the
browser. Simply target the element
youd like to add styles to, and add/
remove styles using the Styles tab.

bit.ly/1bHfcbG
Since Opera
dropped its Presto
rendering engine
and moved to the Chromium engine, which also
powers Google Chrome, Opera is now compatible with
a range of plug-ins for the Chrome browser. This means
any extensions youre already using and familiar with
on Chrome will likely work in Opera too. Similarly, any
specific-to-Opera extensions that have been converted
to use the Chromium engine will work in Chrome.
An example of such a tool is the Accessibility
Developer tools, provided by Google Accessiblity. This
adds an accessibility audit to the developer toolset, and
an additional accessibility sidebar in the Elements tab
inside Chromes developer tools, or Operas Dragonfly.

Youll find a console that allows you


to query existing collections, objects and
variables, and insert breakpoints for code
analysis. Open the console tab, and type in
alert(hello world); to see it in action. If you
have a library included in your page, you
can access any of the methods exposed by
the script use the same syntax as normal.

Web Design Tips, Tricks, & Fixes 29

Code the web


with opensource editor
Brackets
Get to know some of the features and
tools that can make your development
life that little bit easier

01 Download Brackets

Lets download the latest copy of Brackets from


the website. Head over to download.brackets.io to get
a copy of the editor for your operating system. As of
writing, the current version is Sprint 34, but new
versions are released on an approximate cycle of every
three weeks, so your version may differ.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends Brackets

a
<Above>
sBrackets is a great option for
developers who want an easier time
and who wouldnt?

code editor, as every developer knows, is


an incredibly personal choice. We spend
a good majority of our time sat at the
controls of an IDE or editor and as a result
it has to satisfy a number of specific
requirements, namely performance,
comfort and suitability for the tasks in
hand. If we can choose something that can
handle pretty much whatever we need
from it and can be extended and
personalised to suit us 100 per cent, then we can
certainly be happy with using it.
Since it is so important to make a good choice, it is
only right that you consider all of your options. Enter
Brackets, the free open-source code editor from Adobe.
Developed using web standards and HTML, JavaScript
and CSS, Brackets was actually built using Brackets and is
a superb choice for developers everywhere who need
something that makes their life much easier.
In this tutorial we will walk through the installation
process as well as covering JavaScript linting and
extending with plug-ins so lets get going!

An editor has to satisfy a number of


requirements, namely performance, comfort
and suitability for the tasks in hand
30 Web Design Tips, Tricks, & Fixes

02 Install and power up

The Brackets installation is easy and


straightforward. Once complete open the application, at
which point you will be greeted with an incredibly
simple and clean layout. One of the benefits of using
this tool is the lack of distraction from extra navigation
and menu items or IDE panels that clutter the
softwares workspace.

03 Instant help

When you initially launch the editor, Brackets will


load a default project which serves two purposes. The
first is to show you how it organises and manages files
within the workspace environment; a single-click
selection will load the file to edit. The second is that
the HTML file is the basic Getting started guide for
the release.

Code the web with open-source editor Brackets

04 Image management

To assist with focusing on your design and


development processes within the editor, Brackets is
packed full of useful hidden gems and features. One of
these lets you hover your cursor over an image tag src
attribute value and a thumbnail version of the image will
be displayed within a pop-over bubble. This works with
data URI values too.

05 Live Preview

The top-right of the editor has a lightning bolt


icon. With an HTML or CSS file active in the editor,
selecting this will enable Live preview on the closest or
selected HTML file. This will launch a debug-enabled
version of Chrome connected to the editor. Any
changes that are made in Brackets will be instantly
updated and visible in the browser.

06 Live HTML selections

When running Live Preview, any tags selected in


the editor will be highlighted in the browser for quicker
visual identification, much in the same way Chrome Dev
Tools displays selected elements. This can really assist
you during development and debugging phases as you
can instantly see the element you are working on.
HTML updates will also be changed instantly.

Useful extensions

01 _____________Markdown Preview
This adds a new menu icon visible when editing
Markdown fi les. A panel will display the
rendered output of your .md fi le contents
directly within the editor.

07 Quick Edit CSS

Brackets has long-provided the ability to edit


CSS rules directly within the editor from an HTML page.
With your cursor over an HTML element, press Cmd/
Ctrl+E to enable the Quick Edit command. This will scan
the .css files and find the relevant rules that match the
selected element, which you can then edit without
having to switch files.

08 Add CSS Rules

The very same technique can be used to add a


new CSS rule to an element. Using the Quick Edit
process once more, the inline display will open and you
should be able to see a button element that will allow
you to create a new rule, which will be applied to the
nearest space in the .css file, once again allowing you to
remain focused in the editor.

09

Highly extensible

Clicking the building block


icon below the Live
Preview lightning bolt will open up
the Extension Manager modal
window. There is an ever-growing
number of free communitycreated extensions available to
download completely free. There
is no install process with the
exception of clicking the Install
button. Thats all it takes! You can
enhance the editor with plug-ins
that suit your specific needs.

02_____________PageSuck
Ever needed to copy source code from a live
site? This extension will draw in the contents of
a provided URL and create a new fi le for you to
work with.

03_____________Git Control
There are a number of extensions that manage
Git processes and resources. Brackets Git adds Git
control directly into the editor for a cleaner
workflow solution.

Web Design Tips, Tricks, & Fixes 31

10 Theseus debugging

For anyone writing a web app using JavaScript or a Node.js


application, the Theseus extension is crucial. Written by Adobe and
MIT, Theseus allows you to perform retroactive inspection of JavaScript
code, an asynchronous call tree and real-time code coverage as you
develop using Live Preview. Check out the open-source project on
GitHub at github.com/adobe-research/theseus

11 Theseus in action

With the extension installed and Live Preview running, lets start to add some jQuery code
to the document and place a $(document).ready() function call. As soon as it is saved and
automatically reloaded you will see updates in the left margin of the editor to represent the live
callback from the code.

12 Multiple functions

If we continue to add JavaScript functionality within the script block we will start to see how Theseus works
in a little more detail. Here we have added a click handler to a button element. Once saved, the callback count will
update with every click of the button, and the initial .ready function stays at 1 as expected.

Developing extensions
Creating your own extensions for Brackets is
incredibly easy. It is essentially based upon a
single JavaScript file that manages the event
handlers and callbacks, and taps into the core
API components available. These include file
system integration, menu management to
apply extension menu items to the editor itself
and document manipulation and that is

13 Inspect callbacks

The retroactive inspection feature really helps to


dig deeper into the JavaScript methods in place. By
clicking on any of the callback counts in the left margin,
a new panel will open to display the processed code
and any objects that were passed into each function call.

naming only a few.


The best way to develop an extension for
Brackets is to actually build it within Brackets.
While creating and testing an extension in the
same editor instance is possible, it could
potentially cause memory issues. To bypass
this, you can open multiple Brackets windows.
Use the first one to build and write the
extension, and the second window to test the
loaded local extension. There are some
amazing resources available to help you, check
out this overview for a start: monkeh.me/asjpv.

32 Web Design Tips, Tricks, & Fixes

14 Asynchronous calls

Lets now add a JSON request to the click


handler. This will be fired after the event, but the
response wont be immediate. Theseus is able to handle
this and will successfully stack any asynchronous
callbacks within the log inspector panel beneath the
function that initiated the request.

Code the web with open-source editor Brackets

15 Enable Theseus

Should you ever want or need to, Theseus can


be disabled and re-enabled easily through the File
menu. As well as serving files from the local disk, it can
also proxy to a proxy localhost running on port 3000.
Its an incredibly powerful tool and you can expect it to
be improving continuously.

16 JavaScript code hinting

Helpfully, Brackets has been specifically


engineered to assist with all areas of development,
which includes providing code hinting and assistance
where possible. For example, when implementing a call
to a JavaScript function, the editor will highlight the
code and function name as well as any parameters and
their type, if applicable.

17 CSS hinting

Code and syntax assistance is also available for


HTML and CSS files. This includes help with code
completion and attribute or rule definitions. Simply start
typing the value and Brackets will provide you with a list
of possible matches to select from. While seemingly
obvious for an editor, this really helps speed up
development and save time.

19 JavaScript linting

18 Quick Edit colours


CSS rules can also be altered using the Quick Edit function. Hover the cursor over a colour
reference and receive a pop-over with the colour block. Cmd/Ctrl+E will open up the Edit feature to
select a new colour from a dynamic selection tool or manual input in various formats.

Brackets comes with a built-in JavaScript linting tool, JSLint. By


default, all JavaScript files are run through the lint process as soon as
they are saved. This process helps to locate any typing errors or issues
with closing off functions or variables, and the editor will display a
panel showing the errors and line numbers to help you fix them.

Object
inspection
Theseus allows you to dig
deeper into the returned
objects and arguments
within your JavaScript
code directly within the
Brackets editor to
help identify and
manage data.

20 Alter base URL

By default the Live Preview function will start a Node web


server on a specific port to communicate between the Chrome
browser and the editor. The base URL can be customised if you have
another port or domain to use, and this can be managed from the
File>Project Settings menu option.

21 Customise it

The Brackets Extension APIs have been heavily refactored in the later releases to give
developers more power to interact with the file system and the option to harness the full power of
the Node services. Build your own extensions quickly and easily and follow the detailed
documentation available from github.com/adobe/brackets/wiki/How-to-Write-Extensions.

Web Design Tips, Tricks, & Fixes 33

Build a
responsive
WordPress
theme

01 Download FoundationPress

To begin, make sure you have the latest version of


WordPress installed and set up. Head over to the
FoundationPress starter theme GitHub page: github.com/
olefredrik/foundationpress and download this theme.
Once youve downloaded it, extract it and upload it to your
themes directory in WordPress and activate it.

02 Custom stylesheet

Start by opening up the header.php file in your


text editor. Youll want to add in your own custom
stylesheet so that when it comes to upgrading
FoundationPress it wont override any custom work. You
may use Sass with Foundation, but to allow beginners to
follow along this tutorial, well be using pure CSS.

001 <link rel=stylesheet href=<?php echo get

As the most advanced responsive


framework available, Zurbs Foundation
is ideal for your latest WordPress project

_template_directory_uri(); ?>/style.css />

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends WordPress, HTML, CSS

T
< Above>
sStart building responsive WordPress themes using Zurbs own
advance Foundation framework starter theme, conveniently
called FoundationPress

< Above>
s:PVDBOdownload Zurbs Foundation WordPress starter theme,
FoundationPress, with ease over on GitHub

34 Web Design Tips, Tricks, & Fixes

hroughout this four-page


tutorial well be using Zurbs
Foundation framework. Well
be taking this lightweight,
advance responsive
framework with a mobile-first
approach to the popular
CMS/blogging platform WordPress.
Previously to incorporate Zurbs Foundation
framework into WordPress you had to manually
link the necessary JavaScript and CSS using the
WordPress functions wp_enqueue_script and
wp_enqueue_style. But now, thanks to Zurb and
the popularity of WordPress, Zurb has provided
a starter-theme called FoundationPress, which
you can download directly from its GitHub page
to start building your own WordPress theme
with the Foundation framework.
The purpose of this ultimate starter theme is
to act as a springboard; it comes packed with
useful re-useable components, a 12-column
responsive grid, JavaScript functions and much
more. This starter theme contains all the
necessary design elements, including the
JavaScript and CSS libraries.
Still, FoundationPress is not an all-in-one
WordPress theme with plugins, shortcodes,
custom options or custom templates it is only
to be used as a starting point. Luckily it has
done most of the hard work for us including
setting up widgets, navigations, displaying blog
posts and general clean-up of WordPress. Check
out www.filesilo.co.uk/bks-594 for resources.

03 Customise the menu

WordPress already features a built-in Appearance


Menus Screen, enabling users to create custom
navigation. FoundationPress takes this a step further by
allowing us to create multiple navigations on either side
on the nav bar. When you create a new menu in
WordPress, you have the option to enable your
navigations for mobile devices.

04 Customise the header

FoundationPress has already pre-written a lot of


the WordPress basic theming. Were going to dive in and
modify it. To give this theme a visual punch were going
to add in a header with the website name, including a
gradient background. Open up the header.php and
paste in the following HTML code.

001 <header class=main-head>


002 <div class=row>
003
<div class=large-12 columns>
004
<h1 class=title><?php bloginfo
( name ); ?></h1>

005
</div>
006 </div>
007 </header>

05 Style the header

With our header implemented well now need to


style it. Open up style.css in the FoundationPress starter
theme, start by giving the main header a gradient
background, using CSS3 gradient. Position the main h1
above the header. Lets make all characters upper-case and
give it a text shadow to stand out from the light backdrop.

001 .main-head {
002 margin-bottom: 2em;
003 padding: 1.2em;
004 background: #00b3d3;
005 background: -moz-radial-gradient(center,
ellipse cover, #00b3d3 0%, #007295
100%);

Build a responsive WordPress theme

< Above>
sWe used Foundations grid system on the
search form, which will auto scale down for
mobile and tablet devices
< Top>
sIn WordPress, activate FoundationPress
starter theme. This theme includes all the
Foundation framework library

006

007

background: -webkit-gradient(radial,
center center, 0px, center center, 100%,
color-stop(0%,#00b3d3), color-stop
(100%,#007295));
background: -webkit-radial-gradient
(center, ellipse cover, #00b3d3 0%,
#007295 100%);

008 }
009 .main-head h1 {
010 text-align: center;
011 font-weight: 900;
012 text-transform: uppercase;
013 letter-spacing: 10px;
014 text-shadow: 1px 1px 2px rgba
015
016
017 }

(50, 50, 50, 0.59);


font-size: 2.5rem;
color: #fff;

06 Add a search

Currently in our widgets list, the search form is


located in the sidebar. In WordPress Widgets we can
disable the search widget. Now inside our head.php at
the very bottom, paste in the following function, which
will print out the search form. Were going to place our
search form just below the header of our website.

001 <?php get_search_form(); ?>

07 Customise search

< Left>
sEnabling navigation to appear on mobile
devices can be controlled all through the
Menus panel in WordPress

< Bottom>
sFoundationPress allows you to order
menus to be on the left or right side of the
menu and enable for mobiles

With the get search form function added in our


header.php we can now structure this search form by
editing the searchform.php. Directly below the form tag

Update Foundation
with Bower

we have applied a row <div> and changed the default


grid layout to use the large grid system as well as setting
some custom classes to be referenced in our CSS.

Make sure that you have Node.js,


Grunt and Bower installed locally
so you can perform an update to
the Foundation framework
directly just by running this in
the command line:
$ foundation update

001 <div class=row>


002 <?php do_action(foundationPress_
003
004

005
006
007
008

009

searchform_top); ?>
<div class=large-8 columns searchbox>
<input type=text value= name=s
id=s placeholder=<?php esc_attr_e
(Search, FoundationPress); ?>>
</div>
<?php do_action(foundationPress_
searchform_before_search_button); ?>
<div class=large-4 columns
searchbutton>
<input type=submit id=searchsubmit
value=<?php esc_attr_e(Search,
FoundationPress); ?> class=prefix
button>
</div>

08 Modify index.php

The index.php is the main template in WordPress


theming hierarchy. Were going to modify it and remove
some of the grid components and place them in
content.php instead. Remove the <div> row and grid
classes just below the get_header function and replace it
with the code below. Finally, migrate the <?php get_
sidebar(); ?> just above the get_footer function.

001 <?php get_header(); ?>


002 <div class=row data-equalizer>

09 Blog post

With the homepage structure completed, well


want to structure each blog post in a grid column of four
rows; this will lay out three blog posts organised next to
each other on a large monitor. Using the grid system will
force our layout to be responsive. Remove the original
code all the way down to the <footer> tag in content.php.

001 <div class=large-4 columns role=main>


002 <article id=post-<?php the_ID(); ?>

003
004
005
006
007

<?php post_class(panel); ?> dataequalizer-watch>


<header>
<h2><a href=<?php the_permalink();
?>><?php the_title(); ?></a></h2>
</header>
<div class=entry-content>
<figure><a href=<?php the_permalink
(); ?>><?php if ( has_post_
thumbnail() ) {the_post_thumbnail

Web Design Tips, Tricks, & Fixes 35

< Above>
s)FSFXFIBWFPVSfully responsive WordPress site, resizing to
perfectly display on all screen sizes
< Top left>
sEasily set up and use shortcodes in your site to take advantage of
Foundations library of components
< Bottom left>
sUsing WordPress shortcodes, we were able to add Foundations
alert box components throughout the site

008
009

010

011
012

(large); } ?></a></figure>
<?php the_excerpt(); ?>
<p>Posted on <?php the_time(F jS, Y
); ?> in <?php the_category(, );
?></p>
<p class=byline author>Written by
<?php the_author_posts_link(); ?>
</p>
<a href=<?php the_permalink(); ?>
class=button>Read more</a>
</div>

10 Style the blog

With our blog post structure set up in a grid


column in a set of threes, well now implement some
simple styling to this homepage. Back in our style.css,
well add some box shadow so the panels dont look so
flat. We dont need to style the panels themselves as
these styles are already set up inside Foundation.

001
002
003
004
005
006
007
008
009
010

.panel {
box-shadow: 0 1px 5px #D5DEE5;
}
figure {
margin: 0;
}
.entry-content figure img {
margin: 10px 0;
}
@media only screen and
(min-width: 40.063em) {
011 h2 {
012
font-size: 1.8rem;
013 }

36 Web Design Tips, Tricks, & Fixes

014 }

11 Style search form

With our blog posts neatly organised in a row of


threes, our search field and search button are not quite
aligned with the rest of the design. Lets fix this by adding
some padding. With a mobile-first approach, Foundation
takes care of the responsive nature its unnecessary to
add styles for mobile or tablet devices.

001 .searchbox, .searchbutton {


002 padding: 0 15px;
003 }

12 Move the sidebar

Rather than having our sidebar situated on the


right-hand column, we will position it directly below all
the blog posts and just above the footer. Inside the
sidebar.php were going to use Foundations Equalizer
component, which will set equal height to all the widget
panels. We simply place the data-equalizer attribute to
the parent container here.

001 <div class=bottom-sidebar>


002 <aside id=sidebar class=row data003
004
005
006
007

equalizer>
<?php do_action(foundationPress_
before_sidebar); ?>
<?php dynamic_sidebar(sidebarwidgets); ?>
<?php do_action(foundationPress_
after_sidebar); ?>
</aside>
</div>

Working with Sass


Working with Sass provides greater
flexibility and control over this
theme. All Sass variables are
located in scss/config/_
variables.scss and your
site structure within
scss/site/_structure.

13 Widgets

Now to actually lay out our widgets, we will need


to open up the widget-areas.php located in the library
directory. Inside the first array on line 8, remove what is
currently there and replace it with the below, which
uses the large-4 grid and a data-equalizer-watch
attribute that the Equalizer component requires to set
equal heights to each panel.

001 before_widget => <article id=%1$s


class=widget %2$s large-4 columns><div
class=panel data-equalizer-watch>,

14 Style the sidebar

Within WordPress in the Widgets panel, we only


require three widgets so remove any of the other
existing ones. When you check the homepage you will
notice our widget panels all have equal heights to the
tallest panel. To finish up with our sidebar beneath our
blog posts, we will give this section its own background
colour and some padding.

001 .bottom-sidebar {
002 padding-top: 10px;

Build a responsive WordPress theme

003 background-color: #cecece;


004 }

15 Set up shortcodes

Because there is a vast amount of components


available in Foundation, we convert some of them into
shortcodes so that we can reuse these components
whenever were in the editor. Creating shortcodes
requires two steps: create a primary handler method and
hook up the handler into WordPress. Inside the
functions.php we need to set up our primary function.

001 function foundation_add_alerts


002
003
004
005
006
007

( $atts, $content = null ) {


extract( shortcode_atts( array(
type => ,
shape => ,
close => true,
class =>
), $atts ) );

16 Shortcode array

In the previous code snippet we noted that our


function receives the parameters of type, shape and
close. Were going to use this to display alert boxes
using one of Foundations components. The type
attribute will display success, warnings or informative
information using this shortcode. Lets set up an array
that will capture these attributes.

001
002
003
004
005

$class_array[] = ( $shape ) ? $shape : ;


$class_array[] = ( $type ) ? $type : ;
$class_array[] = ( $class ) ? $class : ;
$class_array = array_filter( $class_array );
$classes = implode( , $class_array );

17 Shortcode markup

When this shortcode is executed we want to


make sure that its using the correct formatted markup
and CSS classes. We need to use a wrapping class
alert-box. This is very important because we want to
make sure that Foundation calls the Alert JavaScript
plugin for us. This particular plugin is in fact handled in
the foundation.alert.js.

001 $output = <div class=alert-box . $


classes . >;
$output .= do_shortcode( $content );
$output .= ( false != $close ) ? <a
class=close href=>&times;</a> : ;
004 $output .= </div>;
005 return $output;
006 }

002
003

18 Hook into WordPress

Before finishing off our shortcode were going to


ensure that it has all been registered correctly,
otherwise WordPress wont know what to do with it. To
do this we use the register_shortcodes function and
the add_shortcode method. The first parameter defines

the shortcode in the editor while the second points to


the function that we created previously.

001 function register_shortcodes() {


002 add_shortcode(alert, foundation_add_
alerts);

003 }
004 add_action(init, register_shortcodes);

19 Shortcodes to use

We can now use the following shortcodes in the


editor to display alert boxes, which is a native component
from the Foundation framework. All we have to do is
pass in which type of alert box type we want displayed
by selecting the attributes: success, secondary or alert.
We can even choose what type of shape to use and
whether we want a close off function.

Store all your shortcodes in


a separate file

001 [alert type=success shape=radius

In this tutorial our code for the WordPress

close=true]This is a success message


[/alert]
002 [alert type=secondary) shape=radius
close=true]This is a standard message
[/alert]
003 [alert type=alert shape=round close=
false]This is an alert message[/alert]

shortcodes are placed in the functions.php.


While this is valid, to keep our functions.php
clean and easy to maintain its good practice to
copy all of the shortcodes into a separate file
instead. The benefit of having this separate file is
that it becomes more modular and, should you
have lots of shortcodes, it wont become
cluttered in unnecessary code compared to

20 Alert boxes

Without any CSS styling or JavaScript and just


using the shortcodes we have set up, we can
implement alert boxes wherever we like in our
WordPress site. By simply using shortcodes we can
easily convert many of the rich components from
Foundation to be used easily throughout our site.

21 Footer

To finish up were just going to add in a footer


navigation by using the WordPress WP list pages. Open
up the footer.php and just below the closing </section>
tag, remove everything including the <footer> tag.
Replace it with the following code, which will display a
list of all pages on our site.

001 <footer class=main-footer>


002 <div class=row
003
<ul>
004
<?php wp_list_pages(); ?>
005
</ul>
006
<?php do_action(foundationPress_
007
008
009
010

before_footer); ?>
<?php dynamic_sidebar(footerwidgets); ?>
<?php do_action(foundationPress_
after_footer); ?>
</div>
</footer>

22 Style the footer

Finally, were just adding the final touches by


styling up our footer. Through this tutorial weve taken

being in the functions.php.


To follow FoundationPress standards we can
copy all our shortcodes into a new file called
foundation-shortcodes.php. Within the
functions.php we can just reference this with:

require_once(library/foundationshortcodes.php);
You could even store all of your shortcodes
within a separate plugin. That way, in the event
that you switch themes, they will always be
available and working.

the starter theme FoundationPress and quickly


customised it as our own theme using a variety of
Foundations components and functionality. Using
FoundationPress allowed us to focus on the front-end
development and less on the actual backend efforts.

001
002
003
004
005
006
007
008
009
010
011
012

.main-footer {
padding: 10px 0;
background-color: #9c9c9c;
}
.pagenav ul {
margin: 10px 0 0 0;
}
.main-footer li {
float:left;
margin-right: 10px;
list-style: none;
}

Web Design Tips, Tricks, & Fixes 37

Build a
responsive
slider using
bxSlider
Learn how to use the bxSlider jQuery
plug-in to install and customise a
responsive slider onto your website

04 Call the JavaScript

Call the CSS and JavaScript from the index.html.


Where you make the calls from depends on your template,
but well follow the Bootstrap example and place the CSS
call in the <head> and the JavaScript at the end of the
<body>. If youre not already calling the jQuery library, do so.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends BxSlider, Bootstrap

liders, and the many variations on the


theme that have grown along with
them, are a long-standing staple of
web designs greatest hits. Its probably
fair to say that at least half of the
websites out there have a slider or
carousel of some description, since they
have always been an eye-catching and
effective way of conveying information,
either by image, text, or a combination of both. Over the
years, though, sliders have evolved, expanding their range
from simple rolling image galleries to more complex
parallax animations.
The advent and rapid growth of responsive web
design has meant that sliders have had to adapt to
remain viable and desirable elements. One-by-one,
established slider plug-ins have redesigned themselves,
adding fluid functionality to their arsenal, some with
more success than others. There are a number of
excellent options now available, such as Nivo Slider and
ResponsiveSlides.js, but for sheer ease of installation
and breadth of options, bxSlider is well worth a look.
In this tutorial, well take a simple responsive website,
built using the Bootstrap boilerplate, and learn how to
add a bxSlider carousel to it. Well also explore the
options available for styling and customising the slider.

01 Prepare the website

We have a simple responsive website, built using


the Bootstrap boilerplate, which needs a slider. While
Bootstrap comes with its own carousel for easy
integration, we want to make full use of the options that
bxSlider affords. Open the index.html of your site and
decide where you want to place the slider. Underneath the
navigation bar is the most common position.

38 Web Design Tips, Tricks, & Fixes

001 <!-- bxSlider CSS file -->


002 <link href=css/jquery.bxslider.css
rel=stylesheet />

003
004 <!-- bxSlider Javascript file -->
005 <script src=//ajax.googleapis.com/ajax/
libs/jquery/1.10.2/jquery.min.js></script>

006 <script src=js/jquery.bxslider.min.js></


script>

05 Create the markup

The slider markup itself consists of a simple


unordered list, containing as many slide images as you
wish to include. Wrap the <ul> in a <div> of its own to help
contain all the optional elements which will be added later.
Apply some brief styling to the containing <div>.

02 Prepare your slides


bxSlider can call an adaptive height function for
slides of varying sizes (explored later) but for now well keep
our slides the same size. Also, bear in mind that since this is
going to act responsively, youll want your images to display
clearly at their largest size. Our container has a maximum
width of 1000px.

001
002
003
004
005
006
007
008
009
010
011
012
013

<div class=sliderwrap>
<ul class=bxslider>
<li><img src=img/slide1.jpg /></li>
<li><img src=img/slide2.jpg /></li>
<li><img src=img/slide3.jpg /></li>
<li><img src=img/slide4.jpg /></li>
</ul>
</div>
.sliderwrap{
float:left;
width:100%;
}

06 Fire it up

03 Grab BXSlider

Go to bxslider.com and download the zip file. Youll


see once you have opened it that bxSlider is nice and
lightweight. Place the jquery.bxslider.css and jquery.
bxslider.min.js files into their respective folders. Well look at
the plug-in folder later. Also remember to place the controls
and loader images into your image folder.

Add the code to the bottom of your <body> tag,


below the other JavaScript calls, to fire the slider up. This will
call the function .bxslider() onto the <ul> class bxslider. Note
that this parent element can have any class you like.

001
002
003
004
005

<script>
$(document).ready(function(){
$(.bxslider).bxSlider();
});
</script>

Build a responsive slider using bxSlider

<Left>
sThe bxSlider plug-in makes creating
responsive sliders as simple as can
be. A basic slider can be installed
within only a few minutes
<Below>
sUse the caption feature for
annotated slides, and customise the
elements to suit your needs

Mix it up
07 CSS conflicts

If you are using a template or boilerplate for your


site, which has its own CSS, you may find that there are
some conflicts with bxSliders CSS. The fact that the slider is
using the <ul> may be a cause of some. Here Bootstrap is
placing a margin on all of its <ul> elements that affects the
slides position. A simple CSS addition will sort this.

001 ul.bxslider{
002 margin:0;
003 }

08 Other styling

bxSlider comes with minimal styling included, such


as a box shadow, which you may want to alter or add to.
You may even want to take bxSliders CSS out of the
equation altogether and style from scratch. However, for
this quick example, well change the border colour of the
viewport to make it match our theme.

001 .bx-wrapper .bx-viewport {


002 -moz-box-shadow: 0 0 5px #ccc;
003 -webkit-box-shadow: 0 0 5px #ccc;
004 box-shadow: 0 0 5px #ccc;
005 border: solid #51a351 5px;
006 left: -5px;
007 background: #fff;
008 }

09 Change the transition

BxSlider comes with three base options for


transition. The default, as youve seen, is set as horizontal,

Why not try mixing the


individual steps of this
tutorial? For example, try
multiple slideshows,
with different content.

but there are also options for vertical and fade. Set your
transition option, as well as the sliders transition speed (set
to 500 by default), by declaring them as follows:

001 <script>
002 $(document).ready(function(){
003 $('.bxslider').bxSlider({
004
mode: 'fade',
005 speed: 2000
006 });
007 });
008 </script>

10 Add captions

Adding caption: true to the function will display the


title tag of each image in a semi-transparent bar. bxSlider
keeps the font small in order to accommodate for smaller
width viewports, but a media query will help if you want
larger width labels to have larger fonts. We can also have
the labels use our base font.

011
012
013
014
015
016
017

</script>
@media screen and (min-width: 769px) {
.bx-wrapper .bx-caption span {
font-family: 'Open Sans', sans-serif;
font-size:22px;
}
}

11 Adaptive height function

Lizard"/></li>

If you are dealing with a selection of images at


differing heights, bxSlider can call on an adaptiveHeight
function to create an eased animation between height
changes. The effect is cool, but be aware that this will cause
the content below the slider to move up and down
accordingly, which you may not want.

002
003 <script>
004 $(document).ready(function(){
005 $('.bxslider').bxSlider({
006
mode: 'fade',
007 speed: 2000,
008 captions: true
009 });
010 });

001 <script>
002 $(document).ready(function(){
003 $('.bxslider').bxSlider({
004
adaptiveHeight: true,
005
mode: 'fade'
006 });
007 });
008 </script>

001 <li><img src="img/slide1.jpg" title="Blue

Web Design Tips, Tricks, & Fixes 39

003 <a data-slide-index=1 href=><img

12 Thumbnail navigation

You can use thumbnail paging with bxSlider, which


can give you more of a gallery feel. However, this method
may not be so impressive at smaller screen sizes, so
consider carefully. To implement, add the HTML and script
below, plus a small bit of extra styling in the CSS.

001 <div id=bx-pager>


002 <a data-slide-index=0 href=><img
src=img/thumbs/thumb1.jpg /></a>

src=img/thumbs/thumb2.jpg /></a>
004 <a data-slide-index=2 href=><img
src=img/thumbs/thumb3.jpg /></a>
005 <a data-slide-index=3 href=><img
src=img/thumbs/thumb4.jpg /></a>
006 </div>

007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024

<script>
$(document).ready(function(){
$(.bxslider).bxSlider({
pagerCustom: #bx-pager
});
});
</script>
#bx-pager {
text-align: center;
margin-top: -30px;
float: left;
width: 100%;
}
#bx-pager img{
padding:5px;
}

13 Ticker tape slider

Responsive carousels
Three values are required to create a basic
responsive carousel; slideWidth, maxSlides and
minSlides. SlideWidth sets the maximum width of
each slide in the carousel. If this value is not set,

You can use the ticker function to display a rolling


series of images. These slides can be whatever size you
wish, but keeping them the same will produce a
smoother ticker. Use minSlides and maxSlides to determine
how many images will be visible in the tape at any one
time. The higher the speed value, the lower the speed of
the run.

then each slide will display at 100% of the container.


The carousel can adjust how many slides it displays
at once, depending on screen width, and minSlides
gives it a break point to follow before slide width is
adjusted rather than slide amount. MaxSlides gives
a guide for the larger width adjustments.
To lock the number of visible slides set identical
min and max values. Use moveSlides to control the
amount of slides the carousel shifts by. StartSlide
determines which slide to open with.
Mode:vertical sets a vertical carousel. See Steps 19
and 20 for code examples.

Full width
Remember that bxSlider is
responsive, and 100% can
mean bigger as well as
smaller. Make sure there are
max-widths in place for
full-width sliders on
larger screens.

40 Web Design Tips, Tricks, & Fixes

001 <ul class="bxslider">


002
<li><img src="img/ticker/ticker1.jpg"
/></li>

003

<li><img src="img/ticker/ticker2.jpg"

14 Callback API

JavaScript callback functions can be added by


using the onSliderLoad and onSlideAfter declarations. The
following example demonstrates two simple alerts; one
once the slider itself has loaded, and the other once each
individual slide has loaded. However, you can place any
fancy JavaScript function in those places to create your
own special callback functions if you wish.

001 <script>
002 $(document).ready(function(){
003 $('.bxslider').bxSlider({
004
onSliderLoad: function(){
005
alert('The slider is ready to go.
Click OK right now!');
},
onSlideAfter: function(){
alert('One slide down. Click OK to
see the next one!');
009
}
010 });
011 });
012 </script>

006
007
008

013

15 Easing alternatives

The first of the optional files in the bxSlider plug-ins


folder can be used to increase the number of easing
options available. Place the file in your script folder and
choose between around 30 various Quad, Bounce, Elastic,
Circ, and Quart ranges, and some others. False the useCSS
declaration to deactivate the default easing.

16 Custom text controls

If you want to give the slideshow a little extra


feature, then why not try taking the previous and next
selectors out of the slider <div> and placing them in a <div>
of their own. Then apply some customisation to each
selector ID by choosing the text you wish to use.

/></li>

004

<li><img src="img/ticker/ticker3.jpg"

/></li>

005

<li><img src="img/ticker/ticker4.jpg"

/></li>

006

<li><img src="img/ticker/ticker5.jpg"

/></li>

007 </ul>
008
009 <script>
010 $(document).ready(function(){
011 $('.bxslider').bxSlider({
012
minSlides: 4,
013
maxSlides: 4,
014
slideWidth: 362,
015
slideMargin: 10,
016
ticker: true,
017
speed: 6000
018 });
019 });
020 </script>

001 <div class="controls">


002
<h3>View Our Slides</h3>
003
<p><span id="slider-prev"></span> |
<span id="slider-next"></span></p>
</div>

004
005
006
007
008
009
010
011
012
013
014
015
016
017
019
020

.controls {
width: 200px;
margin: auto;
text-align: center;
}
<script>
$(document).ready(function(){
$('.bxslider').bxSlider({
nextSelector: '#slider-next',
prevSelector: '#slider-prev',
nextText: 'Onward ',
prevText: ' Go back'
});

Build a responsive slider using bxSlider

021 });
022 </script>
023

17 Custom image controls

If you would prefer to make your new controls a


little more visual, then heres how you can replace the
selector text with an image. Simply remove the text from
next and previous and give the a link classes background
images. Youll need fixed widths, but keep them small and
mobile screens wont be an issue.

001 <div class=controls>


002
<h3>View Our Slides</h3>
003
<p><span id=slider-prev></span><span
id=slider-next></span></p>
004 </div>

005
006 .bx-prev{
007 width:100px;
008 height:100px;
009 background:url(img/butterfly-left.png)
no-repeat;
010 background-size:cover;
011 float:left;
012 }
013 .bx-next {
014 width:100px;
015 height:100px;
016 background:url(img/butterfly-right.png)
no-repeat;
017 background-size:cover;
018 float:left;
019 }

020
021 <script>
022 $(document).ready(function(){
023 $(.bxslider).bxSlider({
024
nextSelector: #slider-next,
025
prevSelector: #slider-prev,
026
nextText: ,
027
prevText:
028 });
029 });
030 </script>

18 Multiple slideshows

Though it may often be a little too busy for most


sites, there is an option to include more than one slider on
the same page. These sliders can have different settings
and controls. Note the inclusion of autoControls, which will
display handy Pause and Play icons below the sliders.

001 <ul id="slider1">


002
<li><img src="img/slide1.jpg" /></li>
003
<li><img src="img/slide2.jpg" /></

007
008

<li><img src="img/slide1.jpg" /></li>


<li><img src="img/slide2.jpg" /></

li>

009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031

<li><img src="img/slide3.jpg" /></li>


</ul>
<script>
$(document).ready(function(){
$('#slider1').bxSlider({
mode: 'fade',
auto: true,
autoControls: true,
pause: 2000
});
});
</script>
<script>
$(document).ready(function(){
$('#slider2').bxSlider({
auto: true,
autoControls: true,
pause: 3000,
slideMargin: 20
});
});
</script>

19 Standard carousel

The carousel function of bxSlider uses <div>s rather


than a list, with values set for the image elements in those
<div>s. The carousel will either adjust the number of visible
slides, or the width of those slides, at smaller screen widths.

001 <div class="slider1">


002 <div class="slide"><img src="img/slide1.
jpg" title="Blue Lizard"/></div>
003
<div class="slide"><img src="img/
slide2.jpg" title="Pretty Flower"/></div>
004
<div class="slide"><img src="img/
slide3.jpg" title="Blue Butterfly"/></div>
005
<div class="slide"><img src="img/
slide4.jpg" title="Red Crane"/></div>
006
<div class="slide"><img src="img/
slide5.jpg" title="Fly Up Close"/></div>
007 </div>

008
009
010
011
012
013
014
015
016
017
018

<script>
$(document).ready(function(){
$('.slider1').bxSlider({
slideWidth: 320,
minSlides: 2,
maxSlides: 3,
slideMargin: 10
});
});
</script>

li>

004
<li><img src="img/slide3.jpg" /></li>
005 </ul>
006 <ul id="slider2">

20 Vertical carousel

Vertical carousels can be handy if you would prefer


to use the carousel function but keep each slide at its

maximum possible size on smaller screen widths. Calling


the mode:vertical value will ensure the slides ease upwards
rather than sideways. All other values can still be applied,
but maxSlides is not required.

001
002
003
004
005
006
007
008
009
010
011

<script>
$(document).ready(function(){
$('.slider1').bxSlider({
mode: 'vertical',
slideWidth: 600,
minSlides: 2,
slideMargin: 10
});
});
</script>

21 Using video

The second of bxSliders plug-in files is used to


place responsive videos into the slider. As with the easing
plug-in, place the jquery.fitvids.js into your script folder, and
call it after your library, but before the bxSlider script. Create
a mix of video and image slides, or simply use the plug-in to
create a single responsive video.

22 Reload slider

A cool function with bxSlider is the option to


change the nature of the slider by reloading it with new
elements. Passing settings objects through the
reloadslider() call allows you to swap the settings, or even
call extra slides, when a reload link is clicked. The following
example changes the settings on reload.

001 <div class="sliderwrap">


002
<ul class="bxslider">
003
<li><img src="img/slide1.jpg"
title="Blue Lizard"/></li>
<li><img src="img/slide6.jpg"
title="Pretty Flower"/></li>
005 </ul>
006 </div>
007
<h2><a href="" id="reloadslider">RELOAD SETTINGS</a></h2>

004

008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024

<script>
var slider = $('.bxslider').bxSlider({
mode: 'horizontal'
});
$('#reload-slider').click(function(e){
e.preventDefault();
slider.reloadSlider({
mode: 'fade',
auto: true,
pause: 1000,
speed: 500
});
});
</script>

Web Design Tips, Tricks, & Fixes 41

Code a
stunning
mobile app
with Ionic
Build feature-rich HTML or mobile
apps using the new Ionic framework,
offering both style and substance

01 Install Ionic

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

Ionic runs on Node.js, so you will need to install


this before you proceed. Once installed, open a Terminal
or Command Prompt window to install Ionic globally
using the Node Package Manager. You may also choose
to install the PhoneGap / Cordova command line tools at
this stage, once again as global installations using the
g flag.

001 > npm install -g ionic


002 > npm install -g cordova

tools | tech | trends Node.js, Ionic Framework, PhoneGap / Cordova

m
<Above>
sThe Ionic framework is built for
simplicity, speed, aesthetics and
great user interaction and experience
on the mobile level. The library is
open source and contributions are
widely appreciated by the
community. Get involved and help
shape the framework as
you use it

obile apps are everywhere in the


modern world, and as creative
professionals we tend to get a lot of
requests in from clients to build them.
Thankfully there are a number of libraries
and frameworks already out there that
can help us to create them but we are
going to inject something new into our
next application project.
We are going to explore the new Ionic
framework, an open source project that helps you create
hybrid mobile applications using HTML5 and Angular.js.
Optimised for speed, Ionic behaves well with all the latest
mobile devices and is modelled from popular native
development SDKs, so if youve built a native app for iOS
or Android, this should be a cinch for you.
In this tutorial we are going to take a look at installing
the library and using it in conjunction with PhoneGap to
create new mobile application builds from the command
line. We will also take a look at how to implement a few of
the many CSS elements to create an aesthetically
pleasing user interface that can be updated, manipulated
and revised to suit your needs.

CSS elements create an aesthetically


pleasing user interface that can be
updated, manipulated and revised
42 Web Design Tips, Tricks, & Fixes

02 Starter applications

Ionic is able to generate a starter application


skeleton for you with ease. Using Terminal inside your
selected directory location, simply run the command to
generate a new application as shown in the code
snippet below. In this case we will also select a starting
template that has a dynamic sliding menu section. You
can optionally choose to create a blank template or one
with tabbed navigation elements, its up to you.

001 > ionic start killerApplication sideMenu

03 Generated structure

The Ionic command line script generates a new


application for you in the requested directory location.
The directory structure is designed to match a typical
Cordova/PhoneGap 3 structure to incorporate the same
elements and to build mobile apps using the service. A
Gulpfile is also present to help minify and concatenate
files for deployment.

04 Add a platform

To use the existing code base/application


structure as a PhoneGap mobile application you will
need to add a platform entry for each platform you wish
to generate a build for. This is easily managed through

Code a stunning mobile app with Ionic

<Left>
sThe Ionic command line script generates a
new application for you in the requested
directory location
<Above>
sTo use the existing code base/application
structure as a PhoneGap mobile application you
will need to add a platform entry for each
platform you wish to generate a build for

Built for
Angular.js

the command line and Ionic closely emulates the official


PhoneGap CLI when dealing with this.

001 > ionic platform add ios android

05 Simple build generation

As Ionic is based upon the Cordova framework


and integrates nicely with the CLI tools available, we can
easily generate a build of our application and run it on
an installed emulator applicable to that platform via the
command line. Here we can build the iOS app and run it
on the local emulator.

001 > ionic build ios


002 > ionic emulate ios

06 CSS components

The Ionic framework offers much more than a


method to build PhoneGap-based mobile applications. It
comes with a detailed and impressive CSS framework
that can be added in to any web application, although
the majority of elements have been tailored to work
with mobile applications by default. Simply import the
stylesheet and use the framework for layout styling.

07 Mobile header elements

Ionic handles the common mobile layout


elements in a very similar way to existing libraries or
frameworks you may have used. Here we are simply
adding a new header element to the page and assigning
it one of the default template colours using a specific
class reference applied directly to the HTML.

The Ionic framework has


been built to work seamlessly
with Angular.js to create
dynamic applications. If you
havent yet discovered
Angular.js check it out at
angularjs.org.

001 <div class=bar bar-header bar-balanced>


002 <h1 class=title>Killer Application</h1>
003 </div>

08 Footer and tabbed menus

Adding a footer element is exactly the same at


the header with a small adjustment to the class name. In
this example we have added a tabbed menu interface to
the bottom of the mobile layout, complete with icons for
visual display. All of this can be customised and tweaked
to suit your requirements.

Working with the Cordova/


PhoneGap connections
Ionic has been built to interact beautifully with
the Cordova / PhoneGap platform and the local
command line interface tools available since
version 3 of the respective libraries. This can
be seen in the directory structure generated
by each new application and how simple it is to

001 <div class=tabs tabs-icon-only>


002 <a class=tab-item>
003
<i class=icon ion-home></i>
004 </a>
005 <a class=tab-item>
006
<i class=icon ion-gear-a></i>
007 </a>
008 </div>

build and prepare versions of the application for


each platform as requested, as well as to run and
emulate the generated build on each platform.
For any developers trying out Ionic who
currently use the PhoneGap tooling, some of the
command line tooling may differ ever so slightly
from what you are used to. For example, you have
to declare a specific platform name when running
the build command in Ionic, whereas vanilla

09 Icons included

Ionic comes with its own icon library built in.


These have been designed specifically for this library
and contain pretty much everything you should need

PhoneGap CLI tooling allows you to run a


generic build command that will create a build
for all platforms.

Web Design Tips, Tricks, & Fixes 43

<Far left>
s)FSFXFBSFVTJOHBOJOTUBMMFE
emulator to view a representation of
the iOS app were building, as
outlined in Step 5
<Left>
s*OLFFQJOHXJUIQPQVMBSNPCJMF
layouts a footer element is created.
This is populated with a set of icons
UPDMFBSMZEFOPUF)PNFBOE4FUUJOHT

as standard. It is also available as a standalone font pack


for use in any application and can be installed locally or
referenced by the provided CDN. Visit ionicons.com to
find out more.

001 <ion-content class=has-header ng002


003
004
005
006
007

controller=appController>
<ion-refresher pulling-text=Pull to
refresh... on-refresh=refreshList()>
</ion-refresher>
<ion-list>
<ion-item ng-repeat=item in items>
</ion-item>
</ion-list>
</ion-content>

12 Angular controller

10 JavaScript API

As part of the HTML interface, Ionic contains a


detailed and fairly extensive JavaScript API to help you
extend the Angular.js implementation to use some of
the built-in user interface elements. These can help you
to create feature-rich layouts, including loading displays,
dynamic lists and modal windows. All functions and
optional configuration items are available on the
documentation site: ionicframework.com/docs

11 Dynamic list creation

In this code sample we create a scrollable


content area, which contains a list element item, all of
which have ion- tag prefixes. The list will be populated by
data from our appController code, included from the
Angular.js module. An on-refresh handler is added to run
a specific function when the list is dragged to refresh on
the device.

44 Web Design Tips, Tricks, & Fixes

To manipulate and manage data on the list


element we now need to inform Angular.js of the
controller and set the relevant controls to manage the
interaction. Here we define the controller and set the
refreshList method details, which will be run once the list
is refreshed. To complete the interaction we broadcast a
refreshComplete command.

001 angular.module(killerApp, [ionic])


002 .controller(appController,
function($scope, $http) {
$scope.items = [1,2,3];
$scope.refreshList = function() {
$http.get(/new-items).success
(function(newItems) {
006
$scope.items = newItems;
007
//Stop the ion-refresher from spinning
008
$scope.$broadcast
(scroll.refreshComplete);

003
004
005

Help is at hand
While still a young framework,
Ionic has a number of great
resources from which to
learn. They even have an
online book, which is
definitely worth checking out.
Find it at ionicframework.
com/docs.

009
});
010 };
011 });

13 Angularify your application

We now need to inform the application that it is


an Angular app and which controller it should be using.
To do so we reference the Ionic bundle JavaScript
file (which includes Angular) and amend the body tag
to set the Angular attribute to match the name of
our controller.

001 <script src=js/ionic.bundle.js></script>


002 </head>
003 <body ng-app=killerApp>

14 Local development testing

As with most HTML applications, the local


development phase is crucial and testing on a specific

Code a stunning mobile app with Ionic

server is highly desired. To help with developing your


mobile application you can run a local server using
Python if you have it installed, or use Adobe Brackets to
run a live preview on a specific port, which will update
after any code or style changes.

Code library

A closer look
Lets dig a little deeper into some of the available features
and functions on offer through the Ionic framework
You can obtain platform
and device information
through the onReady
function if you have the
Cordova device plugin installed

15 Device testing

As our mobile application will be using the


Cordova/PhoneGap library, we can now start to use
more of the CLI tooling available. Here we can run a
build of our current application directly onto a
connected Android device for on-device testing. This, of
course, assumes that the correct permissions are
set on the device to allow this.

001 > cordova run android


002

16 Community support

The Ionic framework has attracted a big


following, even from a very early stage in its life. The
online documentation is especially valuable and of great
help, but if you ever need the personal touch when it
comes to requests, help and ideas, the community are
at hand to assist you on the official Ionic forums: forum.
ionicframework.com.

001 ionic.Platform.ready(function(){
002 var thisDevice = ionic.Platform.device();
003 var model = thisDevice.model,
004
platform = thisDevice.platform,
005
version = thisDevice.version;
006 console.log(ionic.Platform.isCordova());
007 console.log(ionic.Platform.isIPad());
008 console.log(ionic.Platform.isIOS());
009 console.log(ionic.Platform.isAndroid());
010 });
001 document.getElementById(exitButton).onclick =

With the platform object


exposed, you can call a
custom function in order to
process data and exit the
application gracefully

Making use of Angular.js


you can implement the
state provider and UI
router to manage
navigational states

exitApplication;

002
003 function exitApplication() {
004 ionic.Platform.exitApp();
005 }
001 var app = angular.module(myApp, [ionic]);
002 app.config(function($stateProvider) {
003 $stateProvider
004 .state(index,
005 {
006
url: /,
007
templateUrl: welcome.html
008 })
009 .state(about,
010 {
011
url: /about,
012
templateUrl: about.html
013 });
014 });

17 Inspiration and existing apps

The Ionic framework has already been used for a


number of mobile applications currently available on
various mobile markets. Explore the examples on the
site and see what others have done with the framework.
Some of the projects are available to view on GitHub too,
so you can dig into the code. ionicframework.com/
examples/showcase.

Web Design Tips, Tricks, & Fixes 45

Create
animated
buttons
with CSS3
Using the transform property,
well create some cool-looking
3D buttons that will add that
extra polish to your site

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends HTML, CSS

01 Get ahead

After creating a new HTML5 file, open it up within


your favourite text editor and add in the head section.
We will need to add in the link to our CSS file and make
sure we have good browser support for our HTML5 and
CSS3 so we will use Modernizr. Head over to
modernizr.com and grab the latest version.

001 <!DOCTYPE html>


002 <html lang=en class=no-js>
003 <head>
004 <meta charset=UTF-8 />
005 <meta http-equiv=X-UA-Compatible
006
007
008
009
010

content=IE=edge,chrome=1>
<meta name=viewport content=
width=device-width, initial-scale=1.0>
<title>Creative 3D Buttons</title>
<link rel=stylesheet type=
text/css href=css/main.css />
<script src=js/modernizr.custom.js>
</script>
</head>

02 Content body

With the head section done, we can now move


on and start adding some HTML within the <body>
section. As always, we are going to add in a container
element with a class name of container to allow us to
centre things easily. Then, we will use the <section>
element and give it a class name of 3D-buttons.

001 <body>
002 <div class=container>

46 Web Design Tips, Tricks, & Fixes

003
004
005
006
007

<section class=3d-buttons>
</section>
</div><!-- END container -->
</body>
</html>

03 Button HTML

Within the <section> element, we add in a


paragraph tag with a class name of btn_perspective,
which well target later using the perspective CSS3
attribute. We then add in our first button, which will
contain several class names that well target later on.

001
002
003
004
005
006
007
008
009
010

<body>
<div class=container>
<section class=3d-buttons>
<p class=btn_perspective>
<button class=btn btn-3d btn-3da>Submit
</button>
</p>
</section>
</div><!-- END container
</body>
</html>

04 Finish up the HTML

We already have the HTML for one button, but


we want to create another three so we can really test out
our 3D skills. So, copy and paste the paragraph tag we
created in the last step and make sure the last class
name is changed accordingly.

001 <body>

SS3 transform has been doing the


rounds for quite some time.
Browsers like Firefox, Chrome and
Opera have full support for CSS3 2D
and 3D transform techniques. Along
with transform, we also have another
cool property called perspective.
The perspective property defines the intensity of the
3D effect. This is because it defines how far the object is
away from the user. So, a lower value will result in a
more intensive 3D effect than a higher value. But one
thing we need to remember is, when defining the
perspective property for an element, it is the child
elements that get the perspective view, not the element
itself. When the transform and perspective properties
are combined, you can create some great-looking 3D
animations on a number of different elements.
In this tutorial were going to work with the transform
and perspective properties and their values to create
four cool-looking 3D buttons that you can use on your
webpages. Each button will be slightly different in its
perspective, which will allow us to really get to know
how the perspective property works. So, open up your
favourite text editor and lets get started!

002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021

<div class=container>
<section class=3d-buttons>
<h2>Creative 3D buttons</h2>
<p class=btn_perspective>
<button class=btn btn-3d btn-3da>Submit
</button>
</p>
<p class=btn_perspective>
<button class=btn btn-3d btn-3db>Submit
</button>
</p>
<br />
<p class=btn_perspective>
<button class=btn btn-3d btn-3dc>Submit
</button>
</p>
<p class=btn_perspective>
<button class=btn btn-3d btn-3dd>Submit
</button>
</p>
</section>
</div><!-- END container -->
</body>
</html>

05 The CSS

Its important to start every project with some


default CSS that we often add to an external CSS reset
file. For this tutorial well just keep it simple and go ahead
and add some CSS to the top of a file called main.css,
and with this CSS we are making sure our box model is
set properly to every single element that uses the box
model (css-tricks.com/box-sizing).

Create animated buttons with CSS3

< Top left>


s8JUIPVS)5.-OPXDPNQMFUF XF
BSFTFFJOHUIFCVUUPOTBOEUIJOHT
BSFOJDFMZDFOUSFE
< Top right>
s/PXUIBUTPNFTUZMJOHJTBEEFEUP
PVSCVUUPOT XFDBOTFFUIJOHT
TUBSUJOHUPtakFTIBQF
< Bottom left>
s*OUIJTTUFQ XFBEEFEUIF
QFSTQFDUJWFWBMVFTCVUBMTPTFUUIF
EJTQMBZWBMVFUPJOMJOFCMPDL.
< Bottom right>
s/PXXFDBOTFFPVSCVUUPOT
MPPLJOHNPSFQPMJTIFE XJUIUIBUMBU
MPPLXFXFSFBGUFS

001
002
003
004
005
006
007
008
009
010
011
012

*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body, html {
font-size: 100%;
padding: 0;
margin: 0;
height: 100%;
}

06 Body styles

Next we need to add in some default styles for


our body and links. This is not vital but makes things nice
and simple as it keeps it all in one place. The background
colour is going to be a nice light blue and were going to
stick to using Arial as our main font.

001
002
003
004
005
006
007
008
009
010
011
012
013

body {
font-family: Arial, sans-serif;
background: #0e83cd;
}
a {
color: #888;
text-decoration: none;
}
a:hover,
a:active {
color: #333;
}

07 Contain it

09 Button styles

Now we need to create a container that wraps


around our content. Were going to set the height of the
outer container to 100% and position it relative. Then
we use a child combinator selector (>) to target our
<section> element and centre everything within and
add some other default styles.

The idea is to give our buttons that flat look,


which can easily be achieved by not adding any rounded
corners or drop shadows. We will make sure they are
fairly large so we can clearly see the 3D effect once we
are finished and, as they are buttons, lets not forget to
add the cursor: pointer at the bottom of our rule.

001
002
003
004
005
006
007
008
009
010

001 /* General button styles */


002 .btn {
003 border: none;
004 position: relative;
005 background: none;
006 padding: 28px 90px;
007 display: inline-block;
008 text-transform: uppercase;
009 margin: 15px 30px;
010 color: inherit;
011 letter-spacing: 2px;
012 font-size: .9em;
013 outline: none;
014 -moz-transition: all 0.4s;
015 -webkit-transition: all 0.4s;
016 transition: all 0.4s;
017 cursor: pointer;
018 }

.container {
height: 100%;
position: relative;
}
.container > section {
margin: 0 auto;
padding: 6em 3em;
text-align: center;
color: #fff;
}

08 Heading styles

What would a page be without a page title? Lets


add some styles to that. Were going to keep it simple
and make the text white with a 20px margin all around.
Then we align it centre and make it uppercase. All nice
and straightforward so lets move on to the buttons.

001 h2 {
002 color: #fff;
003 margin: 20px;
004 text-align: center;
005 text-transform: uppercase;
006 }
007

10 Button pseudo

Using the :after pseudo-element, we will make


sure any content behind our button is taken out by using
the content: property. We then ensure that everything is
positioned absolute so we can then set its index to -1,
with everything else behind.

Web Design Tips, Tricks, & Fixes 47

< Top left>


sOur first 3D button is done and we
have a nice prominent 3D effect
< Top right>
sThe second button is now done,
only this time we have rotated this
at the bottom
< Bottom left>
sNow the third button is done, with
this one rotated on the X axis
< Bottom right>
sThis is our final button the 3D
effect isnt as prominent here but it
looks good nevertheless

Adding
media queries
Use media queries at
breakpoints in your design
for approximations of when
the design changes by
different devices,
reformatting
the content accordingly.

Transform property
There are several different
transform functions, each
applying a different visual effect.
Be sure to experiment
and find your
favourites.
001 .btn:after {
002 content: ;
003 position: absolute;
004 z-index: -1;
005 -webkit-transition: all 0.4s;
006 -moz-transition: all 0.4s;
007 transition: all 0.4s;
008 }

11 Button perspective

The perspective: CSS property gives an


element a 3D-space by affecting the distance between
the Z plane and the user. The strength of the effect is
determined by the value. The smaller the value, the
closer you get from the Z plane and the more
impressive the visual effect is. The greater the value, the
more subtle the effect will be.

001 /* Button */
002 .btn_perspective {
003 -webkit-perspective: 800px;
004 -moz-perspective: 800px;
005 perspective: 800px;
006 display: inline-block;
007 }

48 Web Design Tips, Tricks, & Fixes

12 Button 3D

14 Hover state

The transform-style property will determine


whether that element is in 3D space or is flattened. Of
course we want it to be in 3D, so we add the preserve3d value to bring the button into 3D space and not be
flattened (which is the default).

Now this is where the magic happens. We are


going to rotate the whole button when we hover over it,
making the rotate quite big so that we can see the 3D
effect more prominently. To do that we add a -45
degree tilt to the button on the x plane.

001
002
003
004
005
006
007
008
009

001 .btn-3da:hover {
002 transform: rotateX(-45deg);
003 }

.btn-3d {
display: block;
background: #5cbcf6;
outline: 1px solid transparent;
transform-style: preserve-3d;
}
.btn-3d:active {
background: #55b7f3;
}

13 3D animation

Here we add our first 3D animation to our first


button (a) and set some other styles. The transformorigin property sets the point of origin of a transform;
the first value is the horizontal position, the second is the
vertical position. We rotate the x plane to 90 degrees.

001 .btn-3da:after {
002 width: 100%;
003 height: 42%;
004 left: 0;
005 top: -40%;
006 background: #53a6d7;
007 transform-origin: 0% 100%;
008 transform: rotateX(90deg);
010 }

15 Button B

The next button (button B) will be using similar


styles as our first button, but with a few changes. First
we make sure that the button is positioned 100% to the
top and origin values both set to 0%. Then we just need
to rotate this -90 degrees.

001 /* Button 3db */


002 .btn-3db:after {
003 width: 100%;
004 height: 40%;
005 left: 0;
006 top: 100%;
007 background: #53a6d7;
008 transform-origin: 0% 0%;
009 transform: rotateX(-90deg);
010 }

16 Hover state B

Now we have our first button animated in all its


glory, we just need to use the same property on this
one. To give us some variation, we will not make this as

Create animated buttons with CSS3

007
008
009
010
011
012
013
014
015
016 }

background: #53a6d7;
-webkit-transform-origin: 100% 0%;
-webkit-transform: rotateY(-90deg);
-moz-transform-origin: 100% 0%;
-moz-transform: rotateY(-90deg);
-ms-transform-origin: 100% 0%;
-ms-transform: rotateY(-90deg);
transform-origin: 100% 0%;
transform: rotateY(-90deg);

18 C button animation

Lets animate button C by using the same rule as


before. This time we need to make sure we are rotating
the Y axis. Again, well change things up a little by
making this 3D effect less prominent by giving it a
smaller value of 25 degrees.

001 .btn-3dc:hover {
002 transform: rotateY(25deg);
003 }

19 Finish up

< Above>
sAll done! Now we can see how things look when we
resize the browser window

Mobile first
Even with a small project like
this, you should always think
about making it responsive and
suitable for mobile
like how we made our
buttons larger.
deep as the first button, so we give the rotateX property
a value of just 35 degrees.

001 .btn-3db:hover {
002 transform: rotateX(35deg);
003 }

21 Responsiveness

Its only natural that before we wrap this little


project up, we think about making the buttons
responsive. By default the buttons will fall underneath
each other when the browser window is resized, but we
want to think about making these buttons slightly
bigger so that they are easily clickable using your finger.
So, all we do is increase the font size as shown.

001 @media screen and (max-width:480px) {


002 .container {
003
font-size: 1.2em;
004 }
005 }

22 Final thoughts

Creating 3D buttons can really help enhance


your web projects. Hopefully this tutorial has
demonstrated that not only is it a fun thing to do, but
its fairly straightforward to implement as well. A
challenge for you now would be to try this technique to
other elements on your page, such as vertical menus
it can look really great on logos, too.

Now we are almost done with our 3D buttons.


All we need to do is add some styles to our last button.
Again, theres only some small adjustments in this rule,
but we are staying on the Y axis at a positive 90
degrees and our origin top and left is 0%.

001 /* Button 3dd */


002 .btn-3dd:after {
003 width: 20%;
004 height: 100%;
005 left: 100%;
006 top: 0;
007 background: #53a6d7;
008 -webkit-transform-origin: 0% 0%;
009 -webkit-transform: rotateY(90deg);
010 -moz-transform-origin: 0% 0%;
011 -moz-transform: rotateY(90deg);
012 -ms-transform-origin: 0% 0%;
013 -ms-transform: rotateY(90deg);
014 transform-origin: 0% 0%;
015 transform: rotateY(90deg);
016 }

Understanding
transform-origin
As indicated in this tutorial, the transform-origin
property can take up to two space-separated
keywords or length values for a 2D transform
and up to three values for a 3D transform.

.square {
transform-origin: top left;
transform: rotate(360deg);
}

17 Button C styles

Here we continue on to our next button and add


some slightly different styles. The thing to note here is
that the origin is now set to 100% at the top and we are
rotating the Y axis, not the X. Also, to make sure we are
targeting all browsers, weve added the browser prefixes
to this rule (which you should do for the previous rules)

001 /* Button 3dc */


002 .btn-3dc:after {
003 width: 20%;
004 height: 100%;
005 left: -20%;
006 top: 0;

20 Button D animation

Finally we will add in our animation for Button D.


We are going to rotate this one on the Y axis and again
we will make this a lot less prominent than before by
lowering the value to 15 degrees. Weve also added in
our browser prefixes too.

Using the code above on a 100 x 100px box, with


the transform applied to a transition using a
click event, a box would swing around 360
degrees once clicked on. By default, the origin of
a transform is 50% 50%, which is the centre of
any given element. Changing the origin to top
left (as above) causes the element to use the

001 .btn-3dd:hover {
002 -webkit-transform: rotateY(-15deg);
003 -moz-transform: rotateY(-15deg);
004 -ms-transform: rotateY(-15deg);
005 transform: rotateY(-15deg);
006 }
007

top-left corner of the element as a rotation point.


The first value is the horizontal position, the
second value is the vertical position and the
third value represents the position on the Z axis.
The third value will only work if you are using
3D transforms and it cannot be a percentage.

Web Design Tips, Tricks, & Fixes 49

Add angled
page designs
with CSS
and jQuery
Create a striking page design with
CSS3 by using an angled background
and adding images

while the background is slightly sloping. Add this article tag


inside the <div> in the previous step.

001 <article class=content>


002 </article>

05 Heading for the article

With the <div> tag at an angle and the article at the


opposite angle we can add content inside of the article tag.
Weve added a very simple heading three tag so that there
is a heading for this section as appropriate. Later some
styles can be created for these so that they are designed.

001 <h3>Closing Remarks</h3>

06 Add a paragraph

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends jQuery, Anystretch, CSS3, HTML5, Dreamweaver

ince the advent of browsers beginning


to wholesale support many of the
newer HTML5 and CSS3 features, we
are waiting to see these used to create
new layout techniques. Most websites
still look pretty much the same and the
CSS rotation property is only used to
perhaps slightly angle text or create a
slight animation on rollover. As we can
rotate any section of a webpage, we thought it would be a
great idea to create angled sections of the background,
resulting in some striking designs.
The only problem is that it causes the inner content
such as text and headings to also be rotated with it. The
solution to this is to rotate the inner section back in the
opposite direction so that the text remains easy to read and
legible. So, if we rotate the background five degrees left, we
then rotate the inner content five degrees right in order to
keep the content level. Of course you may prefer to have
angled text, in which case just miss the appropriate CSS
rule out! Were also using a jQuery plug-in called Anystretch,
which stretches images over the rotated background
section but doesnt rotate them, so provides a simple
background image solution.

01 Start the project

From the resource files, copy the Start Folder to


your desktop. Open the file index.html in a code editor,
such as Dreamweaver. In the head section add the two
lines of code shown below. These add the two main
stylesheets that you will create. The first is Eric Meyers CSS
Reset, which reduces browser inconsistencies. The next is
the styles for the page.

50 Web Design Tips, Tricks, & Fixes

Finally for this section well add a paragraph of text.


Add your own text to this or just use placeholder text as we
have done. Save the page, as we are finished here for the
time being. Now switch over to the style.css document as
we are going to create the styles that will power this design.

001 <p>text content goes here </p>

07 Wrap the angles

001 <link rel=stylesheet type=text/css


href=css/reset.css />

We have wrapped all of the angled <div> tags with


a wrapping container, hence the class name given to this of
container. Here were adding the CSS style for this to the
end of the style.css document. Weve added a padding top
to this, but otherwise its all standard stuff.

002 <link rel=stylesheet type=text/css


href=css/style.css />

02 Add the font

The second CSS library already has the style set up


for the heading of the site, since we are mainly concerned
with creating the angled sections, well be adding that in
the style.css file. Now add another CSS link, this time to the
font we are using from Googles font library.

001 <link href=http://fonts.googleapis.com/


css?family=Armata rel=stylesheet type=text/
css>

03 Set up the content

Most of the content has now been added to the


page, but well add one section of content to familiarise
ourselves with the structure. Scroll to the bottom of the
page and add the following code just before the closing
section tag. This will be the section that will be rotated at an
angle, which explains the name weve applied to the class.

001 <div class=angle>


002 </div>

04 Opposite angle

Because the last <div> is at an angle, all the content


inside will also be at an angle. Another container needs to
be created that will be rotated at the opposite angle to the
first. This will give the desired effect of having straight text

001 .container{
002 display: block;
003 width: 100%;
004 overflow: hidden;
005 padding-top: 50px;
006 }

08 A wider margin

The next class that we add might look a little


strange. Were widening the margin by 50px off the left and
right of the screen thats to accommodate the rotated
edges so that we dont see the side of the background
colour. We also define where the rotation point will be: the
left-hand edge in the centre.

001 .angle{
002 margin: 0 -50px;
003 -webkit-transform-origin: left center;
004 -moz-transform-origin: left center;
005 -o-transform-origin: left center;
006 -ms-transform-origin: left center;
007 transform-origin: left center;
008 }

09 Odd angles

We set up a rule now that makes use of CSS3s


ability to change all the odd children of the angle class. So
the first, third and fifth will have a five degree rotation.
Notice that they also have a margin top of -200px. At

Add angled designs with CSS and jQuery

< Above>
s(JWJOHUIFABOHMFDMBTTBXJEFSNBSHJOUIBOUIFQBHFDBVTFTUIFDPOUFOUUPMPXPGUIF
FEHFTPGUIFQBHF CVUUIJTXJMMIJEFUIFFEHFTPGUIFBOHMFMBUFSPO

< Above>
s"EEJOHUIFBDUVBMSPUBUJPOUPUIFFMFNFOUTDBVTFTUIFNUPEJTBQQFBSCFDBVTFXFIBWFB
NBSHJOUPQPGQY TPFBDIBOHMFPWFSMBQT

< Above>
s8FDBOTFFBMMUIFBOHMFDMBTTFTXPSLJOHBUUIFJSEJGFSFOUBOHMFTCVUUIFZIBWFOUCFFO
QSPQFSMZGPSNBUUFEZFU TPUIFZSFTUJMMPWFSMBQQJOHBOEDBOUCFSFBE
< Bottom right>
s'JOBMMZXFIBWFFBDITFDUJPOUBLJOHVQUIFJSEFTJHOBUFETQBDFXJUIJOUIFEFTJHOnOPXXF
DBODPODFOUSBUFPOTUZMJOHUIFJOOFSUFYUPGFBDITFDUJPO

present that will cause these not to be seen, however once


weve added the even children, this will compensate the
bottom angle of those.

001
002
003
004
005
006
007
008
009
010

.angle:nth-child(odd){
border-top: 16px solid #091e3d;
background-color: #666;
-webkit-transform: rotate(5deg);
-moz-transform: rotate(5deg);
-o-transform: rotate(5deg);
-ms-transform: rotate(5deg);
transform: rotate(5deg);
margin-top: -200px;
}

10 Going even

Now we add the code for the even children of the


angle class. We start by adding a background image, set to
repeat a light-coloured angled pattern. Then we rotate in
the opposite direction to the previous sections, so -5 pixels.
Viewing the page doesnt show us a lot, so lets fix that.

001 .angle:nth-child(even){
002 background: #ccc url(../img/shattered.png)
repeat;

003
004
005
006
007
008
009

-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-o-transform: rotate(-5deg);
-ms-transform: rotate(-5deg);
transform: rotate(-5deg);
}

11 Move it down

One of the main problems at the moment is that


the margin top of -200px is really for clearing the angle of
previous sections, so the first section doesnt need this. We
can fix that by overriding the margin-top of the first child of
the angle class and that will help at this stage.

001 .angle:first-child{
002 margin-top: 0px;
003 }

12 Hold the content

Inside each of the angles we have a <div> tag with a


class of content. We add a zero top and bottom margin, but
an auto left and right margin that will centre the content.
Then we add a decent top and bottom padding.

001
002
003
004
005

.content{
margin: 0 auto;
padding: 130px 100px 250px 100px;
}

13 Style the headings

Each section within the angle has a heading three


tag. Weve chosen to style this up with the increased font
size and display it as an inline block. We add a little bit more
padding to the edges and a smaller padding to the top and
bottom. The typeface has also been changed to Armata,
that we added earlier on in Step 2.

001 .content h3{


002 font-size: 60px;
003 position: relative;
004 display: inline-block;
005 padding: 10px 30px 8px 30px;
006 height: 80px;
007 line-height: 80px;
008 margin-bottom: 20px;
009 font-family: Armata, sans-serif;
010 }

Web Design Tips, Tricks, & Fixes 51

<Left>
sThe headings are now in place and the
formatting is starting to come together
on the design with decent space around
the headings
<Below>
Here we see the finished site with the
angles fully working and the background
images all in place without being rotated

<Above>
sThe odd children (one, three and five) of the angle are rotated so
that the text is now straight and is beginning to take shape

14 Concise paragraphs

We now turn our attention to the paragraph. Here


we make it a little smaller with a width of 75% or a
max-width of 500px. We also increase the font size and
with it the line height. Looking at the page in a web browser
now gives us a radically different view.

001 .content p{
002 width: 75%;
003 max-width: 500px;
004 margin: 0 auto;
005 font-size: 18px;
006 line-height: 24px;
007 padding-top: 10px;
008 }
009

52 Web Design Tips, Tricks, & Fixes

<Above>
sBoth the odd and even inner content to the angled sections are
rotated in the opposite direction to the angle so the text is straight

15 Easier to read

A problem that we have is that the text is also


at an angle with the <div> tag and that isnt the easiest
to read. So well rotate the inner container with the
content class back the opposite way with a rotation
of -5 degrees on the odd children. Save and test in
the browser you should see a big difference at
this stage.

001
002
003
004
005
006
007

.angle:nth-child(odd) .content{
-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-o-transform: rotate(-5deg);
-ms-transform: rotate(-5deg);
transform: rotate(-5deg);
color: #fff;

Adding
media queries
Use media queries at
breakpoints in your design for
approximations of when the
design changes by different
devices, reformatting
the content accordingly.

008 text-shadow: 2px 2px 2px rgba(0,0,0,0.7);


009 }

16 Opposites attract

As in the previous step, we rotate the content <div>

Add angled designs with CSS and jQuery

tag back the opposite direction of the angle class. This time
though, we are targeting the even children and the content
is rotated five degrees to compensate. Save this now and
when you view in the browser, youll see we have the basis
for our tutorial covered.

001
002
003
004
005
006
007

.angle:nth-child(even) .content{
-webkit-transform: rotate(5deg);
-moz-transform: rotate(5deg);
-o-transform: rotate(5deg);
-ms-transform: rotate(5deg);
transform: rotate(5deg);
}

17 Reduce the heading

Were going to reduce the size of the headings now


for smaller screens. So, once the page is viewed on a tablet
or lower, the heading is reduced down to 40px. Save this
file, refresh the page and try changing the width of the
browser to see the change in action.

001
002
003
004
005

@media screen and (max-width: 767px) {


.content h3{
font-size: 40px;
}
}

18 Even smaller changes

Now we add our final CSS for when the display


screen is less than 400px. We increase the width of the
margins to 95% for the paragraph and reduce the padding
left and right on the content class. Save this, refresh your
browser and return back to the HTML document while we
make some final changes.

001
002
003
004
005
006
007
008
009
010

@media screen and (max-width: 400px) {


.content p{
width: 95%;
}
.angle:nth-child(odd) .content,
.angle:nth-child(even) .content{
padding-left:60px;
padding-right:60px;
}
}

19 Add a background image

Back in the HTML document find the first angle


class in the document; it will have the heading Full Throttle
after it. Change the class to have the addition of full then
add the data attribute. This will tell the jQuery plug-in which
image to use as the background image for this section.

001 class=angle full data-stretch=img/speed.


jpg

Angles and the extra width


In Step 8 we made the width of the angle section extend an extra 50px off the left and right side of the screen to
avoid seeing the side edges of the angled section. In the image the webpage is the white area while the blue
sections down the left and right are the extended regions off the left and right-hand side of the screen. If we
imagine our angle <div> is the light blue section in the middle then we can see the edges of it on the left and
right clearly, and this stops the design looking like angled bands and more like rotated rectangles. However
the outer edge to this has been taken to the extents of the 50px extra on each side and the sides cannot be seen
in the white section of the page and therefore complete the illusion.

background image to fit but will not rotate the image


despite the angle of the class.

001 class=angle full data-stretch=img/


lightning. jpg

002 class=angle full data-stretch=img/eco.


jpg

003

21 Link to the libraries

Before the closing body tag in the HTML


document, add the following two lines of code these link
to the jQuery library and to the Anystretch jQuery plug-in.
More information on the plug-in can be found at github.
com/danmillar/jquery-anystretch. Another advantage of
using this is that it keeps the image centred vertically.

001 <script src=js/lib/jquery-1.7.1.min.


js></ 002 script>
003 <script src=js/jquery.anystretch.min.

Any stretch of
the imagination
We are using the Anystretch
plug-in to enhance our design
as we cannot easily get the
same result with CSS alone.
This way we are able to keep
our markup clean
and simple.

few lines below the previous code snippet. This tells the
Anystretch plug-in to stretch the image to fill the
background on the full class which were added in Steps 19
and 20. Save the document now and refresh the browser
to see the finished tutorial in action, complete with
background images and angled design.

js></ script>

20 A couple more images

Similar to the previous step, find the third and fifth


angle class and change accordingly to each of the lines
shown below. The Anystretch jQuery plug-in will stretch the

004

22 Activate the images

Finally, to complete this project, add the following

001 <script>
002 $(.full).anystretch();
003 </script>
004

Web Design Tips, Tricks, & Fixes 53

Make a
responsive
menu for a
retina screen
Make sure your menu is responsive
and ready for retina screens by using
custom fonts instead of images

012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends HTML, CSS

esigning the navigation element for


your website in this age of mobile
devices and differing screen widths
can be a real pain in the mouse.
Balancing usability with aesthetic
credibility is the challenge that
responsive design now presents to all
designers. There are a wide variety of
solutions and techniques available to
solve the issue, from fixed drop-down
menus to side-sliding variations. The problem is that, while
these solutions all solve the problem of maintaining
functionality at different screen widths, they can
sometimes lacking visual impact.
These days its nice to see a menu that remembers to
look good, too. Longer, scrolling pages are reducing the
number of menu elements some sites need to present,
and those sites, in particular, can afford to be a little more
adventurous with how they deliver the navigation. So its
time to give the responsive menu a much needed paint job
and raise it above the purely functional. This tutorial will
demonstrate how to create a responsive menu that is
both eminently usable and visually striking. And to keep it
retina friendly, well be using a custom-made icon font
rather than images.

01 Choose your icons

In order to create the custom icon font, well be


using the excellent IcoMoon tools at icomoon.io/app/#/
select. You have a choice here of creating your own icons
as vector images to import into the font creator or choose
from the extensive selection already available. Well choose
ours from the library as they have exactly what we need.

54 Web Design Tips, Tricks, & Fixes

02 Create a custom font

Having selected your icons, click the bottom Font


button. On the next page, you can amend the icons tags
and corresponding letters used to call each icon. Click on
Download and you will get access to the folder with its font
files and stylesheet. Place the font folder into your root.

03 Add the custom font

Copy the custom CSS that came with your


download and paste it into the top of your site stylesheet.
Ensure that the path for the font files is still correct. You may
also want to make sure that each icon is assigned to the
font family individually by name rather than with the default
blanket icon class.

001 @font-face {
002 font-family: 'icomoon';
003 src: url('../fonts/icomoon.eot');
004 src: url('../fonts/icomoon.eot?#iefix')
format('embedded-opentype'),
url('../fonts/icomoon.woff')
format('woff'),
006
url('../fonts/icomoon.ttf')
format('truetype')
007 url('../fonts/icomoon.svg#icomoon')
format('svg');
008 font-weight: normal;
009 font-style: normal;
010 }
011 .icon-happy,.icon-loved,.icon-uniF4F1,.
icon-skull,.icon-uniF539,.icon-rocket,.iconmenu {

005

font-family: 'icomoon';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
.icon-happy:before {content: "\e603";}
.icon-loved:before {content: "\e61c";}
.icon-uniF4F1:before {content: "\e613";}
.icon-skull:before {content: "\e607";}
.icon-uniF539:before {content: "\e612";}
.icon-rocket:before {content: "\e600";}

04 Base CSS

Before we start putting all the menu HTML into the


index.html, we just need to prepare some base CSS for the
project. Start by creating a container, main <div> and a
header into which the site title will be placed, making sure
to call the stylesheet in the head. Use the following CSS to
style the wrapping elements.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017

.main,
.container > header {
width: 100%;
margin: 0 auto;
padding: 16px 32px;
}
.main {
max-width: 1300px;
min-height: 640px;
}
header {
text-align: center;
font-size: 16px;
background: rgba(255,255,255,0.6);
}
header h1 {
font-family: 'Hammersmith One', sansserif;
018
font-size: 75px;
019
line-height: 0.8;
020
margin: 0;
021
font-weight: 300;
022
color:#3f3782;
023 }
024 .movie {
025
font-size:102px;
026
color:#e63c2b;
027 }

05 Menu HTML

Create your menu <ul> using span classes for both


the icon and the text label. The span class fon will create
the styling for the custom icons, while the class item is
used for the labels. The icon name, as declared in the
IcoMoon CSS calls each custom icon to its element.

Make a responsive menu for a retina screen

< Above>
sAs more and more screen sizes flood into the market, it pays to keep your responsive elements as simple as possible to avoid meeting a width they
cant deal with. Having three breakpoints, roughly representing PC, tablet and smartphone, is a tried and trusted approach to this problem

Menu love
Navigation menus can be
overlooked as necessary
items, requiring little thought.
This is a shame since they are
often the part of your site that
is engaged with most.
Love them and make
them shine.

001 <div class="container">


002 <header>
003 <h1>LONDON<br><span class="movie">MOVIE</
span><br>REVIEWS</h1>
004 </header>
005 <div class="main">
006 <nav id="menu" class="nav">
007 <ul>
008 <li><a href="#"><span class="fon icohappy"></span><span class="item">COMEDY</
span></a></li>
009 <li><a href="#"><span class="fon icoloved"></span><span class="item">ROMANCE</
span></a></li>
010 <li><a href="#"><span class="fon icouniF4F1"></span><span class="item">ACTION</

span></a></li>

011 <li><a href="#"><span class="fon icoskull"></span><span class="item">HORROR</


span></a></li>
012 <li><a href="#"><span class="fon icouniF539"></span><span class="item">DRAMA</
span></a></li>
013 <li><a href="#"><span class="fon icorocket"></span><span class="item">SCI-FI</
span></a></li>
014 </ul>
015 </nav>
016 </div>
017 </div>

06 Non media query CSS

There are some styles that apply to all three of the


upcoming menu sizes, setting some navigation styles and
using a WebKit trick to eliminate blue bordering on click.
Here we also colour our navigation element backgrounds,
using the nth property to alternate the colour between the
site theme red and blue.

07 Large screen query

Our first media query targets screens of 800px


or more. The layout is a horizontal strip of rounded
squares, with each element at a percentage for maximum
flexibility. Icon and label are stacked one above the other.
We set the position and size of our .fon icon, while the

.item label begins opaque, to be animated later in


the process

08 First transition step

Now we can arrange hover effects. The first step


will see the .item label fade in on hover, with a .5s transition,
while the .fon icons change their colour to match the
appearing label. Both elements are now black from white.

09 Second transition step

The black characters dont look bad against the


coloured elements, but what would really make the
highlighted icon stand out is having no background at all.
So, well add a transition that fades out the background on
hover, leaving just the icon and visible label. We can also
close that first media query here.

001 .nav li:hover {


002 background:none;
003 -moz-transition: background .5s;
004 -o-transition: background .5s;
005 -ms-transition: background .5s;
006 transition: background .5s;
007 }
008 }

10 Add the background

Well finish off the site properly with an appropriate


background image. In keeping with the London

Web Design Tips, Tricks, & Fixes 55

<Clockwise from top left>


s"OZPOFXIPUBLFTUIF-POEPO
6OEFSHSPVOESFHVMBSMZXJMM
QSPCBCMZSFDPHOJTFXIFSFUIJT
EFTJHOJTHPJOH
s3BUIFSUIBOIBWJOHUPBEBQUUIF
MBZPVUQFSTDSFFOXJEUI XFMMVTF
FBDICSFBLQPJOUBTBOPQQPSUVOJUZ
GPSSFEFTJHOJOH
s)BWJOHGFXFSNFOVFMFNFOUT
NFBOTUIBUXFDBOBWPJEIBWJOHUP
IJEFUIFN*OTUFBEXFDBOBSSBOHF
UIFNXJUIJOPVSTDSFFOTQBDF

Underground theme, were using for our London Movie


site, were going with a white tile motif, and making sure the
Google font is used throughout.

Explore your options


*DP.PPOJTOUUIFPOMZTJUF
GPSDVTUPNJDPOGPOUT$IFDLPVU
Fontello.com Fontastic.me
PSPictonic.co

001 body {
002 font-family: 'Hammersmith One', sansserif;

003 background: url(../img/bg.jpg);


004 }
005 margin: 20px;
006
border: 1px solid red; /* take off
asap

*/

007 }
008

11 Second media query

Our second media query targets screen widths


between 520px and 799px, which covers tablet screens
and some larger smartphones at landscape. Our layout will
differ considerably at this size. Two rows of three blocks, no
margins and no rounded corners. Our fonts are also
considerably smaller and sit side by side.

12 Tablet animation

In a reversal of our hover effects for large screens,


this time were going to change the background colour of
the li element to black and give the white font and icon an
off-white shade and a very slight fade. With that, all of the
tablet styles are completed, so make sure you remember
to close the media query here.

001 .nav li:hover {


002 background:rgba(0,0,0,0.9);
003 -moz-transition: background .5s;

56 Web Design Tips, Tricks, & Fixes

004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020

-o-transition: background .5s;


-ms-transition: background .5s;
transition: background .5s;
}
.nav a:hover .fon,
.nav a:active .fon,
.nav a:active .item,
.nav a:hover .item{
color:rgba(259,259,259,0.9);
-webkit-transition: color .5s;
-moz-transition: color .5s;
-o-transition: color .5s;
-ms-transition: color .5s;
transition: color .5s;
}
}

13 Target smaller screens

The final media query sets the layout for screens


smaller than 520px, essentially targeting smartphones.
Since we have so few menu elements, we can be bold and
eschew the trend for JavaScript drop-down menus. Well
also lose the corners and have six circular elements, with
icon and label fitting together snugly.

14 Header and fonts

The font sizes for the site title need to be reduced


for this screen size, using iPhone as a guide. We can also
allow for a nice, large font size for our icon and we need to
make sure that fumbling fingers are able to click on the
elements. Notice that the icons remain crisp at all sizes
thats the benefit of our custom font.

15 Background changes

Since the order of the elements has now changed,


well need to do some tweaking to the background colours.
At the moment we have one column of red and one
column of blue, which looks a little bit odd. In order to keep
the alternating pattern, we need to arrange a one, two, two,
one repeat of the colours.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018

.nav li:nth-child(6n+1) {
background: rgb(230, 60, 43);
}
.nav li:nth-child(6n+2) {
background: rgb(63, 55, 130);
}
.nav li:nth-child(6n+3) {
background: rgb(63, 55, 130);
}
.nav li:nth-child(6n+4) {
background: rgb(230, 60, 43);
}
.nav li:nth-child(6n+5) {
background: rgb(230, 60, 43);
}
.nav li:nth-child(6n+6) {
background: rgb(63, 55, 130);
}

Make a responsive menu for a retina screen

Code library

The HTML in full


In this tutorial weve covered all of the CSS in detail, so now we take the opportunity to get a
closer look at the inner workings of the HTML

Improve fonts in Chrome

IE will use its most up-to-date


rendering engine. Chrome=1
activates the Chrome Frame
plug-in for early IE versions

For many years, Firefox was the browser of choice


for web developers. It was quick, it had great tools,
and it rendered sites well. While it seems that
recently Google Chrome has usurped Firefox,
Chrome is certainly not flawless.
One area where developers have continually
struggled to get Chrome to behave is in the
rendering @font-face fonts. They tend to render
with a jagged appearance, and sometimes alter

Here we tell the browser that


the site is mobile ready and
make sure the user cant
scale the content, which
they dont need to do
Make sure you remember
to include the Google
Font declaration in the
head of your index.html

the site layout as a whole. The popularity of Font


Squirrel has made this a major sticking point for
Chrome, but there is a solution in the form of a
simple media query:

001 @media screen and (-webkit-mindevice-pixel-ratio:0) {


002 @font-face {
003
font-family:
icomoon; src:
url(../
fonts/icomoon.svg#icomoon)
format(svg);
004 };
005 }

Though it may seem


span-heavy, the span is one
of the most underappreciated HTML
elements. Use them freely!

This has the effect of forcing Chrome to use the


SVG font format, which it is able to render
perfectly. Problem solved!

16 Small screen transitions

This time, well still fade out the background of the


clicked element, but change the icon and label to the same
colour as the background it sits on. The CSS used here
fades the background of all li elements on hover, but the
colour changes need to be targeted individually. Here we
are handling all of the red elements.

17 Last transition

And finally, were handling the blue elements. Close


the media query and were done. We now have three very
distinct layouts between the three breakpoints. Your menu
at small-screen width doesnt have to be a small version of
the large screen layout. You have the opportunity to give
each menu its own appropriate design.

001
002
003
004
005

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=edge,chrome=1">
006 <meta name="viewport" content="width=device-width,
initial-scale=1.0, user-scalable=no">
007
<title>London Movie Reviews</title>
008
<link rel="stylesheet" type="text/css" href="css/style.
css" />
009
<link href='http://fonts.googleapis.com/
css?family=Hammersmith+One' rel='stylesheet' type='text/css'>
010 </head>
011 <body>
012
<div class="container">
013
<header>
014 <h1>LONDON<br><span class="movie">MOVIE</
span><br>REVIEWS</
015 h1>
016
</header>
017
<div class="main">
018
<nav class="nav">
019
<ul>
020 <li><a href="#"><span class="fon icon-happy"></span><span
class="item">COMEDY</span></a></li>
021
<li><a href="#"><span class="fon icon-loved"></
span><span class="item">ROMANCE</span></a></li>
022 <li><a href="#"><span class="fon icon-uniF4F1"></span><span
class="item">ACTION</span></a></li>
023 <li><a href="#"><span class="fon icon-skull"></span><span
class="item">HORROR</span></a></li>
024 <li><a href="#"><span class="fon icon-uniF539"></span><span
class="item">DRAMA</span></a></li>
025 <li><a href="#"><span class="fon icon-rocket"></span><span
class="item">SCI-FI</span></a></li>
026 $(window).scroll(function(){
027 </ul>
028 </nav>
029 </div>
030 </div>
031 </body>
032 </html>

Your menu doesnt have to be a small


version of the large screen layout. You can
give each menu its own design

Web Design Tips, Tricks, & Fixes 57

Create
data-driven
interfaces with
KnockoutJS
Make a modular app that has real-time
UI updates, multiple views, and is easily
maintainable and extendable

001 define([libs/knockout, libs/jquery],


function (ko) {
use strict;
return function () {
/* filmViewModel properties and
methods */
005
};
006 });

002
003
004

04 Observables in VM

The crux of a Knockout view model are


observables. Each property that we want to track we
have to wrap in either ko.observableArray(), if we want
to track an array, or ko.observable() for other types. We
can pass a default value as an argument and well see
the relationship between this and our view.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends JavaScript, HTML5, jQuery, KnockoutJS, RequireJS

001 var self = this;


002 self.films = ko.observableArray(
); //list of films

003 self.currentFilm = ko.observable({}); /


/current film in view

004 self.related = ko.observableArray(); /


/related films

s JavaScript developers have had


it pretty good recently thanks to a
proliferation of excellent MV*
frameworks. One of the most
popular is Knockout, the brainchild
of Bristol-based Steve Sanderson.
Knockout utilises the MVVM
pattern (Model-View-ViewModel)
which sounds scarier than it is. It
starts with a Model, which is your data; this is rendered in
a view, your HTML; the View Model is the glue that binds
data to your view, controlling what is seen and when.
MVVM encourages web developers to think more
about how they structure their JS applications. This
separation allows one of Knockouts best features:
automatic UI refresh; when data in your View Model
changes the UI updates accordingly.
Were going to dive into how to use the Knockout
library with RequireJS to build a web interface. Well build
an app that will list your films, get information about them
from the Rotten Tomatoes API, and let you know where
they physically are. Well also let users update the data
from the view itself with inline editing.

01 Require and Bootstrap

Knockout is compatible with AMD (Asynchronous


Module Definition) loaders like RequireJS. Were using
RequireJS to manage dependencies and load Knockout
files. RequireJS looks for the data-main attribute and will
load js/app.js, which well create in a bit. Were also using
Bootstrap for some basic styles.

001 <head>

58 Web Design Tips, Tricks, & Fixes

005 self.query = ko.observable(); /


/search box value

002 <meta charset=UTF-8>


003 <title>Film Finder</title>
004 <link rel=stylesheet href=//netdna.
bootstrapcdn.com/bootstrap/3.0.2/css/
bootstrap.min.css>
005 <link rel=stylesheet href=styles/
aestheti.css>
006 <script src=js/libs/require.js datamain=js/app></script>
007 </head>

02 Require dependencies

To load our dependencies we give RequireJS an


array of all the files (as strings) well need for our app to
run. DOMReady is a lightweight RequireJS plug-in to
make sure that our callback is only run when the DOM is
ready. filmViewModel is where our view model for the
film logic will reside.

001 //app.js
002 require([libs/knockout, filmViewModel,
libs/jquery, libs/
domReady!],
function(ko, filmViewModel) {
003 use strict;
004 });

03 Film View Model

Our app will contain three view models, one for


the film section, one for the dashboard section, and one
master view model which will wrap the document. You
cannot apply bindings multiple times to the same
element so we need a master one which will allow both
view models to access every single part of the page.

05 Get data

Here is a basic PHP service which returns a list of


JSON encoded films from a database. Each film has
three properties: name, owner, and location. Once this
data has been retrieved we pass the data to the films
observable which will automatically update the view
(once weve initialised it).

001
002
003
004
005
006

//filmViewModel.js
self.getFilms = function () {
return $.getJSON(api.php);
};
//app.js
$.when(filmViewModel.getFilms(
)).then(function (films) {
007 filmViewModel.films(films);
008 });

06 Master View Model

To instantiate our film view model we call new


filmViewModel(). Well then make this view model a child
(property) of the master view model. Well also add an
observable called view, which will dictate whether to
show the film or dashboard. Were also making a
method that will switch between the different views, by
reading the href attribute.

001 var filmViewModel = new filmViewModel();


002 var appViewModel = {
003 filmViewModel: filmViewModel,
004 view: ko.observable(home),
005 switchView: function (model, event) {

Create data-driven interfaces with KnockoutJS

<Above>
s5IF,OPDLPVUTJUFBOElearn.knockoutjs.comBSFJOWBMVBCMFSFTPVSDFTGPSMFBSOJOHBCPVUUIF
GSBNFXPSLJOBOFOHBHJOHBOEJOUFSBDUJWFXBZ

006
007
008
009
010 };

$(event.target).parent().siblings().
removeClass(active);
event.target.parentNode.classList.
add(active);
appViewModel.view(event.target.
getAttribute(href).split(#)[1]);
}

07 Apply bindings

To kickstart Knockout we have to marry together


the HTML (view) with the view model. We do this by
calling ko.applyBindings(), which takes a view model and
an optional element to bind the view model to, if no
element is provided then itll bind to the entire
document. Remember, you cant have multiple view
models on the same element.

<Above>
s3FRVJSFJSMPBETTDSJQUTJOQBSBMMFMSBUIFSUIBOXBJUJOHGPSFBDIJOEJWJEVBMTDSJQU
UPMPBECFGPSFHFUUJOHBOPUIFS

009
</li>
010 </ul>
011 </div>

09 Page structure

Well split the page into two sections, one that


will use the filmViewModel and the second section that
will use the dashboardViewModel. We can specify which
View Model to use in a section with the with binding.
This means that we dont have to specify filmViewModel.
xyz every time as it specifies the scope for us.

001 <section data-bind=with: filmViewModel>


002 <!-- next step -->
003 </section>
004 <section data-bind=with:

001 ko.applyBindings(appViewModel);

So weve called applyBindings, but what are


these bindings? We havent defined any yet! Knockout
works by reading the contents of a data attribute called
data-bind. As of Knockout 3.0 there are 22 types of
bindings. In our navigation were using one, click,
followed by the name of the method to call.

001 <div class=page-header>


002 <h1>Film Finder</h1>
003 <ul class=nav nav-pills>
004
<li class=active>
005
<a href=#home data-bind=
006
007
008

click: switchView>Find a film</a>


</li>
<li>
<a href=#dashboard data-bind=
click: switchView>Dashboard</a>

control data-bind=value: query, valueUpdate:


afterkeydown placeholder=Search for a
film&hellip;>
002 <button class=btn btn-default
type=button>Find!</button>

003

12 Filter film array

Next we introduce some new concepts. A


computed observable is one that watches one or more
observables and returns something new when they
change. Ours fires when the query observable changes.
Knockout has a few utility methods, one being
arrayFilter; it takes two arguments, the array and a
matcher function that returns true or false.

dashboardViewModel>

005 </section>

08 Our view

001 <input type=search class=form-

001 self.filteredFilms = ko.computed(function()


{

10 $root and $parent

Although weve just set our scope to


filmViewModel we can still access properties of the
master VM (view model) by using the $root keyword or
the $parent keyword. We also have to invoke all
observables to read their value (eg view() instead of just
view). Theyre observables, no longer just properties, so
they are to be treated as functions.

001 <div data-bind=visible: $root.view(


) === home>
002 </div>

11 Update values

We have a list of films, so now were just going to


add a search box that will filter the list in real-time as the
person types. This time were using a value binding, this
is what is shown in the search box, and valueUpdate is
which event to fire the update on the model.

002
003

var search = self.query().toLowerCase();


return ko.utils.arrayFilter(self.
films(), function(film) {
004
return search.length ? film.title.
toLowerCase().
indexOf(search) >= 0 : film.
title;
005
});
006 }, self);

13 For each binding

To display our list of filtered films well use


another Knockout binding type, for each. This loops
through an array and for each item in that array itll
show the markup contained beneath. For each film well
add a click handler to get the film data from the Rotten
Tomatoes API.

001 <div class=row>


002 <div class=film-list-container data-

Web Design Tips, Tricks, & Fixes 59

<Above>
s4XJUDIJOHCFUXFFO
WJFXT ZPVDBO
TVCTDSJCFUPXIFO
BOPCTFSWBCMFT
WBMVFDIBOHFT
NBOVBMMZCZVTJOH
UIFTVCTDSJCF
NFUIPE

bind=foreach:

003 filteredFilms>
004
<a href=# data-bind=text: title,

004
005

click: $parent.getFilmData></a>

005 </div>
006 </div>

14 Update observables

Knockout doesnt require jQuery but weve


included it in this coding step to handle AJAX
requests. When you click on one of the film titles, it
passes the observable first and the event second. Were
also using jQuerys extend() to merge the two objects
so that the film data is merged with the owner and
location data. We then pass this object to the
currentFilm observable.

001 self.getFilmData = function (film) {


002 $.getJSON(http://api.rottentomatoes.com/

003
004
005
006

api/public/v1.0/movies.json?q= + film.
title + &apikey=YOUR_API_KEY&callback=?
, function (data) {
var movie = $.extend
(film, data.movies[0]);
self.currentFilm( movie );
});
};

15 Using observable values

Our data is in our view model but were not doing


anything with it in the view yet. To display that data we
can use the text binding. One downside of using a data
binding library like Knockout is the amount of extra
markup thats sometimes needed, although Knockouts
solution to this is virtual elements.

001 <section class=film-data>


002 <div class=page-header>
003
<h2>

60 Web Design Tips, Tricks, & Fixes

006
007
008

<span data-bind=text: currentFilm().


title></span>&nbsp;
<small data-bind=text: currentFilm(
).year></small>
</h2>
</div>
</section>

16 Attribute bindings

Were using the if binding to conditionally show


the poster. We can set HTML attributes using the attr
binding. This takes an object with the name of the
attribute to set and what to set it to. Rotten Tomatoes
sends us a posters object with URIs pointing to different
sizes well use the profile size one.

001 <div data-bind=if: currentFilm().posters>


002 <img data-bind=attr: { src: currentFilm(
).posters.profile } src= alt=Film
poster class=img-rounded>
003 </div>

004

17 Virtual elements

We mentioned Knockouts virtual elements to


cut down on excess markup a little earlier on in Step 15.
These are HTML comments with a special syntax,
starting with ko. Virtual elements arent compatible with
all binding types but it can cut down on extra <div> tags.
For example, here we just want a snippet of HTML to
appear if it has a rating.

001 <!-- ko if: rating -->


002 <p>
003
Average rating:
004
<span data-bind=text: rating></span>%
005 </p>
006 <!-- /ko -->
007

18 Computed observables

The Rotten Tomatoes API returns an average


critic rating and an average viewer rating. Here well
write another computed observable which will add both
the ratings together and divide them by two in order to
get the average for both of them. The second parameter
for a computed observable is optional but sets the value
for this.

001 self.rating = ko.computed(function () {


002 if (this.currentFilm() && this.
currentFilm().ratings) {
return (this.currentFilm().ratings.
audience_score + this.
currentFilm().
ratings.critics_score) / 2;
004 }
005 }, self);

003

006

19 Custom binding

Weve made our own computed observables,


next were going to step it up a notch and write our own
custom bindings. This means that we can do more than
data-bind=click: x, we could do data-bind=edit: x. Were
going to do just that and create an inline editor, credit to
Craig Cavalier for this solution.

001 //based on http://jsfiddle.net/craigcav/


MxU2V/

002 ko.bindingHandlers.liveEditor = {
003 //next step, init and update
004 };

20 Init and update

All a custom binding needs to know is what to do


with a property when its initialised and what to do when
a value is updated. The valueAccessor function reads
what the current value is and were also extending the
observable with a new property, the editor. On update, it

Create data-driven interfaces with KnockoutJS

then updates the CSS class that has been applied to


the element.

001 init: function (element, valueAccessor) {


002 var observable = valueAccessor();
003
observable.extend({ liveEditor: this });
004 },
005 update: function (element, valueAccessor) {
006 var observable = valueAccessor();
007 ko.bindingHandlers.css.update
(element, function () {

008
return { editing: observable.editing };
009 });
010 }

001 <input class=edit data-bind=value:


currentFilm().location, enterKey: currentFilm().
location.stopEditing, selectAndFocus:
currentFilm().location.editing, event: { blur:
currentFilm(). location.stopEditing }>

24 Create Dashboard VM

So far weve only concentrated on the film view


model, so lets turn our attention onto the Dashboard
view. Thisll show statistics on our film collection, like
ownership and average overall ratings. Similar to our
other view model, well define it and let RequireJS know
what other libraries this depends on. Well be using
Chart.js (www.chartjs.org) to visualise it.

004

<canvas id=possession-chart height=


250 width=250></canvas>
005 <h3>Average Rating:</h3>
006 </div>

27 Add Dashboard VM

The final step is instantiating and adding our third


view model to the master view model. This makes all of
its properties and methods available to the view. Further
on down this file weve already called applyBindings so
now itll include the dashboard view model bindings as
well. You could go on and on like this, keeping view
models separated.

001 var dashboardViewModel = new

21 Extend observables

In order to extend an observable we need to


register it with ko.extenders. When we click on an
editable element its replaced with an input box. All
observables that are under the liveEditor binding will
inherit these properties so we could have many bits
of text and corresponding input boxes all keeping in
sync automatically.

001 ko.extenders.liveEditor = function (target) {


002 target.editing = ko.observable(false);
003 target.edit = function () {
004
target.editing(true);
005 };
006 target.stopEditing = function () {
007
target.editing(false);
008 };
009 return target;
010 };

22 Live edit view

To use this live-editing feature we have a click


handler on the location, by calling edit it sets editing to
true. This in turn shows the input box by adding a class
of editing to the surrounding element. We then have
some simple CSS rules that hide and show the input box
depending on the mode.

001 <div data-bind=if: currentFilm().location>


002 <div data-bind=liveEditor: currentFilm(
003
004

005
006
007

).location>
<span class=view>
Location: <a href=# data-bind=
click: currentFilm().location.edit,
text: currentFilm().location()></a>
</span>
</div>
</div>

23 Editing values

The input itself displays the value of the location


observable. The editing state is started when the input
element has focus. When the Enter key is pressed or the
user clicks away (the blur event), then stopEditing is called
and this reverts it back to text with the updated value.

001 define([libs/knockout, libs/chart ,


002
003
004
005
006
007

libs/jquery], function(ko) {
use strict;
return function () {
var self = this;
/* next step */
}
});

25 Create fading binding

Jumping back to app.js, well create another


custom binding to replace the visible binding. Instead of
just appearing and disappearing, well use jQuerys
fadeIn() and fadeOut() functions to toggle between the
elements. unwrapObservable passes back the value of
an observable if it is an observable or just the plain
property if it isnt.

001 ko.bindingHandlers.fadeVisible = {
002 init: function(element, valueAccessor) {
003
var observable = valueAccessor();
004
$(element).toggle(ko.utils.
unwrapObservable(observable));

005
006
007
008

009
010 };

},
update: function(element, valueAccessor) {
var observable = valueAccessor();
ko.utils.unwrapObservable(observable) ?
$(element).fadeIn() : $(element).
fadeOut();
}

dashboardViewModel();

002 var appViewModel = {


003 /* existing properties and methods */
004 dashboardViewModel: dashboardViewModel
005 };

28 Is Knockout a knockout?

Knockout can initially be a little overwhelming


with its confusing terminology and having to wrap
everything in special functions. However, once you
understand the implications of doing it and how to access
the values afterwards, it becomes a lot clearer. Weve seen
how powerful it is keeping dependency chains updated
instantaneously. If youve got a complex app with DOM
manipulation that could be solved by Knockout, then we
highly recommend that you give it a chance.

Knockout in the wider ecosystem


of the web
Knockout is often compared to Angular, but by itself
Knockout only deals with data binding it doesnt
try to do everything, just one thing well. Durandal
(durandaljs.com) is a framework that brings
together Knockout, Require, and jQuery to provide
a feature set more inline with what Angular offers. It
binds together these libraries and also adds a clientside router as well as a few other features on top. If
you prefer Knockouts syntax to Angulars then this
might be the technology stack for you.
Alternatively if the Knockout syntax and
mannerisms dont quite sit right with you then

26 Use fadeVisible

To use our fadeVisible binding, all we have to do


is replace visible with fadeVisible and our different
sections will fade between each other! Its still triggered
by the same condition (if the dashboard is active) but
there should now be a smooth transition between each
view. Weve also made a canvas element for the chart
as well.

you may instead be interested in the Knockout


Punches plug-in (available from github.com/mbest/
knockout.punches) which brings a double-brace
template ( {{ property }} ) and a filter syntax closer to
Angulars and Knockout 3.

001 <div data-bind=fadeVisible: $root.view(


002
003

) === dashboard>
<h2>Dashboard</h2>
<h3>Possession</h3>

Web Design Tips, Tricks, & Fixes 61

Tricks
64

Animate CSS

72

Build an online shop

78

Learn to make the most of modern website


animation tools

Make your first foray into the world of eCommerce


by setting up an online store

Scroll horizontally using jInvertScroll


Stand apart from the crowd by implementing
horizontal scrolling into your site

82

Create a scroll-triggered animation

86

Make an animated SVG header with


Snap.svg

Work with animations triggered by the users


position on the page

102

Create a scaling hover effect

104

Produce a 3D direction-aware
hover effect

108

Add reactive elements to your pages

110

Construct 3D customised cubes

112

Use overlay effects on background


video

116

Create an animated infographic


with SVG
Streamline your workflow with Bower
and Grunt
Simplify your front-end headaches

98

Manipulate the DOM with AngularJS


Use custom directives to create lightbox and
accordion UI components

82
Create scrolltriggered
animations

62 Web Design Tips, Tricks, & Fixes

Create a shake effect using


CSS3 animation

Use CSS to create a three-dimensional rotating cube


on your website

Integrate HTML5 video into your designs

Take your infographics to the next level

94

Give your site a unique twist that will make users


want to keep returning

Present your portfolio using JavaScript and CSS

Achieve crisp graphics at all resolutions

90

Add excitement
and interactivity to
your web pages

Build an HTML5 platform game


Discover the potential for easy game design with
the Quintus Game Engine

CSS animations arent only


simple to create but also take
advantage of the processing
power of todays browsers

108
Make a
shake effect
with CSS

110

116

Make a
rotating
3D cube

Build an
HTML5
game

102
Scaling
hover
effects

Web Design Tips, Tricks, & Fixes 63

ANIMATE

Make a move with this definitive


guide to the latest CSS and
JavaScript animation skills

64 Web Design Tips, Tricks, & Fixes

Animate CSS

veryone remembers the bad old days of Flash;


animations took what felt like forever to load and
splash pages were often self-indulgent code candy
that most users skipped as soon as they could.
Thankfully, the web has moved on significantly since
then, with animation almost being a standard feature
of many of todays site designs. Sometimes its subtle a
menu that sizes up slightly when you mouse over it, or a
button that throbs when you click it. Sometimes its a little more
extroverted and looks like a controlled page scroll or reveal, or a
complicated slider. Then again, sometimes its used as an experiment,
creating new kinds of user interfaces and experiences.
Whatever the application or end result, animation is a core web
skill. When JavaScript ruled the world of web design, animation used
to be much more difficult. You had to set up manual animation loops
and carefully manage the position, colour and other properties of the
objects you were moving around the viewport.
Now with CSS, animation is simpler and far more easily achieved.
You tell it exactly when you want it to start, how to stop, what to do and
it works automatically. The details are kept locked inside your browser,
and you dont have to worry about them if you dont want to.
Basic CSS animation, scripted animation, and 3D animation all work
differently. Theres some overlap, so you dont have to learn three
completely different skills, but there are differences too. To master
animation youll have to master them all the good news is that weve
made it easy for you. Read on for the details

EXPERT
INSIGHT
CSS animations are not only
simple to create and adjust
but also take advantage of
the processing power of
todays browsers. Compared
to JavaScript animations, they
transition much faster and
smoother, which enhances
the user experience. Simple
animations can be used now,
falling back to either basic
state changes or JavaScript
animations for those browsers
without the support. As these
browsers become less and
less prevalent with users, it will
make interface animations easy
to code and we will be finding
more complex and creative
ways of using these techniques.
Luke Guppy
Creative director
redweb.com

BASIC BUILDING BLOCKS


CSS animation isnt complicated. You dont need to use
JavaScript or jQuery and you dont need to be a maths
wizard but you do need to understand a few basics.
The essentials are CSS animations, CSS transitions, CSS
transforms and event management.
CSS3 animations make it possible to tween almost
any CSS property. You can either specify from and to
values, or you can split the animation up into keyframes
animation steps and set the property values for
each step. The browser does the rest, working out the
intermediate values and changing them over time.
CSS3 2D and 3D transforms are used to move,
scale, skew, stretch and otherwise throw elements all
around the viewport. Although you can animate many
properties, 2D transforms are the basic building blocks
of animations that move. 3D transforms do pretty much
the same but obviously with the addition of the third
dimension. You can spin, flip, and create perspective
effects. While theyre slightly more complicated and
difficult to achieve than 2D transforms, theyre much
better at grabbing a visitors attention.
Finally, you need to trigger and control animations.
CSS3 transitions can work with hover and click events.
But this is the one part of the process where JavaScript
or jQuery can take you further. The usual trick for
animations is to create a separate .animated class (you
can name it how you want) and use code to add it and
remove it in response to user events. Adding a class
automatically runs the animations inside it.

CSS3 Animation

CSS3 Transitions

w3schools.org has some good basic


demonstrations of each different animation
option. Visit the page to see some movement.

Make use of transitions in order to achieve some


seamless but simple on-hover and on-click
animations to engage your site visitors.

CSS3 2D Transforms CSS3 3D Transforms


Use 2D transforms to spin, grow, squash, and
expand elements. You can also use the skew
transform to warp elements as well.

3D transforms appear to move elements in and


out of the screen. But creating non-trivial 3D
effects with many elements can be a lot of work.

Web Design Tips, Tricks, & Fixes 65

WHAT MAKES A GOOD ANIMATION?


Avoid a user experience that underwhelms by ensuring that your animations inform, entertain and delight your users
veryone has seen sites that look like
the inside of someones brain in the
middle of a migraine. Its tempting
to make everything on your site
move just because you can, but
animation is a secret sauce and it
makes the most impact when its
been used thoughtfully.
First of all, dont overdo the attention
grabbers. You know those sites that put up a modal
survey or subscription dialog just when youre
about to get to the information you want? Dont do
that. Users hate anything that makes them feel like
theyre not in control of the browsing experience.
Its the same story with attention-grabbing
animations. Use them to hint to users that they
can do something they might have missed, not to
distract them from what theyre already doing.

You should also make use of animation to


highlight context and hint at navigation features.
For example, if your site uses a map, you can use
an animated sidebar to display useful location
information. The sidebar contents change all
the time, and the animation can be helpful in
reminding users that theres something new
and cool they should see. You can also animate
breadcrumbs to highlight information you want
users to see on each page, while keeping other
navigation options visible. Features that resize
automatically are a good way to pack a lot of detail
into a limited space, without sacrificing relevance.
Consider telling a story. You can do this literally
by animating a cartoon but thats more work
than most sites need. A story is a way to control
how information is revealed and good stories keep
users interested because they become curious

about what happens next. A popular styling at the


moment is the full-page scroll. The story suggests
that theres more to read. This kind of scroller
is better at keeping user interest than a menu
tree, because with a menu system there are no
surprises and users are more likely to decide to
skip some of the content.
Make it physical. You can bounce objects,
squash them, shake them and vibrate them.
The maths isnt complicated and simple physics
modelling helps make animations look convincing
by imitating mass and inertia. If your standard
animations arent physically believable, users
are going to find them more distracting than
rewarding. As an occasional special effect you can
also make an object do something believable but
surprising, for example, making an image that bobs
and floats upwards like a balloon.

EFFECTIVE ANIMATION IN THE REAL WORLD

MacPro

FiftyThree

Polygon

Apples MacPro store page demonstrates


how to use attention-grabbers without killing
interest; the main product area rotates, reveals and
spins. At the same time, the statistics by the side are
animated to draw attention to them. You can click the
product photo to go to the next page.

Todays fiftythree.com pencil site has a number


of cool animations. Theres an exploded view
that reveals features of the pencil product as you
scroll down, and a rotating photo that spins as you
scroll. Its a good example of storytelling the user
keeps scrolling to see what happens next.

Polygons Xbox 360 is a good example of


animated navigation. Not only is each sketch
animated, but the menus briefly scroll out to show
you that you can navigate to any section. Mouseover
the menu area to show all the sections at the same
time for instant go-anywhere clicking.

Apples stylish animations use the iOS 7 design


language to maintain interest and complement
the main product views

Keep scrolling to see more details. The animations


become a feature in their own right and leave the
user wanting more

Polygons menu system is only visible


when you want it but it reminds you
its there as you scroll down

BROWSER SUPPORT

Put simply, CSS3 works on all


browsers and has done for a while.
The minimum versions are:

VERSION

VERSION

VERSION

VERSION

VERSION

10.0

5.0

5.0

4.0

12.0

* CSS3 includes previous versions of CSS animation and CSS transitions.

66 Web Design Tips, Tricks, & Fixes

MOBILE
BROWSERS

Mobile browser support is good.


Only Opera Mini lacks any support,
and Chrome for Android was buggy
until version 4.0. All other platforms
support CSS3 animations with no
major issues although remember
that mobile devices dont have fast
processors, so very complex
scripted animations may
still run slowly.

Animate CSS

MAKE IT MOVE
Understand animation from the ground up with this step-by-step guide

MAKE A BOX

Well start by growing a box and


changing its colour. Make a <div> and
give it an id of #box. Add some simple
CSS to give it a width and a height, then
add couple of lines of animation code
to run an animation called animOne
over five seconds.

001
002
003
004
005
006
007
008
009
010

011
012
013
014
015
016
017
018

<!DOCTYPE html>
<html>
<head>
<style>
#box
{
width:100px;
height:100px;
background:blue;
-webkit-animation:animOne
5s; /* Chrome, Safari,
Opera */
animation:animOne 5s;
}
</style>
</head>
<body>
<div id = box></div>
</body>
</html>

2 MAKE AN ANIMATION

To define what animOne does,


add WebKit and standard @keyframe
definitions as usual, you have to
duplicate the code. from {} defines the
CSS at the start of the animation while
to {} defines the CSS at the end and
thats all you need. If youre starting
with useful default CSS, you dont even
need from {} at all.

/* For Chrome, Safari and Opera */


001 @-webkit-keyframes animOne
002 {
003 from {width:0px;
004
height:0px;
005
background:red;}
006 to {width:100px;
007
height:100px;
008
background:blue;}
009 }
/* For everything else */

001 @keyframes animOne


002 {

003
004
005
006
007
008
009

from {width:0px;
height:0px;
background:red;}
to {width:100px;
height:100px;
background:blue;}
}

Need relative or absolute


for movement */
-webkit-animation:animOne
1s; /* Chrome, Safari,
Opera */
-webkit-animation-iterationcount: 4;
-webkit-animation-direction:
alternate;
animation:animOne 1s;
animation-iteration-count: 4;
animation-direction:
alternate;

007

008
009

3 RUN IT

STEP
BY STEP

Load the page into a browser and


the animation should run on load4anim. Thats about all all there is to
know about basic animation. You can
animate most CSS. For a detailed list of
animatable properties, see oli.jp/2010/
css-animatable-properties.

010
011
012

001 #box
002 {
003 width:100px;
004 height:100px;
005 background:blue;
006 -webkit-animation:animOne

001 @-webkit-keyframes animOne


002 {
003 0% {background: red;

013 }
014
/* For Chrome, Safari and Opera */

1s; /* Chrome, Safari,


Opera */
-webkit-animation-delay: 2s;
-webkit-animation-iterationcount: 4;
-webkit-animation-direction:
alternate;
animation:animOne 1s; /*
The rest */
animation-delay: 2s;
animation-iteration-count: 4;
animation-direction:
alternate;

007
008
009
010
011
012
013
014 }
015

005

006

007

008
009

5 BREAK IT UP

MORE CONTROL

You can delay the animation


and repeat it, or even try playing it in
reverse with the animation-direction
property. Each forward or back change
counts as one iteration. Set the count to
infinite if you never want the animation
to end. The total running time is the
count multiplied by the duration.

001 #box
002 {
003 width:100px;
004 height:100px;
005 background:blue;
006 position: relative;

004

left:0px; top:0px; width:


100px; height: 100px;}
25% {background: yellow;
left:200px; top:0px; width:
0px; height: 0px;}
50% {background: blue;
left:200px; top:200px; width:
200px; height: 200px;}}
75% {background: green;
left:0px; top:200px; width:
0px; height: 0px;}
100% {background: red;
left:0px; top:0px; width:
100px; height: 100px;}
}

/*

Instead of from/to, you can define


animation stages with percentage
markers. Add as many as you like,
each sets the CSS properties for that
step. This gives you a lot more control
because you can define movement
paths and colour transformations with
as much detail as you want.

CSS vs
JavaScript
Which one is
better? What are the
differences between
them and are they really
in competition?
In official web-lore CSS
animations are always faster
than JavaScript animations. CSS
just works while JavaScript and
jQuery need custom animation
handlers and need to repeat
thirty or even sixty times a
second. So a browser always
works harder running scripted
animation code than running a
plain CSS equivalent.
Its usually a good idea to
use vanilla CSS for simpler
animations. In 2D, you can do
most of what you need with CSS,
and you only need scripting for
complicated timeline-based
effects, or for effects where you
need to manage the position and
movement of a lot of different
elements at the same time.
3D is more complicated. 3D
animations stress the browser
harder but JavaScript has some
useful features like 3D matrix
operations that just arent
possible in CSS. So, a good rule
of thumb is to see if you can
achieve what you want in CSS
first. If you cant, fallback to
JavaScript and custom code.
Either way, test your
animation on low-powered
hardware to check that it works.
You may find it runs fine on
your MacBook Pro i7, but dont
forget most users will have older,
cheaper hardware and you need
to be aware of what they can
realistically deal with.

6 RUN IT AGAIN

Save the file and load the HTML.


Youll see the square bouncing around
the screen and changing colour
like crazy. At the end, the animation
defaults to the initial properties. If you
want it to finish with different values,
use animation-fill-mode to set them.

JavaScript isnt always slower


than CSS but you should
always test animations on lowpowered hardware anyway

Web Design Tips, Tricks, & Fixes 67

FALLBACK
CODE
You dont have to limit
animation support to
newer browsers, but
fallback code does take
some extra effort
If only fallbacks werent needed.
Unfortunately, they usually are,
so you have find different ways to
work around them.
The simplest way to manage
fallbacks is to include the usual
browser-checking code using
something like Modernizr. For a
CSS-only solution you can use
Modernizr to select animationfree code using the usual .no
prefix to create fallbacks when
features arent available. You can
also check if CSS properties are
available by asking the Modernizr
JavaScript object to check and
report back to you.
A simpler but less flexible
option is a hybrid framework
like cssAnimate (cortys.de/
cssAnimate). It runs CSS
animations if a browser supports
them, but falls back to slower
jQuery effects if it doesnt. The
framework runs and selects the
correct effect automatically, so it
(mostly) just works.
The most reliable but slowest
option is to do everything in
jQuery. jQuerys animation effects
are powerful and open-ended
but theyre not very efficient. This
can cause problems with mobile
support. Because the world, its
dog and iPhone are expected to
support mobile sites now, jQuery
can be risky and youll have to
decide whether its worth taking
a chance on the performance of
your target devices. The upside
is that you can write once and
create complex effects that are
challenging with pure CSS.

EASINGS AND BEZIERS


Get ultimate control of positioning and timing with expert-level
animation easing management

1 SMOOTH MOVES

Well create a simple but non-trivial


text animation using motion control.
Make a <div> with a single letter in it
(this example uses some gratuitous
Google font code). Create an animation
called animX. To avoid duplication, we
only include the WebKit code. Copy it
and remove -webkit- to support IE.

68 Web Design Tips, Tricks, & Fixes

001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
font-size: 100px;
007 position: absolute;
008 -webkit-animation:animX 1s;
/* Chrome, Safari, Opera */
-webkit-animation-timingfunction:linear;

010
001
002
003
004

005
006
007
008
009
010
011
012
013
014

<!DOCTYPE html>
<html>
<head>
<link rel=stylesheettype=
text/css media=all href=
//fonts.googleapis.com/
css?family=Lato/>
<style>
#textX
{
left:100px;
top:100px;
font-family: Lato;
font-size: 100px;
position: absolute;
-webkit-animation:animX 1s;
/* Chrome, Safari, Opera */
}

/* Chrome, Safari, Opera */


@-webkit-keyframes animX
{
from {left:0px;
top:0px;}
to {left:100px;
top:100px;}
}
</style>
</head>
<body>
<div id = textX>X</div>
</body>
</html>

001
002
003
004
005
006
007
008
009
010
011
012
013

2 STRAIGHT LINES
cssAnimate is an interesting
hybrid fallback framework
thats worth a look. Its not
bulletproof, but it can solve
some common problems

STEP
BY STEP

Run the animation. By default,


animations use an in-out motion curve
that accelerates into the movement
before slowing down. The curve is set
using an easing function, which defines
how the animated property moves
from start to finish. Try replacing the
easing function with linear to see how
the movement changes.

011 }

CRASH STOP

The two other options are ease-in


and ease-out. The first starts slowly
and then stops quite suddenly, making
it look as though the element has
crashed into an invisible wall. The
second starts suddenly and stops
slowly, as if the element is gliding to a
stop. The default ease-in-out uses both
to speed up and slow down.

001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
font-size: 100px;
007 position: absolute;
008 -webkit-animation:animX 1s;
009

/* Chrome, Safari, Opera */


-webkit-animation-timingfunction:ease- out; /* Or
ease-in */

010 }
011

4 CUSTOM CURVES

What if you want to roll your own


easing? You can use the cubic-bezier
curve option to define the movement
with a series of four numbers. As a
demonstration, the numbers in the
code copy the ease-in-out curve but
you can change them to create your
own custom easing if you like.

001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;

006
007
008
009

font-size: 100px;
position: absolute;
-webkit-animation:animX 1s;
/* Chrome, Safari, Opera */
-webkit-animation-timingfunction:cubic-bezier(0.4, 0
,0.36,0.66);

010 }
011

HORIZONTAL
5CONTROL
AND VERTICAL
How do you know what the numbers
do? You can experiment with them
at random and end up getting utterly
confused. Or, you can visit the handy
cubic-bezier.com site, which has a cool
preview feature with blobs and curvy
lines and handles you can drag. Click
GO! to preview your custom curve.

001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
font-size: 100px;
007 position: absolute;
008 -webkit-animation:animX 1s;
009

/* Chrome, Safari, Opera */


-webkit-animation-timingfunction:cubic-bezier(0.8,
1.82 , 0.36, 0.66);

010 }
011

6 BOUNCE EFFECT

With some fancy tweaking and


some out of range you can simulate a
simple bounce effect. The other way
to make a bounce is to use percentage
keyframes to move an object past its
target position back again. Repeat this
a few times with decreasing durations
and distances for the smoothest effect.

Animate CSS

3D ANIMATION
Take your animations into the next dimension with 3D transforms
CSS 3D transforms make complicated effects look
easy. The key thing to remember is how to work with
X, Y, and Z co-ordinates. X runs left to right, Y runs up
and down, and Z runs in/out of the screen.
An X rotation flips an element vertically. Because this
is a 3D rotation, it looks as if its spinning in and out of
the screen around its horizontal centre line. A Y rotation
does the same thing around a vertical centre; it looks
like its twirling around. A Z rotation simply spins an
item around in the plane of the screen.
As you might expect, things get a little more
complicated when you combine X, Y and Z. You can
create a combined transform that spins something
in all three axes at once. This makes most users feel

seasick, while most developers feel like their brain is


on fire trying to keep up with the movement but you
never know when thats what you want!
You can also translate elements in 3D, which
simply means moving them. A Z translation is a zoom
in/out. X and Y are familiar left/right and up/down
movements and you can scale them to stretch them
in different axes and you can move the 3D reference
point (origin) and change the perspective view.
So how do you make cool 3D box spinners? With a
lot of code, for one thing. You need to place at least
four, perhaps six, elements at right angles to each
other, then you can apply a common transformation
to rotate or move them all.

Spinning and twirling transforms you have to see


this in action to really appreciate it

STEP
BY STEP

MOUSE CONTROL OF 3D EFFECTS


Spin and rotate elements under mouse control with CSS 3D transforms and not much jQuery at all

1 GET MOUSE CONTROL

Transforms and animations look


great but creating animations that fire
under mouse control instead of onload()
is difficult in pure CSS. Some effects are
challenging, while others arent possible
at all, so well combine 3D transforms
with jQuery to create animations with
the best features of both.

010
011
012
013

font-family: Lato;
font-size: 100px;
position: absolute;
-webkit-animation:animX
2.2s; /* Chrome, Safari,
Opera */
014
-webkit-animation-timingfunction:linear;
015
-webkit-animationiteration-count:infinite;
016 }

017

3
2

NOW IN 3D

Begin by creating a <div> with a


letter X in it, and setting up a rotateX
transform (the example code skips the
duplication for IE to save space). A linear
timing function and infinite repeats
make the X rotate vertically forever. The
effect starts as soon as the page loads.

001
002
003
004

005
006
007
008
009

<!DOCTYPE html>
<html>
<head>
<link rel=stylesheet type=
text/css media=all href=
http://fonts.googleapis.com/
css?family=Lato/>
<style>
#textX
{
left:100px;
top:100px;

SPIN ME ROUND

Add another couple of <divs> for


Y and Z, and create rotateY and rotateZ
transforms for them. As for X, the
animations launch as soon as the page
loads. You can see how the transforms
do different things on each axis.

4 ON-CLICK CONTROL

To set up on-click control of the


animation, simply move the animation
code to a separate .animateX class.
Load jQuery in the header and add
a function that adds .animateX to
the #textX <div> on click, and then
removes it after one animation period.
Note that you have to set the target id
explicitly in the timeout.

001 <script>
002 $(document).ready(function(){
003 $(#textX).on(click,
004

function() {
$(this).addClass

005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022

023
024
025

(animateX);
window.setTimeout(
function(){
$(#textX).
removeClass(animateX);
}, 2300);
});
});
</script>
<style>
#textX
{
left:100px;
top:100px;
font-family: Lato;
font-size: 100px;
position: absolute;
}
.animateX
{
-webkit-animation:animX
2.2s; /* Chrome, Safari,
Opera */
-webkit-animation-timingfunction:linear;
}

5 MOUSE ENTER

Add another handler for mouseenter events for the Y <div>. This works
in similar way to the on-click event that
we looked at earlier, but instead spins
the <div> when the mouse enters it.
Note that you cant use a mouse hover
event because it triggers the spin on
mouse entry as well as exit.

001 $(document).ready(function(){
002 $(#textX).on(click,
003
004
005
006
007
008
009
010
011
012
013
014
015

function() {
$(this).
addClass(animateX);
window.setTimeout(
function(){
$(#textX).
removeClass(animateX);
}, 2300);
});
$(#textY).on(mouseenter,
function() {
$(this).
addClass(animateY);
window.setTimeout(
function(){
$(#textY).
removeClass(animateY);
}, 2100);
});
});

6 FULL CIRCLE

All of that looks okay, but what


if we want to have a lingering mouse
hover animation that completes a full
cycle after mouse exit? To achieve
that we need to trap the secret
animationIteration event, which arrives
after every complete animation cycle.
We can then remove the animation
after the mouse has exited and the
animation has finished, which looks
very cool. There you have it, mouse
control of your effects in no time!

Web Design Tips, Tricks, & Fixes 69

NATIVE
HARDWARE
ACCELERATION

TOP FRAMEWORKS AND PACKAGES


Make your animations look effortless with these top drop-in animation frameworks

You can speed up


animation if you know
the magic words but
only sometimes
It shouldnt be a surprise that
animations put the browser
under quite some stress. Behindthe-scenes animation code
is rendered down to the local
machines graphics sub-system,
which is eventually piped through
the graphics driver.
Graphics cards have features
that can speed up animations. If
your browser is using the main
processor instead of the graphics
card, its working much harder
than it needs to.
The catch is that if youre
writing a game using native
code which will usually be
in a graphics language called
OpenGL you can control what
the graphics card does and
when its used. If youre trying to
write browser animation code,
the graphics system is buried
under the browser and the local
operating system.
Theres a risky fix for this. It
doesnt always work, but it may
be worth experimenting with
it. Add the following code to
an element if you want it to be
rendered by the graphics card:

Animate.css
URL daneden.github.io/animate.css
A lightweight but powerful collection of ready-to-roll CSS
animations, you can download this framework directly from the
site or from GitHub, drop into a project, and get instant access
to a huge collection of animation effects. The list includes
entrances, exits, fades, flips, hinges, and even a few sliders. The
code is simple so its easy to customise it with your own easings
and other additions but for most projects you wont need to,
because the basic effects are so useful right out of the box. Plus,
the subtle colour fade on the site looks lovely.

Move.js
URL visionmedia.github.io/move.js
Move.js packages a collection of CSS animations and makes
them accessible with a few lines of code. Dont be deceived by
the bare site, this is more of a toolkit than Animate.css, so some
assembly is required. You can use the animations as is, but
things get a lot more interesting with the conditional options.
Use them to chain animations together, select animations
depending on other events, set up callbacks and customise
different easings. The sites design doesnt make it obvious that
each feature has a demo under it but it does, so check it out.

001 transform:
translate3d(0,0,0);

002 font-smoothing:
antialiased;
This works but only
sometimes because the null
transform forces the graphics
system to load the element and
process it in harder. The catch, as
you may have guessed, is that it
can kill sub-pixel font smoothing,
so your fonts may not render how
you expect.

Dont forget you can use the


timeline in Chromes Developer
Tools to profile graphics
hardware and render speeds

70 Web Design Tips, Tricks, & Fixes

Anima.js
URL lvivski.com/anima
Anima is a combined CSS/JavaScript animation framework with
physics support. It handles the usual chained/delayed animation
options available in other frameworks, but also includes features
that make it easy to squash and bounce items as you animate
them. The framework is only 5k, so its lightweight enough
to add to any project. The only catch is that its more of a full
animation API than a simple drop-in library of canned effects.
You may want to master a less complex framework before
trying to use this one on a production project.

Greensock GSAP.js
URL www.greensock.com
Making a bid as the next Flash, Greensocks GSAP.js framework
is a fast and efficient HTML5 library for professional animation
applications. Its a streamlined alternative to jQuery animation,
optimised for speed and with added timeline management and
optional plug-ins. The good news is that it does a lot. Its much
more powerful than plain CSS animation, which has helped it
find a home in high-end commercial projects. The bad news? It
costs up to $150 per year if you use it in games or subscription
sites. Still, basic use is free, so its definitely worth a look.

Animate CSS

RESOURCES

ANIMATION IN ACTION
Are you ready to take on the best? Get inspired and discover what the
competition is getting up to with these must-see examples of CSS animation

SPECKYBOYS TOOLS &


TUTORIALS
speckyboy.com/2013/09/30/cssanimation-tools-tutorials
A fabulously
rich and detailed
collection of
frameworks, tools,
tutorial links and
other goodness from the speckyboy
blog and online design magazine.
Links, transitions, fallbacks,
frameworks, examples, previews,
and nice pictures its all here, free
for the price of a few mouse clicks
and perhaps a new mug of coffee.

URL dataveyes.com
DataVeyes skirts the dangers
of the retro-Flash swamp to produce
a splash page thats worth loading.
The animation looks simple its
just dots and lines but some clever
coding and physics modelling take it
a couple of steps beyond the basics.
The result is a coherent presentation
that appeals to the eyes and mind
and sells the skills of the design team.
Theres enough visual ingenuity
to make the site stand out, but not
so much that the design falls over
the edge into being self-indulgent
eye-candy glued on for the sake of
making something move.

BENJY STANTONS WEB


ANIMATION RESOURCES
www.benjystanton.co.uk/work/
side-projects/web-animationresources
More a collection
of whys than hows,
this handpicked
resource
directory includes
articles and
demonstrations
exploring
animation design from the UX point
of view. It includes details of books,
courses and even conference talks
as well as a handy collection of tool
and framework links.

CSS3 ANIMATION
CHEAT SHEET

URL bit.ly/1lH9GNk
This outstanding animated periodic table throws tiles
around the viewport, shaping them into a flat 2D table, a sphere,
a helix/carousel and a grid format in full 3D, with mouse control
of zoom and rotation. You probably wouldnt use this design in
a typical business project but its a brilliant example of whats
possible with CSS 3D, coded with the three.js framework.

URL http://hakim.se/experiments
Hakim El Hattabs experiment pages have breathtakingly
creative examples of the art in CSS animation. Highlights include
fold-out 3D menus, 12 different table effects, a collection of mini
JavaScript frameworks for zoom effects and web presentations
and even an animated DOM Christmas tree. Most of the code is
on GitHub, so you can download it for use in your own projects.

FUTURE DEVELOPMENTS

Is this the future of web animation?

www.justinaguilar.com/
animations
As the name says,
this is a handy
cut-out-and-keep
cheat sheet of
canned CSS3
animations. Theres a collection of
buttons, a pile of code and a quirky
demo area so you can see what
each animation does. There are also
some notes about creating more
sophisticated effects by linking the
animations into jQuery scripts.

The W3C seems to have some


interesting plans in the pipeline for
animation on the web

So whats the future of animation on the web?


CSS3 has been a success and WebGL certainly
has potential, even if it hasnt quite made its way
into every browser just yet.
The W3C is committed to taking animation
further. Discussions are in the early stages,
and as always its impossible to know which
proposals will appear in mainstream browsers
or how widely theyll be supported.
Still, as a heads-up, the Web Animation
1.0 discussion proposal suggests expanding
the core features of web animation to make
them more powerful. The biggest change is
the addition of a timeline. As and when this
appears in browsers, youll be able to specify

and control a series of animations. Youll also be


able to repeat some of the animation steps and
even have multiple unsynchronised animation
streams working at the same time.
But with increased power comes increased
confusion. The Web Animation 1.0 spec can do
a lot, but its not the simplest API in the world
to master. Future changes may make it more
streamlined. At the moment its perhaps better
suited to the complexities of audio and video
editing than to motion graphic design.
Even so, the future looks exciting. A few years
from now youll be able to create more complex
and creative animations than ever before and
that can only be a good thing.

Web Design Tips, Tricks, & Fixes 71

expert insight

Richard Stevenson
Head of PR, 1&1 Internet Ltd www.1and1.co.uk
While selling online is now a necessity for
retailers, fierce competition and tough
consumer expectations are a constant challenge
to manage. Therefore, it is important that you
have a well-defined eCommerce strategy, set of
objectives and target audience before launching
your online store. With many easy-to-use and
increasingly powerful solutions, such as DIY-style
packages from web hosts, business owners can
now get a shop online in a matter of minutes. But
what should you be looking for in order to create
the best online presence possible?
There are a now number of basic elements to
cover when designing an efficient eShop in order
to boost traffic, sales and profits.

01
Starting an online store can be overwhelming.
:HUHYHDOWKHVHFUHWVWKDWFDQKHOS\RXUUVW
foray into eCommerce be a success

re you still stuck with just selling


your products at a local retail store?
It probably comes as no surprise that
you could be losing out on an incredible
stream of online revenue. eCommerce is the fastestgrowing retail area in Europe, especially with
mobile shopping having already become a booming
market. It is estimated that only one quarter of
Europe will be looking to reach over 111.2 billion of
eCommerce sales by the end of 2014.
Launching an online retail business can be
challenging but also highly rewarding as there are
multiple benefits to starting up an eCommerce
shop. Typically, a start-up online store is considered
relatively low cost, as it requires far less capital
outlay when compared against a traditional retail
shop, which can be costly for hiring business
premises. With an online store you are not limited
by your geographical location, which can lead you
to an increased number of customers online, the
whole world is now your customer base.

72 Web Design Tips, Tricks, & Fixes

SEO plays a major role in marketing successful


online shops, as once you start gaining momentum
and a higher search ranking, your brand awareness
increases in the market. This in turn can then lead
to greater customer exposure which then increases
your revenue of course, the more people that
know about you, the better.
Besides the aforementioned bonuses for
merchants, customers also receive added
benefits. Along with not having to queue up for
purchases, products are typically cheaper due
to lower overheads, which creates a great saving
for customers. Its also easier for customers to
find products and compare prices online. In the
past, more specific products may be difficult for
customers to get hold of due to area or availability
but online, location is not a real factor.
In this guide, well be taking a look at the key
points to consider when launching an online shop
and also walk through a tutorial on how to set up a
Magento Go store, with plenty of tips along the way!

THE NAME OF YOUR SHOP - Choose a


clear option relevant to your business while
staying under 20 characters.

02

MCOMMERCE - A mobile optimised


eShop is now essential to improve
accessibility and increase sales conversions.
Consumers are sensitive usability from mobile
devices needs to be great, not just passable.

03

CONSIDER DIFFERENT SALES


CHANNELS - Synchronise your
professional site with marketplaces like eBay and
Amazon and through your social media channels.
Integrating Facebook, Google+ and Twitter
buttons can also help boost your sales.

04

SECURE PAYMENT OPTIONS - Offer


multiple online payment options such
as PayPal and Billsafe. Businesses can apply
for a Trusted Shops seal to illustrate a highly
respected award for reliability and security.

05

SITE PRESENTATION - Ensure that both


the layout and the navigation of your site
are clear and structured to encourage visitors to
stay and explore the site. Some eShop packages
offer rapid conversion for international languages
and support for multiple currencies
significant for trade overseas.

Build an online shop

KEY POINTS TO CONSIDER WHEN SEC RITY


ESSENTIALS
STARTING AN ONLINE STORE
Get to grips with the essentials of the eShop

DESIGNING AN ECOMMERCE SHOP

When designing a new eCommerce shop, you


need to make sure it matches your current brand
image. Usability is of utmost importance; the
navigation in particular must be easy to use and make it
as straightforward as possible for visitors to find products.
The design should be attractive and capture the feel of
your products. The buying process should not be long and
confusing; many shopping cart applications come bundled
with ready-made, customisable templates, or you can
develop your own only simple knowledge of HTML and CSS
is required in order to customise your own store.

SELECTING AN
ECOMMERCE PLATFORM

There are many shopping cart applications out


there that can help get you started with selling
online. It is much easier and quicker to use a reliable and
trusted eCommerce application than to build your own from
scratch. When looking for an eCommerce solution, always
look for what it can do to help your business thrive and how
it can help make your online management easier and hassle
free. One eCommerce package may well be brimming with
rich features but you may find that you will never fully utilise
it all, while a less feature-rich but more user-friendly solution
suits your purposes perfectly.

PRODUCT DESCRIPTION

Make sure you have clear and understandable


product descriptions that help sell your product
and increase your conversion rate. Dont try to
write your descriptions for a general crowd of buyers; instead
focus on addressing an ideal buyer, this way your content
is more targeted and focused. Entice potential customers
by highlighting the benefits of purchasing your product.
Keep your descriptions short, reducing any long sentences,
and use bullet points where necessary. Your product pages
should be scannable but key points should be highlighted.
Consider allowing customers to leave comments and reviews,
as this has been proven to build confidence in your store.

PAYMENT OPTIONS

There are many payment gateway providers


available to help you accept payments online,
some of the well-known ones being PayPal, Sage
Pay, and WorldPay. Still, its worth noting that not all payment
gateway providers are created equal. Each payment gateway
has different transaction fees (or even monthly fees), so
make sure that you do your research and find the most
competitive rate for your business. It is also vital that payment
gateway providers are PCI compliant and fight against fraud.
Support is another factor that is often underestimated and
overlooked; if you ever experience any issues, being able to
pick up the phone and speak to someone directly in order to
resolve your problem is a great benefit.

SHIPPING

CUSTOMER SUPPORT

The best way to determine shipping rates is to


use your shipping carriers guidelines. Where
possible, always try to negotiate better shipping
rates with your carrier. Most eCommerce platforms will allow
you to integrate shipping services that will auto calculate an
orders shipping cost. It is always more preferable to offer free
shipping, specifically on orders above a certain monetary
amount. This should increase average order value and can
potentially differentiate you from your competitors.

When looking for an eCommerce platform, try


to find one that provides customer relationship
management (CRM) as it can make managing
any enquiries and support requests easier. A CRM tool can
help streamline your support requests more readily when
customer information and order details are all located on
one system. Setting up a dedicated phone line for customer
service is also recommended. Another trend for online
retailers is to set up and operate a live chat system to create a
virtual online assistant for customers while they shop. Timely
responses are also a major factor getting back to customers
quickly is vital in order to not miss out on a sale.

Use SSL certificates for


data protection
When handling sensitive customer
information, whether its their personal
details or credit card information,
you will want to use a Secure Socket
Layer (SSL) to encrypt data passing
from customers directly to your web
server. SSL certificates also aid in
authenticating the identity of your
business, which helps bring faith to
customers when shopping at your store.
PCI compliance
Make sure your web server, eCommerce
platform and payment gateway are
PCI compliant. PCI compliance is an
industry-set standard for handling
credit and debit cards for merchants. To
guarantee compliance you must ensure
credit card details are heavily protected.
Performing quarterly scans will help
reduce vulnerabilities to hacking.
Layers of security
Setting up layers of protection from
unwanted intrusions should be
considered a necessity. You should
set up a firewall, as this is essential in
stopping attackers. This, as well as a
monitoring system, should be used so
that you can be instantly alerted of any
suspicious activities.
Keep systems up to date
New versions of web applications are
frequently released, so make sure you
upgrade to the latest iteration. Doing
so will typically provide bug fixes and
security patches which will help protect
your site from cyber criminals who take
advantage of outdated software.

Enforcing a secure checkout process is vital


for any online checkout

IMAGES AND VIDEOS

The drawbacks of shopping online are not being


able to touch, feel, taste, smell or try online
products. So the next best thing is a range of clear
and crisp images that do your product justice. Dont try to cut
corners with imagery but it isnt vital to spend lots of money
for a professional photographer either. Providing videos
is another asset that can help sell your products; this has
become a growing trend, since providing a moving product
gives substantially more information to customers, further
convincing them to make a purchase.

With the increasing number of cyber


crimes and hackers, it is imperative that
customer details are protected and all
data is kept secure these tips should
keep your site safe

IKEAs customer service page is a great example of providing


helpful customer support information

Displaying site seals of approval for security


vendors can be a huge confidence boost
for customers shopping at your store

Web Design Tips, Tricks, & Fixes 73

STEP
BY
STEP
01

GUIDE TO BUILDING A MAGENTO


GO
ECOMMERCE
STORE
Get up and running in no time with the easy-to-use Magento Go platform

Sign up to Magento Go

Magento Go

05 dashboard

Head over to go.magento.co.uk and


click on the Start Your Free Trial
button. Pick your store name (this can be
edited later) and enter an email address to sign
up for a free 30-day trial account. After the trial
period you can upgrade to a paid plan.

Fill out your

02 personal details

On the next screen, fill out your


personal information including name, phone
number, password, location, industry and
experience level. You may find you cannot
change your username and name if you
already have an account set. Once you hit the
Create my store button, Magento will begin
to assemble everything for you.

When at the Magento Go


Admin Dashboard, you will be
presented the latest order
information from your store.
Because we have just set up our
store, there will be no orders and
therefore none displayed.
Familiarise yourself with the
Magento Admin dashboard
because you will likely be
spending a bit of time in here.

06

Store theme

If you head over to frontend of your store (the URL will be http://<your_
username>.mygostore.co.uk), you will notice that it is currently very plain, with a
simple black and white design. This is because we are yet to upload our own products and
its set to using the default T-Shop theme.

03

Your store is now set up

Congratulations, your store has now been set up! After signing up, you will be
presented with the URL of your store and login information to the Magento Admin
Panel. You will also receive an email containing your new store URL and login details,
informing you that your store is up and running.

07

Theme editor

Lets change that by choosing our


own store theme. Navigate to
Design>Themes Editor. In here are 39
pre-made designs you can select from.
Pick the design you prefer, give this theme
a new Theme Name, add in a description
and click Save. Your store has now been
updated with this new theme design.

Customise

08 store theme

04

Log in to your admin panel

Once you have received the confirmation email, head over to the admin panel.
Your admin login URL will be https://<your_username>.mygostore.co.uk/admin.
Input your personal login information, click Login and youll be taken to the Magento Go
Admin Dashboard, where the fun really begins!

74 Web Design Tips, Tricks, & Fixes

You can customise your


chosen theme and style it with
your own brand. In the Theme
Editor, click on Customise. On the
right side bar of the Theme
Customisation screen, you have
options to change the design
settings including headings,
header, footer as well as having
the ability to add in your own CSS
styles, JavaScript code and
catalogue image sizes.

Build an online shop

Upload

09 your own
logo

As well as branding your


theme, lets upload a logo.
To achieve this, navigate to
Theme Customisation,
select Design Setting Editor
and open up the Headers
Settings tab. Under the
Logo section, select
Choose File, browse and
find your logo before
clicking the Save button.

13

Upload product image

To upload your product images, under the Images tab, select Browse Files, locate
your images and then simply click on Upload Files. Once uploaded, you can add
an alt text to each of the images in the label field. You will want to assign an image as your
base, small and thumbnail. Finally, click Save.

Upload your
10 own favicon

View your

14 store

You can also upload


your own favicon. To do this,
head over to System>
Configuration>Design and
expand the HTML Head tab.
In the Favicon Icon section,
choose your favicon and click
Save. In this section you are
also able to edit the default
store title and, in the Header
tab, you can apply an alt text
to your own logo image.

Now that the


products have been imported
and the theme customised,
you can preview your store
by going to http://<your_
username>.mygostore.
co.uk. All of your custom
design changes (any CSS,
JavaScript, design changes)
will be reflected on your store
including all of your products.

Set up

15 payment
gateway

11

Add a new product

Lets start importing products to the new store. If you wish to upload a large sum
of products in one lot, you can import all via a CSV file. Alternatively, to manually
create a new product, head to Catalogue>Manage Products>Add Product.

Create a

12 product

Leave the Attribute


Set on Default to set up a
simple product and click
Continue. Now you can
create your product by
inputting all of your
product details including
product name, pricing,
categories to appear in,
URL key, meta information,
shipping details, custom
options and more.

The easiest form of payment to


accept is PayPal. Navigate to
System>Configuration>
Payment Methods, expand the
PayPal Express Checkout tab
and click on Configure. You
either enter in your PayPal
email address or click on the
Grant Permission to Magento
Go with PayPal button. Make
sure Enable this Solution is set
to Yes and then click Save.

Set up tax

16 rates

You can set up tax


rates under Sales>Tax
(VAT). Firstly, you need to
create a customer tax class,
followed by tax rates for
products, then set up tax
zones for particular
countries and zones. You
are then able to combine
all these into a tax rule that
can be implemented
directly for products.

Web Design Tips, Tricks, & Fixes 75

17

Delivery rates

With your products


created and store
design set up, lets create a list
of delivery rates. You can set up
your own table rates with one
of three conditions: weight and
destination, price and
destination, or number of items
and destination. Go to
System>Configuration>Delivery
Methods>Tablet Rates and
enable this to Yes.

21

Activate domain name

With your domain name added, you will need to make sure you configure your
DNS to point at the IP address supplied by Magento. Once this is complete, jump
to your Magento Admin Panel and navigate to System>Configuration>Web>Active Domain
and select your custom domain name before clicking Save.

CSV delivery

18 rates

Purchase SSL
22 certificate

Under the Current


Configuration Scope, make
sure you select your store.
Once you have you will see
an Export CSV button to
download the CSV. Open this
up in your spreadsheet
editor software and you will
be able to add your delivery
rates within the CSV. After
editing and saving any
changes, you can import it
into Magento Go.

19

Royal Mail

If you prefer to use an


automated delivery
service such as Royal Mail to
calculate your shipping cost,
you can enable this in System>
Configuration>Delivery
Methods>Royal Mail and
enable it to Yes. Ensure when
you edit your products under
the Shipping tab you assign the
Shipping Group to a product.

20

Back in the Manage Your Magento


Account section, under the custom
domain, click Purchase SSL. Youll be
directed to the Purchase an SSL certificate
page. Select the SSL provider you wish to
purchase and fill out your organisation
details and admin contact information to
continue through to payment.

Add a custom domain name

Make sure you have already pre-purchased a domain name. Log in to your
Manage Your Magento Account, located at: https://go.magento.co.uk/go/index/
stores. Click on the Magento Go link on the left side bar menu, click on the Add link button
next to Custom URL, type in your domain name and click Save.

76 Web Design Tips, Tricks, & Fixes

23

Register SSL certificate

After purchasing an SSL certificate you will be required to change the A record of
your custom URL to point to the new IP address provided by Magento. This will
vary depending on your DNS manager and registrar. Once the A Record has been
updated, click Confirm DNS Change to certify that the A Record has been updated.

24

Go live!

Now all of thats out of the way, youre ready to launch your store for production.
In the Magento Admin Panel, at the top click on Start My Store and select Get
Going>Launch Your Store. This will open a dialog box. Click on the Go button and
congratulations, your new store is now live!

Build an online shop

MAINTAIN A SUCCESSFUL ECOMMERCE WEBSITE


*HWWLQJ\RXUVWRUHXSDQGUXQQLQJLVMXVWWKHUVWVWHS7KHUHDUHDOZD\V
WKLQJVWRNHHSLPSURYLQJRQVRKHUHDUHWKHVHFUHWVWRDVXFFHVVIXOVWRUH

ONLINE MARKETING

UPDATES AND FRESH CONTENT

Marketing is vital for any online business. The simplest


form of online marketing is SEO. Make sure your content
is rich with keywords, optimising your content from titles,
headings, friendly URLs and image alt text. Make sure
you incorporate social media awareness by sharing your
products on Facebook, Twitter, Google+ and Pinterest so
that they may spread virally. Be sure to connect with
third-party sites to sell and reach a larger audience, such
as eBay, Amazon and comparison sites.

Give reasons for customers to keep coming back to your


store. Constantly freshen up your site with new content,
whether thats updating your blog on a regular basis,
updating the visuals on your website, or incorporating
the latest summer promotions informing customers of a
sale or event coming up.

KEEP AHEAD OF TRENDS


Since the web is based on technology, there are always
new tools available and new ways to keep your store
looking cool; responsive web design, making sure your
store is device-friendly and incorporating a CMS to run a
blog are just a few suggestions. You should also make
use of the latest technology, such as HTML5 and CSS3,
to continue improving the user experience for customers
while shopping. Incorporating interactive videos will also
make for an improved buying experience.

ANALYTICS
Keep a close eye on your analytic stats, these wont just
tell you where customers are coming from but also
where they may be dropping out. Consistently improve
the user experience to ensure pages are conversion
optimised to keep customers on site for longer and
ensure they reach the end of the checkout process.

Amazon consistently updates its homepage with the latest


products that suit customers and keep them coming back

MONITOR YOUR PRODUCTS


Always keep a look at which products are selling the
most and making sure you keep inventory stocked up. If
products are out of stock, customers will inevitably go
some place else to buy what they want.

ALTERNATIVE SHOP SOLUTIONS


0DJHQWR*RPD\QRWEHWRHYHU\RQHVOLNLQJEXWWKHUHDUHPDQ\FORXGEDVHG
DOWHUQDWLYHVKRSSLQJFDUWVROXWLRQVDYDLODEOHWRJHW\RXVHOOLQJRQOLQH

SHOPIFY

www.shopify.com
Launched in 2006, Shopify houses over 90,000 stores
and is a great platform for any start-up merchants that
want to begin selling online.

BIGCOMMERCE

bigcommerce.com
Bigcommerce boasts a wide range of feature-rich tools
available to business owners so they can get their
store going in no time at all.

VOLUSION

www.volusion.co.uk
A fully cloud-based eCommerce solution that has an
outstanding back-office system with all the features
necessary to run a successful online store.

PROS:

PROS:

PROS:

s/PUOFDFTTBSZUPCFBOFYQFSUXFCEFWFMPQFSPSBO
FYUSBPSEJOBSZEFTJHOFS TJODFUIFSFBSFPWFS
QSPGFTTJPOBMUIFNFTUPDIPPTFGSPN
s /PUIJSEQBSUZQBZNFOUHBUFXBZTFUVQSFRVJSFE 
4IPQJGZIBOEMFTBMMQBZNFOUQSPDFTTJOHGPSZPV

s1SPWJEFT4&0UPPMT JOUFHSBUJPOXJUIF#BZ "NB[PO


BOENBOZPUIFSPOMJOFTIPQQJOHDPNQBSJTPOTJUFT
s*ODMVEFTPWFSQSPGFTTJPOBMEFTJHOUFNQMBUFT
UIBUBSFIJHIMZDVTUPNJTBCMFVTJOHJUTESBHBOEESPQ
DBQBCJMJUJFT

s'FBUVSFTBXPOEFSGVMMZFBTZUPVTFJOUFSGBDF 
JODMVEJOHNBOZLFZTFMMJOHBOENBSLFUJOHGFBUVSFT
TVDIBTAEFBMPGUIFEBZ
s4FBNMFTTMZTFMMPOPUIFSQPQVMBSNBSLFUQMBDFT
JODMVEJOHF#BZBOE"NB[PO

s"TZPVSTUPSFHSPXT UIFNPOUIMZDPTUHSPXTXJUIJU
nQMVT4IPQJGZUBLFTCFUXFFOPOFBOEUXPQFSDFOU
POBMMUSBOTBDUJPOT
s&EJUJOHBOEBEEJOHDPOUFOUDBOTPNFUJNFTCF
EJJDVMUBOEMFTTJOUVJUJWF

s5IJTQMBUGPSNMBDLTBOZNVMUJMBOHVBHFTUPSFGSPOU
BOEUSBOTMBUJPOGFBUVSFT
s5IFSFBSFBMBSHFBNPVOUPGUFNQMBUFTUPTFMFDUGSPN
CVUNBOZPGUIFNMPPLBMJUUMFPOUIFPVUEBUFETJEF
BOEBSFOUSFTQPOTJWF

s"EWBODFEBOEIFMQGVMGFBUVSFTBSFPOMZBWBJMBCMF
GPSUIFUPQUJFSQBJEGPSQMBOT
s&YQFOTJWFPWFSDIBSHFTXIFOFYDFFEJOH
CBOEXJEUIMJNJUT XPSLJOHPVUBUSPVHIMZGPS
FWFSZ(#PWFSZPVSBMMPDBUFEMJNJU

CONS:

CONS:

CONS:

Web Design Tips, Tricks, & Fixes 77

Scroll
horizontally
using
jInvertScroll
To see the bigger picture, wide can be
better than tall, and using horizontal
parallax showcase that

007

<img src="images/cloudsandballoons.png"
alt="" />
008 </div>

03 The content layer

The content layer is last and given the class front


scroll. You can of course add additional parallax layers if
you wish but try to keep the right balance between
achieving a design that is visually rich with one that is
simple enough to render smoothly. Each of the content
panels is added as a separate <div>.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends Parallax scrolling, JavaScript, jInvertScroll

ou dont need to spend long with


marketing and design people before
someones going to use a phrase like
Yes, but whats the differentiator?.
But theyre not talking algebra or
electronics, theyre just reaching out for
something, anything, that might make
what they are working stand apart from
the competition.
Different is good because it causes
people to pause, and pausing enables
an opportunity to consider. It helps the brain to remember
and it encourages people to share that experience with
others. These are good reasons for doing things differently
and providing your visitors with a fundamentally different
way of interacting with your content must be worth a try.
Computer and TV screens are wide rather than tall
because its more natural for us to engage with the world in
that orientation. Ancient man didnt do much for his survival
or hunting chances by spending his time looking up and
down. Looking around is how youll find most of whats
interesting and what makes landscapes and panoramas so
compelling. So why not give your visitors a break from
vertical scrolling and an opportunity to take the wide view?

01 The HTML

The head of the HTML code is kept fairly simple


here, with the Open Sans font being loaded from Googles
font library. Next a link to the jInvestScroll stylesheet is
made that includes only ten lines of code. Last of all there is

78 Web Design Tips, Tricks, & Fixes

a link to the styles for the parallax elements and the


content panels.

001
002
003
004
005
006

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>The Hot Air Balloon</title>
<link href="http://fonts.googleapis.
com/css?family=Open+Sans:400,300,700"rel="s
tyle sheet"type="text/css" />
007 <link rel="stylesheet" href="css/
jInvertScroll.css" />
008 <link rel="stylesheet" href="css/style.
css" />
009 </head>

02 Background

The background consists of the horizon scroll and


middle scroll. In the artwork used for the tutorial the
horizon scroll is the landscape graphic and plain blue sky
and this sits as the background layer on the page. The
middle scrolls sits in front and provides the graphics.

001
002
003
004

<body>
<div class="container">
<div class="horizon scroll">
<img src="images/background.png" alt=""

001
002
003
004
005
006
007
008
009

<h1 class="intro">Scroll down</h1>


<div class="panel1 page">
<h2></h2>
<p></p>
</div>
<div class="panel2 page">
<h2><h2>
<p></p>
</div>

04 The script

After all the content has been loaded the jQuery is


called, then the jInvertScroll.js plug-in before the plug-in is
actually executed. The plug-in ships with jQuery version
1.10.2, so youll want to test the functionality is not affected if
you use an earlier or later version of jQuery to deliver other
functionality for your site.

001

<script type="text/javascript" src="js/


jquery.min.js"></script>
002 <script type="text/javascript" src="js/
jquery.jInvertScroll.js"></script>
003 <script type="text/javascript">
004 (function($) {
005 $.jInvertScroll(['.scroll']);
006 }(jQuery));
007 </script>

05 Hide and scroll

These styles are found in the jInvertScroll.css and


are likely to remain the same whatever your design. This
technique uses the vertical scrollbar to show the user how
far along the page they are, so the horizontal scrollbar is
switched off here. The page elements are anchored to the
bottom of the browser and this will suit most designs.

001
002
003
004
005
006
007
008
009

{
overflow-x: hidden;
}
.scroll
{
position: fixed;
bottom: 0;
left: 0;
}

/>

005
006

</div>
<div class="middle scroll">

06 Design-specific styling

Padding and margins are set to 0px to assist with

Scroll horizontally using jInvertScroll

<Above>
sParallax scrolling is very much in vogue. It provides a great method
for telling stories, delivering timelines and presenting statistics.
<Right>
sWhen choosing colours, remember that its normally much more
effective to use darker shades in background layers and lighter ones
in the foreground

Out in the wild


cross-browser consistency. A Google font is selected
(loaded in the HTML as usual) and a fallback is listed.
Font-weight 300 sits nicely between light and regular,
an elegant but readable weight. Simple touches such
as this can really help to elevate your design above
the norm.

001
002
003
004
005
006
007
008
009

{
padding: 0;
margin: 0;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
font-size: 16px;
color: #555;
background: #9fdefd;
}

07 Headings and background

Here the headings are set to a suitable colour to


integrate in your design. The first parallax element is styled
here. With the lowest z-index number it will sit at the back

Russian digital agency Hot Dot


(hotdot.pro) uses parallax
horizontal scrolling to great
effect. Out of focus foreground
elements help to add depth
to the presentation.

of the design. As the rearmost object it will scroll at the


slowest speed and should therefore be the narrowest
element (in this case 3,000px).

001
002
003
004
005
006
007
008
009
010
011

h1,
h2
{
color: #238acb;
}
.horizon
}
line-height: 0;
z-index: 100;
width: 3000px;
}

08 Clouds, balloons and birds

The sandwich filling in this three-layer arrangement


comes next and so has a middling z-index value. This
element is 50 per cent wider than the background. In the
tutorial it contains the clouds, balloons and birds. Youll

need to use a transparent PNG for the graphics on this


layer so that youll see the layer behind it.

001
002
003
004
005
006

.middle
{
z-index: 250;
line-height: 0;
width: 4500px;
}

09 Content layer

This layer is the top of the sandwich, the front-most


layer with the highest z-index value. This is your content

Web Design Tips, Tricks, & Fixes 79

<Top>
s$POTJEFSIPXUIFFMFNFOUTXJMMJOUFSBDU*UTFBTZJGZPVS
TVCKFDUTBSFMZJOH CVUDBSTBOEQFPQMFNJHIUOFFEBSPBE
UPNPWFBMPOH

<Left>
s%POUNBLFZPVSGPSFHSPVOEDPOUFOUTPMBSHFUIBUJU
QSFWFOUTQFPQMFGSPNBQQSFDJBUJOHUIFFGPSUZPVQVUJOUP
ZPVSCBDLHSPVOEMBZFST

<Right>
s4USVHHMJOHUPDIPPTFBTVCKFDUUPUSZPVUUIJTUFDIOJRVF +VTU
UIJOLXIBUZPVXPVMEEPJGZPVSESFBNDMJFOUKVTUCSJFGFEZPV
BOEUBLFJUGSPNUIFSFnMFUZPVSJNBHJOBUJPOSVOXJME

Mixing it up
$IFDLPVU/FX:PSLBHFODZ
'MVHFSTTIJOJOHFYBNQMFPG
QBSBMMBY XIJDIDMFWFSMZ
JOUFHSBUFTIPSJ[POUBMBOEWFSUJDBM
TDSPMMJOHBTUIFZUBLFZPVPOB
MZQBTUUPVSPGUIFJS
TFSWJDFT$IFDLJUPVU
BU fluger.com


The benefits of parallax


The use of parallax effects in web design has

layer and moves the most when it is scrolled. With a width


of 6,000px it moves twice a fast as the background. In this
tutorial the layer contains the information panels.

007 background: url('../images/scroll.png')


no-repeat right 5px;

008 }

11 Content panels

This class determines the basic properties of the


content panels. You can make these as complex or as
minimal as you prefer. Having discrete areas of content with
good sized gaps between each panel works well with this
technique though, so keep in mind usability if you do
decide to start getting really creative.

become hugely popular and for many years before


that in computer games. The word comes from the
Greek parallaxis, meaning alteration. From our
perspective, nearby objects move more than distant
objects when observed from different positions.
Parallax techniques can be used to create fun,
interactive features and approaches such as
horizontal scrolling can take their place among the

10 Avoid confusion

As with any technique that doesnt work exactly


how the user is expecting, its important to help things
along with a little instruction. This first element is set at
500px from the left of the page, which should work for
most setups. Theres no responsive solution here because
we want people to scroll beyond the width of their viewport.

skills you can bring to your next suitable project.


Still, its important to keep the needs of your
visitor in mind. Consider the experience on a slow
connection, with a mobile design and provide
alternatives. Finally, dont sacrifice SEO if people
cant find your page it doesnt matter how cool it is.

80 Web Design Tips, Tricks, & Fixes

001
002
003
004
005
006

.intro
{
position: absolute;
left: 500px;
top: 0px;
padding-right: 50px;

001 {
002 top: 0px;
003 width: 500px;
004
background: white;
005
padding: 10px 30px;
006
border: 1px #eee solid;
007
position: absolute;
008 }

12 Panel positioning

Now its just a case of finding the right place for


each of your panels to appear. Its easy to get drawn into
overtweaking this as you fine-tune the interplay between
the layers. However, remember that the height and width

Scroll horizontally using jInvertScroll

of the browser will play a huge part in the positioning of the


elements and aim for a design with some flexibility.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016

.panel1
{
left: 1500px;
}
.panel2
{
left: 2575px;
}
.panel3
{
left: 3800px;
}
.panel4
{
left: 5100px;
}

Code library

The plug-in
The jInvertScroll is a lightweight plug-in, written by Alex Franzelin and sponsored by
Pixxelfactory. Easily configured, it can help you achieve the perfect horizontal scroll effect
Extract all selected
elements from the DOM
and then save them into
an array

13 In context

This tutorial just shows the horizontal-scrolling


element of a page, but with a real website youll probably
want to include other non-scrollable elements. Fortunately
that has been thought of and only the elements with the
attribute position: fixed; will scroll. Your header can be
styled as normal and, as this is likely to include a navigation
menu, it will helpfully remain in view at all times.

Use the longest elements


width and height if set to
auto then set the body to the
selected height

14 Your design concept

Horizontal scrolling is a useful technique when you


want to show a sweeping panorama or a journey with
stages along the way. A comic strip would be particularly
suitable for this style of presentation. Here the we use a free
graphic from vectorbackground.net separated into its
component elements starting with the background.

15 The sandwich filling

If you are going to use mainly words on your top


layer, for example when telling a story, your middle layer is
likely to be the graphical subject of your design. This layer
probably needs the most amount of attention if you are
creating a portfolio-standard piece of work.

Listen for the actual scroll


event and set the variable
scrollPercent to the current
percentual position

winHeight)).toFixed(4);

16 Content panels

In the tutorial these panels have been kept simple


and provide a contrast to the busier balloons and
landscape background. However if your design warrants it,
this layer can be as visually rich as you want. You can apply
more formatting, images, etc, to achieve your design goals.

Call the onScroll callback


and do the position
calculation for each element.
Math.floor() returns the
largest integer less than or
equal to a number

17 All together now

When you bring all of the elements together, does


your design work as you expected it to? You might need to
go through several rounds of iteration changing elements
as necessary so that they work together. Youll know youve
cracked it if you can picture your audience not asking
themselves why youve used a slightly quirky layout trick
but just being drawn into the content and accepting your
presentation of it as the most natural and logical solution.

001 $.each(sel, function(i, val) {


002
$(val).each(function(e) {
003
var tmp = {
004
width: $(this).width(),
005
height: $(this).height(),
006
el: $(this)
007 }
008
009 elements.push(tmp);
010
011 if(longest < tmp.width) {
012
longest = tmp.width;
013 }
014 });
015 });
016
017 if(config.width == 'auto') {
018
config.width = longest;
019 }
020 if(config.height == 'auto') {
021
config.height = longest;
022 }
023 $('body').css('height', config.height+'px');
024
025 $([document, window]).on('ready resize', function (e) {
026
totalHeight = $(document).height();
027
winHeight = $(this).height();
028
winWidth = $(this).width();
029 });
030
031 $(window).on('scroll resize', function (e) {
032
var currY = $(this).scrollTop();
033
034
var scrollPercent = (currY / (totalHeight -

035
036
037
038
039
040

if(typeof config.onScroll === 'function') {


config.onScroll.call(this, scrollPercent);
}
$.each(elements, function (i, el) {
var pos = Math.floor((el.width - winWidth) *
scrollPercent) * -1;
041
el.el.css('left', pos);
042
});
043 });

Youll know youve cracked it if your


audience accepts the presentation as the
most natural and logical solution

Web Design Tips, Tricks, & Fixes 81

Create a
scroll-triggered
animation
Give your content beautiful animations
for when the user has scrolled to that
position perfect for responsive sites
when content can be pushed further
down the screen

open the entire folder so that we can use its built-in Node.
js server. Open the start.html file and then add the
following stylesheets and fonts.

001 <link rel=stylesheet


href=css/animate.min.css />

002 <link href=http://fonts.googleapis.com/


css?family=Gafata rel=stylesheet
type=text/css>

003

02 Set up the background

The animate.css file is from daneden.github.io/


animate.css and weve added it already. Well start styling
the page up now, so add the CSS shown below for the
body tag inside of the empty style tags. This adds the
background image so that it covers the page entirely.

Source files
available
sIUUQXXX
JMFTJMPDPVL
CLT

tools | tech | trends Brackets, Animate.css, jQuery, appear.JS

a
<Above>
s#ZPSHBOJTJOHUIFJOJUJBMTDSFFOTDPOUFOUXFDBOMBUFS
BOJNBUFUIFMBSHFSMPHPBOEUFYUPOUPUIFTDSFFOGPS
XIFOJUDPNFTJOUPWJFX

<Above>
s"UUIJTTFDUJPOXFXJMMCFBCMFUPBEEBOJNBUJPOUP
FBDIPOFPGUIFDJSDMFJDPOTTPUIBUUIFZBQQFBSPO
TDSFFOPOFBUBUJNF

82 Web Design Tips, Tricks, & Fixes

OJNBUJPOFFDUTBSFBMMXFMMBOE
HPPECVUJUTOPUBMXBZTQPTTJCMF
UPTFFUIFNJGUIFVTFSIBTOU
TDSPMMFEUPUIFJSMPDBUJPOPOUIF
QBHFXIFOUIFZSFCFJOH
USJHHFSFEThe problem is, that
location is getting harder and
harder to predict, given the sheer
multitude of different-sized screens
that users can be looking at your site with. Libraries such as
Scrollr are great but its all based on pixel sizes and whether
the user has scrolled a certain number of pixels down the
page. This isnt possible to predict with responsive devices,
as content gets pushed further down the page and those
pixel sizes go up the spout.
In this tutorial we are going to take a different approach
to animating content on the screen and it will work well
with many responsive frameworks such as Bootstrap and
Foundation. Weve opted to use Foundation but that isnt
the main focus here; instead we are focusing on using the
free animate.css library of animations. To trigger these we
are using the appear.js plug-in for jQuery, which enables us
to detect when certain elements will appear on the screen.
When they do appear, we will then add in the relevant
animation effects so that the user sees the right animation
at the right time. This is perfect for anything that you really
want to draw the users attention to.

01 Start the project

From the resource files, copy the tutorial folder to


your web server, your local server or, if you are using
Brackets, to anywhere on your hard drive. In Brackets,

001 body{
002
background: url(img/bg.jpg)
003
004
005
006
007
008

no-repeat center center fixed;


-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}

03 Link up the typeface


Now add the next lines of CSS, which add the
correct typeface from the Google font we added in Step 1
to the heading tags. We also change all the typography to
have a white colour that will enable it to stand out against
the different-coloured backgrounds that we will add.

001 h1, h2, h3, h4, h5, .subheader


002

{ font-family: Gafata, sans-serif; }


h1, h2, h3, h4, h5, p, .subheader
{ color: #fff; }/

04 Style the hero

We will add some space between the first content


and the menu so that the background image can be seen
on the screen. We will make this first block of colour behind
our text semi-transparent so that on desktop devices the
background can be seen through. The heading and image
are also given a little padding at the top.

001 #hero{
002
margin-top: 500px;
003
background: rgba(256, 154, 9, 0.7);
004
min-height: 500px;
005
}
006
#hero h1{ padding-top: 20px;}
007
#hero img{ padding-top: 90px;}

05 Sign-up colours

The next section down in our design is the sign-up


section, so we will add the styling for this, which will give the
section a light teal background colour. Later we will add

Create a scroll-triggered animation

<Above>
s*OJUJBMMZUIFTJUFOFFETTPNF$44UPTUZMFUIFFMFNFOUTVQTPUIBUUIFSFJTNPSFPSHBOJTBUJPO
UPUIFQBHFBTXFMMBTTPNFEJTUBODFCFUXFFOFBDIFMFNFOUTPUIBUUIFZDBOCFTDSPMMFEUP

animation to the heading to draw attention to the sign-up


element within this section of the website page.

001 #signup {
002
margin-top: 300px;
003
background: #0ec8b0;
004
padding: 90px 0;
005
}

06 Three-column section

The next section of the site is the three-column


section, so in a similar way to earlier we will add the colours
for the background of this section. We are adding plenty of
margin top to each section of the page so that the
animation can clearly be seen as we reach each section.

001 #three {
002
margin-top: 300px;
003
background: #00add8;
004
padding: 90px 0;
005
}
006

07 Finish the page

Now we add the lower section of the site, which


contains an image and text. This has a light purple
background and the footer is a dark grey colour. This
concludes the backgrounds of the page and spaces our
design out ready for us to start thinking about adding the
animated elements to the page.

001 #lower {
002
margin-top: 300px;
003
background: #df86ca;
004
padding: 90px 0;
005
} #footer {
006
background: #333;
007
padding: 30px 0;
008
}

browser. You will see the large image automatically


animated down from the top of the page.

001 <div class=medium-7 columns


animated fadeInDownBig >

09 Move in the text

Find the <div> with the ID introText and change


the class as shown below. Again, refresh your browser so
that you can see that in action. Now both of the elements
on the screen animate into place. This is good but if this
were a mobile device this content would likely be off the
bottom of the screen, which might cause users confusion
when they see the logo fly past.

001 <div id=introText class=medium-5


columns animated fadeInUpBig >

08 Add the first animation

Locate the <div> tag with the ID for the hero


section. Inside the row that immediately follows is a <div>
with a class of medium-7 columns. Change this as shown
in the following code snippet and refresh your page in the

10 Use appear.js

A better way to solve the animation is to only


trigger the animation to take place once the relevant parts
are on the screen. For this we will use the jQuery plug-in

Web Design Tips, Tricks, & Fixes 83

<Top left>
sThe last section of the site has an
image that we will be able to animate
into position later, when the user
scrolls this far down the page

<Top right>
sNow as we have added our JavaScript content,
we dynamically add the animation to the
elements as they are in view in our browser. Here
the main logo and text is in mid transition

called appear.js, available from github.com/morr/jquery.


appear, however weve already included it. Add the
following code after the Foundation JavaScript library at
the bottom of the document.

001
002 <script src=js/jquery.appear.js></script>
003

11 Readable text

After the line $(document).foundation(); add the


code shown below. Here we are ensuring that any element
with the class animated has the appear functionality
enabled. When they do appear on the screen we will then
store their animation properties from the data element in
the animation variable.

001 $(document).ready(function($) {
002
003
$(.animated).appear();
004
$(.animated).on(appear, function() {
005
var elem = $(this);
006 var animation = elem.
data(animation);

84 Web Design Tips, Tricks, & Fixes

<Bottom left>
sThe Free Download text is being bounced into
position in order to draw attention to the call to
action here. You can see the text is just slightly
off centre as it comes to rest

AJAX loading
Many of the effects used in this
tutorial only work when viewed
from a server, so ensure your site
is on a local server, a web
server or being viewed in
the live preview
from Brackets.

12 Save the delay

When the animation is visible, we check if there is


any element data for an animation delay and we will use
this to chain animations later. If there is, it is stored in the
animationDelay variable, ready to trigger the correct
animation after the delay time has passed.

001 if ( !elem.hasClass(visible) ) {
002
var animationDelay = elem.

<Bottom right>
sAs the three icons appear on the
screen they are delayed slightly so that
each icon rotates into position with a
3D transform one at a time

amount of time has passed before calling the animation


to actually play. This is done by passing through the
animation as a class into the element.

001 if ( animationDelay ) {
002
setTimeout(function(){
003
elem.addClass
004
005

( animation + visible );
}, animationDelay);
}

14 No delay, just animate

If there is no delay stored with the animation then


we just want the animation to play, so the else statement
were using here simply adds in the animation to the
element without the delay ready for it to start. With these
in place we can now go ahead and amend our tags that
we added to the animation to earlier.

data(animation-delay);

13 Apply the delay

If anything was stored in the animationDelay


variable that we used in the previous step then here we
add a timeout function to wait until the appropriate

001 else {
002

elem.addClass
( animation + visible );
003
}
004
}

Create a scroll-triggered animation

005
});
006 });
007

15 Style the animation

Initially we are going to make the animated


elements invisible and only turn on their visibility as the
page scrolls to them. We can then call their animation from
the JavaScript we have just added. Add these two classes
to the style tags at the top of the document.

001
002
003
004
005
006
007

.animated {
visibility: hidden;
}
.visible {
visibility: visible;
}

16 Set up the animation

Now we will amend the tag that we changed in


Step 8 with the code shown below. Notice how we move
the animation class into the data-animation tag? We grab
that content in JavaScript once it is on the screen and then
add it again as a class; this will trigger the animation and
ensure that it only fires when on screen.

001 <div class=medium-7 columns animated


data-animation=fadeInDownBig>

002

What are we doing with appear.js?


The appear.js library is great at detecting exactly what is on screen. We call it by telling it which classes to work
on. In our case its anything that has the class animated. When something does appear on screen we can use
the custom event on(appear). Its at this point that really interesting things can happen. The main thing we are
doing is taking the data-animation properties and writing that in as a class. This triggers the animate.css library
of animations. A secondary point we are implementing is checking if the animation should be staggered and
calling a setTimeout function to handle this.

17 Delayed animation

What the final result is for the end user is animations that trigger nice and smoothly, as the elements that
have animation on them appear in their browser window.

Now amend the tag that we set up in Step 9. This


time we also add a data element for animation-delay. As
before, this will be picked up by our JavaScript and used to
set the timeout function so that the animation is delayed
before being called. We are now triggering this animation
only when it is fully on the screen.

the next couple of columns so that they appear in


sequence along the page.

001 <div id=introText class=medium-5 columns

002

Add and remove CSS


Rotating an element is very easy
with transform, but just
remember the origin
of the rotation is at
the centre of
the element.

001 <div class=medium-4 columns animated


data-animation=flipInY>

animated data-animation=fadeInUpBig
data-animation-delay=200>

002

18 Throwing a wobbly

Look a little further down the document at the


signup <div> id. Inside here you will find a heading 1 tag.
Amend the tag as shown below. Here we are adding a
wobble animation, which really draws attention to the
heading as the user reaches this part of the page.

20 Stagger the second column

Now find the second medium-4 columns content


and add in the data animation and delay attributes as
shown below. This waits almost half a second before this
content starts to animate onto the page. By staggering the
animation here we can draw far more attention to the
content on the page.

001 <div class=medium-4 columns animated


data-animation=flipInY data-animationdelay=400>

001 <h1 class=text-center animated dataanimation=wobble>Free download</h1>

002

002

19 Three columns of content

A little further down the page in the <div> tag with


the id of three are three four-column sections. Change the
first as shown below so that it flips in along the y axis.
There is no delay on this first one, however we will stagger

21 Last of the three columns

Find the final column that has the class medium-4


columns and again add the animation and delay, data
attributes. Here we are waiting a little longer than before to
almost a second before animating. Save the page and
scroll to this section of the page to trigger it.

001 <div class=medium-4 columns animated


data-animation=flipInY
data-animation-delay=800>

22 Animate the last image

Finally, move down the page to find the image tag


of the jeans and add in the class and animation for this
element. Save the page and preview this in the browser in
order to see this image move in. This is a particularly useful
technique for any element that you would like to draw
attention to on your webpage.

001 <img src=img/jeans.jpg class=animated


data-animation=wobble>

002

Web Design Tips, Tricks, & Fixes 85

Make an
animated SVG
header with
Snap.svg
Achieve crisp graphics at all resolutions
and add interactivity and animation
with Adobes new Snap.SVG library

03 Rename the graphics

Head down the Interaction group in the Layers


panel and locate the layers that have the bowtie, face
and arm graphics on them rename them as such in
the panel. The names we add here will eventually
become IDs in the SVG file, so we can add interactivity
or animation to them later on.

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends Illustrator, Snap.SVG, code editor

his tutorial will be working with


adding both animation and
interactivity to an SVG graphic
with the new Snap.svg library. The
SVG format is now 14 years old and
yet it has really only just started to
get traction as a web format over
the last few years.
Because it is a vector format, the
image is made up out of mathematical points rather
than out of pixels and this is what makes it scalable.
Snap.svg has been created by the author of Raphael.JS
(an earlier SVG library) to take advantage of modern
browser capabilities and is created in a simple
jQuery-like way.
In the tutorial we are going to cover naming content
in Illustrator, which will output as IDs in the SVG file,
adding Google fonts to style up your logo in the SVG,
loading the SVG using Snap.svg then adding both
animation and interactivity to your image using Adobes
new Snap.svg library.

01 Get started

To start this project drag the Start Folder from


the online resource files (see link above) and place it in
your local server folder such as MAMP/LAMP/WAMP.
The Snap library uses AJAX to load the SVG so we need
a server. Open Scene.AI in Illustrator, open the Layers
panel and drag it out to its own window. Inside the
Logo group, rename the content to Designs, Dojo
and Strapline.

86 Web Design Tips, Tricks, & Fixes

02 Install the font

We are using the typeface Lobster in the design


because this is available on Google Fonts as a web font.
If you dont have it installed and its not displaying
correctly, go over to www.dafont.com/lobster.font to
download and install it. Once installed, you may need to
restart Illustrator to make it show up.

04 Create hit areas

We are going to make some interactive rollover


sections in our code later on, so we need some hit
areas to trigger the rollover. Use the Rectangle tool and
add three rectangles so that each of the three
characters are covered, as shown below. Using the
Layer panel, rename each of the three respective
rectangles to dog, bear and chick.

05 Export the SVG

All thats needed now is to go to File>Save As


and choose SVG as the file type. Make sure you save it
in the same folder as used previously and name it
scene.svg. Click Save and then in the SVG Options
window keep all the defaults and click the OK button. At
this point we can now minimise Illustrator and open the
index.html file in our code editor.

Make an animated SVG header with Snap.svg

What is an
SVG then?
The scalable vector
graphic format is an XML
file, its plain text just like
your HTML documents.
Open it in your code
editor and you
will be able to read
it, but therell be a
lot of numbers!

<Above
sUsing Snap.SVG we can easily add animation and interactivity to our SVG graphics. Snap gives us a simple way to traverse the structure of an SVG and
target specific IDs in much the same way as jQuery lets you do with the DOM

06 Add the font

Once you have the index.html page open in


your code editor its time to link up the Google font.
Were using Lobster, as we used that in Illustrator, so we
can style up the SVG with it here. Next we link up the
Snap.svg JavaScript library to our document so that we
can use that to control our SVG image. Add these lines
of code to the head section of your HTML.

001 <link href=http://fonts.googleapis.


com/css?family=Lobster rel=stylesheet
type=text/css>
002 <script src=snap.svg-min.js></
script>

07 Typography styling

Back in Step 1 we named the different


elements in Illustrator. These names are converted into
IDs, so if we set up CSS style rules we can apply the
Google font to them. Copy the code shown into the
head section of the HTML document to style up the
elements correctly. We also centre our SVG content on
the page.

001 <style>
002 svg{
003 display: block;
004 margin: 0 auto;
005 }
006 #Dojo{ font-family: Lobster,

cursive; }
007 #Designs{ font-family: Lobster,
cursive; }
008 #Strapline{ font-family:
Lobster, cursive; }
009 </style>

Animate the arm

08 Load the SVG

We are now going to load the SVG file, so add


the code shown into the head section of the HTML
page. This creates all the variables that we are going to
need and, when the window has loaded, we set up a
new snap SVG and load the scene into it. Notice we are
using the same dimensions as our Illustrator document.
Save this and view it in the browser.

001 <script>
002 var dojo, designs, strap, chick,
bear, dog, tie, face, arm;
var timer;
003 window.onload = function () {
004 var s = Snap(960, 400);
005 Snap.load(scene.svg, function(f) {
006 s.append(f);
007 });
008 };
009 </script>

01 _____________The arms race


CSS keyframes animate the chicks arm
and we use some strange numbers for the
origin of the animation. Start by clicking
on the arm with the Direct Selection tool.

02_____________Anchor point
Hover over the icons in the top bar until the
pop-up for reference point displays. This is
a 3x3 point square. Click on its left-centre
point and it will darken when it is selected.

09 Select the elements

If all went according to plan you should have


seen your SVG displayed. We now need to work with
our logo and make it animate onto the screen as the
page loads. Add the following code and make sure its
added to the line before s.append(f);. This stores the
elements in variables.

001 dojo = f.select(#Dojo);


002 designs = f.select(#Designs);
003 strap = f.select(#Strapline);

03_____________Check out the code


The numbers to the right of the reference
point are the same as the transform origin
code in Step 16. This enables us to rotate the
arm around this left-hand reference point.

Web Design Tips, Tricks, & Fixes 87

bowtie of the dog to spin 360 degrees over .4 seconds,


and rotate it back to 0 when the mouse is rolled out.

CSS
keyframes
Keyframes are elements to
be blended together by
changing one set of CSS
styles to another, dictating
what something should look
like at different points along
the animation.

001 dog.hover(dogOver, dogOut);


002 function dogOver() {
003 tie.animate({ transform:t0,0r360},
400);
004 }
005 function dogOut() {
006 tie.animate({transform:t0,0r0},
007 0);
008 }

Using the Snap.svg library


The library makes use of AJAX to load the SVG
graphics and inject them into the DOM. As it does
this it means that just previewing the page in the
browser wont work and this will leave us with an
empty page. To get this working we need to set up
a server to allow us to serve the pages over http.
To do this you can do a Google search for
MAMP, LAMP or WAMP depending on the OS

code was added. Here we animate the dojo text into


place by scaling it up and bringing the opacity up. This
is done using elastic easing so that it bounces into
place. We then set a timer to delay by half a second and
we animate the designs text and the strapline. Save
and refresh your browser to see.

being used. The M stands for Mac, L for Linux and


W is for Windows. With this set up, you will have a
htdocs folder, which is where you will place your
web documents. You can alternatively do a search
for Node.js and download and install that instead
if you prefer, but it is a little more complicated. If
you have a server online, then obviously you can
just upload the files to there instead.

10 Hide the logo

Add the code shown before the s.append(f);


line. This code changes the opacity of all elements to
zero and therefore makes it invisible in the document.
The dojo and designs text is also scaled down as well
to 10 per cent of the original size. If you refresh your
browser now you will see the changes reflected.

001 dojo.attr({opacity: 0, transform:


002 scale(0.1, 0.1) });
003 designs.attr({opacity: 0,
transform: scale(0.1, 0.1) });
004 strap.attr({opacity: 0});

001 dojo.animate({opacity:1, transform:


scale(1, 1)},800, mina.elastic);
002 timer = setTimeout(designIn, 500);
003 function designIn() {
004 clearTimeout(timer);
005 designs.animate({opacity:1,
transform: scale(1, 1)},800, mina.
elastic);
006 strap.animate({opacity:1}, 1500);
007 }

12 Change opacity

Now add the following code as shown after the


previous code that we added. Here we are storing the
IDs of the graphics in variables to make it easy to
manipulate them. We set the Opacity of the hit areas to
zero so we cant see the green rectangles over the
characters. The last line is commented out because we
havent created the CSS class for arm just yet.

001
002
003
004
005
006
007
008
009
010

chick = f.select(#chick);
bear = f.select(#bear);
dog = f.select(#dog);
tie = f.select(#bowtie);
face = f.select(#face);
arm = f.select(#arm);
chick.attr({opacity: 0});
bear.attr({opacity: 0});
dog.attr({opacity: 0});
//arm.attr({class: arm});

13 Animate the dog

11 Animate the logo

Add the code shown below after where the last

88 Web Design Tips, Tricks, & Fixes

Place the code below after the line s.append(f);.


This adds a hover event to the dog. When the mouse is
over the function, dogOver is called and when the
mouse rolls out, dogOut is called. We animate the

14 Interactive bear

Now we add our rollover functions for the bear.


In this case we see that we make the bears face pop
out over a period of .4 seconds. When it moves back
into position it uses the backin animation preset,
making the face get slightly bigger before returning to
its original size. Refresh your browser to test.

001 bear.hover(bearOver, bearOut);


002 function bearOver() {
003 face.animate({
transform:t0,0s1.5}, 400, mina.
elastic);
004 }
005 function bearOut() {
006 face.animate({transform:t0,0s1},
200, mina.backin);
007 }

15 CSS3 keyframes

We are going to set up some CSS keyframes


now, so go to the style tag in the head section of the
document and add the code shown below. Duplicate
this and change all of the -webkit prefixes to -moz on
the duplicate.

001
002
003
004
005
006
007
008
009
010
011
012

@-webkit-keyframes wave{
0% {
-webkit-transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(30deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}

Make an animated SVG header with Snap.svg

16 Apply keyframes

Now add the following rules so that we can


rotate the arm back and forth using the wave animation
keyframes. The arm has the class arm applied, when
we rollover the arm we are going to add the extra class
of animating which plays those wave keyframes over a
period of .4 seconds and repeats this process.

001 .arm {
002 -webkit-transform-origin: 808px
273px;
003 -webkit-transition: -webkittransform .4s;
004 -moz-transform-origin: 808px 273px;
005 -moz-transition: -moz-transform .4s;
006 }
007 .arm.animating {
008 -webkit-animation: wave .4s
infinite;
009 -moz-animation: wave .4s infinite;
010 }
011

17 Final step

We will now uncomment the line arm.attr({class:


arm}); that we added in Step 12 by removing the two
slashes at the beginning of the line. Now add the code
shown below after the bearOut function from Step 14.
This applies and removes the class of animating to the
arm when the chick graphic is hovered over. Save and
test in the browser to view your animation.

001 chick.hover(chickOver, chickOut);


002 function chickOver() {
003 arm.attr({class: arm
animating});
004 }
005 function chickOut() {
006 arm.attr({class: arm});
007
008 }
009 }

Code library

Interact with the SVG


Snap.svg gives us a simple JavaScript library for manipulating and working with the SVG
graphics, enabling us to apply animations and rollover effects with ease

The Snap.svg library


loads the SVG graphic via
AJAX and then adds this
to the DOM. Before we
add it though, we can
alter how elements look
so that we can animate
them into position

We animate the logo into


position on the page by
using animate method. This
allows our logo to appear in
its final position of the SVG
after its animated into place
Snap has some easing
functions built in so we can
apply an elastic, bouncing
into position for the logo as it
scales up into place

The hit areas we created for


hovering over the creatures
in Illustrator are made
invisible so they cannot be
seen. Its sometimes useful
to have slightly larger hit
areas, then the user stands
more chance of finding
these hidden gems

Each of the creatures have a


rollover and rollout function
attached to them that is
called when the mouse rolls
over and out of the hit area.
These functions then trigger
the animation to play

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039

<script>
var dojo, designs, strap, chick, bear, dog, tie, face, arm;
var timer;
window.onload = function () {
var s = Snap(960, 400);
Snap.load(scene.svg, function(f) {
dojo = f.select(#Dojo);
designs = f.select(#Designs);
strap = f.select(#Strapline);
dojo.attr({opacity: 0, transform: scale(0.1, 0.1) });
designs.attr({opacity: 0, transform: scale(0.1, 0.1) });
strap.attr({opacity: 0});
dojo.animate({opacity:1, transform: scale(1, 1)},800,
mina.elastic);
timer = setTimeout(designIn, 500);
function designIn() {
clearTimeout(timer);
designs.animate({opacity:1, transform: scale(1,
1)},800, mina.elastic);
strap.animate({opacity:1}, 1500);}
chick = f.select(#chick);
bear = f.select(#bear);
dog = f.select(#dog);
tie = f.select(#bowtie);
face = f.select(#face);
arm = f.select(#arm);
chick.attr({opacity: 0});
bear.attr({opacity: 0});
dog.attr({opacity: 0});
arm.attr({class: arm});
s.append(f);
dog.hover(dogOver, dogOut);
function dogOver() {
tie.animate({ transform:t0,0r360}, 400); }
function dogOut() {
tie.animate({transform:t0,0r0}, 0); }
bear.hover(bearOver, bearOut);
function bearOver() {
face.animate({ transform:t0,0s1.5}, 400, mina.
elastic); }
040 function bearOut() {
041
face.animate({transform:t0,0s1}, 200, mina.backin);
042 }
043 chick.hover(chickOver, chickOut);
044 function chickOver() {
045
arm.attr({class: arm animating});
046 }
047 function chickOut() {
048
arm.attr({class: arm});
049 }
050 });
051 };
052 </script>

Web Design Tips, Tricks, & Fixes 89

Create an
animated
infographic
with SVG
Why just look at an infographic when
you can interact with one? We make it
possible using SVG, CSS and JavaScript

code editor (eg Sublime Text) what you see may not be
as unfamiliar as you expect.

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends Illustrator, CSS, JavaScript

eople like to interact with and


investigate things and providing
interactive content on your
website is one of the best ways of
holding the interest of visitors for
longer. Thankfully, modern web
browsers will happily display SVGs
(Scalable Vector Graphics), which
is great news for anyone wanting
to create interactive content,
because SVGs can easily be manipulated. The graphics
for your entire interactive stage comprise only one
small file versus the plethora of larger GIFs, PNGs or
JPEGs you might need for a complex animation
developed using more traditional techniques.
Additionally, since all of the elements within the SVG are
scalable, you can use zoom effects without anticipating
and dealing with potential image quality deterioration.
This tutorial will walk you through the steps of
creating an engaging animated infographic, so you can
really hold readers attention. Weve based the
information off a demo developed by the Canadian
designer, Adam Coloumbe, whose original work can be
found here: bitly.com/WOQ5fy.

01 Choose your tools

This tutorial assumes that you will be using


Adobe Illustrator to create your SVG file. You can of
course use any application you like. as long as it
supports the SVG file format. You could even create the
file by hand if you are that way inclined.

001 <?xml version=1.0 encoding=utf-8?>

90 Web Design Tips, Tricks, & Fixes

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019

<svg>
<g id=background></g>
<g id=logo></g>
<g id=quote>
<g id=quote-left-speech></g>
<g id=quote-right-speech></g>
<g id=quote-text></g>
</g>
<g id=timeline>
<g id=stage-one>
<g id=stage-one-badge>
<g id=stage-one-title></g>
<g id=stage-one-details></g>
</g>
</g>
//repeated for subsequent stages
</g>
</svg>

04 Safety first

002 <!-- Generator: Adobe Illustrator 16.2.1,


SVG Export Plug-In . SVG Version: 6.00 Build 0)
-->
003 <!DOCTYPE svg PUBLIC -//W3C//DTD SVG 1.1//
EN http://www.w3.org/Graphics/SVG/1.1/DTD/
svg11. dtd>
004 <svg version=1.1 id=InteractiveSVG
xmlns=http://www.w3.org/2000/svg
xmlns:xlink=http://www.w3.org/1999/xlink
x=0px
005 y=0px width=1024px height=800px
viewBox=0 0 1024 800 enable-background=new 0
0 1024 800 xml:space=preserve>

For safetys sake, keep a native version (in Adobe


Illustrator this will be a .ai file) of your infographic that
you can go back to. If you make any changes to the
SVG file that make it invalid, Illustrator may no longer be
able to open the file and you might have a file you
cant fix.

02 Group into IDs

The infographic will be animated using CSS


applied to the various IDs that comprise the graphic. An
ID is assigned to an element of your graphic when that
element is turned into a group. These groups are
identified within the SVG with the <g> and </g> tags and
you will see that these groups can be nested.

001 <g id=stage-one>


002 <g id=stage-one-badge>
003
<g id=stage-one-title></g>
004
<g id=stage-one-details></g>
005 </g>
006 </g>

03 Have a look inside

You will need to do some editing of your SVG file,


so its worth understanding the basic structure that
needs to be in place. The SVG file format is an
XML-based file, so when you open it in your preferred

05 Tweak away

Your Illustrator-generated file will only take you


so far though. When you start making changes in your
SVG file, for example to tweak the font names,
remember you cant go back to Illustrator and edit again.
If you do, more likely than not, your manually applied
changes will be overwritten.

06 Using fonts

The following code is an example of a single


outlined letter in the SVG file (in this case, the T of
STAGES). As you can see, its not pretty and its certainly
not going to be easy to edit. If youre using text in your
SVG, youll want to keep any text within your SVG as a
font because this will make the text much more
accessible and also help with keeping the file size down.

001 <path fill=#EFC94C d=M234.508,85.439l-

Create an animated infographic with SVG

<Above>
sIf you have something interesting or entertaining to share, and can turn it into an attractive infographic, you might find you have a hit on your hands. There always seems to be an infographic going
viral, which can score plenty of kudos for the creator if not actual money!

5.778,0.329l0.271-2.5l-0.823,0.046l1.304,11.747l1.687-0.104l-0.66,6.749
l-11.146,0.729l1.059-6.812l1.746-0.104l1.77311.817l-0.842,0.047l-0.395,2.521l5.704,0.329l1.788-9.413l19.039-0.994
L234.508,85.439z M232.604,83.433l0.444.949l-15.384,0.822l-0.898,5.018l1.8780.104l0.436-2.601l4.591-0.253l-2.249,16.229
l-1.712,0.104l-0.34,2.364l6.484-0.414l0.2582.354l-1.708,0.107l1.988-16.188l4.624-0.255l0.254,2.569L232.604,83.433z/>

07 Whats my name again?

Depending on the font you use, Illustrator may


not set the font family name correctly for you. The font

name needs to appear exactly as it is specified in the


CSS to work. If youre using a web font as this tutorial
does, youll simply need to reference the font in the CSS
as you normally would and then update the SVG so that
the name matches it everywhere it is referenced.

001 <g id=quote-text>


002 <text transform=matrix(1 0 0
1 573 74.9998) fill=#EFC94C fontfamily=LeagueGothic font-size=27>The nice
thing about not planning is that failure </
text>
003 <text transform=matrix(1 0 0
1 573 99.9998) fill=#EFC94C fontfamily=LeagueGothic font-size=27>comes as a

Error
loading SVG?
Many browsers wont
enable access to the SVG
DOM locally. For troublefree development, use
Mozilla Firefox when
working on your own
interactive SVG.

complete surprise rather than being </text>


004 <text transform=matrix(1 0 0
1 573 124.9998) fill=#EFC94C font-

Web Design Tips, Tricks, & Fixes 91

Infographic
inspiration
If you are stuck for a subject for
your own infographic, why not
check out the sites dedicated to
promoting them? You could do
worse than visit www.
coolinfographic.com or
dailyinfographic.com.

Other SVGs are available


Youre not restricted to using Adobe Illustrator if
you need to create an SVG. Inkscape (inkscape.
org) is an Open Source vector graphics editor, with
capabilities similar to Illustrator, CorelDraw, or
Xara X, using the W3C standard Scalable Vector
Graphics (SVG) file format. An advantage of using
Inkscape over its competitors, apart from the fact
its free, is its ability to create classes within an
SVG, which enables you to exercise greater control
when manipulating these elements. If youre
interested in taking your SVG skills further, you
dont need to content yourself with animated
infographics, you can use SVGs for creative design
concepts, such as using an SVG graphic as an alpha
channel that video plays behind (bit.ly/dOM1JH).

family=LeagueGothic font-size=27>preceded
by a period of worry and depression.</text>
005 </g>

08 Have we met before?

Those pesky vendor prefixes quadruple the


number of lines of CSS required for this tutorial, so dont
be put off when you open the CSS file and just keep
scrolling down. Theres also a large amount of repetition,
so once you understand what is going on its all much
more straightforward than it might initially appear.

92 Web Design Tips, Tricks, & Fixes

09 Set up the animations

Here were moving onto the CSS. When called,


this snippet will first fade in the left-hand speech mark
from 0% to 100% during the first half of the animation,
and then move it 220px to the left during the second
half. Add the code for the right speech mark, repeat the
code for every browser and youll find that youve
already created 143 lines of code!

001 @keyframes left-speech-intro {


002 0% {
003
transform: translateX(220px);
004
opacity: 0; }
005
006 50% {
007
opacity: 1;
008
transform: translateX(220px); }
009
010 100% {
011
transform: translateX(0px); } }

10 Fade and scale

Next up, we have just fading on its own and


scaleY (which changes the vertical size of an element
while keeping the horizontal size constant) and scaleX
(which changes the horizontal size of an element whilst
keeping the vertical size constant).

001
002
003
004
005
006
007
008
009
010
011
012
013

@keyframes fade-in {
0% {
opacity: 0; }
100% {
opacity: 1; } }
@keyframes grow-y {
0% {
transform: scaleY(0); }
100% {
transform: scaleY(1); } }
@keyframes grow-x {

014 0% {
015
transform: scaleX(0); }
016
017 100% {
018
transform: scaleX(1); } }

11 Just grow up

Finally, the scale(x,y) operation is used where


concurrent horizontal and vertical scaling is required. At
this stage, we have all of the animation set up as well as
nearly half of the CSS accounted for.

001 @keyframes grow {


002 0% {
003
transform: scale(0, 0); }
004
005 100% {
006
transform: scale(1, 1); } }

12 Get your @font-face on

Your web font choice(s) are loaded in the


CSS remember, the font-family name needs to
match the name that appears in your SVG file. The
example code here is a more established method
for using web fonts but the cool kids are heading
over to fontsquirrel.com and using their web font
generator, which outputs CSS using Paul Irishs
Bulletproof method.

001 @font-face {
002 font-family: LeagueGothic;
003 src: url(../fonts/league-gothic/leaguegothic.eot);
src: url(../fonts/league-gothic/leaguegothic.eot?#iefix) format(embeddedopentype), url(../fonts/league-gothic/leaguegothic.woff) format(woff), url(../fonts/
league-gothic/league-gothic.ttf)
005 format(truetype), url(../fonts/leaguegothic/league-gothic.svg#League_Gothicwebfont) format(svg);
006 font-weight: normal;
007 font-style: normal; }

004

008

13 Set the stage

This is where all of the action happens. You need


to ensure the values entered here exactly match the
width and height of your SVG. The tutorial uses a little
drop shadow but you can leave that out or use another
technique to delineate the stage if you have joined the
drop-shadow-averse design trend.

001 #stage {
002 background-color: #fff;
003 width: 1024px;
004 height: 800px;
005 margin: auto;
006 -webkit-box-shadow: rgba(0, 0, 0, 0.3)
0px 0px 10px;

Create an animated infographic with SVG

-moz-box-shadow: rgba(0, 0, 0, 0.3) 0px 0px


10px;
007 box-shadow: rgba(0, 0, 0, 0.3) 0px 0px
10px; }

14 Lets back it up

Your finished artwork should show each of the


stages in their hovered state so we need to make some
transformations to each of these and put them in a
pre-hover state. The advanced CSS selector (dollar
symbol) enables us to select all IDs that end with
content that follows the equals symbol rather than
listing them all out.

001
002
003
004

[id$=badge] {
transform: scale(0.6, 0.6); }
[id$=title] {
transform: scale(1.3) translate(0px, 48px);

Code library

HTML and JavaScript


All that remains to display your infographic is to reference the Stage ID in your HTML and
then load the SVG using a tiny amount of JavaScript, here we show you in more detail

Create a standard
HTML document and
link to your CSS file.
Modernizr will give
you some backward
compatibility

content=IE=edge,chrome=1>
007 <meta name=viewport content=width=device-width,
initial-scale=1.0>

008
009
010
011

005 [id$=details] {
006 transform: scale(0, 0); }

012
013 <script src=js/modernizr.custom.js></script>
014 </head>
015
016 <body>
017
018 <div id=stage></div>
019
020 <script src=http://ajax.googleapis.com/ajax/libs/

In the following code, the hover states for each


stage are set and a short transition period is used in
order to achieve a slick-looking animation.

001 #timeline > g:hover [id$=badge], #timeline


>

g:hover [id$=details] {
transform: scale(1, 1); }
#timeline > g:hover [id$=title] {
transform: scale(1) translate(0px, 0px); }
[id$=badge], [id$=title], [id$=details] {
transition: transform 0.25s ease-in-out; }

The Stage ID is loaded in the


HTML body and finally
jQuery is loaded along with
the infographic script

16 Position project stages

By default, transformations to any SVG element


use the top-left of the SVG graphic (0px, 0px) as their
origin. This means that the positioning of each project
stage needs to be set before doing any transforming.
You should be able to obtain these co-ordinates by
referring to the centre point of each element in the
application you used in the SVG.

001
002
003
004
005
006
007
008
009

#stage-one {
transform-origin: 200px
#stage-one-badge {
transform-origin: 130px
#stage-one-title {
transform-origin: 110px
#stage-one-details {
transform-origin: 110px

200px; }
400px; }

The SVG is loaded into the


#stage ID and the .
svgLoaded class is applied
to the <div>

An error is generated if the


SVG cant be loaded. You did
remember to use Firefox or
upload the files to a web
server didnt you?

320px; }
320px; }

17 Go Intro sequence

This is triggered by the JavaScript file by adding


the .svgLoaded class to each of the elements. This
sequence runs pretty fast because you obviously dont
want to keep your visitors waiting too long while you
show off your various animation techniques.

<title>Interactive SVG using CSS and JavaScript</title>

<link rel=stylesheet type=text/css href=css/


infographic.css />

15 Set the hover transformations

002
003
004
005
006

001 <!DOCTYPE html>


002
003 <html lang=en>
004 <head>
005 <meta charset=UTF-8 />
006 <meta http-equiv=X-UA-Compatible

jquery/1.9.0/jquery.min.js></script>
021 <script src=js/infographic.js></script>

022
023 </body>
024
025 </html>
001
002
003
004
005
006

$(function()
{
$(#stage).load(infographic.svg,function(response){
$(this).addClass(svgLoaded);
if(!response){ // Error loading SVG
$(this).html(Error loading SVG. Be sure you are running
from a the http protocol (not locally));

007
008 }
009 });
010 });

If the SVG cannot be loaded, an error is


generated. Make sure you remember to use
Firefox or upload the files to server to
prevent this from happening

Web Design Tips, Tricks, & Fixes 93

Streamline
your workflow
with Bower
and Grunt
Create your own build process and
simplify your front-end headaches with
these two tools

json file and install all of the projects dependencies for


you. When specifying version numbers you can use a
similar convention to npms package.json; a full list of rules
can be found at http://bower.io/docs/api/#install.

001 dependencies: {
002
normalize.css: 3.*.*,
003
jquery: 2.1.1,
004
angular: *,
005
angular-animate: *,
006
angular-resource: *
007 }
008 $ bower install

06 List dependencies

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends AngularJS, JavaScript, HTML, CSS

ites are complicated. As web


developers we start with a nice fresh
index file and say to ourselves This
time Im going to do it right. You go to
jquery.com and click the download link,
you decide on a JS framework and find
that, then you start searching for a CSS
framework. Stop. Theres a better way
courtesy of the developers at Twitter. Its
called Bower, named after the bowerbird.
The bowerbird flies off and finds the most beautiful objects it
can to build its nest, sound familiar? Bower will find all of
these items for you and manage any dependencies they
may have.
Well look at how to use Bower to manage web projects
and well also use Grunt to interact with Bower and unleash
its full potential. Youll learn how to configure Grunt plugins
and how to setup a build process for your own site. The
result will be a concatenating (multiple files into one),
minifying build system. Bower was originally released in 2012
by Jacob Thornton (of Twitter Bootstrap fame) and Alex
MacCaw. Its now headed by a core team of seven talented
developers and is gaining traction.

01 Install Bower
Bower requires Node, npm, and Git to be
installed on your computer. If you dont have them
already then install Node from nodejs.org and Git from
git-scm.com/downloads. Both sites have installation
instructions for OS X, Linux, and Windows. npm is
installed with Node so you dont have to worry about
separately installing it.

001 $ npm install -g bower

94 Web Design Tips, Tricks, & Fixes

Once the packages have been installed you can


look at what your project consists of with the `list`
command. This will trigger a check for new versions
and show a tree structure with the version youre using
and the latest version (if there is one) next to it. The
paths flag will show you where each of the main files are
for that package.

001 $ bower list


002 $ bower list --paths

02 Search for packages


After Bower has installed you can use it from the
command-line and `search` will look for every package,
unfortunately for popular packages like jQuery and
Angular the number of plugins and unofficial packages
make it quite hard to find what youre likely looking for.
Fortunately though these packages can often be installed
by their common name.

001 $ bower search jquery

03 Install packages
In our fictional project were going to build a
complicated web app with different views, routing and
third-party dependencies. We can go for two approaches,
we could install them individually (as below) but for
long-lived projects it would be good to have a reference
for what our app depends on.

001 $ bower install jquery angular -S

04 Create bower.json
A bower.json file can quite easily be created
interactively through Bower itself via some yes or no and
also some multiple choice questions. If theres already an
existing bower.json it will replace the values within that file
(rather than creating a new one). The file contains
metadata about your project such as name, URL, and
importantly, dependencies.

001 $ bower init

05 Install from metadata


If you use `bower install`, it will look for a bower.

07 Project resources
A handy feature included with Bower is the
ability to easily go to the projects homepage (and
hopefully documentation as well) with just a single
command. This will then automatically open the site in
your default browser.
It doesnt always have the outcome you may expect
though, the code below takes you to the very specially
managed Bower-compatible version of Angulars
GitHub page.

001 $ bower home angular

08 Clean the cache


When Bower installs a package, it also caches that
version in your user folder to make it faster and work
offline next time (you can also force to use an offline
version with `--offline` or even simply `-o`). However, be
aware that over time this can accumulate to quite a few
versions! You can manage the cache by using the
following command:

001 $ bower cache clean

09 Update packages
If a new version of a package does become
available then you can update it with the following
command. If you decide that you dont want to include a
projects development dependencies, then add a
production flag. Bower will let you know if a new version
conflicts with a package so you shouldnt really be having
any nasty surprises.

001 $ bower update -p


002 # or

Streamline your workflow with Bower and Grunt

<Above>
s5IFTFEBZTJOTUBMMJOH/PEFBOEOQNJTB
DJODIXJUIUIFCJOBSZJOTUBMMFSGPSNPTU04T

<Above>
s:PVDBOFBTJMZDSFBUFBCPXFSKTPOXJUIUIF{JOJU{
DPNNBOECZBOTXFSJOHTJNQMFRVFTUJPOT

003 $ bower update angular

10 Uninstall a package
If you find that you no longer require a package
(or if you happen to --have installed one accidentally) then
you can remove it with the `uninstall` command. The
flags S and D stand for save and save dev respectively.
Passing these will then remove the package from the
projects bower.json file as well meaning it stays current.

001 $ bower uninstall angular-password

-SD

11 Install Grunt
Now that we know how to use Bower were going
to introduce another tool to improve our workflow, Grunt.
Despite its macho appearance and name its actually
quite useful. Grunt is a task runner and requires the
command-line interface to be installed globally and Grunt
itself within the project folder.

002
grunt.initConfig({
003
//further steps
004
});
005 };

13 Write package file


Were also going to create a separate file called
package.json. This is for npm to install packages relating
to our application (but not for the frontend). Like we
did with Bower you can create one interactively with
`npm init`. The main part that well concern ourselves
with in this file is `devDependencies` which we will look
at next.

001 {
002
003
004
005

001 $ npm install -g grunt-cli && npm


install grunt

12 Write Gruntfile
Grunt is configured with a Gruntfile, were going
to write one called Gruntfile.js. This is what Grunt looks
for when being run from the command-line. If you prefer
to write CoffeeScript then you can do that too, it
supports both with no additional configuration.
CoffeeScript does produce a nicer looking syntax so its
down to personal preference.

001 module.exports = function(grunt) {

<Top left>
s8JUIUIF{MJTU{DPNNBOEXFDBOTFFIPXPVS
QSPKFDUTEFQFOEFODJFTSFMBUFUPPOFBOPUIFS

006
007
008 }

name: deps,
version: 0.0.1,
description: An example of
package.json,
author: Tim Stone <you.name@
example.org>,
dependencies: {},
private: true

14 List development

<Above>
s3VOOJOH{JOTUBMM{XJMMJOEBMMPGUIFQSPKFDUTMJTUFE
JOCPXFSKTPOBOEGFUDIUIFNJOUPZPVSQSPKFDU

useful. Nodes `NODE_ENV` variable will change which


are installed.

001 devDependencies: {
002
grunt: ~0.4.5,
003
grunt-contrib-uglify: 0.5.*,
004
grunt-bower-concat: 0.3.*,
005
grunt-wiredep: 1.8.*
006 }

15 Install dependencies
Well then install all of our project dependencies.
The projects that we specified are: Uglify which minimises
files; Bower concat which concatenates files together; and
Wiredep, which will inject files installed with Bower into
our HTML files. Well look at each one in more detail when
we come to configuring.

001 $ npm install

16 Read package file


Back in our Gruntfile were going to configure our
Grunt plugins. The package.json file which we just created
will be read to add project-specific data, like directories
and app names. If your JSON isnt well-formed then this
will throw an error usually with the line number that it
couldnt parse.

dependencies
We list our build dependencies as devDependencies.
Imagine a scenario where our app is deployed to a new
production server, we want to install whats needed to run
it but not to build it. This is where the separation between
dependencies and development dependencies is really

001 pkg: grunt.file.readJSON(package.json),

17 Configure Concat
Each plugin to be configured is referenced by its
name (as a general rule hyphens are replaced with

Web Design Tips, Tricks, & Fixes 95

<Top left>
s-JLF#PXFS OQN
XJMMSFBEJUT
NFUBEBUBJMFBOE
JOTUBMMBMMPGUIF
EFQFOEFODJFTUIJT
DBOUBLFUJNF
<Top right>
s"GUFSUIFA6HMJGZ
UBTLIBTSVO PVS
NFSHFEJMFTXJMM
UIFOCFNJOJNJTFE
GSPN.#UP
,#

<Bottom left>
s#PXFS
DPODBUFOBUFXJMM
NFSHFPVS
EFQFOEFODJFTJOUP
POF TBWJOHPO
OFUXPSLSFRVFTUT

<Bottom right>
s/PXBMMPGUIF
QJFDFTBSF
UPHFUIFS SVOOJOH
{HSVOU{XJMMSVOPVS
tasks creatingBO
PQUJNJTFETJUF

underscores). We can specify variables in strings with


`<%= my_var %>` We also want to exclude all CSS files
from being included in the JS file, unfortunately bower_
concat doesnt accept a wildcard match.

001 bower_concat: {
002
all: {
003
dest: dist/<%= pkg.name

app/views/**/*.html
]

19 Uglify our files


%>.js,

004
005
006
007
008
}
009 },

004
005
006
}
007 },

Substituting
Gulp for Grunt

exclude: [normalize.css],
bowerOptions: {
relative: false
}

18 Configure Wiredep
Wiredep magically gets the correct file from
Bower and inserts a path to it in your HTML files. It also
supports Jade, Sass, and YAML without any additional
plugins. It has many other optional configuration options
at: https://github.com/stephenplusplus/grunt-wiredep
and its parent project:
https://github.com/taptapship/wiredep.

Minimising our files is taken kindly care of by


Uglify. The banner is the comment that appears at the
top of the file. We will then tell it to display our apps name
and when the code was generated. We then specify
where to output the code and what the source is (ie the
output of bower_concat).

001 uglify: {
002
options: {
003
banner: /*! <%= pkg.name %> <%=
grunt.

004
005
006
007

template.today(dd-mm-yyyy) %> */\n


},
dist: {
files: {
dist/<%= pkg.name %>.min.js:

96 Web Design Tips, Tricks, & Fixes

008
009
010 }

20 Load the tasks


Loading each of the tasks in turn is slightly
different to using `require` as you would in Node. Calling
`loadNpmTask` and the name of the plugin loads it into
the task runners environment. Failing to include one of
these will result in an error message reading: Warning:
Task uglify not found. Use --force to continue. Aborted
due to warnings.

001 grunt.loadNpmTasks(grunt-contrib-uglify);
002 grunt.loadNpmTasks(grunt-bower-concat);
003 grunt.loadNpmTasks(grunt-wiredep);

21 Register tasks

[<%=
bower_concat.all.dest %>]

001 wiredep: {
002
target: {
003
src: [

:PVDBOBMTPVTF(VMQBTB
UBTLSVOOFSCVUUIFSFBSFMFTT
PVUPGUIFCPYQBDLBHFTGPS
(VMQJODPNQBSJTPO
UP(SVOU

}
}

In this step we will register named groups of


tasks and an array of tasks in the order that they should
be run. When we run `grunt install` itll only run the
Wiredep task, if we run build then itll concatenate and

Streamline your workflow with Bower and Grunt

minify, and if we dont specify anything then it will run


all three.

001 grunt.registerTask(install, [wiredep]);


002 grunt.registerTask(build, [bower_
concat,
uglify]);
003 grunt.registerTask(default, [wiredep,
bower_
concat, uglify]);

22 Run it all
Finally we can execute it all with `grunt`. Without
any arguments it will run the task called default. To
execute a specific task all you have to do is `grunt build`,
or whatever youve named your task. If there are errors in
your files Grunts explicit error handling should save you.

001 $ grunt
002 $ grunt build
003 $ grunt install

23 Wiredep placeholders
For Wiredep to work we need to include the
following comments in our HTML file (or Jade, or
wherever you want to output them). Your project files will
then come after them. If for some reason you dont like
this text its configurable within the Gruntfile using a
regular expression.

001
002
003
004
005
006
007
008
009

<head>
<!-- bower:css -->
<!-- endbower -->
</head>
<body>
<!-- bower:js -->
<!-- endbower -->
<script src=../app.js></script>
</body>

24 Minify CSS
So far in this tutorial what we have been doing is
concentrating on concatenating and minimising our
JavaScript dependencies. Next we will then apply the
same principles to our CSS files. Although, Uglify only
works on JavaScript files, so you will have to include a
new CSS minimiser (one such as grunt-contrib-cssmin). It
would be very convenient to have one tool which would
do both concatenating and minimising of course but not
everyone wants that kind of overhead for their project.

25 CSS concat object


Well add a `css` object within bower_concat, the
task runner automatically picks up this new object so this
is the only extra configuration we need to get our CSS
packages working. We have to specify a main file as
otherwise the tool doesnt know which file in the package
to include.

001 bower_concat: {

002
003

004
005
006
007
008
009

css: {
dest: dist/<%= pkg.name
%>.dependencies
css,
include: [normalize.css],
mainFiles: {
normalize.css: normalize.
css
}
}
}

26 Concatenate CSS files


If you would like to further concatenate your own
app files with the dependencies then you will have to use
another concatenation tool (like grunt-contrib-concat).
This is because grunt-bower-concat only handles files
from Bower. Although its an extra step its easy enough to
configure it similar to the Bower one. Dont forget that you
will need to load it with `grunt.loadNpmTasks(gruntcontrib-concat)`.

<Above>
sGrunt has inserted the dependencies between the
placeholders with a relative link to them

001 concat: {
002
dist: {
003
src: [dist/*.css, app/ui/*.
004
005
006 }
007

css],
dest: dist/<%= pkg.name %>.css
}

27 Lesser known packages


Oftentimes in your projects youre going to be
using packages that arent known by a single name. You
can specify these either with the persons GitHub
username and the project name or if the code is
self-hosted then by specifying the URL. Note that these
projects will be flagged as extraneous and therefore they
wont benefit from easy updating and automatic
dependency resolving.

001 $ bower install samuelgbrown/jquery.


circular-carousel

002 $ bower install http://christophercliff.


com/sausage/
jquery.sausage.js

003

Alternative
workflows
An alternative to using Bower
and Grunt is a package
manager called Duo
(duojs.org). It looks like a
promising evolution and
integrates maintenance
and building.

28 Configure Bower
You can further configure Bower with a .bowerrc
file. This can be stored in multiple locations: your home
folder (~), the project folder, or root folder (/). Were not fans
of the name bower_components folder name and this is
the place that you can change it. Other examples are at
www.bower.io/docs/config. It follows a JSON format.

001 {
002
003 }
004

directory: dependencies

29 In review
Bower aims to help you manage dependencies
over the lifetime of your project and Grunt along with its
plugins enables you to use these packages to create
optimised versions of your project for production.
Theres no doubt that this duo goes a long way to
improve the current process, but the amount of
configuration and learning curve hampers what could
be a really great workflow.

Web Design Tips, Tricks, & Fixes 97

Manipulate
the DOM
with
AngularJS
Create an Angular application, with
custom directives to create lightbox
and accordion UI components

HTML page and you can then display any data defined in
$scope. In a browser window you should now see the
$scope.title value displayed in a H1 tag.

001 <!DOCTYPE html>


002 <html lang=en xmlns=http://www.
w3.org/1999/xhtml>

003 <head>
004 <meta charset=utf-8 />
005 <title>Angular UI App</title>
006 <script src=http://ajax.googleapis.com/

007

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends AngularJS, JavaScript, HTML, CSS

ngularJS is an application
framework that clearly separates
the DOM from any logic, by
means of a view (your HTML)
and a range of controllers (your
JavaScript logic). This is all held
together using directives, and
AngularJS has a huge range of
directives available. These are
used to join the DOM elements
with any data and logic held within your controllers and
are added to the markup as attributes. With jQuery for
example, the DOM elements are referenced from the
JavaScript and not the other way around. This means
that to get these DOM references, the entire (or a
significant portion) of the markup must be looped
through for each element.
As well as utilising the standard directives, custom
directives can be built. This tutorial will cover the creation
of such directives to provide both lightbox and
accordion UI components that can be easily reused.
Following this you will be able to create your own
custom directives for any custom UI interactions you
may need as part of your AngularJS application.

001 <!DOCTYPE html>


002 <html lang=en xmlns=http://www.
w3.org/1999/xhtml>

003 <head>
004 <meta charset=utf-8 />
005 <title>Angular Listing App</title>
006 <script src=http://ajax.googleapis.com/

007
008
009
010

02 Create the scripts

In your scripts folder create a folder for


modules. Then create a file named myApp.js in the
scripts folder and a file named ui.js in the modules
folder, reference these in your HTML page. Add the
following code to these files; this defines your core
application and uses dependency injection to add your
module to this application.

001
002
003
004

01 Set up the HTML

Start by adding a reference to AngularJS from the


Google CDN to your HTML page. Then add a reference to
your application on the body tag using an attribute as
shown. If you use the data-ng- prefix for your Angular
attributes as opposed to ng- your HTML will be valid.

98 Web Design Tips, Tricks, & Fixes

ajax/libs/
angularjs/1.2.15/angular.min.js></
script>
</head>
<body data-ng-app=uiApp>
</body>
</html>

//modules/ui.js
angular.module(ui.module,[])
//myApp.js
var myApp = angular.module(uiApp, [ui.
module]);

03 Add a controller

Define a controller in ui.js and pass in $scope. All


data and methods defined in this controller will extend
$scope. Add a reference to your new controller in your

008
009
010
011
012
013
014
015
016
017
018
019
020
021

022

ajax/libs/
angularjs/1.2.15/angular.min.js></
script>
<script src=scripts/modules/ui.js></Q
script>
<script src=scripts/myApp.js></script>
</head>
<body data-ng-app=uiApp>
<section data-ng-controller=uiCtrl>
<h1>{{title}}</h1>
</section>
</body>
</html>
//modules/ui.js
angular.module(ui.module, [])
.controller(uiCtrl, [$scope, function
($scope) {
use strict;
$scope.title = DOM manipulation with
AngularJS;
$scope.lightboxText = Some text that
should be
displayed in a lightbox;
}]);

04 Create your first directive

Create a directives folder and a file named


uiDirectives.js. In this newly created file you can create
a directive module named myLightbox as shown.
Then add this directive module to your application as
shown and add a reference to this new script file within
your HTML page, making sure myApp.js is the last script
file referenced.

001 angular.module(ui.directives, [])


002 .directive(myLightbox, function () {
003 use strict
004 return {
005
restrict: AEC,
006
template: <div class=lightbox>
<p>{{lightboxText}}</p></div>

007 }
008 };
009 //myApp.js
010 var myApp = angular.module(uiApp, [ui.
directives,ui.module]);

05 Use your directive

Now you can add your directive to the HTML. This

Manipulating the DOM with AngularJS

<Above>
s"MMJMFEPXOMPBETBSFBWBJMBCMFGSPNhttps://angularjs.org
PSPO(JU)VCBMPOHXJUIFYUFOTJWFEPDVNFOUBUJPOBOE
UVUPSJBMTPOCBTJDVTBHF

can be done by attribute (A), element (E), or class (C). This


can be restricted within the directive itself by changing
the restrict property. After this step we will use attributes
for the rest of this tutorial.

001 <section data-ng-controller=uiCtrl>


002 <h1>{{title}}</h1>
003 <!-- directive referenced using attribute

<Above>
s1SPQFSUJFTEFJOFEXJUIJOZPVSDPOUSPMMFSTDPQFBSF
BWBJMBCMFUPSFOEFSXJUIJOZPVS)5.-VTJOHBTUSBJHIU
GPSXBSEAIBOEMFCBSTTZOUBY

that should be in another lightbox;

006
007
008
009

<div data-my-lightbox></div>
<!-- directive referenced using element
-->
<my-lightbox></my-lightbox>
<!-- directive referenced using class
-->
<div class=my-lightbox></div>
</section>

022

template: <div
class=lightbox><p>{{content.
text}}</p><button data-ngclick=content.testFunc
()>click me</button></div>

015 //myApp.html
016 <div data-my-lightbox data-mycontent=lightboxText>
</div>
017 <div data-my-lightbox data-mycontent=lightboxText2>
</div>

-->

004
005

<Above>
s5IFMJHIUCPYEJSFDUJWFSFOEFSTUIFNBSLVQEFJOFECZJUT
UFNQMBUFQSPQFSUZJOBMMJOTUBODFT BOEUIJTNBSLVQIBT
BDDFTTUPUIFDPOUSPMMFSTDPQF

07 Passing functions

You are not limited to just passing strings into a


directive; you can pass any object in from the controller
$scope. Create a new object in your controller with a
text property and function that fires an alert. Now adjust
the directive template property with a data-ng-click
binding and you will be able to run this function from
your lightbox.

023 }
024 });

08 Toggling the lightbox

If we want to hide and show the lightbox we


need a Boolean property on the $scope.lightboxObject
that defaults to false. Then change
$scope.lightboxObject.testFunc to a toggleView
function that switches this property.

001 $scope.lightboxObject = {
002 text: some text as a separate property
in an

06 Isolating directive scope

This directive will only support one instance within


the same controller as the same content will be displayed
each time. To fix this we need to isolate the scope of the
directive. Attributes can be passed to a directive and
added to the scope property. We will use my-content as
an attribute.

001 angular.module(ui.directives, [])


002 .directive(myLightbox, function () {
003 use strict
004 return {
005
restrict: AEC,
006
scope: {
007
contentText: =myContent
008
},
009
template: <div class=lightbox>
<p>{{contentText}}</p></div>

010 }
011 });
012 //modules/ui.js
013 $scope.lightboxText = Some text that
should be
displayed in a lightbox;
014 $scope.lightboxText2 = Some different text

001 <section data-ng-controller=uiCtrl>


002 <h1>{{title}}</h1>
003 <!-- directive referenced using attribute
-->

004
005
006
007
008

009
010
011
012
013
014
015
016
017
018
019
020
021

<div data-my-lightbox data-my-content=


lightboxObject></div>
</section>
//modules/ui.js
$scope.lightboxObject = {
text: some text as a separate property
in an
object,
testFunc: function(){
alert(testFunc is running);
}
}
//directives.uiDirectives.js
angular.module(ui.directives, [])
.directive(myLightbox, function () {
use strict
return {
restrict: AEC,
scope: {
content: =myContent
},

object,

003 visible: false,


004 toggleView: function () {
005
this.visible = !this.visible;
006 }
007 }

09 Add toggle controls

Within the directive template property we need to


add a close button that calls our toggleView function and
a data-ng-show attribute to set the display state of the
lightbox. Then add a button within your HTML that calls
the toggleView function. Use the data-ng-click attribute to
bind the functions.

001 //directives/uiDirectives.js
002 template: <div class=background data-ngshow=
content.visible></div><div
class=lightbox
datang-show=content.visible>><button data-ngclick=
content.toggleView()>close</
button><p>{{content.

Web Design Tips, Tricks, & Fixes 99

<Above>
sBy isolating the directive scope you can render different
content across multiple instances of a directive

<Above>
sFunctions defined within the controller $scope
can be run from within a directive

<Above>
sCombining the data-ng-show attribute and a Boolean property in
the controller makes it really easy to hide and show the lightbox

class=lightbox data
-ng-show=content.visible><button
data-ng-click=
content.toggleView()>close</
button><div

text}}</p</div>

003 //myApp.html
004 <section data-ng-controller=uiCtrl>
005 <h1>{{title}}</h1>
006 <!-- directive referenced using attribute
data-ng-

-->

007

<div data-my-lightbox data-my-content=


lightboxObject></div>
008 <button data-ng-click=lightboxObject.
toggleView
()>Show lightbox</button>
009 </section>

10 The transclude property

The problem now is we would have the same


HTML structure for the content of each lightbox. This is
where the transclude property comes in. It passes the
content of the directive reference into the directive itself
including any bindings to the controller $scope. Set the
transclude property to true within your directive and then
add the attribute data-ng-tansclude in the directives
template property.

001 angular.module(ui.directives, [])


002 .directive(myLightbox, function () {
003 use strict
004 return {
005
restrict: AEC,
006
transclude: true,
007
scope: {
008
content: =myContent
009
},
010
template: <div class=background
data-ng-show=
content.visible></div><div

100 Web Design Tips, Tricks, & Fixes

transclude></div></div>

011 }
012 });

11 Add your lightbox content

You can now put any HTML content you wish


within your lightbox in myApp.html. This content has
direct access to everything within controller $scope so
you can reference your lightbox content from $scope.
lightboxObject.text as well as any other functions or
values set within the controller. Remember this HTML
doesnt have access to the directive scope so {{content.
text}} will not work.

001 <div data-my-lightbox data-mycontent=lightboxObject>


002 <h2>The title of my lightbox</h2>
003 <p>{{lightboxObject.text}}</p>
004 </div>

12 Simplify the HTML

We can simplify our HTML by passing $scope.


lightboxObject to the directive attribute itself. Any
attributes set on a HTML element are available within a
directive but this will keep our markup a bit tidier.

Directive naming
It is best practice to always prefix
your directive names. This will avoid
any conflicts with future changes in
HTML elements. Do not us ng as a
prefix as this would then confuse
custom directives with the standard
set provided as part of AngularJS.
Also note that when referenced in
HTML the directive names are
hyphenated opposed to
being camel case.

004 scope: {
005 content: =myLightbox
006 }

13 Separate the directive

template

You may find it gets difficult to read and manage the


template property as a string if it gets larger. Alternatively
a templateUrl property can be set that references a path
to a HTML file that holds this structure. Separate the
lightbox template HTML into a file and reference it from a
templates folder as shown.

001 //directives/templates/lightbox.html
002 <div class=background data-ngshow=content.visible></div>

003 <div class=lightbox data-ng001 //myApp.html


002 <div data-my-lightbox=lightboxObject>
003 //directives/uiDirectives.js

004

show=content.visible>
<button data-ng-click=content.
toggleView()>close</button>

Manipulating the DOM with AngularJS

005 <div data-ng-transclude></div>


006 </div>
007 //directives/uiDirectives.js
008 templateUrl: scripts/directives/templates/
lightbox.html

14 Add an accordion directive

Now we have our lightbox directive all working we


can start the accordion component. This will require two
nested directives: myAccordion and myItem. Firstly create
the myAccordion directive with transclude set to true and
a very simple template.

001 .directive(myAccordion, function () {


002 use strict
003 return {
004
restrict: AEC,
005
transclude: true,
006
template: <div class=accordion
data-ng-transclude></div>

007 }
008 })

15 Add a controller

This directive will need some functionality defined


within it so we need to create a controller inside the
directive itself. Inside this controller create an empty array
called items and an addItem function to push items to this
array. We will use these shortly.

001 controller: function($scope, $element){


002 this.items = [];
003 this.addItem = function (item) {
004
this.items.push(item);
005 };
006 }

16 Create the item directive

Now, lets create the myItem directive with the


require property set to ^myAccordion. This denotes
that this directive can only be used as a child of
myAccordion. We will need some things to be set up
when this directive is called so add a function to the link
property as shown.

001 .directive(myItem, function () {


002 use strict
003 return {
004
restrict: AEC,
005
require: ^myAccordion,
006
transclude: true,
007
link: function(scope, element, attrs,
parentCtrl){
008
// code here will run when the
directive is called
009
},
010
template: <div
class=accordionContent data-ng-transclude></
div>
011 }

012 })

17 Add your accordion HTML

Now add some accordion items to your HTML


using these two directives. Once this is done you
should see the HTML structure changed to match
the directives templates when you inspect in a
browser. You can define any desired content within the
accordion items.

001 <div data-my-accordion>


002 <div data-my-item>
003
<p>Some intro text to this

19 Extend the accordion items

accordion

item</p>

004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027

parentCtrl){
013
// code here will run when the
directive is called
014
},
015
template: <h2>{{title}}</h2><div
class=accordionContent data-ng-transclude></
div>
016 }
017 });

<ul>
<li>Bullet item 1</li>
<li>Bullet item 2</li>
<li>Another bullet item</li>
</ul>
</div>
<div data-my-item>
<h3>A sub heading</h3>
<p>Some text for the second
accordion</p>
<ol>
<li>Numbered item 1</li>
<li>Numbered item 2</li>
<li>Another numbered item</li>
</ol>
</div>
<div data-my-item>
<p>Some intro text to the last
accordion item</p>
<ul>
<li>Bullet item 1</li>
<li>Bullet item 2</li>
<li>Another bullet item</li>
</ul>
</div>
</div>

18 Add titles

Now add a title attribute to each myItem in the


HTML and create a title for each item within the myItem
directive. The title attribute can be added to the directive
scope with an @ symbol if using the same namespace as
the attribute.

001 <div data-my-item title=Accordion item 1>


002 //directives/uiDrectives.js
003 .directive(myItem, function () {
004 use strict
005 return {
006
restrict: AEC,
007
requires: ^myAccordion,
008
transclude: true,
009
scope: {
010
title: @
011
},
012
link: function(scope, element, attrs,

To set and control the open state of an item we


need to extend the scope of the item within the link
function. Add scope.open as a Boolean defaulted to false
and scope.toggle as a function toggling this state. Then
make sure you use data-ng-show and data-ng-click within
the template.

001 link: function(scope, element, attrs,


parentCtrl){

002 scope.open = false;


003 scope.toggle = function () {
004
if (scope.open) {
005
scope.open = false;
006
}
007
else {
008
scope.open = true;
009
}
010 };
011 },
012 template: <h2 data-ngclick=toggle()>{{title}}</h2><div
class=accordionContent data-ng-transclude
data-ng-show=open></div>

20 Automatically close items

You can now open and close accordion items but


only one item should open at a time. To fix this you need
to give the myAccordion directive a reference to each
item. You can call parentCtrl.addItem() from the myItem
directive and push your item scope to this array.

001 parentCtrl.addItem(scope);

21 Add a closeMe function

The myAccordion directive needs to be able to


close all items. So now add a closeMe function to each
item keeping the close functionality within the item
scope. Your myItem directive should now be ready. See
the full code at http://www.filesilo.co.uk/bks-594 for
more information.

You can
define any desired
content within the
accordion items
Web Design Tips, Tricks, & Fixes 101

Create a scaling
hover effect
inspiration www.fancyfeast.com

he hotly-tipped new word for


the 2015 edition of the Oxford
English
Dictionary
is
showrooming: the practice of
examining merchandise in a
traditional retail store without
purchasing, but then shopping
online for the same item. Online
retailers would probably rather we didnt feel
the need to go out and touch the things we

INSPIRATION
Move me

Sometimes its the small touches, the little


visual prompts that say, Yes, I noticed that,
Im ready if you need me. These cues help
show the user the site is alive, ready to share
its content with you if youre ready to explore.
The agency responsible for bringing
Fancy Feast to life, ROKKAN, needed to
want to buy, but the cold, hard surface of a
make the site as appetising to users as the
computer monitor or smartphone screen can
products are to their ultimate consumers
act as a barrier to the buying experience
cats! The large square panels are a major
and thats why online interaction
feature of the site with a subtle scaling effect,
is so important. While we may
just enough to make them interesting. With
Are we there yet?
not be able to touch it, we
so much to explore, there seems to be
Did you know the first CSS3 drafts
can present the product
were published in 1999? Since
no need to go anywhere else, and
then, CSS3-enabled techniques
in a way that is fun and
every site visitor who agrees is
like rounded corners and drop
interactive we can
another confirmation of the
shadows have gone out of
move people.
effectiveness of this site.
fashion. Still, there is a chance
theyll be back by the time that
the CSS3 specification is finalised.

3
Unique 404 pages

A customised 404 page


is a really great way of
grabbing hold of your
lost user before they
head somewhere else.
With a little creativity,
they are also a great
opportunity to
reinforce the brand.

Responsive layout

Visual appeal

Number of pages

Hidden gems

Brand trust

The magazine-style layout is


friendly and accessible. The
responsive design has also
been tweaked to suit
everything from the largest
screen to the smallest

It may be cat food but it looks


appetising. The site contains
only the highest quality
images, the product range,
and more than a few pictures
of some cute cats

The site is a useful reminder not to


try and second guess the number of
site pages a new client might require
you probably wouldnt have
factored in a requirement for over
one hundred products

A little like an advent calendar


door, youre invited to click to
reach deeper into the site and
rewarded with a variety of hover
transformations in different
parts of the page

Customer testimonials,
product ratings and
social media are given
prominence within the
site layout, reinforcing
trust in the brand

102 Web Design Tips, Tricks, & Fixes

Create a scaling hover effect

Sticking to simplicity
<comment>
What our
experts think
of the site

The workshop files have purposely been kept simple in order to focus on the
technique and will work without problems in the current version of Firefox. Out in
the wild, youll need cross-browser support and there are a number of ways of
achieving this. One simple method you might want to check out is prefixr.com.
Jayson Winters

TECHNIQUE
Create a scaling
hover effect
01 Set some styles

ROXXAN wasnt tempted to add a cats paw


background, but the workshop layout is a little sparser,
so paws it is. With no other text on the page, the body
attribute has been co-opted to display caption text.

001
002
003
004
005
006
007
008
009
010
011

html {
background: url(paw.png) repeat;
}
body {
color: #eee;
font-family: sans-serif;
font-size: 20px;
font-weight: 800;
line-height: 1.75;
text-align: center;
}

02 Centre in browser
Centring content should be a straightforward
task, but the longer you look into the subject, the more
youll end up being reminded of Jack Nicholson in A
Few Good Men You want centred content? You cant
handle centred content!. Anyway, its just about handled
here in the following snippet.

001
002
003
004
005

#container {
margin-top:200px;
float:right;
position:relative;
left:-50%;

Know your audience


It is so important to know your target audience
and what appeals to them once you do, youll
have them eating out of the palm of your hand.

006
007
008
009
010

}
#inside {
position:relative;
left:50%;
}

TECHNIQUE
Experiment with
transformations
With about twenty transform property
values, you can scale, skew, translate, etc, any
element in a 2D or 3D plane. But just
because you can, doesnt mean you should.
Dont sacrifice legibility or usability.

01 Up a bit

The transform property is most


useful when it is used subtly, like the nod of
a head or the wink of an eye. Here the
property transform: translateY(-15px) is used
to move the <div> up by 15px.

03 Create your scalable <div>

The natural state of this <div> is its non-hovered


state, and the transition value used here determines
how long it takes to return to this state after it has been
transformed in some way. 0.3s is snappy, but not jarring
like 0.0s would be.

001
002
003
004
005
006
007

div.scales {
width:400px;
height:272px;
float:left;
transition: 0.3s ease-out;
padding: 0px 10px 50px 10px;
}

04 Set the hover state

02 Round a bit

Here transform: rotate(10deg); is used


primarily so the effect can be seen in the
picture but something like 5deg or less
would be sufficient in normal use.

Here is the important line that specifies the exact


transformation that is required. The whole <div> and
any images or text that are contained within it is to be
scaled down to 90 per cent of its original size in both
the X and Y dimensions.

001
002
003
004

div.scaleOn {
transform: scale(0.9,0.9);
transition: 0.3s ease-out;
}

05 Create the HTML

The onmouseout and onmouseover events are


used to execute JavaScript at the strategic points that
their names would suggest. In this case, the <div> already
has the class (scales) and is having the value of scaleOn
added to it when the onmouseover event occurs.

03 Skew a bit

Transform: skew(5deg,5deg); is used


here to tweak the X and Y dimensions at the
same time. Its also possible to make 3D
transformations. Take a look at the examples
available online to see what other people
have achieved using the transform property.

001 <div id=container>


002 <div id=inside>
003 <div class=scales
onmouseout=this.className=scales
004 onmouseover=this.className=scales
scaleOn>
005 <img src=2todinner.jpg>TWO HOURS
UNTIL DINNER
006 </div>

Web Design Tips, Tricks, & Fixes 103

Produce a 3D
directionaware hover
effect
Present your portfolio using JavaScript
and CSS to create a 3D effect
tools | tech | trends HTML, CSS and JavaScript

t the heart of all digital technology


everything is just on or off.
Ultimately, it all reduces down to a
binary state; a one or a zero. Hover
states are like this as well because
either you are hovering over
something or you are not. The
demonstrated technique uses a
small amount of JavaScript to
determine the cursors direction of
travel and trigger direction-aware animations.
This creates a new experience for the user that cries out for
the user to interact with it. A little like trying to eat a
doughnut without licking your lips, as soon as you have
experienced the effect in action, you cant quite stop
yourself from having a little play with it. Like trying to see if
the fridge light actually goes out when you close the door,
you might even find yourself trying to catch it out. Its
certainly interesting to see how the experience changes
depending on the speed of the cursor and also the speed
of the animations. Interacting with the effect moves the
user from passive browsing to being an active and
engaged visitor, so maybe by using this technique youll be
able to turn your site visitors from off to on as well!

01 CSS first

This technique uses CSS3 animation triggered by a


small amount of JavaScript. It doesnt require the jQuery
library either, so is very lightweight. The CSS starts by
loading suitable fonts for the project courtesy of Google
fonts. Next, the widely used box fix technique is added and
finally Chris Coyiers Perfect Full Page Background Image
technique (css-tricks.com) as well.

104 Web Design Tips, Tricks, & Fixes

03 Header and link styles

The h1 heading and paragraph text will sit inside a


<header> <div> and the text is centred here. Some styling is
applied to the links. Its worth taking time to look at details
such as link styling as it can really improve the usability and
visual appeal of your site for not a great deal of effort.

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

001 header {
002 text-align: center;
003 margin: 50px 0 25px;
004}
005 a:link {
006 color: #fff;
007 text-decoration: none;
008 }
009 a:visited {
010 color: #40eaee;
011 text-decoration: none;
012 }

04 Text styling

Finally the paragraph text in the header is styled.


Margins have already been applied around the h1 and the
header itself, so the paragraph text margin is set to 0. When
choosing web fonts its helpful to check how they look on
different browsers to ensure you get good results.

001 @import url(http://fonts.googleapis.com/


002
003
004
005
006
007
008
009
010
011

css?family=Bangers|Sofadi+One);
* {
box-sizing: border-box;
}
html {
background: url(../images/bg.jpg) norepeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}

02 Heading and container

A negative pixel value for the text-shadow is used to


move the shadow upwards rather than the usual shadow
below. The page is styled here at a fixed width but the
technique will still work properly with responsive layouts
all youll need to do is add in some additional code to
centre the content on the page.

001
002
003
004
005
006
007
008
009
010
011
012

h1 {
margin: 0 auto 5px;
text-align: center;
font-size:70px;
color: #00acae;
text-shadow: 0px -4px #fff;
font-family: Bangers, serif;
}
.container {
width: 840px;
margin: 0 auto;
}

001
002
003
004
005
006

header p {
margin: 0;
font-size: 13px;
color: #00acae;
font-family: Sofadi One, serif;
}

05 The unordered list

Perhaps not unexpectedly, this technique uses the


unordered list as its framework, with each gallery item
designated as a list item. The pseudo-element ul:after is
used to apply the Clearfix Hack (also known as the Easy
Clearing Hack) described in detail here: bit.ly/1iiHKeb.

001
002
003
004
005
006
007
008
009
010
011
012

ul {
padding: 0;
margin: 0 0 50px;
}
ul:after {
content: ;
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}

06 Style the gallery

The list item (li) is used for each item within the
gallery. The various dimensions can easily be changed
without breaking the technique. You might want to remove
the rounded corners (border-radius) if youre going for the
full Windows Metro look.

Produce a 3D direction-aware hover effect

<Left>
sBeing direction aware isnt
a super power, so its not on
the list. However, if it
encourages your site visitor
to linger a little bit longer,
stimulates their interest, or
perhaps triggers an enquiry,
you might find that the
technique has a commercial
power for you

001
002
003
004
005
006
007
008
009
010
011
012
013

li {
position: relative;
overflow: hidden;
border-radius: 10px;
list-style: none;
float: left;
width: 200px;
height: 180px;
margin: 5px;
padding: 0;
perspective: 500px;
font-family: Sofadi One, serif;
}

07 Link and heading

If you are using a rounded corner effect it also


needs to be applied to the link. Inline-block is used to tell
the browser to display each item inline (ie without starting a
new line) but to retain their block-level characteristics that
means their width and height can be set.

001
002
003
004

li a {
display: inline-block;
vertical-align: top;
text-decoration: none;

005
006
007
008
009
010
011
012
013
014
015
016

border-radius: 10px;
}
li h3 {
margin: 0;
font-size: 18px;
color: rgba(255, 255, 255, 0.9);
}
li p {
font-size: 12px;
line-height: 1.5;
color: rgba(255, 255, 255, 0.8);
}

08 Style the gallery item

The normal state of the gallery item is the


mouseout state. This tutorial uses a full-sized picture so no
styling is needed but if you are going to put text in here,
li.normal is where youd style it. The overlay does have text
and has more styling applied.

001
002
003
004
005

li.normal {
width: 100%;
height: 100%;
}

Playground rules
Hats off to Mexican front-end
developer Noel Delgado who
published this technique at
CodePen (codepen.io)
the playground for
the front-end side
of the web.

006
007
008
009
010

li .info {
width: 100%;
height: 100%;
padding: 20px;
position: absolute;

09 Overlay

This element swings into place when it is triggered


by the JavaScript, so pointer-events is set to none to avoid
the default HTML-targeting behaviour conflicting with the
JavaScript. The transform is used to render the overlay
invisible until its needed. If you want each gallery item to be
covered initially when the page loads, just remove this line.

001 top: 0;

Web Design Tips, Tricks, & Fixes 105

<Left>
sBeing
direction-aware
enables you to
provide novel
methods of
interaction. Okay,
so its not quite the
Minority Report
experience yet but
gesture-based
interaction is
getting closer all
the time

Knowledge is power
Understanding the direction of the mouse
movement makes this an interesting technique
that you can build on. You can trigger additional
animations to provide more functionality, eg
making two icons appear: one to provide a gallery
image zoom option and the other to link to
another page or website. However you could also
use this technique to simulate a gesture-based
(albeit using the mouse) interface. Swiping the
mouse over the hotspot to the left or right might
trigger one response (eg paging backwards or
forwards) and swiping down or up another
response (eg moving deeper or higher in a
hierarchical structure). You could even trigger
different tooltips based on the direction of your
mouseover, for example, mousing from the top
for a brief description or from the bottom for a
more detailed version.

Cross-origin
requests
Youll need to review this in
Firefox unless you want to
run a local server or keep
uploading and reviewing
each change online.

010 transform-origin: 50% 100%;


011 animation: in-bottom 500ms ease 0ms 1
012
013
014
015
016

002
003
004
005
006
007
008

left: 0;
overflow: hidden;
border-radius: 10px;
pointer-events: none;
background-color: #00acae;
transform: rotate3d(1, 0, 0, 90deg);
}

10 The mouseover state

There are four possible mouseover states. The


mouse may enter from the top, right, bottom or left. The
JavaScript takes care of allocating the correct class and
the difference between each .in class is the position of the
transform-origin. This is the point around which the
element will then rotate.

001 .in-top .info {


002 transform-origin: 50% 0%;
003 animation: in-top 500ms ease 0ms 1
forwards;
}
.in-right .info {
transform-origin: 100% 0%;
animation: in-right 500ms ease 0ms 1
forwards;
008 }
009 .in-bottom .info {

004
005
006
007

106 Web Design Tips, Tricks, & Fixes

forwards;
}
.in-left .info {
transform-origin: 0% 0%;
animation: in-left 500ms ease 0ms 1
forwards;
}

11 The mouseout state

These states exactly match their sisters mouseover


origin points. Imagine a door opening and then closing
on the same rotation point. The direction of the animation
(the opening or closing effect) is set in the following steps
of code.

001 .out-top .info {


002 transform-origin: 50% 0%;
003 animation: out-top 500ms ease 0ms 1
004
005
006
007
008
009
010
011
012
013
014
015
016

forwards;
}
.out-right .info {
transform-origin: 100% 50%;
animation: out-right 500ms ease 0ms 1
forwards;
}
.out-bottom .info {
transform-origin: 50% 100%;
animation: out-bottom 500ms ease 0ms 1
forwards;
}
.out-left .info {
transform-origin: 0% 0%;
animation: out-left 500ms ease 0ms 1
forwards;
}

12 Animation keyframes in

The rotate3d method enables you to specify the


axis of rotation (X, Y or Z) as the first three values and the
last value is the degree of rotation. When the mouse comes
in from the top, the animation starts with the element
rotated on its X axis at 90 degrees to the screen and then
transforms to a non-rotated position.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016

@keyframes in-top {
from {
transform: rotate3d(-1, 0, 0, 90deg);
}
to {
transform: rotate3d(0, 0, 0, 0deg);
}
}
@keyframes in-right {
from {
transform: rotate3d(0, -1, 0, 90deg);
}
to {
transform: rotate3d(0, 0, 0, 0deg);
}
}

13 Animation keyframes out

Each in animation has its corresponding out


version. When the mouse moves out of the list item
element the overlay is animated from its non-rotated
position to being roughly at right angles to the screen. To
have the element fully disappear you need to rotate it just a
little more 102 degrees should just about do the trick.

001 @keyframes out-top {


002 from {
003
transform: rotate3d(0, 0, 0, 0deg);
004 }

Produce a 3D direction-aware hover effect

005
006
007
008
009
010
011
012
013
014
015
016

to {
transform: rotate3d(-1, 0, 0, 102deg);
}
}
@keyframes out-right {
from {
transform: rotate3d(0, 0, 0, 0deg);
}
to {
transform: rotate3d(0, -1, 0, 102deg);
}
}

Code library

Extended JavaScript
Got lost along the way? Dont panic, we delve into some of the intricacies of the code below
Each of the list items are
selected and converted
into an array with the
variable name nodes

14 Set the head

Noel Delgado has provided detailed comments on


steps taken to improve compatibility across different
browsers, new and old, so if you are considering using this
technique and are concerned about compatibility, please
do check out the notes with the original solution files in the
downloads. Prefixfree.js is loaded to avoid having to
manually add vendor prefixes to the experimental CSS3.

007
008
The logic for calculating the
mouse direction is discussed
here: stackoverflow.com/
questions/3627042 but
might not be too helpful
unless you know your atan2
from your modulo

15 Set the header

The HTML has purposely been kept simple to help


explain the technique. With a real site youre likely to have a
whole interface to load first. This header element is
assigned its own <div> and given the container class that
fixes the width of the header and centres it on the page.

001 <body>
002 <header>
003 <div class=container>
004
<h1>Most wanted super powers</h1>
005
<p>According to <a href=
http://www.ranker.com>Ranker</a> with some
descriptions from <a href=http://
powerlisting.wikia.com/wiki/Superpower_
Wiki>Superpower Wiki</a><br />Creative
Commons images link to originals at
Flickr</p>
006 </div>
007 </header>

001 var nodes = document.querySelectorAll(li),


002
_nodes = [].slice.call(nodes, 0);
003 var getDirection = function (ev, obj) {
004
var w = obj.offsetWidth,
005
h = obj.offsetHeight,
006
x = (ev.pageX - obj.offsetLeft - (w / 2) *

The switch statement is


used to select which
class_suffix to add based
on the returned direction

An event listener
determines whether the
mouse is inside a list item
element (and adds in to the
class) or if it is outside

(w > h ? (h / w) : 1)),
y = (ev.pageY - obj.offsetTop - (h / 2) *
(h > w ? (w / h) : 1)),
d = Math.round( Math.atan2(y, x) /
1.57079633 + 5 ) % 4;

009
010
return d;
011 };
012 var addClass = function ( ev, obj, state ) {
013
var direction = getDirection( ev, obj ),
014
class_suffix = ;
015
016
obj.className = ;
017
018
switch ( direction ) {
019
case 0 : class_suffix = -top;
break;
020
case 1 : class_suffix = -right; break;
021
case 2 : class_suffix = -bottom; break;
022
case 3 : class_suffix = -left; break;
023
}
024
025
obj.classList.add( state + class_suffix );
026 };
001 _nodes.forEach(function (el) {
002
el.addEventListener(mouseover, function (ev) {
003
addClass( ev, this, in );
004
}, false);
005
el.addEventListener(mouseout, function (ev) {
006
addClass( ev, this, out );

16 Start of list

You can put anything within the anchor tags, in


which case you might need to style the li .normal class. The
tutorial just uses images sized to the <div> (200px x 180px)
so no detailed styling is needed. The content within the
<div> class info is what swings into place on hover.

001 <div class=container>


002 <ul>
003
<li>
004
<a class=normal href=http://bit.
ly/1fZuF9K><img src=images/1.jpg alt=>
</a>
005
<div class=info>
006
<h3>#1 Teleportation</h3>
007
<p>The power to transfer matter or
energy from one point to another without

traversing the physical space between them.


</p>
008
</div>
009
</li>

17 End of list

The li .info is used for styling the hover overlay. You


can create additional classes if you want the overlays to
have different coloured backgrounds to each other, for
example. A great deal has been written on when and how
to load scripts but in this relatively simple page, calling the
script at the bottom of the page makes sense.

001 <li>

002

<a class=normal href=http://bit.


ly/1nDql5n><img src=images/12.jpg
alt=></a>
003
<div class=info>
004
<h3>#12 Super Strength</h3>
005
<p>The power to exert super physical
strength.</p>
006
</div>
007
</li>
008 </ul>
009 </div>
010 <script src=js/index.js></script>
011 </body>
012 </html>

Web Design Tips, Tricks, & Fixes 107

Create a shake
effect using CSS3
animation

inspiration cervezaaustral.cl/viajealorigen
his website for a Chilean beer
makes use of the countrys
scenery to sell the product.
The bottle is shown against a
series of backgrounds that
promote the idea of the product
being produced using natural
ingredients. Clever photography also blends the
bottle into the landscape.

INSPIRATION
Interactivity

One of the most engaging ways to connect


with your website visitors is to create rich
interactive elements that will take them by
surprise, and encourage them to continue
further exploring of your website. This
website uses such an approach to make
both the landscape and the bottle react to
the users mouse positioning, while also
allowing the product to always appear at the
focal centre of the composition.
There is also a series of videos explaining
Fullscreen images are currently very
the processes behind the brewing of
popular in web design, and help to
the beer, and this beautiful fullscreen
create an immersive feel that
Fullscreen product
presentation of both the imagery and
draws the visitor into the site.
placement
videos helps to create an immersive
Cervaza Australs site uses
The beer bottle has been placed
user experience. This already great
this technique not just for
at the focal point of the
composition, reflecting the
user experience is then further
the images, but also the
landscape around it with the
heightened by the use of parallax
five videos that tell the
graphical depiction of mountains
scrolling and interactive elements.
story of the beer.
on the bottle matching
those in the backdrop.

1
3
Individual elements Parallax motion

Reactive elements

Realism

Marketing

Navigation

The background is
composed of several
elements which move and
scale independently to
ensure that the bottle
remains the focal point

The bottle reacts to user


input, and is also reused
across the first three
slides, showing it in
context across different
parts of the landscape

The bottle is partially


transparent in the centre,
so the background remains
visible through the glass.
This lends realism, placing
the bottle in the scene

The product itself features


imagery that reflects the
background. This helps to
connect the two in the
composition, cementing the
marketing message of nature

The arrow moves the


entire slide off screen.
There are four slides in
total, with the final slide
a fullscreen shortcut to
five different videos

The clouds move in


response to the mouse
position, creating a nice
sense of parallax motion
as the user interacts with
the website

108 Web Design Tips, Tricks, & Fixes

Create a shake effect using CSS3 animation

Fullscreen images and video


<comment>
What our
experts think
of the site

This site makes good use of the current trend towards images and video that
fill the screen, regardless of how large the browser window is. Movement
between the different slides that make up the site is fluid, and the parallax
effects work to help create a sense of depth.
Sam Hampton-Smith

TECHNIQUE
Shake your bottle
with CSS3
01 Some basic HTML

Our page doesnt require much in the way of


HTML markup. A simple <div> for the bottle (although
an image would have done equally well), and an image
for the bottle to sit on is sufficient. Theres no need for
any scripting with this technique at all!

02 Add basic styles

The body element will be given a background


image thats set to fill the screen, regardless of window
size. Well add the styles at this stage for the bottle, so
add the code to your HTML document between the
style tags, within the <head> section. Note the
background-size, forcing the image to fill the space.

03 Create an animation
We need to define a preset animation that will be
applied to the bottle when its hovered over. To do this
we use the @-keyframes directive. Were testing in
Chrome, so to save replicating the code for all vendor
prefixes, weve just used the WebKit variant. You should
ensure you cover all vendors in your code.

001 @-webkit-keyframes shake {


002
0% { -webkit-transform:
translate(2px, 1px) rotate(0deg); }
003
10% { -webkit-transform:
translate(-1px, -2px) rotate(-2deg); }
004
20% { -webkit-transform:
translate(-3px, 0px) rotate(3deg); }

Our bottle starts to shake when the mouse moves


over it, and stops shaking when the mouse moves
out. This is achieved using the :hover class and
CSS animation keyframes no need for scripting!

005
30% { -webkit-transform:
translate(0px, 2px) rotate(0deg); }
006
40% { -webkit-transform:
translate(1px, -1px) rotate(1deg); }
007
50% { -webkit-transform:
translate(-1px, 2px) rotate(-1deg); }
008
60% { -webkit-transform:
translate(-3px, 1px) rotate(0deg); }
009
70% { -webkit-transform:
translate(2px, 1px) rotate(-2deg); }
010
80% { -webkit-transform:
translate(-1px, -1px) rotate(4deg); }
011
90% { -webkit-transform:
translate(2px, 2px) rotate(0deg); }
012
100% { -webkit-transform:
translate(1px, -2px) rotate(-1deg); }
013 }

04 Apply the animation

We can apply our animation automatically to the


bottle element by creating a pseudo class for the hover
state in our style code. We apply the animation by
calling the animation-name property, adding additional
properties to tell the browser how long the animation
should take, and how many times it should run. Add the
code (at bit.ly/1mBfNTu) to create the animation.

TECHNIQUE
Cut out the bottle
In order to animate an element that appears
to be non-rectangular, youll need to cut out
your image and save it as a transparent
PNG. Your bottle should be partially
transparent so you can see through the
centre follow our steps to see how to do
this in Photoshop.

01 Grab a bottle

Locate an image of a bottle on the


web, or take your own. An image with a
clean background will work best for this
technique, as youll need to isolate the bottle
from its background.

02 Create a selection

Use the Quick Selection tool, or the


Pen tool if you prefer, to make a selection
around the outside of the bottle. If youve
used the Quick Selection tool, invert your
selection by tapping Cmd+Shift+I/Ctrl+Shift+I
before moving on to the next step.

05 Set the origin

If you test your page now, youll see the


animation in place. Theres one issue, however. The
rotation is happening about the wrong point in the
bottle. Wed like the base of the bottle to stay (largely) in
situ, with the rotation about that point. We can set this
using the transform-origin property. Add this now to see
the final effect in place.

001 #bottle:hover {
002
-webkit-animation-name: shake;
003
-webkit-animation-duration:
0.8s;
004
-webkit-animation-iterationcount: infinite;
005
-webkit-animation-timingfunction: linear;
006
-webkit-transform-origin:
50% 100%;
007
008 }

03 Create a mask

Click on the Create Mask button and,


once your bottle is isolated successfully,
paint in the central area of the bottle mask
with a light grey to introduce a small amount
of transparency to this area, before saving
for web as a transparent PNG file.

Web Design Tips, Tricks, & Fixes 109

Construct 3D
customised cubes
inspiration www.benjandsoto.com

f you are going to sell


personalised 3D cubes that
customers can sit on, what
would be the best way to do
this? Over the internet, of
course! Its likely most of you
designers will already be
thinking about the best way to
show these off in a web context. There
are many demonstrations of 3D cubes

INSPIRATION
The custom
element

As Benj & Sotos cubes are to be customised


by the buyer, the site enables users to easily
customise the cubes with their own images.
Using a simple image uploader that we see
all the time on sites like Facebook, Benj &
on the web and they are being used in
Soto are able to let the customer add their
a number of ways on websites as
own unique images. Building the cube in
image carousels and the like. Now we
real time and rotating it to see how it might
have the power of CSS3 and 3D
look ensures that the customer knows
transforms, there are loads of
exactly what they are getting before
Finishing touches
cube-like galleries. This lends
placing the order. This is a superb
The site has a swishy 3D cube for
itself perfectly to beautifully
example of using 3D on the web to
showing off the custom features of
visitors designs, but the finishing
display Benj & Sotos
enhance a product rather than for
touches to the site are very subtle.
customised cubes, made out
gimmicky reasons. Its a simple
Notice the background; it resembles
of flexible pu-foam.
case of form following function.
a photo studio so that the cube sits
in an environment, rather than on
just a plain background.

3
2

Rotation options

Main focus

Inspiration

Simple uploader

Complete order

The cube can be rotated so that


the user can see all the sides of
their upload. The cube is rotated
by using either the buttons on the
interface, or by using the cursor
keys on the keyboard

The cube is the central, focal


point of the design, with all
elements of the interface
surrounding this. The cube
displays custom images that can
be placed on different sides

Images already mapped


onto the cube are available
for the user to look at so
that they can be inspired
before creating their own
unique design

There is an image uploader


for all the sides of the cube.
Once images are uploaded,
they can be cropped and
resized to display the right
part of an image

Once the images are


uploaded, the user can
order their own custom
cube, which are made
out of pu-foam and will
be delivered to them

110 Web Design Tips, Tricks, & Fixes

Construct 3D customised cubes

Bring sitting cubes to life

<comment>
What our
experts think
of the site

Benj & Soto is a young and creative company, and that requires an innovative
website. Here weve made use of WebGL and the wonderful Three.js library
so that users are able to interactively create their own sitting cubes in 3D. The
social aspect also plays a major role within the websites flow.
David Viaene - Web developer at Weblounge.be

TECHNIQUE
CSS 3D rotating cube
01 Add the <div> structure

The cube in benjandsoto.com can be replicated


by creating a cube with <div> tags in HTML but of
course its the CSS that will transform these into a cube
shape, which well add later on. To start us off, add the
starting code (which can be found at bit.ly/1kwwBoP)
into the body section of your webpage. As you will be
able soon see, there are six <div> tags for each face of
the cube as well as some wrapping elements.

02 Create the CSS

Add the CSS as follows to your head section, or to


a separate CSS file. The first CSS that we add controls
the holder element (which wraps the content), then we
set the perspective and the perspective origin. We place
the vertical origin off the top of the page so that we are
looking slightly down on the cube.

001 <style>
002 #holder {
003 -webkit-perspective: 800;
004 -webkit-perspective-origin: 50%
-30%;
005 }
006 #cube {
007 position: relative;
008 margin: 100px auto;
009 height: 200px; width: 200px;
010 -webkit-transform: rotateY(45deg);
011 -webkit-transition: -webkittransform 1s linear;

While benjandsoto.com created their cube using


WebGL, it can easily be reproduced using
transformed DIV tags with CSS3, this enables
greater reach across platforms that do not
currently support WebGL such as iOS.

TECHNIQUE
Create the
background
The background of benjandsoto.com is
reminiscent of a photographers studio and
can easily be recreated in Photoshop just by
applying some subtle gradients.

01 First layers

012 -webkit-transform-style: preserve3d;


013 }
014

Fill your screen with a very light grey.


Switch to a darker grey and choose the
Radial Gradient tool with the gradient going
from the grey to transparent. Add two dark
areas at each side of the screen by dragging
inwards from the appropriate side.

03 Describe each side

We next add the CSS for the face class. This


makes each element 200px in width and height with a
semi-transparent grey background. We then style up the
first side of our cube by rotating it 90 degrees on both
the x and y axis, so that it sits on the top of the cube.

04 Different angles

As we did in the previous step with the first side of


the cube, we continue to style each remaining side.
Notice that each face is rotated in a different direction.
The translate on the z axis moves it 120px on this axis so
that the sides are not just sitting in the middle of the
screen but instead become a cube shape.

05 Make it work

02 Build the layers

Select a lighter grey and in the middle


of the screen add a small gradient circle. Now
use Edit>Transform>Scale to scale the circle
to the full width of the document and place it
in the lower third. Do the same again but this
time position it in the top third.

If you test what you have so far, you will see a


cube on the screen. To make it move with the cursor
keys, add the following code before the closing body
tag. This checks the keys and if the left or right key is
pressed, the code rotates the cube by 90 degrees in the
appropriate direction. Save and test in the browser.

001
002
003
004

<script>
var yAngle = 45;
document.
addEventListener(keydown,
function(e){
005 switch(e.keyCode){
006 case 37:
007
yAngle -= 90;
008
break;
009 case 39:
010
yAngle += 90;
011
break;
012 };
013 document.getElementById(cube).
style.webkitTransform=rotateY(+yAngle
+deg);
014 }, false);
015 </script>
016

03 Add colour

Now add a Color Balance Adjustment


layer. In the window for the Color Balance
settings, add a little cyan and a some blue to
give it a better look. Now choose File>Save
for Web and use this as the background for
your content to sit on.

Web Design Tips, Tricks, & Fixes 111

Use overlay
effects on
background
video
HTML5 video is currently supported in
over 80 per cent of browsers so here
we integrate it into designs with a
variety of creative effects

01 Start the project

From the resource files, copy the Start Folder to


your desktop and open the file index.html in a code editor.
In the head section, add the two lines of code shown
below. These add a normalize stylesheet for resetting all
elements for cross-platform display and the Google font
that we will use in the design of the menu.

001 <link href=normalize.css rel=stylesheet


type=text/css/>

002 <link href=http://fonts.googleapis.com/


css?family=Amaranth:400,700 rel=stylesheet
type=text/css>

02 Add the video

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends HTML, CSS3, Dreamweaver

< Above>
sAt this stage we have added the
video and set it behind our other
content using CSS to position the
video. Now we need to start styling
the page and visual effects

upport for HTML5 video is almost


ubiquitous now and we can start to fully
explore all that this offers to us as
designers. In this tutorial we are using video
as a background element for a page design.
As you may be aware, CSS doesnt allow you
to add video as a background element so
we have to add a little CSS to make this a
fixed element in the background of the
design. This offers some opportunities to
use a variety of textures, gradients and text effects over the
top of the video, which will allow the video to form
interesting breaks between sections of the page.
This effect is perfect for one-page websites, as video
takes a while to load, what with it being considerably larger
than an image background. By adding it to a one-page
website you will only need to load it once for your site that
said, it should cache after the first load.
The video also provides interesting background for
quotes or other content that you want to draw attention to,
as it will have a motion background behind it. The effect
works best when there is subtle movement in the
background, but weve added quite a fast-moving
background to draw emphasis to what we are doing.

CSS doesnt allow you to add video as a


background element so we have to add a
little CSS to make this a fixed element in
the background of the design
112 Web Design Tips, Tricks, & Fixes

The index page already has some content. We are


primarily concerned here with adding visual effects and
styling using CSS. However, we need to add our video to
the body of the page, so add the code below immediately
after the opening body tag. After adding this, your page will
merely have video placed at the top of the document.

001 <video autoplay loop>


002
<source src=loop.mp4 type=video/mp4>
003
<source src=loop.webm type=video/
webm>

004
<source src=loop.ogv type=video/ogg>
005 </video>

03 CSS to the rescue

First we need to just set up the headings and body


content to have the correct typeface and colours. Move
back into the head section of the document and add the
CSS style tags. All the code for the rest of the tutorial will be
placed before the closing style tag.

001 <style>
002 h1, h2, h3, h4, a { color: #636; fontfamily: Amaranth, sans-serif;}

003 body {
004
color: #555;
005
font-family: HelveticaNeue-Light,
Helvetica Neue Light, Helvetica Neue,
Helvetica, Arial, Lucida Grande, sans-serif;
006
background: url(images/bg.jpg) #000 norepeat center center fixed;

007
008
-webkit-background-size: cover;
009 }
010
011 </style>

04 Video background

With the following code shown below, we turn the


video into a background by fixing the video into position.
The video is positioned in the top-left corner of the browser;
we also set the video to fill the browser with the minimum
width and height settings and move the video behind any
other content with the z index. Refresh your browser so
you can see this in action.

Use overlay effects on background video

<Left>
sWe have produced the logo entirely out of CSS
and a background pattern. The pattern adds
visual interest and allows the text of the logo to
stand out and the circle is achieved using the
border radius property
<Above, top to bottom>
sHere we have begun styling up the strapline.
Notice how we have added a transparent
background tile of an x pattern to the screen.
This creates an interesting visual effect and
allows the text to stand out more as well
s.PTUPGUIFDPOUFOUPOUIFTDSFFOXBT
unreadable, so we create a class called white to
add a white background to the main text areas
draw more attention to it over the video

001 video{
002 position:fixed;
003 left:0;top:0;
004 min-width:100%;
005 min-height:100%;
006 width:auto;
007 height:auto;
008 z-index:-100;
009 visibility: visible;
010 }

05 Style the logo

We are now going to create our logo, which will be


designed entirely using CSS. The first part of this is to set
the width and height of the logo. We set this to be centred
on the page and also make the border radius 50%, which
turns the <div> into a circle. In order to see this, we need to
add a background image, which is semi-transparent stripes,
allowing the video to be seen behind.

001 #logo{
002 width: 320px; height: 320px;
003 margin: 80px auto;
004 padding: 20px;
005 text-align: center;
006 border-radius: 50%;

007

Gradients in CSS

background: url(images/thick_stripe.

png);
008 }

06 Vertically centring

We are now going to centre the text vertically. To do


this, we need to tell the browser to render the content as a
table with a set height and width. Add the code as shown
which applies this to the <div> with the id of vCent (short
for vertical centre).

001 #vCent{
002 display: table;
003 height: 320px; width: 320px;
004 overflow: hidden;
005 }
006

07 Vertically centred

The previous step doesnt completely solve the


problem of the vertical centring, however, because we have
just set it to behave like a table. Now we tell the content
inside, which is the heading 1 tag, to act like a table cell. This
now allows us to add a vertical align of middle to this and
we get the look that we are trying to achieve. Refresh your
browser to see it in action.

Gradients are supported by most


of the major browsers and can
be a little difficult to create
because of the complex colour
stops. If you are having difficulty,
try an online tool
such as www.colorzilla.com/
gradient-editor.

001 #vCent h1{


002 font-family: Amaranth, sans-serif;
003 display: table-cell; vertical-align:
004
005
006
007
008 }
009

middle;
font-size:5em;
letter-spacing:.02em;
line-height: .8em;
color: #636;

08 Create the strapline

Underneath the logo we plan to have a strapline


that tells people exactly what the VDO site is and who it

Web Design Tips, Tricks, & Fixes 113

<Above>
sCreating spaces between content sections help to show the division of content, but it also allows the background video to
show through for the user
<Top right>
sThis transparent section features a quote and also a semi-transparent black background allowing the video to show through
<Bottom right>
sAgain we combine CSS3 gradients with a tiled dot image to add an interesting space. The gradient fades into the footer
section at the bottom of the page

represents. The strapline class sets up the typeface to


stand out against the background, but what will also help is
if we put a tiled image that is transparent in the
background. We add an x pattern as a transparent PNG.

001 .strapline{
002 padding: 20px 0;
003 color: #fff;
004 font-size: 2.5em;
005 font-family: Amaranth, sans-serif;
006 }
007

09 Centre the text

Now our text is really beginning to stand out


against the background, we just need to centre the text on
the screen. By having this as a separate class, we can add it
several times to other dominant text so that it becomes
reusable in other contexts. Add the code shown and
refresh your browser to see the result.

001 .cntr{
002 margin: 0 auto;
003 width: 95%;
004 max-width: 960px;
005 line-height: 1.6em;
006 }

10 Side view

We are now going to put more emphasis on the

114 Web Design Tips, Tricks, & Fixes

text by adding a borderline at the top and bottom of the


text this also has the added appeal of increasing the
space around the text. By doing this we get to add an extra
padding at the bottom of the line, which will help to keep
this content separate from what comes next.

001 .lines{
002 border-top: 2px solid #fff;
003 border-bottom: 2px solid #fff;
004 padding-bottom: 10px;
005 }

11 Readable text

One of the main problems with the design of the


page is that all the content is largely unreadable because of
the video in the background, so we will address this now by
making a class called white. This will create visible text with
a white background colour. While we will not be able to see
the video, we can use this to create visually interesting
video spacers between sections.

Disguise the
compression
Adding a transparent tiled
image over video helps to
disguise the compression of
the video, so add these if you
have heavily compressed
video that saves time
downloading the large
file sizes.

colour of purple and change the text colour to white. We


also add in a transition property so that we can create our
rollover transition as well.

001 .white{
002 background: #fff;
003 padding: 40px 0;
004 }

001 a{
002 display:inline-block;
003 color:#fff;
004 text-decoration:none;
005 background: #636;
006 padding:.5rem;
007 transition:.3s background;
008 }

12 Style the link

13 Rollover transition

We have added a link for the Creative Commonssourced video background that we have used, so we need
to make that link stand out. Here we add a background

Here were going to add a different colour


background for the hover effect in this tutorial. All this
involves is changing the background colour to a darker

Use overlay effects on background video

purple, giving the user the impression of more emphasis as


they roll over the link. Save your work now and refresh your
browser so that you can see all the updates.

001 a:hover{
002 background:#303;
003 }

14 Horizontal rules

The default look of the horizontal rule harks back to


when interfaces had a chiselled-edge look. This doesnt
look that great now, so we make the rule 1px high with a
plain colour. This gives the horizontal rule a better look.

001 hr {
002 height:1px;
003 background-color:#ddd;
004 border:none;
005 }

15 Rule of thirds

We are going to style the text that appears further


down the page into three columns, so we add the third
class as shown here. When any content is floated to the left,
the next content doesnt sit in the right position unless it
clears the floated content. This is solved by creating the
class clearfix, so it clears the other content.

001 .third{
002 float: left;
003 width: 30%;
004 padding: 0 1.5%;
005 }
006 .clearfix{ clear: both; }

16 Create spaces

In this step we will add a space between the initial


intro text and the About section of the design. This adds
an interesting space for the video to show through and this
can be used to surprise the user with the video
background. By not allowing the entire video to show
through, it creates good visual interest.

001
002
003
004
005

.spacer { min-height: 240px; }


.dark_bg { background:rgba(0,0,0,0.5); }
.smll { font-size: 0.8em;
color: rgba(255,255,255,0.5);
}

17 Fold it up

In our previous step we also created a dark space


with a semi-transparent black background for the quote.
Now all we do is add a responsive class for the images and
also add a small space between other sections of content.
Preview this in your browser to see the sections starting to
be more clearly defined.

001 .respond {
002 max-width: 100%;
003 }

004 .small_spacer { min-height: 120px; }

18 Click the cube

Now we add a background that incorporates an


image and a semi-transparent gradient, as this still allows
the video to show through slightly. Whatever is the first
element in the background will be the top-most
background in this case its the gradient. We are only
adding the WebKit prefix for brevity.

001 .thin_bg{
002 background: -webkitgradient(linear, left top, left bottom,
color-stop(0%,rgba(55,55,55,0.9)),
color-stop(80%,rgba(55,55,55,0)),colorstop(100%,rgba(55,55,55,0.3))), url(images/
thin_stripe.png);
003 }

Latest on HTML5 video codecs


19 Fix the image

Here we are adding just a small fix to make the


image float to the right. We are also scaling the image
down so that it will fit comfortably into small-screen
browser windows. This is a good use of the space and
allows other graphics not to take over with having such
bold areas of visual interest elsewhere.

You may notice inside the video tag that there are
three different versions of the same video this is
because different browsers support different
video types. This is actually becoming easier to
cater for than in the past. At present Safari,
Chrome, IE (version 8 onwards) and Firefox
(version 21 onwards) all support the MP4 format.
Hot on their heels is Opera, which currently is the

001 .about-img
002 {
003 max-width: 360px;
004 display: block;
005 float: right;
006 }

only browser lagging behind with support for the


WebM format. Opera is supposed to be moving to
WebKit as the rendering engine, which might
mean it will soon support MP4. This could mean
that we only need to include the WebM and Ogg
Theora video types for legacy browsers and, as
most browsers have a good upgrade policy, even

20 Dark gaps

Further down the page we are going to add


another gradient into the space just before the footer
section. The footer will be darker, so well position the
gradient to get darker at the bottom. We also combine the
gradient once again with an image tile but this time the
image is a repeating dot pattern.

001 .dark2_bg {
002 background: -webkit-gradient(linear,
left top, left bottom, colorstop(20%,rgba(45,45,45,0)), colorstop(100%,rgba(45,45,45,0.8))), url(images/dot.
png);;
003 }

21 Add the footer

The last part of the general code is to add the styles


for the footer. The footer features a darker-coloured
background, so the text has to be lighter over the top of
this to be more visible. As a result, weve added styles for
the paragraph and heading 2 tag to be lighter. Save the
document and preview in your browser.

001 .dark{
002 background: #222;

this could become a thing of the past.

003 padding: 40px 0;


004 }
005 .dark p, .dark h2{
006 color: #999;
007 }
008

22 Final step

The final element we need to add is the changing


of the sizes of various elements when being viewed on a
smaller screen. Here we also turn off the visibility of the
video element because some mobile browsers bring the
video to front before allowing it to play, so its safer to just
remove it. Save and test for the final time and thats it!

001 @media screen and (max-width: 768px) {


002 video{ visibility:hidden;}
003 #logo{width: 200px; height: 200px;
margin: 30px auto;}

004 #vCent{width: 200px; height: 200px;}


005 #vCent h1{font-size:3em;}
006 .strapline{font-size:2em;}
007 }

Web Design Tips, Tricks, & Fixes 115

Build an
HTML5
platform game
Your time has come the Quintus
Game Engine makes it easier than
ever for you to create your own
HTML5 game
tools | tech | trends Tiled map editor (www.mapeditor.org)

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

here are so many good reasons for


building your own game that its
difficult to understand why we all
havent already done so.
Smartphones in virtually every hand
has led to an unprecedented growth
in casual gaming. The search for
sticky content is becoming more and
more demanding and social sharing
makes it ridiculously easy to share
even the most faintly enjoyable experience within seconds
across all your social and professional networks.
So, why have you not created your own game that
drives masses of traffic to your website while youre busily
sweeping up piles of kudos? Is it because creating a game
is actually quite difficult? Well, that may have been the case
a while ago, but its certainly not anymore.
Along with a supportive community on hand to make
the process even easier to learn, the Quintus Game Engine
takes care of all the most common elements that you will
need to make all manner of different games work, leaving
you to focus on creating amazing levels and original,
visually rich experiences. Finally, this is a game engine thats
tailor-made for the players and one thats just as easy for
the developers to manage as well.

<Left>
sIts all very pretty but, as a
web designer, you already
know that if it doesnt work
well and look good on
smaller devices youve lost
over half your audience
before youve started.
Fortunately Quintus does
work well and it does look
good right out of the box

116 Web Design Tips, Tricks, & Fixes

Build an HTML5 platform game

01 Get your motor running

To start your game design journey, head over to


html5quintus.com (actually, the GitHub provided on that
site) and download the Quintus Master files. The engine is
in active development so it makes sense to always use the
latest version. Create an HTML file and add links to each of
the Quintus modules. Make sure your have your folder
structure in place for data, images and the library (lib).

001
002

<script src='lib/quintus.js'></script>
<script src='lib/quintus_sprites.js'></
script>
003 <script src='lib/quintus_scenes.js'></
script>
004 <script src='lib/quintus_input.js'></
script>
005 <script src='lib/quintus_anim.js'></
script>
006 <script src='lib/quintus_2d.js'></script>
007 <script src='lib/quintus_touch.js'></
script>
008 <script src='lib/quintus_ui.js'></
script>

011
012
013
014
015
016

</style>
</head>
<body>
</body>
</html>

06 Level design

Later on youll be adding baddies to the level but at


the moment youll want to create a map that provides a
degree of challenge. For example, a failed jump requires
the player to start a section again, or you might leave it to
the player to try to work out which is the best route.

03 Tiled map editor

Download Tiled from www.mapeditor.org. This


powerful, free and easy-to-use application will save you
hours of time. Once your level has been created, it will be
uploaded to the data folder as a TMX file. You do need to
specify XML format as the layer format. The tiles are
uploaded to the image folder as a sheet (tiles_map.png)
and the TMX file is used by Quintus to render the level.

07 Sprite design

You need to design a player sprite and then a


couple of baddies and upload them to the images folder. It
is especially important that your transparent areas are
correct with the sprites for them to look right on the map.

02 Complete the HTML

The engine wont run as a local file so install a local


web server (eg WAMP, MAMP or LAMP) or keep your FTP
client running and edit and save your files remotely. One
extra JavaScript file link is necessary to link to your game
and the rest of the HTML. This provides a page title and
assists with cross-browser and platform compatibility.

001
002
003
004
005
006

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">

04 Create your tiles

The first thing to decide is the width and height of


your tile this tutorial uses 70 x 70 pixels This tutorial uses
a 10 x 2 tile sheet (700px x 140px). opengameart.org
provides a wide range of tiles which you can use as is or
adapt (be sure to check the individual licences). Once you
are happy, simply create a new tileset in Tiled and finally
youll be ready to start building your map.

<meta name="viewport"
content="width=device-width, user-scalable=0,
minimum-scale=1.0, maximum-scale=1.0"/>
007 <title>Spacewars</title>
008 <script src='spacewars.js'></script>
009 <style>
010
body { padding:0px; margin:0px; }

05 Create your map

Make it
your own
Storm the enemy mothership
in your one-man shuttlecraft,
fight off the baddies and
reach the golden container.
Other childhood fantasies are
available. With Quintus its
now a lot more achievable
for everyone.

Quintus and Tiled can support many layers for a


map but were just using a single layer here. Once youve
decided on the width and height of your map you can set
about populating it by clicking on an individual tile and then
painting it on the map. Mistakes can be easily removed by
using the eraser its as simple as that.

08 Now for some code

One of the best things about the Quintus engine is


its extendibility. You can create a very simple game and
leave it at that, or you can add a little, then add a little more.
The first step is to listen for if the webpage has loaded,
which triggers the process running your game file (here
spacewars.js). Then, simply create an instance of the
engine and add some very handy modules.

001 window.addEventListener("load",function() {
002
003
var Q = Quintus()
004
.include("Sprites, Scenes,
Input, 2D, Anim, Touch, UI")
005
.setup({ maximize: true })
006
.controls().touch();

09 The player

Here you need to create your player sprite that


includes functionality for flipping its direction. The sprites
starting position is set here (weve set the player to fall
through space for a short while at the start). You can also
adjust the jumpSpeed changing this parameter can make
an enormous difference to a games difficultly.

001
002

Q.Sprite.extend("Player",{
init: function(p) {

Web Design Tips, Tricks, & Fixes 117

003

this._super(p, { asset:
"player.png", x: 110, y: -1000, jumpSpeed:
-400});
004
this.add("2d,platformerContro
ls");
005
},
006
step: function(dt) {
007
if(Q.inputs["left"] &&
this.p.direction == "right") {
008
this.p.flip = "x";
009
}

Attributions
and licences
Some game tiles are derived from
work by Csaba Felvegi (chabull at
opengameart.org) and the player
sprite is partly derived from work
by MillionthVector, both licensed
under CC3.0. The map and game
code is partly derived from
the tutorial posted by
Pablo Farias Navarro at
gamedevacademy.org.

Whats your flavour?


It doesnt have to be all 2D platform games,
however. There are examples of other game

010

if(Q.inputs["right"] &&
this.p.direction == "left") {
011
this.p.flip = false;
012
}
013
}

014
015

});

10 Baddies

All of the baddies in this game are killed by jumping


on them. If the player sprite comes into contact with a
baddie on either of its sides or from the bottom, the player
dies and the game is over. To give some impression of
Newtons third law of motion being observed in this world,
the player jumps back a little after making contact.

001
002
003
004

Q.component("commonEnemy", {
added: function() {
var entity = this.entity;
entity.on("bump.
left,bump.right,bump.
bottom",function(collision) {
005
if(collision.obj.
isA("Player")) {
006 Q.stageScene("endGame",1, { label: "Game
Over" });
007
collision.obj.destroy();
008
}
009
});
010 entity.on("bump.top",function(collision) {
011
if(collision.obj.isA("Player")) {
012
//make the player jump
013
collision.obj.p.vy = -100;

014
015
016
017
018
019
020
021

//kill enemy
this.destroy();
}
});
},
});

formats, from asteroids to space invaders to


breakout-type games that can be found over at
html5quintus.com, on github.com and through
an active Quintus community at Google+. Theres

11 Ground baddies

These baddies need to change direction when they


reach a wall or when they would otherwise fall off an edge.

even a comparison site for HTML5 game engines


(www.html5gamengine.com) that compares
features from over twenty game engines.
Before diving in, or after completing this
tutorial, you might like to try a few different
options out, get a feel for their strengths and
weaknesses and understand which engine might
suit your own needs best. If youre relatively new
to coding you may find that you prefer an engine
that is better supported by an active community
of developers. Remember that, as is true with
some other software, premium options (you can
pay over $200) may not always be better than the
open source options available to you.

118 Web Design Tips, Tricks, & Fixes

001
002
003

Q.Sprite.extend("GroundEnemy", {
init: function(p) {
this._super(p, {vx:
-100, defaultDirection: "left"});
004
this.add("2d, aiBounce,
commonEnemy");
005
},
006
step: function(dt) {
007
var dirX = this.p.vx/
Math.abs(this.p.vx);
008
var ground = Q.stage().
locate(this.p.x, this.p.y + this.p.h/2 + 1,
Q.SPRITE_DEFAULT);
009
var nextTile =

Q.stage().locate(this.p.x + dirX * this.p.w/2


+ dirX, this.p.y + this.p.h/2 + 1, Q.SPRITE_
DEFAULT);

010
011 //if we are on ground and there is a cliff
012
if(!nextTile && ground) {
013
if(this.p.vx > 0) {
014 body > header.halfsize {
015
if(this.p.defaultDirection
== "right") {

016
017
018
019
020
021
022
023

this.p.flip = "x";
}
else {
this.p.flip = false;
}
}
else {
if(this.p.defaultDirection

== "left") {

024
025
026
027
028
029
030
031
032
033

this.p.flip = "x";
}
else {
this.p.flip = false;
}
}
this.p.vx = -this.p.vx;
}
}
});

12 Flying baddies

The critters just need to float up and down, so here


we make sure that gravity is turned off for them.

001 Q.Sprite.extend("VerticalEnemy", {
002
init: function(p) {
003
this._super(p, {vy: -100,
rangeY: 200, gravity: 0 });
this.add("2d,
commonEnemy");
005
this.p.initialY = this.p.y;
006
},
007
step: function(dt) {
008
if(this.p.y this.p.initialY >= this.p.rangeY && this.p.vy >
0) {
009
}

004

010
011

else if(-this.p.y +
this.p.initialY >= this.p.rangeY && this.p.vy <
0) {
012
this.p.vy = -this.p.vy;
013
}
014
}
015
});

016

13 Play again?

This is the event that is triggered when your player


dies. A message is displayed and the level is ended.

Build an HTML5 platform game

Game graphics
The tone of your game will be determined by the visual style you choose. Take some time to see what has
been done before and then go off and create something amazing and unique

While you can and should do your own


thing, youll want to provide some solid
ground for your players. Walkable surfaces
should have a top but underground
elements shouldnt.

001 Q.scene("endGame",function(stage) {
002 var container = stage.insert(new Q.UI.
Container({
003
x: Q.width/2, y: Q.height/2, fill:
"rgba(99,99,99,0.5)"
004 }));

005
006

var button = container.insert(new Q.UI.


Button({ x: 0, y: 0, fill: "#CCCCCC",
007
label: "Play Again?" }))
008
var label = container.insert(new Q.UI.
Text({x:10, y: -10 - button.p.h,
009
label: stage.options.label }));
010 // When the button is clicked, clear all
the stages
011 // and restart the game.
012 button.on("click",function() {
013
Q.clearStages();
014
Q.stageScene('level1');
015 });

016
017

// Expand the container to visibly fit


its contents
018 // (with a padding of 20 pixels)
019 container.fit(20);
020 });

021

14 Insert the elements

The nifty Q.repeater function provides developers


with a very easy method for adding a nice parallax
background to the level. You will see that it is set to move at
half the speed of the foreground. The main map is then
loaded by referencing the TMX file.

Edges can also be used to good effect and


provide extra refinement. You can add
sophisticated-looking tiles even if they dont
actually offer any function.

Game design really is a tweakers paradise.


If you think of a way to improve the look of
a tile, you can deploy all of your
refinements with just a few clicks.

001 Q.scene("level1",function(stage) {
002
003
stage.insert(new Q.Repeater({

.png"}],

asset: "background-wall.jpg", speedX: 0.5,


speedY: 0.5 }));

004
005

stage.collisionLayer(new
Q.TileLayer({ dataAsset: "level1.tmx",
layerIndex:0, sheet: "tiles", tileW: 70,
tileH: 70, type: Q.SPRITE_DEFAULT }));

006
007

var player = stage.insert(new

Q.Player())

15 Release the flying monkeys

Only some of the baddies are shown here, but that


is the beauty of baddy creation: once one is set up its really
easy to create another. You just need to change its starting
position and, in the case of the flying baddies, what their
range of movement is. As computers are good at maths,
you dont need to work out the actual pixels. You know that
each tile is 70px wide and tall so six tiles across and three
down can just be specified as 6*70 and 3*70.

001 ["VerticalEnemy", {x: 18.5*70, y: 13.5*70,


rangeY: 3*70, asset: "fly.png"}],
002
["VerticalEnemy", {x:
23.5*70, y: 10*70, rangeY: 1.5*70, asset: "fly.
png"}],
003
["VerticalEnemy", {x:
39.5*70, y: 4*70, rangeY: 2*70, asset: "fly.
png"}],
004
["VerticalEnemy", {x:
40.5*70, y: 8*70, rangeY: 3*70, asset: "fly

005

["GroundEnemy",
y: 3*70, asset: "ground.png"}],
006
["GroundEnemy",
y: 6*70, asset: "ground.png"}],
007
["GroundEnemy",
y: 0, asset: "ground.png"}],
008
["GroundEnemy",
y: 0, asset: "ground.png"}],

{x: 6*70,
{x: 18*70,
{x: 20*70,
{x: 11*70,

16 Load assets

The assets need to be loaded into the engine in


order for it to be able to use them. The follow function is
used to keep the player sprite in the centre of the screen at
all times. When you create a new sprite or sprite sheet you
need to ensure it is added here for loading.

001 stage.loadAssets(levelAssets);
002 stage.add("viewport").follow(player,{x:
true, y: true});
003 Q.load("tiles_map.png, player.png, ground.
png, fly.png, level1.tmx, background-wall.jpg",
function() {
004
Q.sheet("tiles","tiles_map.png",
{ tilew: 70, tileh: 70});
005
Q.stageScene("level1");
006
});

17 Keep building

With your own graphic and level design this is


already something that you can show off, but if you take a
little time to check some other examples and read up on
Quintus youll be adding sound effects, player lives, new
levels, and more before you know it!

Web Design Tips, Tricks, & Fixes 119

Fixes
122

Supercharge your CSS

128

The theory of text and type

134

Modernizr masterclass

138

Revolutionise your workflow by introducing a


CSS preprocessor

We delve into modern web typography and reveal


how to create beautiful web type

Ensure that your site runs as smoothly as possible


by making use of Modernizr

Create sticky table headers using CSS


and jQuery

Enhance all aspects


of your web design
with key solutions

150

Get faster, smarter code with RequireJS

154

Create responsive sites with intention.js

158

Make an eCommerce web element


with CSS3

162
166

Speed up responsive sites


with Foundation

Automatically test your JavaScript


with Jasmine
Ensure code quality by testing with Jasmine

Build a custom Foundation template


Get started with the latest edition of this responsive
framework tool

128
The theory
of text
and type

120 Web Design Tips, Tricks, & Fixes

Customise a map with the Google


Maps API
Go beyond the simple embedded map

Prepare your sites for mobile viewers

146

Get started intention.js and build a responsive


music player

Make a simple shopping cart web element

Help your users make sense of data

142

Use RequireJS to manage library dependencies by


building an image-viewer

170

Automate development processes


with Grunt.js
Remove the stress of repetitive tasks

146
Build a
Foundation
template

162

170

Discover
the Google
Maps API

Automate
processes
with Grunt

122
Take your
CSS to the
next level

Web Design Tips, Tricks, & Fixes 121

SUPERCHARGE
YOUR CSS
Do you want to spend less time writing CSS and more time
doing fun stuff? A CSS preprocessor could change your life
ts that meeting on Friday. Your team has
worked on the site for the last month. This is the
final client review. Everyone loves it, until the
client leans in and says Fantastic. But I dont like
that font. And my new phone has rounded
buttons, not square ones. So could you add those
too? Otherwise good job everyone. If you put your
site together with plain old CSS, even making basic
changes will take a while.

But you didnt. You used a CSS preprocessor. Most


of the key styling is in a few lines of a single file.
Instead of hours of manual search and replace, which
will probably break the site because its nearly
impossible without making any mistakes, you can
make a few minor changes that take a few minutes.
You can even make them live in the meeting, and
run the changes there and then for approval. Instead
of gloom, everyone cheers and officially votes you

WHAT IS A PREPROCESSOR?
CSS preprocessors take the CSS code youve always
wanted to write, and turn it into the CSS code youve
always had to use. CSS has always been half a
solution. Its better than manual markup, but its not a
sleek and efficient way to specify styling elements.
A key problem apart from the crafty syntax is that
CSS has no memory or intelligence. In coder-speak, this
makes it WET: Write Everything Twice. So youll often
have to write the same stylings again in many places.
Plus, if you want to change something, you have to find
those places again and hand-edit them.

122 Web Design Tips, Tricks, & Fixes

Preprocessors take some ideas from hardcore


computer programming and put them back into CSS,
making code thats DRY Dont Repeat Yourself. With
a preprocessor you can get closer to having every
key design element defined in exactly one location.
This has many benefits. You can change an entire
sites styling with a few edits. You can reuse the same
code across multiple projects, completely separating
styling from content mechanics. And you can write
smarter CSS that does basic script-style maths to
manage elements, makes the relationship between

Most Awesome Person of the Week when you break


for a nice early weekend an hour later.
And thats the power of preprocessors. Manual
CSS is like building a skyscraper out of matchsticks.
Preprocessed CSS sends your productivity soaring
into a cloudless sky, leaving you free to concentrate
on all those elements of design that really matter. But
what does that mean in practice? Read on to find out
exactly what CSS preprocessors can do for you.

classes and selected elements much clearer, and


generally helps you keep the design templates that
are cleaner, simpler, and easier to manage.
But there is a catch: theres no direct browser
support for preprocessed CSS. So you can choose to
compile your pre-CSS on your development machine,
and upload the standard CSS thats generated. Or you
can set up your server to work with raw pre-CSS files,
generating the CSS on the fly. The good news is tool
support for pre-CSS is getting better all the time, and
some editors now work with pre-CSS code directly.

Supercharge your CSS

THE BIG THREE

There are three popular mainstream CSS preprocessors


and theyre all great but heres how to tell them apart
QSASS
sass-lang.com
SASS (Stylistically Awesome Stylesheets)
is newer than LESS, but has a serious
following among professional developers,
especially when associated with the
Compass framework (compass-style.org).
SASS is written in Ruby, which is
preinstalled on OS X, but must be installed
on Linux and Windows. SASS works best
developer-side, compiling preprocessed
CSS to standard CSS you upload to web
servers. There are many tools to automate
the compilation and upload.
As a language, SASS is a two-in-one. You
can write SCSS, which like LESS is a
strict superset of CSS. Or write pure SASS,
which isnt. Compared to LESS it has some
extra smarts, including conditionals/

repeats outside of mixins, and more


complex selector management. When
used with Compass, it adds features like
sprite management, simplified grids and
typography, easier cross-browser support,
and plenty of predefined style options.
Its also being maintained and
developed more consistently than LESS.
On the downside, it can compile more
slowly, which can be an issue. The extra
features also mean there is a learning
curve. The tutorials and references on the
main SASS site could be a little more
generous too. But theres a strong support
community, and many online examples,
including some standout sample code on
The Sass Way blog (thesassway.com).

TWO ALTERNATIVES
If none of the big three are appealing, you
could always give these options a try
QSWITCH
bit.ly/18AbUbB

QLESS
lesscss.org

QSTYLUS
learnboost.github.io/stylus

LESS was originally developed by Alexis Sellier. It has


very good foreign language support, so its worth
considering if English CSS isnt your main interest.
LESS defined the basic feature list for a
preprocessor. It includes variables, allowing you to
set a value in one place and use it by reference
everywhere; mixins, which are variables that drop all
the content of a class into another with a single line;
rule nesting, which clarifies inheritance; functions,
which can modify variables with arithmetic; and
plenty of colour-management features.
LESS includes guarded mixins, which produce
different CSS according to tests you specify but it
doesnt have fully general conditionals. Often used
with Bootstrap, LESS is great for grids with optional
CSS3 support for animations and gradients.
Client-side, you can run LESS from the command
line, or from visual tools. Server-side, you can install a
native LESS compiler a bad idea if you get a lot of
hits a day. Youll get a much better performance from
Node.js or Mozillas Rhino JavaScript engine.

Stylus isnt as popular, but it is certainly worth a look.


Transparent mixins are a big win. You can define
functions normally, but you dont need to specify a
list of parameters. Stylus can copy any parameter
string into the CSS, making functions more powerful.
It also has iteration and loops, so you can generate
repeated elements with styles under code control.
Stylus extends this with interpolation, which is its
own way of allowing what mainstream programming
languages called enumeration the ability to step
through a predefined list of strings of values with a
few lines of code, and to drop the strings/values into
the final CSS. Its a good way to write efficient code,
with the downside that it can be harder to read.
Stylus syntax can be pared to the bone. You dont
need to include colons, semi-colons, or curly
brackets. But you do need to include whitespace so
Stylus knows when youve started a new definition.
Stylus runs under Node.js, so youll need that, and
then use NPM, the node packet manager, to install
Stylus. Try some experiments online on the Stylus site.

Switch is a preprocessor in
Embryo. Its big feature is
out-of-the-box Apache
compatibility it runs as an Apache module
under mod_python, which gives Apache support
for the Python programming language. The
code is freely available at code.google.com/p/
switchcss. If youre minded to explore full-cream
code development, Python is a good language
to start with. Its much easier to work with than
heavyweight languages like C++ and its not
impossibly difficult to customise Switch to create
your own mini-preprocessor.

QSPIFFING
spiffingcss.com
Do you need a preprocessor
that plays stirring patriotic
music while draping red, white
and blue bunting around an
old red British phone box?
Probably not. But just in case, take a look at
spiffingcss.com. It swaps spellings like color
and gray into sensible English words like colour
and grey. It even converts the brashly selfabsorbed !important keyword into !please. Tea
and scones not included, unfortunately. But its
smashing for weather apps.

Web Design Tips, Tricks, & Fixes 123

INSTALLATION OPTIONS
COMMAND LINE
LESS is written in JavaScript. You can
include the script in your sources while
developing but not for production,
unless you want to cripple your server.
For a one-time final compile, install
Node.js on a dev machine and run the
.less files through the lessc tool (visit
bit.ly/1bG2N9D).
SASS works with Ruby. See
rubyinstaller.org for Windows, and
www.ruby-lang.org/en/downloads for
Linux and OS X (Mavericks includes a
version of Ruby, but RVM can manage
multiple versions). You can then gem
install sass, and use sass input.scss
output.css in order to compile.

Stylus also needs Node.js. Once


installed, Stylus gives you many more
command line options than the other
tools, including some clever features
for handling entire directories of files.
See bit.ly/1bagyKS for examples.

There are great GUI tools


that make the command
line unnecessary. You only
need the command line if
youre doing big scripted
builds with many files, or if
you want to write your own
shell scripts to compile CSS,
upload it, and archive it at
the same time.

The basics and limitations of installing


each of the popular CSS preprocessors

SERVER-SIDE
If you have Node.js on your server, you
can install LESS as an npm package
with npm install g less. You can then
use the lessc tool to compile files
manually, just as you would on a
development machine. But you can
also render CSS live with Nodes less.
render command but this can get
pretty complicated.
In theory, SASS is never run
server-side. In practice you can set up
Ruby on a server and have it either
compile on the fly whenever the user
loads a page (inefficient) or compile
then cache, so only changed files are
rebuilt when they need to be.

Stylus is available for Node.js as an


npm package. With Node you can use
scripting to customise your compilation
workflow in the usual way. Alternatively,
use another web server called Harp.js,
which has support for Stylus baked in.

For simplicity its always


better to compile once
then upload/copy and
forget. The main benefit to
running server-side is you
can copy the files to a final
server destination
directory without having
to upload them from one
machine to another.

You can include the script in your sources while developing but
not for production, unless you want to cripple your server

TOOLS TO MAKE PROCESSING EASIER


QCODEKIT
incident57.com/
codekit
CodeKit is the ultimate preprocessor
toolkit, with built-in GUI support for
LESS, SASS, and Stylus and automatic
compilation after any edit. Forget the
command line, with CodeKit you can
experiment with all the preprocessors
in one place to see which suits you best.
CodeKit speaks fluent CoffeeScript,
Jade, HAML, if you need those as

QLIVERELOAD
livereload.com
LiveReload combines built-in
compilation for SASS, LESS, Stylus and
an alphabet soup of other tools.
LiveReloads big feature is
automated compilation: it monitors the
files in your project and automatically
recompiles CSS when you edit it, so
you dont need to worry about
command line tools or setting up a
preprocessor on your server.
Optionally you can run a script after

124 Web Design Tips, Tricks, & Fixes

extras. For $28 payable after a free


trial period you get an impressive
selection of tools for HTML, JavaScript,
as well as CSS management. You can
even mash JavaScript and CoffeeScript
files together, then minify them before
uploading, optimise images. and test
JavaScript with JSHint and JSLint.
CodeKit is only available for OS X.
Theres no Windows or Linux version,
and its unlikely there ever will be. Note
though that CodeKit is not an editor
its a compiler and packager.
each compilation for example, to run
FTP and upload the compiled files to a
production server.
LiveReload is available from the Mac
App Store for $9.99. Versions are also
being developed for Windows and
Linux, but theyre not quite ready for
prime time but they are free, so you
can try them out and see if they do
enough to be worth working with.
Theres a useful knowledge base with
information about getting started,
selecting an editor, and setting up
frameworks and other topics.

Check out some of these offerings to help simplify


processing, from toolkits to editors

QSCOUT
mhs.github.io/
scout-app
Scout takes the effort out of Ruby,
Compass and SASS for Mac users, by
bundling them all into one
development environment. It includes a
project console for file and directory
management, and an embedded
terminal output window.
Its not a full GUI editor like CodeKit,
youll need to do your editing elsewhere

QCRUNCH
crunchapp.net
Crunch is a LESS editor and compiler.
You edit LESS, you save CSS. Its that
simple. You dont need to set up a
command line tool, or install any extra
add-ons, plug-ins, extensions,
daemons, apps, or anything else.
Crunch is Mac-only, and free from
the website. There really isnt all that
much else to know. It works in a simple
GUI-editor kind of a way. You are able
to have multiple files open at the same

but it simplifies project management


for developers who want to work with
SASS and Compass but dont want to
end up dealing with command line
directory copying and compilation. You
are able to set up development and
production environments, specify input
and output directories, and leave Scout
to handle everything else.
Scout is Mac-only but its completely
free. Its also open source. The code is
available on GitHub, so you can fix and/
or modify it for yourself.
time. Its LESS only, so theres no
support for SASS or Stylus. It also
doesnt have any direct links to
Bootstrap or any other LESS-friendly
frameworks.
Nevertheless, Crunch is a good
option if you want to do some quick
experiments with LESS without getting
distracted by the time needed for a
more comprehensive server- or
client-side installation. Its by no means
the most complete CSS editor out
there, but its simple, clean, accessible
and it does what it sets out to do.

Supercharge your CSS

PREPROCESSORS IN ACTION
VARIABLES AND ARITHMETIC
All preprocessors support variables with optional
math functions. Even if you never use any other
preprocessor feature, variables can save you hours of
update time by concentrating critical definitions in
one location in one file. This is usually at the start of
the file, although for even simpler maintenance you
can keep all the main colour palette and font
definitions in one file and import it into the others. In
LESS, variables begin with @. In SASS, they start with
$, rather like PHP variables. Stylus is understated, and
you dont need any special symbols.
The following code illustrates a very simple SASS
example, compiled in CodeKit. It defines two
variables: a font list, and a text colour. There are also
a couple of sketched out container definitions, so you

USE MIXINS

Create DRY code with simple automated colour effects

can see exactly how the variables are used. The


compiler takes the variable values and parks them
inside the standard CSS. The second example also
applies some basic arithmetic to the predefined
colour. All the preprocessors have more
sophisticated colour features, but note how easily
you could create a palette of related colours, given a
base colour and some very simple extra code.

001
002
003
004
005
006

So how do you use a preprocessor in


practice? Here are some examples

//Original scss
$font-list: Helvetica, sans-serif;
$bodytext-color: #111;
.acontainer {
font: 100% $font-list;
color: $bodytext-color;

007 }
008 .another_container {
009 font: 50% $font_list;
010 color: $bodytext-color*0.1;
011 }
012 //Compiled CSS
013 /* line 4, ../sass/new.scss */
014 .acontainer {
015 font: 100% Helvetica, sans-serif;
016 color: #111111; }
017 /* line 9, ../sass/new.scss */
018.another_container {
019 font: 50% Helvetica, sans-serif;
020 color: #010101; }

Manage browser support with one-off browser-specific definitions

CSS3 can drive you insane with endless repetitions of


browser-specific code every time you want to use a
feature. A mixin is like a variable that contains
boilerplate definitions you define once and re-use
over and over. To confuse you, this time LESS uses a
dot to define a mixin, while SASS uses @. Stylus
mixins look like functions, with round brackets,
although theyre treated like standard properties.
Although mixins look more complicated than
variables, theyre almost as simple and they may be
more useful, especially for CSS3. LESS has an extra
feature called a guarded mixin, which can include a
conditional if/else test that only applies the mixin if
the test triggers true. Just add when after the
mixin, and follow it with a condition.
The following SASS code provided is simpler, and
shows how to simplify basic CSS3 browser support.

CREATE LOOPS
CSS is literal; unlike real programming
languages, it has no concept of
repetition or progress. You can fix this
in a preprocessor. Some possible
applications of repetition include
creating grids and tables with optional
shrinking/expanding elements, a set of
font sizes from a base size, a colour
palette from a base colour and a list of
URLs given the keywords they differ by.
LESS has basic looping. You have to
make it behave with a combination of a

Note how it uses @include, and a variable called


$radius and passes its value to the mixin, which fills in
the details when its compiled. You can change the
value thats passed each time you use the mixin.

001
002
003
004
005
006
007
008
009
010
011
012

//Original scss
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
-ms-border-radius: $radius;
-o-border-radius: $radius;
border-radius: $radius;
}
.rounded_box {
@include border-radius(50px); }
.very_rounded_box {
@include border-radius(500px);

Save time by creating repeated


code with a simple loop
loop index variable and @when followed
by a conditional that ends the loop. SASS
has much simpler syntax, with a proper
@for statement for basic counting, and
@each for reading items from a list and
doing something with each one. Stylus
can do both, without the punctuation.
Use for in and follow it with (1..5) for
counting, or a list of text items.
A detailed demonstration of this
looping code can be found online at
bit.ly/VEPTDe.

013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029

}
//Compiled CSS
/* line 9, ../sass/new.scss */
.rounded_box {
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
-ms-border-radius: 50px;
-o-border-radius: 50px;
border-radius: 50px; }
/* line 13, ../sass/new.scss */
.very_rounded_box {
-webkit-border-radius: 500px;
-moz-border-radius: 500px;
-ms-border-radius: 500px;
-o-border-radius: 500px;
border-radius: 500px; }

NESTED RULES
Inheritance can kill a bigger project
where the basic elements have tens of
variations. With nested rules, you can
keep all the related details in a single
location, indented for clarity. Nested
rules make it much easier to keep track
of which sub-elements have which
styles, and even more usefully the
added readability makes it easier to
see where you need to make changes
to update some elements, while
leaving others unchanged.

Lost your way with inheritance?


Preprocessing can lead you home
Nested rules in SASS and LESS look
very similar. You add extra curly
brackets and indentations as you work
your way down the inheritance tree.
Stylus is simpler, and uses plain
indentation with no extra brackets.
This makes it easier to read, and edit.
Theres no practical limit to the extra
definitions you can add, or the order
you can add them in. A SASS example is
at www.webdesignermag.co.uk/
tutorial-files/issue-218-tutorial-files/.

Web Design Tips, Tricks, & Fixes 125

THE FUTURE OF
PREPROCESSING

Theres even more to come, as CSS gets closer and closer to a real
programming environment

The biggest change in the near future of web design will very likely be the wider
use of preprocessors. In a css-tricks.com survey last year, it was revealed that
nearly half of all users still hadnt tried a preprocessor. Its true theres a certain
learning curve involved especially if youre installing a server-side
implementation or working at the command line but the initial time demands
are tiny compared to the effort you can save yourself if you add a preprocessor to
your workflow.
All the main CSS preprocessors are continuing to be developed, but at the
moment there are no plans to roll any of them into official w3.org CSS
specifications so dont expect to see native browser support for a while yet. A
few features, such as smarter selectors, are working their way into mainstream
CSS. But for the time being, the inefficient official syntax is unlikely to change.
What may change, however, is the way developers think about CSS. The official
aim of CSS was to abstract content from presentation. HTML and CSS includes

QNicole Sullivans object-oriented CSS is influencing future CSS developments

126 Web Design Tips, Tricks, & Fixes

hints of a mainstream coding technique called object-oriented programming, but


they certainly dont take it as far as it could be taken.
Nicole Sullivans Object Oriented CSS (for a helpful introduction provided by
Nicole herself, visit slidesha.re/4y3U0u) doesnt just try to fix inefficient CSS
syntax, it attempts to fix inefficient design practices. The idea is to move CSS and
HTML towards a cleaner, more straightforward but more abstract form, where its
easier to make content containers smart and responsive, while also avoiding
unnecessary repetition in coding.
The other likely development is an ever-growing number of drop-in
frameworks. In the same way that LESS is associated with Bootstrap, SASS is
closely associated with Bourbon (bourbon.io) and also with Zurb (foundation.
zurb.com), while Stylus is associated with Jeet (jeetframework.com). Expect
more of this in the future, and less reinvention of grids and wheels as site
developers share their tools.

Supercharge your CSS

TOP TIPS

Preprocessors can seem


intimidating here are some
quick notes to get you started

QThe big picture


Think workflow, frameworks, and creative benefits
It may seem like there isnt an easy way to decide which preprocessor to use.
They all speed up your workflow, at the cost of some initial learning and thats
what you want.
But thats not the whole story. The goal is to create superb, silk-smooth and
stylish websites. A preprocessor will save you time, but youll get a bigger
benefit if you combine it with the right framework. So ignore any set-up and
deployment issues, and ask yourself exactly which framework you want to
work with. Then work back from there.

QPain-free debugging
Swat those bugs by using readily available, smarter code tools
Debugging preCSS can be challenging. The target browser never sees your
native preCSS code, it only sees the compiled CSS, because thats the only code
it can make sense of.
So how do you fix bugs? A diligent web search will find tools you can add to
most environments. Theyre often in an alpha-ish state, so dont expect a
polished performance but theyre better than nothing. For example, try the
FireSass add-on for FireBug (mzl.la/gXg7x2). Other tools include Sass Sleuth for
Safari and OS X Chrome (bit.ly/18jD94x), and Sass Inspector for Chrome (bit.ly/
YiVSGO). Chromes Developer Tools can work with LESS and Stylus files as well,
as long as you compile them with the source maps option.

QAnd for HTML


Its not just CSS that could do with a little tightening up
QWork smarter
Explore your workflow options to maximise your productivity
One of the secrets of success is making sure that once youve decided on a
preprocessor and framework, you understand the workflow options you
can use.
The two choices are simple: manual or automated. With a manual workflow
you use an editor or a GUI tool to create CSS in the usual way, with the difference
being that you write preprocessor code and upload the compiled code.
Automated workflows are more complex, and you dont have to set one up
immediately. You can get comfortable with learning the preprocessor first, then
worry about setting up a workflow separately.

For maximum productivity, consider using an equivalent HTML preprocessor.


HAML and Jade, among others, can take you some way towards working with
condensed, shorter and clearer HTML without the over-complications built into
native HTML.
If youve set up a CSS preprocessor workflow, youll already have the tools you
need to work with an HTML preprocessor. But is it worth the extra time? Youll be
writing cleaner code thats easier to read and maintain. It wont be standard
HTML any more, which may not be a good thing for some applications
although of course, you still get raw HTML files after compilation.
Arguably HTML isnt as half-finished as raw CSS, so the benefits of a
preprocessor may not be as obvious, but its still worth exploring whats out
there. Done right, integrated preprocessing can make your projects run more
smoothly, increasing your chances of delivering work on time and under budget.

Web Design Tips, Tricks, & Fixes 127

Text
T he theory of

and

Type
The perfect typeface does not exist yet,
proclaimed legendary typographer Jan
Tschichold in 1925. In this article we delve
into modern web typography and reveal how to
create beautiful web type
128 Web Design Tips, Tricks, & Fixes

The Theory of Text and Type

Getting web fonts

and typography right


In the last couple of years, advances in web technology have meant that weve been
spoilt for choice when it comes to font choices. As a result theres been a surge in
popularity around the subject of type. But is the popularity a passing fad in the
ever-changing world of web design, or is there something more at the core that relates
back to the actual tenets of typography?
Truth is, most people dont notice typefaces. This is not necessarily a bad thing for if
they do notice it, it might be because they cant see what theyre meant to be reading.
Just like in film scores, if you notice the music then its missed the mark. A good
typeface should enhance the ability to read, not detract from it. It doesnt need to show
off; the font itself is not the star of the show here. If you remember that, and continually
remember to check whether you find something easy or difficult to read, then youll be
running along the right lines.
Its also about remaining in context. If youre dealing with an in-depth report to be
read by people on their phones, where clarity and ease is key, then itll be quite
different to someone reading a poem designed as part of a brands story page, where
you can afford to be much more elegant.

completely unreadable by setting it at a tiny size, reducing letter spacing to -4px, and
finishing it off with everything in lowercase in a light grey on a white background.

Font of Knowledge

Tom

Fonts vs Typefaces
An oft misunderstood area (and one that today only really bothers typographic geeks),
its still useful to know the difference and its really rather simple. A typeface relates to
the overall family, whereas a font relates to a specific version of the typeface. For
example, Helvetica is a typeface, Helvetica Bold is a font.
The simplest way to remember it is to consider the typeface as an album and the
fonts are the tracks contained on it.

Legibility vs Readability
Legibility relates to the clarity of the typeface itself. Blackletter typefaces have low
legibility thanks to their decorative nature. Their ancient style featuring heavy serifs or
accents that often contain ligatures (the joining of letters together) reduce clarity and
should be reserved strictly for the design of old English pub signs.
Readability, on the other hand, is about typesetting. It refers to the individual
elements that can be adjusted with the font itself size, line height, letter spacing,
contrast, colour, and more Its possible to make a very legible font (Times, lets say)

The Guardian website uses their own in-house typeface for its masthead. They also
have a sparing approach towards bolding for serif and sans serif typefaces

Leading vs Tracking (vs Kerning)


In the old days of hand-typesetting, physical blocks of lead were placed between lines
of type to create the vertical space within a block of text on a page, and thats where
leading obtained its name. Although seldom used now, the phrase stuck. In CSS,
leading had its name changed to the rather more obvious line-height.
Tracking is the overall adjustment of the space between individual letters. Titles
often get tracked out to give impact and you may reduce tracking to body copy
if the type appears too spacious. This is configurable in CSS, using the
letter-spacing property.
Incidentally, kerning is something else again that involves the space between two
individual characters. Not something that can be adjusted as simply in CSS, this is
generally more concerned with design for logotypes, heavily designed titles, and
particularly large type where additional control is required.

Wittlin

For me its not


necessarily
about great
fonts, although they
can make a big
difference. Its more
about what you do
with them. Any font
(including Times) can
look good if laid out
correctly. Leading
(spacing between
lines) is very important
the wider the better
in my opinion. A
leading of 160 per cent
may seem too much
for some people to
cope with. My
advice try it.

Web Design Tips, Tricks, & Fixes 129

The Headline Act


Selecting the right headline font is not as simple as you might think. Follow
these suggestions to find the perfect option

he art to selecting the right headline font is


having a good understanding of the
subject and being sympathetic to the tone
of the writing (or the company/brand). This
is where your inherent skill as a designer or
creative is required. You have to feel your
way through potentially hundreds of typefaces before
you know youve hit upon the right one.
This is something that only improves with time, and
the quickest way to get better at finding the right
typeface is to do as much work as you can and to keep
practicing. Each time you read an article, see a design or
open a magazine, notice the font thats been selected
and how it relates to the subject. Ask yourself how youd
do it if you had the chance or how it has inspired you.

No codes or protocols
There are no hard and fast rules that must be applied to
selecting headline type, but theres a few guidelines that
can assist in adding that touch of professionalism to your
design. Focus on readability first (see previous page), test
out lots of different typefaces, use a type testing tool like
Typecast app, and ensure they also have the right feel for
the design of the site.

Tabloid headlines
If we look at newspapers for their approach to titles youll

The sans serif for the offer shown above immediately grabs the attention of potential customers
notice tabloids generally favour large sans serif, impact
fonts set in uppercase while more traditional
broadsheets opt for serifs set in lowercase. This comes
back to the content; tabloid headlines tend to be more
sensationalist with attention grabbing phrases, whereas
broadsheets have more subtlety, which is reflected in the
fonts they have chosen.

Great headline fonts

Helvetica
Sans serif
www.fonts.com
No prizes for originality but it wouldnt
be right to not mention this milestone of
design in an article about type. Helvetica
is to type what black is to fashion it
goes with anything. Coupled with its
vast range of variations from extra-light
through to rounded bold, Helvetica
gives instant gravitas to any design.

130 Web Design Tips, Tricks, & Fixes

Glober
Sans serif
http://bit.ly/1vq61ap
Despite being a new typeface, Glober
has an instantly familiar look with a wide
variety of feels thanks to its 18 available
weights (two of which are free). Based
on simple geometric shapes, Globers
modern design is also optimised for
web, making it an ideal consideration if
youre after something a little different.

Tip
If using all caps on titles, be sure to play with letter
spacing in CSS to ensure the greatest readability. Also,
if your design looks great with a title on one line, how
might it look if titles are longer and run onto two lines,
or more? Line height may also needs adjusting.

Weve selected four top headline fonts that range from the
old faithfuls through to the young upstarts of web type

Baskerville
Serif
http://bit.ly/1tGCmry
For class and tradition you cant go
far wrong with Baskerville. It works as
well in uppercase as it does in
lowercase. While not ideal for smaller
body copy, its unique characteristics,
such as its beautifully distinctive capital
Q and lowercase g, make headlines
stick out a mile.

Adobe Caslon Pro


Serif
www.adobe.com
Simple, classic and inherently legible,
Adobes Caslon has some of the
most inspiring italics and small caps
around that offer a real sense of calm to
any page design. This face has a
maturity about it that brings instant
respect to designs across all platforms
at varying sizes.

The Theory of Text and Type

Get the
best body

Are system fonts the


answer to a great body?
Or should you consider
an alternative?

Arguably one of the first questions designers face


is whether to opt for a system or web font when
choosing body type. Theres definitely a warm sense of
comfort knowing youll be safe with Arial, Georgia or
Verdana with fewer concerns for rendering thanks to
being designed expressly for screen. Screen fonts
generally have higher x-heights (a standard type
measurement of a lowercase x that determines the
height of all letters excluding ascenders or descenders)
and greater letter spacing than traditional typefaces
designed for print.

But with all the beautiful alternatives to system fonts


available youll want to branch out and experiment and
why not? Whats stopping you? Just ensure you
consider a few things.
First make a decision on serif or sans serif. After this,
things are considerably easier. To aid in this decision, just
come back to asking who its for; what is the message,
what is the tone, will it suit the overall feel?
Once youve committed to one, begin your search by
testing legibility. If youre set on using a web font, be sure
not to design purely in Photoshop (or any design
application for that matter). Most design programs
ability to render type leave a lot to be desired and never
provide a real measure of how the end result will look.
Use something like Typecast that allows you to see how

body
Here we choose excellent
choices for creating greatlooking body copy

Choose your family: Arial or a new kid-on-the-block?

What to consider

The perfect

type renders in HTML. Alternatively, try jumping into


creating HTML prototypes (though Typecasts service is
way simpler).

Arial
Sans serif
Although generally considered to be a poor mans
Helvetica, Arial is still a workhorse of screen
typefaces. It also comes with the advantage of
displaying on screen better at smaller sizes than
its Swiss counterpart, and can again be used in
email design without concern for the user
owning the typeface.

Looking for legibility


Compare and contrast. Remember, youre looking for
legibility. Reduce the type to a smaller size than
you might ordinarily have it set (10px or so) to see
how it performs at lower levels - necessary for
microcopy and so on.
Give thought for download times and the weight of
the web font youre selecting. Most subscription services
give the physical sizes, so compare these as you go. A
tip to keep weight down is to not always select all the
available variants unless you absolutely need them - can
you get away with just italic and not bold italic?

Proxima Nova
Sans serif
To many, this has become the new standard Arial
replacement and its easy to see why. Beautifully
designed, taking inspiration from greats such as
Futura and Akzidenz-Grotesk, Proxima Nova is
perfect for web body copy thanks to its high
readability at smaller sizes.

Roboto
Sans serif
The original system font designed for Android
OS by Google was slammed for its awkward and
overly digital appearance. However, thanks to an
overhaul just this year, Roboto has now been
transformed into a thing of beauty. Designed
uniquely as a UI typeface, its guaranteed to work at
all sizes on all screens; from a television to a watch.

Georgia
Serif
Destined to be a classic yet still only 21-years-old.
Originally designed for Microsoft as a partner for
their Verdana typeface, Georgia works well in upper
and lower case. Out of all the serifs, its highly
readable at most sizes and, usable on webpages
and in emails safely as its a system typeface.
The Roald Dahl site combines hand-written fonts with Baskerville to create a timeless and classic style

Web Design Tips, Tricks, & Fixes 131

The perfect match


Just like the great movie star duos Butch and
Sundance, Thelma and Louise, Han and Chewie
theres some typefaces that just share a natural
chemistry. Opposites very much attract and theres a

real art to selecting a good pairing. A well matched pair


of typefaces can instantly enhance a webpage through
harmony and balance. Finding two typefaces that work
well together while not looking too similar but,

equally, arent too far apart sounds awfully


confusing. Though it does have a fuzzy logic to it.
Here are a few examples of classic pairings to get
you started.

Headline: Brandon Groteske


Body: Roboto Slab

Headline: Avenir
Body: Georgia

A nice contrast between the bold rounded nature of Brandon Groteske and the
angular edges of slab serif, Roboto. Easy to read on full desktop view at 20pt but
watch for how well slab serifs translate at smaller sizes as well as on mobile or tablets.

Again, similar to the above, punchy headlines make way for a more subtle readable
typeface. The feel of the site as a whole is very clean and modern. Using the italicised
serif for the kicker works well for the title sequence.

Headline: Freight Display


Body: Georgia

Headline: Museo Sans


Body: Adobe Calson

Rare for a duo of serifs to work exceptionally, but this carries it off well. Freight Display
brings clarity to the titles on a text heavy design. The additional white space given
allows it to breathe and the condensed space is filled with the ever-legible Georgia.
A classic look, popular at the moment for that old field notes/journal vibe.

This combination has been used to create a much more classic feel. The serif callouts
give an editorial feel and the size plays a vital role in the visual hierarchy. When it
comes to using a san serif as the title, the punchier Museo at smaller sizes brings
clear and concise subtitles and navigation.

Headline: Gotham
Body: Chronicle
With a very minimal theme and colour palette, Gotham seems the ideal choice to get
that clean polished look easily. The font allows the medium weight to be scaled up to
gigantic proportions without looking overwhelming and can be tracked as to not feel
too cumbersome. The book weight is ideal for body copy with its light appearance
and wide, spacious characters.

132 Web Design Tips, Tricks, & Fixes

The Theory of Text and Type

Type for all screens


Type needs to be perfectly formed for more than just the desktop. Find out
what you need to know to get it right on all screens

ne of the biggest challenges facing


designers today is the number of
platforms that their work could
potentially be seen on. How type
appears on everything from a
widescreen TV to a pair of glasses
should be part of the consideration. While this sounds
daunting, provided you spend a bit of time ensuring
your selected typeface works well at all sizes then you
should be safe.
Were still at a stage where to test on absolutely
everything is nigh on impossible, if not from a cost
standpoint of owning all devices, then certainly a time
one, which is precisely what responsive design sets out
to deal with. There are many apps available to allow
you to quickly test on multiple platforms, but theres
nothing like moving a design into an HTML prototype
and testing on a mobile and tablet to really give you a
feel for readability.
To help with getting your font size right on all
platforms, theres several interesting developments in
the responsive web typography field. Fit Text (fittextjs.
com) for example, effectively does the same for type
that percentages do for your images in that it makes
font sizes flexible.
Its important to play about with media queries to
ensure line lengths meet your desired limit. Google
Trent Waltons article on Fluid type which, despite being
a couple of years old, offers a neat solution for this.
In terms of typeface selection, bear in mind most
typefaces were designed with a specific use in mind, so
youll often need to make adjustments in CSS as to
how they display. Line height should be adjusted to
between 140 to 160 per cent depending on your
preference but this again may need to change
depending on the platform.
Remember, not all fonts were designed for screen,
so spend time early on in the design process selecting
typefaces that youre certain will translate to devices
and not just the computer youre designing on. Many
of the larger foundries have been redesigning their
most popular typefaces to adapt for screen reading, so
where possible check to see if screen specific versions
of the font youre looking for is available.

Tip
When testing type, dont use lorem ipsum use real
copy and read it. Relax your gaze on the screen to see
how the typeface feels. If you find it difficult or youre
straining in any way, look at something a little less

Remember to test your chosen typeface on multiple platforms. Its imperative when creating a responsive design

What next for web type?


With increasing browser standards we can expect
more interesting developments for reading and
absorbing the written word in the future. CSS and
JavaScript have reached a stage where things that can
be achieved now were only thinkable in Flash

previously. With CSS shapes lurking on the horizon well


begin to see enhanced visual storytelling (check out the
Alice in Wonderland CSS shapes demo) and with apps
like Spritz (www.spritzinc.com) we may even begin to
change the way we read altogether.

busy or up the point size.

Web Design Tips, Tricks, & Fixes 133

MODERNIZR
MASTERCLASS

Ensure that your site runs as smoothly as possible by


acquainting yourself with the wonders of Modernizr

he modern web is a wonderful thing. The arrival of HTML5, CSS3 and


mature JavaScript frameworks such as jQuery has completely transformed
the landscape of web design, which allows designers to create advanced
interactivity and craft beautiful layouts with ultimate ease. We have never
had it so good!
Unfortunately, while this utopian view is certainly based in truth, we cant ignore the
past. For practising web designers, theres a daily consideration that presents
challenges and frustrations alike: the out-of-date browser.
The problem with older web browsers is that they dont necessarily support all
those fancy new features that youre desperate to use. They might not understand
some of the CSS you plug in to your stylesheet, but happily deal with other, older
properties. It can quickly become frustrating working to support these less-capable
browsers, and it can be tempting to fall back to the lowest common denominator.

134 Web Design Tips, Tricks, & Fixes

By avoiding the latest features of CSS3, and sticking with tried-and-tested XHTML
tags, all the problems of testing and providing workarounds can be avoided right?
One of the biggest challenges with adopting new practices and tools is knowing
which browser supports which features. When we only had to contend with a couple
of versions of Internet Explorer, and the first version of Firefox, it was straightforward;
we knew what each browser was capable of. This allowed designers to target the
behaviour and capabilities of the two, optimising a design to suit each different one.
These days, however, there are at least half a dozen perfectly viable and capable
browser options for web users to choose from, and each has several versions in the
wild at any one time. Its become almost impossible to be intimately familiar with the
individual support characteristics of each web browser that might be used to access
your website. As a result, its no longer practical to target individual browser versions.
Thankfully, theres a simple and elegant solution.

Modernizr masterclass

WHAT IS MODERNIZR?
Modernizr is a JavaScript library that allows you to use
feature detection to determine whether the browser
being used to access your website is going to be able
to render specific types of content, or will support
particular features. The library works by allowing you to
check for support within the browser against a series of
tests. For example, if youre using CSS transitions, you
can test for the browsers ability to render these and, if
the browser doesnt handle animations, provide a
fallback or alternative.
Put in simple terms, Modernizr allows you to write
conditional CSS and JavaScript to tailor the experience
of your website according to the capabilities of the
users web browser.
The library is quick to install, and simple to use. When
a page with Modernizr loads, a JavaScript object is
created that contains the results of the tests. CSS
classes are added to the <html> element, allowing you
to check either via script or CSS whether a specific
feature is supported.
You may be wondering what tests can be run, and
which features are supported by Modernizr. What
makes the library so useful is that its almost a one-stop
shop for browser functionality-support testing.
Modernizr allows you test for over 40 next-generation
features including font-face, rgba, CSS animations,
gradients, canvas, HTML5 audio and video, local
storage and WebGL. Youre not tied into running tests
for every single feature, however. A great strength of
Modernizr in particular is its modular nature; you only
need test for the features you need, rather than having
to conduct every individual feature.

Most importantly of all though, Modernizr allows you


to use cutting-edge HTML5 and CSS3 features to
progressively enhance your designs, without excluding
older browsers. You can use the library to selectively
enhance the user experience for modern browsers by
employing the script loader, allowing you to provide a
basic consistent experience for all browsers, then add
bells and whistles safely.
A further benefit of Modernizr is that you can tailor
the library in a modular fashion so that youre only
downloading the code necessary for the specific tests
you require. If youre happy to accept the overhead
associated with all 40+ tests, you can still get
performance enhancements by using a Content
Delivery Network (CDN) hosted version of the library.
This latter option allows the users browser to cache its
first download of the library, and then call upon the
cached version on all other sites that use the same
Content Delivery Network.
However, the slimmest and best solution is to tailor
the library to the specific tests you need to run on your
website. If you only need to test for support of
geolocation, or only want to know if youll be able to
load external fonts successfully, the custom builder
allows you to exclude all other tests, and any
unnecessary utility methods, making the download
(and overhead) tiny.

WHY USE IT?


The benefits of using Modernizr as opposed to the
more traditional approach of sniffing for a particular
browser and operating system are vast and numerous.
The feature-detection approach is more reliable by far, it
isnt tied to specific browsers and takes account of
individual users manually overriding their browsers
user agent property.
Modernizr makes it simple to build a set of
functionality and polyfills once. You can then rest safely
in the knowledge that as browsers are updated and
new functionality is introduced, your website design will
continue to work as expected.
Its also a much more convenient method of
providing a fallback for less-capable browsers. The
library executes in milliseconds, providing access to all
the hooks you need to identify feature-deprived
browsers. Plus giving you a single framework to use for
all your polyfill (where you replicate functionality using
alternative solutions) requirements.

The library can be tailored to reduce its footprint and overhead, or


you could use a CDN-hosted version to improve performance

Modernizr allows cutting-edge HTML5


and CSS3 features to enhance your designs

The Modernizr website provides full access to all documentation


and example code

THE BENEFITS OF USING MODERNIZR


Weve already touched on how Modernizr is superior to
the more traditional method of browser sniffing, using
navigator.userAgent. While this method worked at the
time, the premise was based on a limited number of
browsers and sketchy support for features, to the extent
that it was necessary to target individual browsers in
order to achieve a consistent look between them.
Whereas in the past it was extremely common to use
CSS hacks, were now in a more enlightened age where
were happy to accept that not every browser will
render a page identically. However, we do still have the
problem of different browsers offering differing levels of
support for features.
There are numerous ways of dealing with the issue,
but Modernizr offers the cleanest solution to featuredetection, and allows you to embrace the most
cutting-edge features within HTML5 and CSS3, all
without compromising the user experience for older
web browsers.
As well as the ease of developing according to
supported features, theres a further benefit that might
not be immediately apparent.
As websites have become more complex collections
of rich media and user interactivity, so the weight of
page downloads has increased. Its not uncommon for
one page to require as many as a hundred files to be
downloaded. This is especially true where the designer
has provided workaround solutions or polyfills for older
browsers. Frustratingly in the case of workarounds, not
all browsers actually need the workaround code only
those that dont support the given feature.
Modernizr allows you to circumnavigate this issue,
but acting as a loader for stylesheets and scripts,
according to the result of the test(s) conducted. This is
made easier by the integration of yepnope.js, which is a
library designed to allow for conditional resource
loading. YepNope actually adds some additional
features that can further improve performance,
including the ability to prevent the same script being
executed twice.

Web Design Tips, Tricks, & Fixes 135

As well as feature-detection and conditional resource


loading, there are other reasons to use Modernizr. If
youve ever used HTML5shiv/shim youll be familiar with
the idea that older browsers, especially in the Internet
Explorer family, dont support the newer HTML5 tags
such as <article>, <section>, <header> and <nav>. The
shiv adds support and sets these new tags to behave
akin to a <div> tag.
Modernizr has an optional HTML5 shiv built-in, and
this can be enabled from the Extra section of the
production-library configuration tool. By including the
shiv within Modernizr, youre automatically fixing older
browsers at the same time as conducting tests for
features. Thats not to say that browsers that dont
support <audio> will suddenly be able to play audio
files, but it provides a fail-safe way to use the latest
semantic HTML5 tags without having to worry about
older browsers.
Setting up the library is very quick and easy to do.
And whats more, by customising the features that
youre testing for, you can limit the weight of the script
to a minimum. This makes it a really effective way to
handle and cater for browser differences without
adding bloat.

001 .cssanimations [your normal selectors] {


002 /* CSS rules in here */
003 }

How to setup Modernizr


1. Configure and download

While for those that dont, the following selector would


be applicable:

004 .no-cssanimations [your normal selectors]


{

005 /* CSS rules in here */


006 }

Take a visit to the Modernizr website at http://


modernizr.com and click on the Download menu
option. If you want to run every test, you can take a
shortcut and click on the download button for the
Development version, which includes the kitchen
sink. If youre creating a production-ready version,
however, the configuration utility allows you to
choose specific features to test for.

Script customisation
Not everything can be handled with CSS alone. In
above example, JavaScript would offer a good solution.
We could provide animation using CSS if supported, but
fall back to a jQuery animation in browsers that dont
support CSS animations. In this case, we could use a
simple jQuery selector to only run the JavaScript
animation on non-supported browsers:

2. Add the script


Now that youve got your version of Modernizr, either
as a development version or a custom-build, you
need to add it to your page source code. Use a set of
standard <script> tags to add the library, making sure
you do inside the <head> section of the page. This
will ensure the library runs as early as possible when
the page is loading.

001 $(.no-cssanimations [your normal


selectors]). each(function(){

002 // normal jQuery animation code


003 }

USING YOUR TEST RESULTS

001

<script type=text/javascript href=/


scripts/modernizr.js></script>

3. Use the library

Testing for the features that youre targeting happens


automatically as part of your build of Modernizr. As
soon as the library is included in your page, the tests
are run and the result is saved to the JavaScript
Modernizr object, alongside a series of HTML-element
classes indicating support for (or lack of support for)
individual features being tested against.So, now that
you have this information, what do you do with it?

An alternative is to use the Modernizr object to retrieve


the status of support for a particular feature. In the case
of geolocation, for example, you might add a
conditional clause in your script as follows:

001 If (Modernizr.geolocation) {
002 // This code only runs if the browser
supports geolocation

The quickest way to make use of the library is to


target specific styles using the handy classes
appended to the HTML element. This allows you to
restrict particular CSS code to browsers that support
specific features. If youre using JavaScript on your
page, youll can also check individual properties of
the Modernizr object for a boolean value true
means the feature is supported.

003 }

CSS-only customisation
For CSS-specific customisations, its as simple as
providing an alternative set of rules that uses the class
system to target browsers that dont support the
feature in question separately from those that do. For
example, you might have one set of rules introducing a
CSS transition for browsers that support animation, and
a second set for those that dont.
The CSS selector for those that support animations
would be:

<HEADER>
<NAV>

<ARTICLE>

<ASIDE>

CSS and script customisation


If you need to customize both your scripts and your
CSS, you can use a combination of both the methods
above to provide support for both. This is particularly
useful if you want to use a single JavaScript file and a
single CSS document in your page.

Conditional loading of styles and scripts


If youre able to split out your code into separate
sections, the addition of YepNope allows you to
conditionally load resources according to the result of
each test. A major benefit of conditionally loading
scripts and styles according to browser feature-support
is that you avoid having to load all your workaround
options into every browser; only those that need the
polyfills get them. Check out the next page for full
details on how to use YepNope with Modernizr!

001 <style>
002 .no-csscolumns body {
003 /* this browser doesnt support CSS columns
*/

004 }
005 </style>
006 <script>
007 if (Modernizr.touch) {
008 // the browser supports touch events, so
run the code within this section

009 } else {
010 // the browser doesnt support touch, so
provide an alternative

011 }

Using polyfills
<FOOTER>
Some older browsers do not support the newer HTML5 tags, an
issue that is easily resolved with Modernizr

136 Web Design Tips, Tricks, & Fixes

The whole purpose of Modernizr is to allow you to use


modern features with safety, providing the opportunity
to put a fallback or alternative polyfill in place for
browsers that dont support a specific feature. Rather
than re-invent the wheel each time that you need to

A useful library of polyfill solutions can be found at https://github.


com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills

Modernizr masterclass

polyfill a specific feature, the team behind Modernizr


has compiled a list of pre-built polyfill options,
categorized by feature. You can access this list at http://
bit.ly/10S2kHA.

LOADING CSS AND JS FILES


WITH MODERNIZR
Modernizr has a handy load method which can be
optionally included within your build. This method was
spun out as the YepNope project, but originates within
the Modernizr library and includes a series of useful
features that can boost the apparent download speed
of your page, as well as conditionally load resources
according to browser capability.
The basic syntax for loading a CSS or JavaScript file
using Modernizr.load is shown below:

001 Modernizr.load([
002 // object notated list of tests and
responses
003 {
004 test : Modernizr.canvas && Modernizr.
cssgradients,
005 // Multiple resources can be loaded for
each condition
006 // This condition is not met, so load
two files
007 nope : [presentational-polyfill.js,
presentational.css]
008 },
009 {
010
// This just has to be truthy

011
test : Modernizr.JSON,
012
nope : functional-polyfills.js,
013
// These resources will be loaded
014 regardless of the result:
015
both : [ app.js, extra.js ],
016
complete : function () {
017
// Run this after everything in this
group has downloaded
// and executed, as well everything in
all previous groups
019
myApp.init();
020
}
021 },
022 // Run your analytics after youve
already kicked off all the rest
023 // of your app.
024 post-analytics.js
025 ]);

018

001 // Test for <track> element support


Modernizr.addTest(track, function(){

002 var video = document.


createElement(video);

003 return typeof video.addTextTrack ===


004 function
005 });
This extensibility allows you to add tests for cuttingedge or experimental browser features that arent
available cross-browser. And, test progressive
enhancements without adversely affecting nonsupporting browsers or being reliant upon the library
updating to test for features you want to test against.

Youll notice that the final element in the object is a


simple filename. In the absence of a test, the notated
file will be simply loaded, allowing you to offset the
loading of resources until your code is executed. This
can give the impression of a faster loading page.

SETTING UP YOUR OWN TESTS


The Modernizr API provides direct access to a number
of useful methods that you can use to add your own
bespoke tests. The example provided in the
documentation for the library, which can be found at
http://modernizr.com/docs/, demonstrates the addition
of a test for support of the <track> element:

YepNope allows you to conditionally load resources into your


page according to the result of the test youre using

Using
YepNope with Modernizr
YepNope makes it easy to load JavaScript and CSS resources into your page according to the result of each Modernizr test.
Well show you how to use the library to only load content each browser needs.

3. Load resources
1. Load the library

2. The basic syntax

YepNope can either be downloaded from www.


yepnopejs.com, or you can include it directly in
your Modernizr build by ticking the Modernizr.
load checkbox under the Extra section. If you
have included it in your Modernizr build, then you
only need to include that particular file. If youre
keeping it separate, add a <script> tag in the head
section of your page, linking to the yepnope.js file.

The basic syntax for a YepNope conditional load is


very simple and easy to understand. The YepNope
object is called and a series of properties are
passed in representing the test to perform and
the resources to load. The example below loads a
polyfill script for browsers that do not support
HTML5 video.

001 yepnope({
002 test: Modernizr.video,
003 yep: video.css,
004 nope: [video-html5.css,videopolyfill.js],

Yepnope has a respository on Github with the latest updates

005 callback: function(url, result, key){


006
if(url == video- html5.css){
007
alert(HTML5 Video Ready);
008
}
009 )};

As well as loading on the basis of the result of


the test, you can also use YepNope to load
resources regardless of the test. There are
further methods for handling events associated
with the load of these resources (such as
initiating an object), callback and complete the
latter being fired once everything has loaded
and processed.

001 Yepnope({
002 test: /* condition to be tested, with a
boolean result (true / false) */,
yep: /* list of resources to load if
condition is true */,
004 nope: /* list of resources to load if
condition is false */,
005 both: /* list of resources to load
regardless of result */
006 });

003

Web Design Tips, Tricks, & Fixes 137

Create sticky
table headers
using CSS
and jQuery
Make it easier for visitors to process
large amounts of data with sticky table
headers on both the X and Y axis

016
<td>Winter</td>
017
<td>2011-03-17</td>
018
<td>771-581-3017</td>
019
<td>brain.rob@slopeslow.me</td>
020
<td>89 W Blackjack</td>
021
<td>Apt 16</td>
022
<td>VA</td>
023
<td>21450</td>
024
<td>Iraq</td>
025 </tr>

03 Format table

There is one more step needed before we can use


the dummy data; we need to make sure that the HTML
used to generate it is semantically valid. We need to ensure
that the thead and tbody sections are defined correctly,
as we will be referencing these later on in the tutorial. Add
the code below around your table headings and body.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends Dreamweaver, jQuery

hen dealing with large


amounts of table data
your users can easily
become lost, so making
things as readable as
possible is important.
Using CSS to create
striped table rows and
columns will allow the eye
to remain in the correct
place as a user scrolls through the data. Adding sticky table
headers means the headings on your table will follow the
user as they scroll through the page, saving them from
returning to the start of the document to find out what data
each row represents.
In this tutorial well look at a pure CSS option for this
before moving on to a combination of both jQuery and CSS.
The reason for this is that the pure CSS version is only
supported by a small number of very modern browsers, by
adding in jQuery we can target a larger section of visitors
across all browsers. This tutorial assumes you have a
development environment already configured to work on
localhost or a remote development server. You will not need
any server-side platforms enabled on this environment, but
check your JavaScript security settings when running locally.

01 Generate dummy data

To create a table that we can scroll around in, well


be using Dummy Data Me (dummydata.me). Add at least
ten rows, generating as much data as you need, and export
to HTML. Create a blank HTML file ready for data.

001 <!DOCTYPE html>

138 Web Design Tips, Tricks, & Fixes

002
003
004
005
006
007
008

<html>
<head>
<title>Sticky table headers</title>
</head>
<body>
</body>
</html>

02 Import data

Once you have generated the table data, right-click


on the page and select view-source. Unfortunately the
dummy data code isnt very well formatted, so well have to
tidy it up a bit before we can actually use it. Copy the
source and head over to www.freeformatter.com, paste
the HTML in and youll get nicely indented table HTML
ready to go into a new HTML file.

001 <table cellpadding=3 cellspacing=1


002
003
004
005
006
007
008
009
010
011
012
013
014
015
016

id=resultTable>
<thead>
<tr>
<th>First Name</th>

<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hilario</td>

<td>Iraq</td>
</tr>

</tbody>

04 Style the table

As mentioned previously, it is important to make


the table as readable as possible. In order to achieve this in
a simple way, we will use some CSS to create a striped
table. This CSS uses the nth-child element to only apply the
style to even or odd rows, however, it is a CSS3 selector
and some older browsers may not support it.

001 <table cellpadding=3 cellspacing=1


id=resultTable>

002 <tr>
003
<th>First Name</th>
004
<th>Last Name</th>
005
<th>Date</th>
006
<th>Phone Number</th>
007
<th>Email</th>
008
<th>Address 1</th>
009
<th>Address 2</th>
010
<th>State</th>
011
<th>Post Code</th>
012
<th>Country</th>
013 </tr>
014 <tr>
015
<td>Hilario</td>

001 <style>
002
html {font-family: arial, sans-serif}
003
tbody tr:nth-child(odd) {
004
background-color: #cccccc;
005
}
006
tbody tr:nth-child(even) {
007
background-color: #999;
008
}
009 </style>
010

05 CSS sticky headers

It is possible to create sticky headers using just


CSS, however, this is only supported by bleeding-edge
browsers for the time being. Adding the following CSS

Create sticky table headers with CSS and jQuery

< Above>
s5IFEVNNZEBUBJOJUTSBXFTU
GPSN HFOFSBUFEVTJOHdummydata.
meXJUIOPTUZMFBQQMJFEUPJU

< Below>
s6TJOHBMUFSOBUJOHTUSJQFE$44CBDLHSPVOE
DPMPVSTJOPVSUBCMFEBUBJNQSPWFTJUTSFBEBCJMJUZ
HSFBUMZ#FDBSFGVMBCPVUDPNQBUJCJMJUZUIPVHI

< Above>
s$PNCJOFFWFSZUIJOHXJUICPMEMFGUIBOEDPMVNOIFBEFSTGPSBUSVFCJBYJBMTUJDLZUBCMFFGFDU

code will enable sticky headers but until it is


standardised, it should not be used in a production
environment. It is unlikely youll be able to see the results
for now, but well address that in the next step.

001
002
003
004
005
006
007
008
009

Thead {
position:
position:
position:
position:
position:
top: 0;
}

-webkit-sticky;
-moz-sticky;
-ms-sticky;
-o-sticky;
sticky;

06 Test the CSS

At this stage you will need to download and install


either Google Chrome Canary or one of the WebKit
nightly builds. We will focus on Canary as were
developing on a Windows machine. Head over to www.
google.co.uk/intl/en/chrome/browser/canary.html and
grab the latest build. You can run Canary alongside the
standard stable version of Chrome. Once installed, run
your code to view the results.

07 Wider support

Now we have dabbled with some bleeding edge,


untested, unsupported and unstable code, its time to focus
on supporting the other 94 per cent of users. Remove the
thead CSS element that contains the sticky property and
add the CDN-hosted version of jQuery to the <head>
section of your HTML using the following code.

001 <script src=//ajax.googleapis.com/ajax/

libs/jquery/1.11.0/jquery.min.js></script>

08 jQuery cloning

In order to achieve the sticky effect in jQuery, we


need to clone the thead HTML elements, and present
them on the page separate to the existing table. This way,
we can alter the thead element, without affecting the rest
of the table. The following code will do just that.

001 <script type=text/javascript>


002
$( document ).ready(function() {
003
$(#resultTable).find(thead).
clone().appendTo(#resultTable);

004
});
005 </script>

09 Some required CSS

Before we start making our duplicated thead sticky,


we need to add some CSS that wraps around our table.
Add the following code to your style section, we will
programmatically apply this style to our table through
jQuery. This is useful if you want to apply the sticky headers
to multiple tables on the page.

001
002
003
004
005
006
007
008
009
010

.wrapper {
overflow-x: auto;
position: relative;
margin-bottom: 1.5em;
width: 100%;
}
.wrapper .sticky-thead,
.wrapper .sticky-col,
.wrapper .sticky-intersect {
opacity: 0;

011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033

position: absolute;
top: 0;
left: 0;
transition: all .125s ease-in-out;
z-index: 50;
width: auto;
}
.wrapper .sticky-thead {
z-index: 100;
width: 100%;
}
.wrapper .sticky-intersect {
opacity: 1;
z-index: 150;
}
.wrapper .sticky-intersect th {
background-color: #666;
color: #eee;
}
.wrapper td,
.wrapper th {
box-sizing: border-box;
}

10 Wrap the table

The following code snippet will search all of the


code for any tables, and then wrap it all with some CSS.

001 <script type=text/javascript>


002
$( document ).ready(function() {
003
$(table).each(function () {
004
$(this).addClass(stickyenabled).css({margin: 0,width: 100%}).
wrap(<div class=wrapper />);

Web Design Tips, Tricks, & Fixes 139

13 Move header function

This next function will do the actual moving of the


header; the if statement will check to see if the user is at the
top of the page, and hide the cloned header if they are.
Otherwise, it will display the cloned header and move it
accordingly with a smooth scroll.

14 Move columns

To create the biaxial scrolling headers, we need to


move the column headers as well. This next function does
pretty much the same as the last, but it is applied to the
column HTML, ensuring the left-hand headers are always
visible on the page. You may have to add more data to
your table to see this in action.

<Above>
s5IJTJTour appended table data, driven by jQuery. You may notice at this stage that not all the data is present

CSS colours
When creating a striped table, it
is not recommended that the
two colours are vastly different
from a readability perspective.
Keep them to subtle shades
of the same colour.

005

$(this).after(<table
class=sticky-head />)
006
$(this).after(<table
class=sticky-col /><table class=
sticky-intersect />);

007
008
009
010
011
012
013
014
015

var $stickyHead = $(this).


siblings(.sticky-thead),
$stickyCol = $(this).
siblings(.sticky-col),
$stickyInsct = $(this).
siblings(.sticky-intersect),
$stickyWrap = $(this).
parent(.sticky-wrap);
})
});
</script>

11 Append thead

You may have noticed that we removed the clone


step from the previous step in our code here, this is
because we need to clone the thead and wrap it in some
CSS. The following code will do exactly that and needs
to replace the code you used earlier on in Step 8 of
this tutorial.

140 Web Design Tips, Tricks, & Fixes

001
002
003
004
005
006
007

$stickyHead. Append($(this).
find(thead).clone());
$stickyCol
.append($(this).find(thead,
tbody).clone())
.find(thead th:gt(0)).remove()
.end()
.find(tbody td).remove();
$stickyInsct.html(<thead><tr><th>
+$(this).find(thead th:first-child).
html()+</th></tr></thead>);

008

12 Helper functions

Here we are going to add some helper functions to


our JavaScript file that we will call at a later date. To keep
things neat you can choose to place these functions in a
separate JavaScript file or simply keep them within the
same code block its entirely up to you. This first function
will set the widths of the columns.

001 var setWidths = function () {


002 $t
003
.find(thead th).each(function (i) {
004
$stickyHead.find(th).eq(i).
005
006
007
008
009
010
011

012

width($(this).width());
})
.end()
.find(tr).each(function (i) {
$stickyCol.find(tr).eq(i).
height($(this).height());
});
$stickyHead.width($t.width());
$stickyCol.find(th).add($stickyInsct.
find(th)).width($t.find(thead th).
width())
},

001
002
003
004
005
006
007
008
009
010
011
012

repositionStickyCol = function () {
if($stickyWrap.scrollLeft() > 0) {
$stickyCol.add($stickyInsct).css({
opacity: 1,
left: $stickyWrap.scrollLeft()
});
} else {
$stickyCol
.css({ opacity: 0 })
.add($stickyInsct).css({ left: 0 });
}
},

15 Calculate allowance

This final function will prevent the sticky header


from travelling all the way to the end of the table. If we did
not place this here, the final rows could be obstructed
when we get to the bottom of the page. The function
calculates the height of the last three rows and prevents
the header from going lower than that.

001
002
003
004
005
006
007
008
009
010
011

calcAllowance = function () {
var a = 0;
$t.find(tbody tr:lt(3)).
each(function () {
a += $(this).height();
});
if(a > $w.height()*0.25) {
a = $w.height()*0.25;
}
a += $sticky.height();
return a;
};

16 Call the functions

Now we have got all of the functions declared we


can start calling them. The first will calculate all the table
widths and is a single line; all the hard work is done by our
function that we wrote previously. You can customise the
CSS to modify the colours, but make sure you do not
change any of the fundamental CSS.

17 Bind objects

Now we have all the widths calculated we can bind


them to the window. This allows them to be called when

Create sticky table headers with CSS and jQuery

the user scrolls down or across the page. You may notice
that the below call uses the $w variable, this is a shorthand,
and well set this later on in the tutorial.

Code library

001 $load(setWidths)

By making some small changes to our code, we can greatly increase


the performance that is seen by a user

A tidier JavaScript code block

18 Check for resize

As we are calculating the width of the table data, we


need to implement a check that recalculates these
variables if the size of the window changes. If we did not,
the offset would be wrong when it comes to scrolling and
our sticky headers would not sit at the top of the table.

001
002
003
004
005

By placing this entire block


at the bottom of your HTML
file, you should see an
increase in page load times

resize($.throttle(250, function () {
setWidths();
repositionStickyHead();
repositionStickyCol();
})

The top statement will


check for tables and only
execute if they are found,
rather than executing on
document ready

19 Call the scroll

The next call will do the repositioning of the table


headers unfortunately this will be called a great number
of times and have a considerable impact on JavaScript
performance. To get around this well need to implement a
throttle to limit the number of calls that are made.

001 .scroll(repositionStickyHead));

20 Implement throttling

Head to bit.ly/1iW78qm and grab the awesome


JavaScript throttling library from Ben Alman. Create a new
JavaScript file and paste the contents into that file. Save it
and add the JavaScript reference in the <head> section of
your index page with the following code.

These shorthand vars


mean we can simplify
JavaScript functions and
call them multiple times
throughout the rest of
the code script

001 <script src=JS/throttle.js></script>

21 Modify the JavaScript

To implement the throttle, update the line from Step


19 to the following code. At this stage we will pass a time to
the throttle function as well, so now the throttle will prevent
our page from spamming the jQuery functions with
requests. The next step is to define our shorthand variables
so that the table actually works.

repositionStickyHead));

22 Define shorthand

The final step is to hook up our shorthand


JavaScript vars. The following code will set these vars at the
top of the script and allow them to be referenced
throughout the rest of the code. Place the following lines
near the top of your JavaScript code block.

clone();

005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040

001 .scroll($.throttle(250,

001 var $w
= $(window),
002
$t = $(this),
003
$thead = $t.find(thead).clone(),
004
$col = $t.find(thead, tbody).

001 <script type=text/javascript>


002 $(function(){
003
$(table).each(function() {
004
if($(this).find(thead).length > 0 &&

The throttle prevents too


many calls and drastically
improves client-side
JavaScript performance.
See the source files for
more information

041
042
043
044
045
046
047
048
049

$(this).find(th).length > 0) {
var $w = $(window),
$t = $(this),
$thead = $t.find(thead).clone(),
$col = $t.find(thead, tbody).clone();
$t
.addClass(sticky-enabled)
.css({
margin: 0,
width: 100%
}).wrap(<div class=wrapper />);
$tatter(<table class=sticky-thead />);
if($t.find(tbody th).length > 0) {
$t.after(<table class=sticky-col
/><table class=sticky-intersect />);
}
var $stickyHead = $(this).siblings(.sticky-thead),
$stickyCol = $(this).siblings(.sticky-col),
$stickyInsct = $(this).siblings(.sticky-intersect),
$stickyWrap = $(this).parent(.sticky-wrap);
$stickyHead.append($thead);
$stickyCol
.append($col)
.find(thead th:gt(0)).remove()
.end()
.find(tbody td).remove();
$stickyInsct.html(<thead><tr><th>+$t.find(thead
th:first-child).html()+</th></tr></thead>);
var setWidths = function () {
$t
.find(thead th).each(function (i) {
$stickyHead.find(th).eq(i).width($(this).width());
})
.end()
.find(tr).each(function (i) {
$stickyCol.find(tr).eq(i).height($(this).height());
});
$stickyHead.width($t.width());
$stickyCol.find(th).add($stickyInsct.find(th)).
width($t.find(thead th).width())
},
repositionStickyHead = function () {
var allowance = calcAllowance();
if($t.height() > $stickyWrap.height()) {
if($stickyWrap.scrollTop() > 0) {
$stickyHead.add($stickyInsct).css({
opacity: 1,
top: $stickyWrap.scrollTop()
});

Web Design Tips, Tricks, & Fixes 141

Speed up
responsive
sites with
Foundation
Dont hide content from desktop to
mobile devices, use the Interchange
feature to only load the content
required by the device

001 <div class="full">


002
<div data-interchange="[v-default.
html, (small)], [v-medium.html, (medium)],

003 [v-large.html, (large)]">


004 </div>
005 </div>

04 Video for desktop browsing

Create a new HTML page and make sure it is


empty of all tags we dont need body and HTML tags as
they will be added to our existing page. Now input the
code as shown below, which adds the stylesheet for the
content well be adding. Were making our video 100 per
cent wide with a height of 600px.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends Foundation 5, Dreamweaver

ver noticed when creating a


responsive site that if you have a
huge image for desktop, it is far too
big for mobile devices? Of course
you have and youve probably even
tried to find a solution. There are
some out there but by and large
they require a lot of work. Foundation
is a responsive framework and with the new release
of Foundation 5, we have access to a new module
called Interchange.
Interchange lets the designer specify which content is
viewed on different screens. It doesnt turn <div> tags on
and off, instead it checks the device width with a media
query and using AJAX it loads the right content for that
device it doesnt just work on images either.
This is a significant improvement over hiding desktop
content, as doing that forces mobiles to still download the
content, using extra bandwidth and precious memory.
Now you can apply Interchange to a <div> tag and load in
external HTML snippets that will populate that tag for you
this is known as HTML partials.
This is probably the easiest way to create truly
responsive content that doesnt force mobile to have a
bloated desktop experience shrunk to the device.

01 Starting the project

From the resource files, copy the Start Folder to


your htdocs/web folder of your local server, such as W/L/
MAMP. Open the file index.html in a code editor and add

142 Web Design Tips, Tricks, & Fixes

the code as shown below to the head section of the page.


This links up the Foundation stylesheet with the Modernizr
library, which identifies which HTML5 elements are
supported by the browser.

001 <link rel="stylesheet" href="css/


foundation.css" />
<script src="js/modernizr.js"></script>

001 <style>
002 #vid {
003 width: 100%;
004 height: 600px;
005
overflow: hidden;
006 }

05 Style the video

Here we are adding in the CSS for the video tag


itself, so that the video fits the size we want it to. Notice that
we also close the style tag down at this point. We could also
put these styles inside a master stylesheet on our main
page if we wanted to

001 video{
002
min-width:100%;
003
min-height:600px;
004
width:auto;
005
height:auto;
006 }
007 </style>

002

02 Link up Foundation

Now scroll to the bottom of the document and add


the following script tags before the closing body tag. This
links up both the jQuery and Foundation library to the
document. The last script tag starts Foundation, enabling
the Interchange options to work properly on our webpage.

001 <script src="js/jquery.js"></script>


002 <script src="js/foundation.min.js"></
script>
<script>
$(document).foundation();
</script>

003
004
005

06 Add the HTML5 video

Directly after the stylesheet we add the following


code, which is for an HTML5 video with options for MP4,
WebM and Ogg Theora video in order to cover all the
major browsers. We set this video to play automatically and
then to loop. Now save this page as v-large.html in the
same folder as the index page.

001 <div id="vid">


002 <video autoplay loop>
003
<source src="header.mp4" type="video/
mp4">

004
005

03 Add the video

We are going to add some video to a desktop


browser but substitute this with an image for smaller-screen
devices. Add the code below after the start video
comment in the body of the document. As you can see, it
loads different HTML content for the different-sized devices
into this part of the document. In the next few steps well
create those external pages.

<source src="header.webm" type="video/

webm">
<source src="header.ogv" type="video/

ogg">

006 </video>
007 </div>

07 Medium screens

If you view your index page now over an HTTP


connection on a local server you will see the video load in
and play. Because we havent created the smaller pages yet

Speed up responsive sites with Foundation

< Above>
s8FBEEPVS)5.-WJEFPUIBUXJMMPOMZCFWJFXBCMFJOUIFEFTLUPQCSPXTFST5IJTXJMMTBWF
CBOEXJEUIPOUIFTNBMMFSTDSFFOEFWJDFTUIBUNBZCFBDDFTTJOHZPVSTJUFXJUIBEBUBQMBO

< Above>
s'PSBNPCJMFEFWJDFXFDBOOPXMPBEBTNBMMFSJNBHFTPUIBUOPCBOEXJEUIJTXBTUFE

< Above>
s8IFOJUDPNFTUPPUIFSTJ[FTDSFFOT *OUFSDIBOHFXJMMPOMZMPBEVQUIFSFMFWBOUDPOUFOUGPS
UIBUTDSFFO)FSFPONFEJVNTJ[FEUBCMFUTDSFFOTXFMPBEBOJNBHFJOTUFBEPGUIFWJEFP
< Right>
s"TXFMMBTMPBEJOHTFQBSBUF)5.-DPOUFOUGSPNEJGFSFOUJMFT XFDBOBMTPDIBOHFUIF
JNBHFUPUIFBQQSPQSJBUFEJTQMBZTJ[F

it will not change for lower screen widths, so again create


another new HTML page and add the following code.

001 <img src="img/vid-medium.jpg">

08 Create the default image

Save the last page as v-medium.html and create


another new HTML page. Here we add the code as shown
below and then save this page as v-default.html. Now if
you refresh your browser you can resize this and see the
different images load depending on the size of screen.

001 <img src="img/vid-default.jpg">


002

09 Switch the images

Images can easily be switched inline. To switch


content we use the data-Interchange HTML5 parameter.
Inside here information is passed to the JavaScript so that
the appropriate image can be loaded into the page. Add
this code after the horizontal rule under the Welcome title.

001 <img data-interchange="[img/spacesmall.jpg, (small)], [img/space-medium.jpg,


(medium)], [img/space-large.jpg, (large)]">

10 Default image view

The next code that we add directly below the last


step is a no script tag, so if JavaScript is disabled for any

reason, this will be the image loaded here. Weve added the
smallest image to the page because if theres no JavaScript,
the user will likely want a low rendering of the page.

001 <noscript><img src="img/space-small.jpg"></


noscript>
<hr>

002
003

11 Readable text

Test the page in the browser now and you will see
the video and image are responsive but rather than just
downsizing, they actually change to a lower bandwidth for
the smaller-screen devices. Now lets add a little space

Web Design Tips, Tricks, & Fixes 143

<Left>
sFoundations Interchange is very good at loading specific content for devices
and we can create separate files that feel a little like includes in PHP
<Above>
sHere we have added a YouTube video for desktop-sized browsing. As you can
see, it fits responsively into the Foundation grid

between the heading tag and the video. Go back into


your code and add the spacer class to the row as
shown below.

001 <div class="row spacer">

12 Style the link

Now move to the head section of the document


and well add in the style tags and the spacer class, just to
give the heading a little more space from the video or
image that is loaded. Save and view this in the browser
again to see the changes take effect.

001 <style>
002
.spacer{ padding-top: 40px;}

13 Responding map

In the document, scroll down through the body


until you come to the comment for the map panel. Add
the following code just below that comment. Here we are
going to load either a Google map for the large-screen
display or just a small image for the reduced screen size.

001 <div class="row">


002 <div class="large-12 columns">
003
<div data-interchange="[default.html,
(small)], [medium.html, (medium)], [large.html,
(large)]">

144 Web Design Tips, Tricks, & Fixes

AJAX loading

14 Close the <div>s

All we are going to do here is close those three


<div> tags and save our document. Create a new HTML
document as we are going to add our Google Map into
here. Head over to maps.google.co.uk and copy the
embed options of your chosen map, as we will need this
for our design very shortly.

Foundation uses AJAX to load the


appropriate content into the page,
as such this will only work if you
are hosting the page on a server,
which can be a local server
on your computer or
your web host.

15 Style the map

We will style the map up first, so in the new HTML


document make sure there are no other tags in there, such
as a head section or body section. Then, add the following
code in as shown. This is going to style up the <div> tag
surrounding the map so that it is the full width of space
available and 400px high.

001 <style type="text/css">


002 #map {
003 width: 100%;
004 height: 400px;
005 }
006 </style>

16 Add the map

Now we will add the map inside a <div> with the id


of map. So, paste in the code we copied from Google
Maps in Step 14. We will need to make some changes
though; change the width to 100 per cent and height to

400 as shown. Also you might want to get rid of the text to
view a larger map, but thats down to your preference.

001 <div id="map">


002 <iframe width="100%" height="400"
frameborder="0" scrolling="no" marginheight="0"
marginwidth="0" src="https://maps.google.
ca/?ie=UTF8&amp;ll=43.447946,-79.624382&amp;spn
=0.445663,0.467606&amp;t=m&amp;z=11&amp;output=
embed"></iframe>
003 </div>

004

17 Medium map

Save the HTML page as large.html and create


another new HTML page. This one is going to be much
simpler and have a static image display instead of the live
Google Map. Its also a good idea to add the address as text

Speed up responsive sites with Foundation

<Left to right>
sThe mobile-sized image replaces the Google Map on much smaller device
screens. This is very useful for targeting the right content for your user
sOn other devices we can swap out the HTML code for a Google Map and
make it load an image instead
sAs an alternative to the YouTube video, weve added text as a description of
the content that was presented in the video for smaller-screen devices

in here as well, as that will be more useful. Make sure you


save this page as medium.html.

001 <img src="img/map-medium.jpg">

18 Small map

Create another new HTML page and add only the


code shown below. Now save this page as default.html. Go
back to your browser and refresh the page. You will now
see all of your map details on the screen. You will need to
replace the map images with your own map screenshot.

001 //code// <img src="img/map-small.jpg">


002

19 Create YouTube content

Move to the comment YouTube Panel and add the


following code after that comment. This is going to create
an Interchange section for YouTube video content on the
page. Notice that we are calling the same file for both small
and medium displays. Save the current page after adding
this code as it is now finished.

001 <div class="row">


002 <div class="large-12 columns">
003 <hr>
004 <div data-interchange=" [yt-medium.html,
(small)], [yt-medium.html, (medium)], [ytlarge.html, (large)]">
005 </div>
006 </div>
007 </div>

20 Grab some content

Head to YouTube and grab the embed code for a


video in there. Now return to your code editor and create a
new HTML page. Make sure there are no other tags in the
HTML page and add in the flex-video tag as shown in the

Going further
Custom media queries can be
defined for changing content
with Interchange and events can
be fired through JavaScript, visit
bit.ly/1fQPF49 to find
out more.

code snippet below. Now paste in the embed code. Save


the page as yt-large.html.

001 <div class=flex-video>


002 <iframe width=560 height=315
src=//www.youtube.com/embed/FBmkFYym9hE
frameborder=0 allowfullscreen></iframe>
003 <div class=flex-video>

Interchange and handling


retina images
Retina screens cause web designers no end of
problems, one of the major ones being that images

21 Alternate video content

just look so low quality on them. Essentially, a retina

Now create a new HTML page (last one, we


promise!) and instead of the video we are going to add in a
title and description of the video to inform the user about
the information presented. This means that smaller screen
devices will still get the content but in a different format
as text instead of video.

screen has a higher ratio of pixels so a single pixel

001 <h3>What we do</h3>


002 <p>Description Goes Here</p>
003

001 data-interchange=[image/path/to/

gets stretched over about usually 4px.


The solution from Foundation is to have a named
query for retina, so as well as specifying a small,
medium and large image, you would also specify a
retina image, like this:

retina.jpg, (retina)]
Perhaps a larger problem is that retina screens

22 Final step

Finally save this document as yt-medium.html. Go


back to your browser and refresh the page. You should
see all the content swapping in and out depending on
your page size and obviously on smaller devices you
are saving bandwidth for the user, giving them optimised
page content.

appear on mobile, tablets and desktop computers,


so it is hard to know the width that you are dealing
with. As yet this remains largely unsolved, as you
would need to query width and retina then serve
the appropriate image. Still, solutions will emerge
as these devices become more widespread.

Web Design Tips, Tricks, & Fixes 145

Build a
custom
Foundation
template
Get started using Zurbs Foundation
framework to build a responsive
template that can be reused

03 HTML head

Within the HTML head well add a custom Google


Font called Cabin, which can be found and downloaded at
www.google.com/fonts#UsePlace:use/Collection:Cabin.
Its good practice not to directly edit the foundation.css,
which contains all the framework styles. We should house
all our custom styles in a separate CSS file called style.css.

001 <link href=http://fonts.googleapis.com/


css?family=Cabin:400,500 rel=
stylesheet type=text/css>
002 <link rel=stylesheet href=css/
foundation.css />
003 <link rel=stylesheet href=css/style.
css />

04 Basic styles

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends HTML, CSS, JavaScript

hen starting a new


responsive web design
project, trying to custom
develop your own
framework that includes a
flexible grid system, media
queries, typography,
JavaScript media including
video, carousels, lightboxes and more can be
exhausting. Not to mention the rapidly changing web
arena, youll have to rigorously maintain and update
your framework to keep up to date with all the cool
new features.
Using an open source framework like Foundation by
Zurb helps to relieve the stress on developers. This robust
and flexible framework is well documented and has a host
of ready components to reuse; the best part is you can
easily customise it, adding and removing functionality to
suit your needs. Foundation is built to be mobile first, so as
soon as you start using this framework for your web
project its instantly responsive.
Through this tutorial well touch upon some of
Foundations core components and how to assemble
these to create your own custom template, which can be
reused for any project.

01 Download Foundation

To begin, navigate over to the Zurb Foundation


framework website at foundation.zurb.com. Click on the
Download Foundation 5 button and you will be
presented with multiple choices to download
Foundation. You can select from a complete package,
lightweight, custom or Sass. In this tutorial well be using

146 Web Design Tips, Tricks, & Fixes

pure CSS to allow beginners to follow along, so go ahead


and download the complete version.

Now that we have our head of our HTML set up we


can start applying some default styling. Create a new
style.css in the CSS directory. Lets change the default font
colour to a dark grey and make sure all of our headings are
now using the new Google font Cabin.

001
002
003
004
005
006
007
008

body {
color: #666;
}
h1, h2, h3, h4, h5, h6 {
font-family: Cabin, sans-serif;
font-weight: 500;
color: #666;
}

05 Build the navigation

Create a <nav> wrapper and within this have a <ul>


with a <li> item for the main title, with a second <li> for the
mobile menu (this will only appear on a small mobile
screen). The top-bar class is used for presentational
purposes, the data-option stick_on will force the navigation
to stick to the top of the browser window.

001 <nav class=top-bar data-topbar data-

02 Unarchive the zip

Unarchive the Foundation framework you just


downloaded; inside you will find a CSS directory that
includes the complete Foundation CSS file and Normalize
a CSS reset. Within the JS directory is the complete
JavaScript library and scripts. The index.html has all the
standard HTML5 boilerplate ready. Start by removing
everything within the body tag.

002
003
004
005
006

007
008

options= sticky_on: large>


<ul class=title-area>
<li class=name>
<h1> <a href=#>Foundation
Custom Template</a></h1>
</li>
<li class=toggle-topbar menuicon><a href=#><span>Menu
</span></a></li>
</ul>
</nav>

06 Sub menu

Creating drop-down menus can sometimes be


overly complex and tricky but Foundation makes the
whole process very simple. Within the <nav> create a
<section> with the class top-bar-section. Within this we
create a <ul> and our <li> items, making sure to add the
class has-dropdown to act as our secondary menu.

Build a custom Foundation template

< Left>
sUsing the Top Bar
plug-in you can easily
create functional
drop-down menus,
the only real work is
styling it up
< Below>
sIncorporating a
responsive rotating
slider with swipe- and
touch-enabled
functionality is a
breeze using the
Orbit plug-in

< Above>
sThe Top Bar plug-in is fully responsive navigation,
even the drop-down menus are device-friendly

001 <section class=top-bar-section>


002
<ul class=left>
003
<li class=has-dropdown>
004
<a class=active href=#>
005
006
007
008
009
010

Main Item 1</a>


<ul class=dropdown>
<li><a href=#>Dropdown
Option</a></li>
</ul>
</li>
</ul>
</section>

07 Style the menu

The beauty of an advanced framework such as


Foundation is that it provides a lot of default styling for us,
which means we can concentrate on structuring our page
and customising our styling a lot less. You will notice the
menu will have its own custom styling already. Well just
add a drop shadow with some browser vendor prefixes.

001 .top-bar {
002 -webkit-box-shadow: 0px 3px 7px 0px rgba
003
004
005 }

(50, 50, 50, 0.75);


-moz-box-shadow:
0px 3px 7px 0px rgba
(50, 50, 50, 0.75);
box-shadow:
0px 3px 7px 0px rgba
(50, 50, 50, 0.75);

08 Orbit slider plug-in

Creating a carousel slider is extremely simple when


we use the Orbit slider plug-in. First well wrap the code
within a row class, followed by a large-12 columns grid to lay
out our carousel. Apply a orbit-container class and a dataorbit data-attribute using a <li> item to separate each slide.

001 <div class=row>


002 <div class=large-12 columns>
003
<ul class=orbit-container
004
005
006
007
008
009
010
011
012

data-orbit>
<li>
<img src=img/slides/slide-1.jpg
alt=slider 1 />
<div class=orbit-caption>
Text to go here
</div>
</li>
</ul>
</div>
</div>

09 Orbit JavaScript

Before the ending </body> tag there is an initial


Foundation JavaScript, simply used to call all plug-ins on
the page. Using this we can customise the plug-in
initialisation. We can configure the options for the Orbit
plug-in, so lets change the default slide effect to a fade
animation and change the speed at which it rotates.

Foundation
with Sass
Throughout this tutorial we have
focused on pure CSS but you could
use Sass, which allows greater
customisation of the framework
using nested styles,
variables, function and
reusable code.

001 <script>
002
$(document).foundation({
003
orbit: {
004
animation: fade,
005
animation_speed: 500,
006
time_speed: 1000,
007
pause_on_hover: true,
008
bullets: false,
009
}
010
});
011 </script>

10 Basic content

The grid system is one of Foundations most


powerful features, making it easy to create multi-device
layouts. The row class is used to hold all the columns,
defining a grid column of 12 indicates the number of

Web Design Tips, Tricks, & Fixes 147

< Left>
sCreating forms
with Foundation
is easy; forms
are versatile
and packed
with powerful
features including
form validation
< Below>
s5IJTJTUIFfinal
finished custom
Foundation
template by just
using a fraction of
what this
framework offers

<Above>
s5IFOrbit plug-in cannot handle variable height
images but the Clearing Lightbox plug-in can and
makes scrolling through images friendly

<Below>
sEach thumbnail is set as a href
wrapped around an image tag which
contains the large high-res image

columns we need in a row. Below is a basic structure of


content using the grid system.

001 <div class=row main-content>


002
<div class=large-12 columns>
003
<h1>Our latest work</h1>
004
<p>Lorem ipsum.</p>
005
<img src=img/photo.png alt= />
006
</div>
007
</div>
008

11 Add a video

Adding a video is extremely easy. Foundation will


automatically help you to scale your video from an intrinsic
ratio, so you can guarantee it can be properly scaled and
viewed on any device. Simply add the class flex-video as a
containing <div> around your video.

001 <div class=row>


002
<div class=large-6 columns>
003
<div class=flex-video>
004
<iframe width=560 height=315
src=//www.youtube.com/embed/_ejeqxRdGwk
frameborder=0 allowfullscreen></iframe>
005
</div>
006
</div>

007

148 Web Design Tips, Tricks, & Fixes

Follow
documentation

12 Panel component

Lets have some accompanying content next to


our video. Well use another six-column grid and to add
components that help outline sections on a page we can
use the panel component. All you have to do is create a
wrapping <div> called panel encasing your content and
Foundation will automatically apply a border and
background colour to this panel.

001 <div class=large-6 columns>


002 <div class=panel>
003
<p>Lorem ipsum .</p>
004 </div>
005 </div>

13 Lightbox gallery

To build a lightbox gallery of photos to slide


through with a variable height, we can use the Clearing
plug-in. Again, wrap the code in a row class with the grid
columns, open a <ul> and apply a class of clearing-thumbs
and a data-attribute of data-clearing. Each <li> item will act
as a separate photo slide.

001 <div class=row gallery>


002
<div class=large-12 columns>
003
<h2>Gallery</h2>
004
<p>View our latest photos</p>
005
<hr />

Foundation contains a whole host of


helpful components and the best
place to read and understand all
this is by looking at their detailed
documentation at
foundation.zurb.com/docs
/index.html.

006
007
008
009
010
011
012
013
014

<ul class=clearing-thumbs
data-clearing>
<li>
<a href=img/photo.jpg>
<img src=img/photo.jpg
alt= data-caption=Text to go here />
</a>
</li>
</ul>
</div>
</div>

14 Gallery styles

Lets apply some styling to the gallery. Well give this


section a light grey background and some top and bottom
padding. Each <li> item will have a bottom and right margin

Build a custom Foundation template

forms is wonderfully simple in Foundation. Lets create a


contact form: first, open a <form> tag and within this give it
a data-abide data-attribute to enable validation. Make sure
the input field has a required attribute with a pattern to
define restraints on what users should input.

Foundations wide range of


navigation options
Foundation offers a wide range of navigation
options and within this tutorial weve only
covered Top Bar, which functions as a main

001
002
003
004

005
006
007

<form data-abide>
<div class=name-field>
<label>Name:
<input type=text placeholder=
James Smith required pattern=
[a-zA-Z]+ />
</label>
</div>
</form>

20 Form styles

Now with our HTML structure of our contact form


completed, we can look at applying some styling. Because
Foundation has a lot of in-built default styles, we dont need
to heavily customise the form styling and its already
responsive. We will just make sure the labels are aligned to
the left and provide an explicit height for the <textarea> field.

001
002
003
004
005
006
007

label {
text-align: left;
color: #666;
}
textarea {
height: 200px;
}

navigation includes incorporating a complex


responsive drop-down menu. You also have
additional options to easily make this navigation
stick to the top of the web browser.
Other popular navigation choices include Off
Canvas, which many may have seen on mobile
devices. This type of navigation is positioned
outside of the viewport and slides in when
activated by the user. Again, as it is highly

17 Error message

If you do not fill out the input field or input the


incorrect data this will return an error. However this does
not display an error message to the user, which is not
helpful. To apply an error message, add a <small> tag with
the class error and place your error message within this.

001

customisable, you could even have menus

<small class=error>Please enter your


name</small>

appearing on both sides of the canvas.


Other more simplified navigation options that
help keep track of the page while scrolling is
Magellan. It acts like a Sub Nav but remains in a
fixed position at the top of your screen.

so theyre equally separated. Using the CSS pseudo class


first-child we can give the first <li> item a margin-left.

001
002
003
004
005
006
007
008
009
010

.gallery {
padding: 20px 0;
background-color: #f2f2f2;
}
.clearing-thumbs li {
margin: 0 20px 20px 0;
}
.clearing-thumbs li:first-child {
margin-left: 10px;
}

15 Common styles

To create a uniformed look and give all our


elements equal spacing, well style the main content,
gallery and the subsequent contact form (in the following
step) with some margin and make the content aligned
centre. If you ever use Sass with Foundation, you can
always use the @extend for this case.

001 .main-content, .gallery, .contact-us {


002 margin-bottom: 30px;
003 text-align: center;
004 }

16 Contact form

Creating user-friendly and HTML5 validation-ready

18 Email input

Its the same markup again to set the email input


field, but instead of using the pattern attribute as we did
previously, we can use the input type attribute and place
the pattern name within this to help validate our input field.
To set an error message below this within the same <div>,
add the <small> tag with the class error.

001 <div class=email-field>


002 <label>Email:
003
<input type=email placeholder=
james@email.com required />
</label>
<small class=error>
Please enter your email</small>
006 </div>

004
005

19 Message field

A contact form would not be complete without a


message field. Similarly to our input fields we created
previously, and using the same <div> structure, we will
place a <textarea> in place of the input field. Again, apply
an error message directly below this. Following this we
also add a Submit button to finish it off.

001 <div class=message-field>


002 <label>Message:
003
<textarea placeholder=Enter your
004
005
006
007

comments here required></textarea>


</label>
<small class=error>Please enter your
comments</small>
</div>
<button type=submit>Submit</button>

21 Build the footer

No website template would be complete without a


footer. Lets add a <footer> tag that wraps the footer
content inside. Again well need to dictate a row class and
wrap a large-12 columns grid within our content. We will
then separate the footer to two equal halves using two
children large-6 column grids.

001 <footer class=row>


002
<div class=large-12 columns>
003
<hr />
004
<div class=large-6 columns>
005
<p>&copy;Copyright notice to go
006
007
008
009
010
011
012
013
014
015

here</p>
</div>
<div class=large-6 columns>
<ul class=inline-list right>
<li>
<a href=#>Link 4</a>
</li>
</ul>
</div>
</div>
</footer>

22 Style the footer

Finally well style our footer. Lets give this a gradient


background colour of a light black fading into a dark black.
Included are some browser vendor prefixes. And thats all it
takes! Weve quickly constructed our own custom template
using the Foundation framework and havent had to write
our own components, with minimal styling involved.

001 footer {
002 color: #fff;
003 background: rgb(43, 43, 43);
004 background: -moz-linear-gradient(90deg,
rgb(43, 43, 43) 30%, rgb(29, 29, 29) 70%);
background: -webkit-linear-gradient
(90deg, rgb(43, 43, 43) 30%, rgb
(29, 29, 29) 70%);
006 background: linear-gradient(180deg, rgb
(43, 43, 43) 30%, rgb(29, 29, 29) 70%);
007 }

005

Web Design Tips, Tricks, & Fixes 149

Get faster,
smarter
code with
RequireJS
By understanding how to code in a
modular fashion youll level up your
JavaScript prowess

005
app.js
006
slides.html
007
jquery.js
008
main.js
009 styles
010
main.css
011 index.html

03 Require configuration

The first thing well do in our main.js file is set up


some custom configuration options. The baseUrl
defaults to the folder that data-main points to in our
HTML, but in this case most libraries are housed under
components. We can also set up paths for each
dependency separately Now RequireJS will look
for domReady at scripts/components/requirejs/
domReady.js.

Source files
available
sIUUQXXX
JMFTJMPDPVL
CLT

tools | tech | trends HTML, JavaScript, RequireJS

uilding websites can often lead to


head tags stuffed with tens of
script tags, some of which may
depend on each other, others of
which may be standalone.
Managing these files and the order
in which theyre loaded can be time
consuming, and browsers stop
rendering when parsing these files.
This can, at worst, cause a highly unresponsive UI.
Like a knight in shining armour, RequireJS comes to
the rescue. Unlike other programming languages,
JavaScript doesnt have a package management
system but Asynchronous Module Definitions (AMD)
are part of a solution to this. RequireJS is a module
loader, which, as the name might suggests, loads in
modules that you specify asynchronously (ie without
blocking the page from rendering).
The RequireJS project also has a few helpful plug-ins
and tools: domReady, text, a CoffeeScript adapter, i18n,
and r.js. In particular, i18n makes converting
international strings a doddle and r.js is a separate tool
to help minify files or projects, concatenating
dependencies into a single file to reduce HTTP
requests. We will be using domReady, text, and r.js.
In this tutorial youll learn how to use RequireJS to
manage library dependencies by building a simple
application thatll pull in photos from Flickr and display
them in a slideshow.

01 Data-main

Well start with our HTML page. The most


interesting part here is the script tag. We load Require.js
as we would any other JavaScript file but this one has a

150 Web Design Tips, Tricks, & Fixes

data-main attribute. This sets the base URL to the


scripts folder and runs the code found in scripts/main.js
with most RequireJS definitions you can omit the
file extension.

001 <!doctype html>


002 <html>
003
<head>
004
<meta charset=utf-8>
005
<title>Flickr Slideshow</title>
006
<link rel=stylesheet href=styles/
main.css>
</head>
<body>
<div class=slideshow></div>
<script data-main=scripts/main
src=scripts/components/ require.js></
script>
011 </body>
012 </html>

007
008
009
010

02 Directory structure

Our directory structure will look like the following


code, as RequireJS encourages a shallow structure.
However, it can be customised when it is being
configured to match your preferences. Instead of
thinking of your scripts by filename, think of them like
IDs. For example, if we require jQuery as an ID itll
request scripts/components/jQuery.js.

001 .
002 scripts
003
app.build.js
004
components

001
002
003
004
005
006

require.config({
baseUrl: scripts/components,
paths: {
domReady: requirejs/domReady
}
});

04 Shim configuration

Many scripts will need to be shimmed so that


RequireJS can work with them. Scripts that declare
themselves in the global scope are legacy and
RequireJS needs to be told what they call themselves
(eg Underscore.js is _). We can also set dependencies so
if we define a module which requires Backbone, then itll
automatically grab jQuery and Underscore too.

001
002
003
004
005
006
007
008
009
010
011
012
013

shim: {
handlebar: {
exports: Handlebars
},
jquery.slideshow: [jquery],
backbone: {
deps: [underscore, jquery],
exports: Backbone
},
underscore: {
exports: _
}
}

05 Define a module

Defining a module is pretty simple but there is


actually a lot going on here. First we call define and pass
it three things: a module ID (main), its dependencies (if
any) and a function thatll contain the rest of the code.
The dependencies get passed to the function in the
order that you specify them so you could write
function(require, app).

001 define(main, [require, app],


function(require) {});

002

Get faster, smarter code with RequireJS

<Left>
s5IF3FRVJSFJSTJUFJTBO
JOWBMVBCMFSFTPVSDFUIBOLTUPJUT
FYIBVTUJWFEPDVNFOUBUJPOBOE
MJOLTUPJUTIFMQGVMDPNNVOJUZ
<Below>
s5BEB8IFOBMMUIF
EFQFOEFODJFTBSFNFU PVSCBTJD
TMJEFSJTEJTQMBZFEBOECSPVHIU
UPMJGF

002 console.log(domReady, data, app);


003 });

09 Define another module

Now well write app.js. Along with domReady,


another RequireJS plug-in is text.js. This is used to load
simple text files, well use it in conjunction with
Handlebars, a JavaScript templating engine, to load in
some HTML. Its simple to use, just text! suffixed
with the filename. Weve already told RequireJS that
jquery.slideshow is dependent on jQuery, so itll
load both.

001 /*global define */


002 define(app, [text!slides.html,
handlebar, jquery.
function (slides) {
003 });

slideshow],

<Right>
s)BOEMFCBSTIBTVTFGVMIFMQFST JOUIJTDBTFXFSFEJTQMBZJOHB
NFTTBHFJGOPSFTVMUTXFSFSFUVSOFEVTJOHJUT\\FMTF^^IFMQFS

10 Text.js and Handlebars

slides.html contains this morsel of HTML. The


curly brackets are where Handlebars will replace the text
with the value of the data that well pass to it. The great
thing about Handlebars is that its highly readable. It
goes through each photo if theres a length greater than
0, else it displays the message.

<Below>
s/PUFUIBUUIFTMJEFTIPXQMVHJOJTOUDBMMFEVOUJMUIFK2VFSZ
EFQFOEFODZIBTCFFOTBUJTJFE

001 <ul class=slides>


002 {{#each photos.photo}}
003
<li><img src={{url_l}}
alt={{title}}

06 Requiring dependencies

Within our module well require domReady, a


RequireJS plug-in. domReady is a cross-browser solution
to waiting for the DOMContentLoaded event without
having to wait for jQuery to be loaded. Its especially
important waiting for domReady with asynchronous
scripts because they could attempt to change the DOM
before its finished parsing.

001 use strict;


002 require([domReady, http://api.flickr.com/
services/ rest/?method=flickr.interestingness.
getList&api_key=dfe82aea164aa1
83a555938
136493c82&format=json&extras=url_l&jsoncallback=
define, app], function (domReady, data, app)
{
003 domReady(function() {
004
app.setSlides(data);
005 });
006 });

07 External dependencies

RequireJS can also make AJAX calls to different


domains, making it very useful for API calls. In this case
well get a JSONP feed containing Flickrs most

interesting photos and images; note that the callback


method is called define. Importantly, this means
that we can depend on external services alongside
other dependencies, such as libraries from content
delivery networks.

001 use strict;


002 require([http://api.flickr.
com/services/rest/?method=flickr.
interestingness.getList&api_key=API_
KEY&format=json&extras=url_l&jso
ncallback=define]);

08 Custom dependencies

Requiring app will make a request to scripts/


components/app.js where well define our own module.
Again, we pass through the arguments in order so:
domReady, the Flickr response well call data, and the
app will be an object with different methods attached to
it. If you get script errors it could be because the file
cannot be found.

title={{title}}></ li>

004 {{else}}
005
<li><p>There were no results!</p></li>
006 {{/each}}
007 </ul>
008

11 setSlides method

Within our app module definition we can set up a


method that will take the Flickr data (although because
of the implementation abstracting the source away it
could be any service). We then return the method so
that our service will be able to be used by other parts of
the application.

001 var setSlides = function(data){/* next step


*/};

002 return {
003 setSlides: setSlides
004 };

12 Compile Handlebars template

001 use strict;

Weve made a request to get slides.html with the


Handlebars brackets and passed it in as a variable called
slides. To interpolate our data with the template we need
to compile the HTML (Handlebars.compile) and then
pass the data to the template, appending it all to our
slideshow element.

require([app], function (domReady, data, app)


{

001 var setSlides = function(data) {

Web Design Tips, Tricks, & Fixes 151

How
it works

<Above>
s8FSFHPJOHUPBEEBTJNQMFTFBSDIGVODUJPOBMJUZUPPVS
slideshow to display images that are determined by the user

RequireJS loads JavaScript


files asynchronously by
creating a new script tag
and calling head.
appendChild(script) but
it has many other features
that make it more than a
simple script loader.

<Above>
s+VTUMJLFUIBUXFDBOOPXHB[FVQPODVQDBLFTUPPVSIFBSUT
(stomachs?) content instead of moody cityscapes

17 Listen for submit

Well use jQuery to listen for the form to be


submitted. When it is submitted well get the text of what
they typed in (by reading .value) and pass it through
encodeURI, this converts special characters e.g. &
becomes %26, so that the search term can be passed
to a URL parameter.
<Above>
s0QUJNJTJOHPVSQSPKFDUPWFSUIFDPNNBOEMJOFNBLFT
you feel quite empowered, and there are real benefits
of doing so

002 var template = Handlebars.compile(slides);


003 $(.slideshow).html( template(data) );
004 };

13 Responsive slides plug-in

Well use Viljami Salminens ResponsiveSlides.js to


easily convert our list of images into a slideshow that
simply fades between each one. Again, because of our
implementation, its trivial to swap this out with another
library if needs change. Because we call this after the
Handlebars template has compiled and been appended,
we can trust that .slides exists.

<Above>
s#FGPSFUIFSKTPQUJNJTBUJPOXFIBWFOJOFTDSJQUDBMMTUPUBMMJOH
87.8kb. Still, at least now theyre not being loaded synchronously

Thats all there is to it! At this point the most


interesting Flickr images will populate the slideshow. By
arranging individual pieces of functionality into separate
files, RequireJS encourages a more modular approach
to your front-end software architecture. This is
something that other languages have had for some time
and comes into its own in large-scale projects.

15 Form HTML

Now well add search functionality to our page.


Well build a simple form with a search input and a
button so that people can type in a search term and
well ask Flickr for all of the images that are tagged with
that term.

001 <form>
002 <input type="search"
placeholder="Search for
something" required>
003 <button>Find</button>
004 </form>

16 Flexibility of asynchronicity

In our original main.js file well require domReady,


app.js and jQuery. Newer versions of jQuery register
themselves as a named AMD module called jquery.
Again well wait for domReady but heres where the
asynchronicity of RequireJS comes in to play because
were not waiting for a response from Flickr, this function
will fire before the one above it.

001 require([domReady, app, jquery],


001 require([ ... app], function (domReady,

function (domReady, app) {

data, app) {
002 console.log(domReady, data, app);
003 app.setSlides(data);
004 });

002 domReady(function() {
003
// next step
004 });
005 });

152 Web Design Tips, Tricks, & Fixes

(e) {

002
003

001 $(.slides).responsiveSlides();

14 Use app module

001 $(.search-flickr).on(submit, function


e.preventDefault();
var term = encodeURIComponent(e.
target[0].value);
004 // next step
005 return false;
006 });

18 Get images

This time well use jQuery to make the request


using $.getJSON and adding the term in as the tags
value. When theres a response we call the setSlides
method exactly as we did before. As the data format is
the same we dont need to change anything else, and
you should see the images update.

001 $.getJSON(http://api.flickr.
com/services/rest/?method=flickr.
photos.search&tags= + term + &api_
key=API_KEY&format=json&extras=u
rl_l&jsoncallback=?, function (data) {
002 app.setSlides(data);
003 });

19 RequireJS command line

RequireJS isnt limited to just handling


dependencies, a spinoff project of RequireJS is r.js, which
can be loaded either from Node or Java (Node is
recommended as its much faster). Note that to install it
youll need to have Node installed and you may have to
use sudo if you get permission errors.

001 $ npm install -g requirejs

Get faster, smarter code with RequireJS

20 Minify main.js

r.js traces all of the dependencies in a given file


and collates them all into a single output file it has
extensive configuration options but checking out the
documentation (requirejs.org/docs/optimization.html)
is a very good place to start. It does have some
limitations, especially when working with remote
sources like CDNs but there are workarounds for this.

001 r.js main.js


002 // => results in a minified main.js
file

Code library

Structuring a RequireJS application


RequireJS can be confusing and daunting at first, but knowing how to structure your
application is half the battle to understanding it.

RequireJS has many


configuration options
available to customise
your project, details of
which can be found at
bit.ly/153Gdzy

21 Build configuration

You can pass arguments over the command line


each time but its easier to maintain if you have a build
file with your settings in it. Well write a new file called
app.build.js in the scripts directory. appDir is the root of
the project, baseUrl is where the majority of our required
scripts live.

001 ({
002
appDir: ../,
003
baseUrl: scripts/components,
004
dir: ../build,
005
paths: {
006
main: ../main
007
},
008
modules: [{
009
name: main
010
}, {
011
name: app
012
}]
013 })
014

Our application specifies


Backbone and
Underscore but doesnt
use them and Require is
clever enough to know
not to include them

Registering as a named
AMD module is safest
as some concatenation
scripts do not know
how to handle
anonymous modules

22 Use build file

In the configuration weve added a custom path


for main (because it lives above the other scripts) and
told it what our two named modules are called. To build
it now we run r.js with the -o[ptimise] flag pointing to our
app.build configuration file. Note that command line
values supersede those set in the configuration file.

001 $ r.js -o app.build.js


002

23 Exclude files

Optimising a project will combine all of the


JavaScript files into as little as possible and collate CSS
files using @import into one file too. However, this
process can be quite complicated and can take up a lot
of time when developing. As a result, a shallow exclude
function is also added in order to exclude the file(s) that
youre currently working on.

001 //app.build.js
002 baseUrl: scripts/components,
003 optimize: none,
004

RequireJS fires the


callback when each of
the dependencies is
satisfied, no matter
where its specified
in the code

001 require.config({
002 baseUrl: scripts/components,
003 paths: {
004
domReady: requirejs/domReady
005 },
006 shim: {
007
handlebar: {
008
exports: Handlebars
009
},
010
jquery.slideshow: [jquery],
011
backbone: {
012
deps: [underscore, jquery],
013
exports: Backbone
014 },
015
underscore: {
016
exports: _
017
}
018 }
019 });
020 define(main, [require, app], function(require) {
021 use strict;
022 require([domReady, http://api.flickr.com/services/
rest/?method=flickr.interestingness.getList&api_key=API_
KE

023 Y&format=json&extras=url_l&jsoncallback=define, app],


function (domReady, data, app) {
domReady(function() {
app.setSlides(data);
});
});
require([domReady, app, jquery], function
(domReady, app) {
029
domReady(function() {
030
$(.search-flickr).on(submit, function (e) {
031
e.preventDefault();
032
var term = encodeURI(e.target[0].value);
033
$.getJSON(http://api.flickr.com/services/
rest/?method=flickr.photos.search&tags= + term + &api_key=d
fe82aea164aa183a555938136493c82&format=json&extras=url_l&json
callback=?, function (data) {
034
app.setSlides(data);
035
});
036
return false;
037
});
038 });
039 });
040 });

024
025
026
027
028

RequireJS has many configuration


options to customise your project
Web Design Tips, Tricks, & Fixes 153

Create
responsive
sites with
intention.js

04 Orientation axis
This JavaScript is the heart of intention.js, and its
known as an axis. The ID value is how we call it with in-ID
or in this case in-orientation. Contexts is an array of
objects, the name is the class name that will be applied
and the value attached to it will be used when
measuring it.

Write a responsive music player with


intention.js and learn what it means to
create custom axes and contexts

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends HTML5, JavaScript

ntention.js is a JavaScript library from


Dow Jones; its main job is to measure and
respond to things. Its prime use is when
building complex responsive websites that
switch elements around at different widths,
add and remove classes and switch out
sources. Intention.js is similar to AngularJS
in that you describe the pages behaviour
within the HTML structure through data-*
attributes and the intent keyword.
Intention.js has four keywords for placing
elements: before, prepend, after, and append.
The key to understanding intention.js is its
terminology. An axis is comprised of multiple contexts
that contain a name and a value. So the width axis
could have a context called tablet and a value of 510.
Intention uses this information to say when listening to
the width, apply a class of tablet when the width is
510px or greater.
Were building a responsive, browser-based music
player to learn how to use intention.js data attributes,
create custom axes and write contexts so we can gain a
firm understanding of how it works.

01 Script dependencies
Intention.js depends on jQuery and Underscore
in order for it to work, so be sure to include these before
intention.js. Intention also comes with an optional
bootstrap file called context.js, which gives four
common measurements: width, orientation, touch
capable, and whether its high DPI. We then include our
own JavaScript file after it. All of these dependencies
weigh in at a hefty 115.5kb pre-gzip.

154 Web Design Tips, Tricks, & Fixes

001 <script
002 <script
script>
003 <script
script>
004 <script
005 <script

src=js/jquery.js></script>
src=js/underscore.js></
src=js/intention.js></
src=js/context.js></script>
src=js/app.js></script>

02 Intent attribute
To signify that Intention should update an
element, we have to use the data-intent attribute as a
keyword. You can just put intent but itd be nice if we
could write with standards. Once intention.js knows to
do something to an element, we then tell it what
specifically we want to update.

001 <body data-intent>


002 </body>
003

03 In orientation
In the case of the body tag, we want to add a
class of portrait or landscape each time it changes.
Context.js gives us some default behaviour, one of which
is detecting orientation so we can simply write
in-orientation: to add the class. Dont panic, we have a
look at the JavaScript behind this in more detail in the
following step.

001 <body data-intent data-inorientation:>


002 </body>
003

001 var orientation_axis = intent.


responsive({
002
ID:orientation,
003
contexts: [{name:portrait,
rotation: 0},
004
{name:landscape,
rotation:90}],
005
measure: function() {
006
return Math.abs(window.
orientation);
007
}, /* next step */
008 });

05 Matcher method
The measure method runs the test and the
matcher method returns a true or false value depending
on if a contexts value passes the test against the
measurement (eg the orientation value). Were doing a
comparison between window.orientation and each of
the contexts: portrait (0) and landscape (90).

001 matcher: function(measure, ctx){


002
return measure === ctx.rotation;
003 }

06 Respond to change
Following on from the orientation axis, if window.
orientation is 90 then itll add the class of landscape to
all elements that have data-in-orientation on them, and
when its 0 the class will switch landscape out with
portrait. This isnt completely magic though, context.js
still adds an event listener calling respond(), which
re-evaluates the measure and then calls the matcher.

001 //call immediately


002 orientation_axis.respond();
003 //also call on orientation change
004 $(window).on(orientationchange,
orientation_axis.
respond);

07 Now playing markup


Weve now got a class to dynamically change on
orientation. Thats great and all, but you dont need a
15kb library to do that for you. To show how versatile
Intention is well build a music player, starting with
the markup for showing whats currently playing. This
is all standard HTML5 markup with some hooks
for JavaScript.

001 <section class=now-playing cf>


002
<div class=left-column column>
003
<img class=artwork src=

Create complex responsive sites with intention.js

<Above>
s5IFUXPJOTQFDUPSTTIPXUIFDMBTTDIBOHJOHXIFOJOEJGFSFOUPSJFOUBUJPOTEVFUPUIFBYJT
EFUFDUJOHBDIBOHF

<Above>
s8JUIKVTUBTQSJOLMJOHPG$44BOEUIFBEEJUJPOPG'POU"XFTPNFTJDPOT XFIBWFBTJNQMFJOUFSGBDF
GPSBNVTJDQMBZFS

<Above>
s8IFOUIFQMBZFSSFTQPOETXJUIGBMTF UIF1MBZCVUUPOJTTIPXOUPJOJUJBUFQMBZJOHCZDBMMJOHB
UPHHMF1MBZJOHGVODUJPO

<Above>
s$POWFSTFMZ XIFOUIFQMBZFSSFTQPOETXJUIUSVF UIF1BVTFCVUUPOJTEJTQMBZFEJOPSEFSUPQBVTFUIF
QMBZJOHPGUIFUSBDL

alt=Album
artwork>
004
</div>
005
<div class=right-column column>
006
<p class=song></p>
007
<p class=album></p>
008
<p class=artist></p>
009
</div>
</section>

08 Player controls markup


Well add markup for the player controls too.
These classes relate to icons in Font Awesome
(fortawesome.github.io/Font-Awesome). The main
control here is the Play button, which will become a
Pause when clicked. In-playing doesnt exist yet well
be writing a custom axis for it shortly.

001 <section class=player-controls>


002
<i class=library-icon iconreorder></i>

003
<i class=icon-step-backward
previous control></i>
004
<i class=play icon-play control
data-intent data-inplaying:></i>
005
<i class=icon-step-forward next
control></i>
006
<div class=volume-container></
div>
007 </section>
008 <audio></audio>

09 Custom axis
To make a new axis, we pass intent.responsive()
as an object with an ID, an array of contexts: the name
will be used for the class and the value can be anything
to match against. In this case itll be true or false but it
could be a number or anything else. Calling .respond()
will evaluate it immediately.

001 var playing = intent.responsive({

002
ID: playing,
003
contexts: [{
004
name: icon-pause,
005
val: true
006
}, {
007
name: icon-play,
008
val: false
009
}],
010
//next two steps
011 }).respond();
012

10 Measure method
Within our custom axis requires a measure
function, some sort of test that our contexts will be
measured against. Were going to write a simple
music player that will have a playing method, so
thatll be our measure for if its playing or not. If you
grasp this concept, then intention.js will be a snap
for you.

Web Design Tips, Tricks, & Fixes 155

001 var pause = function () {


002
playing = false;
003
player.pause();
004
intent.axes.playing.respond();
005
return playing;
006 };

15 Volume axis

<Clockwise from top left >


sClicking the Play button triggers the player.play()
method, its just a log at the moment but trust that
its playing!
sLikewise, clicking the Pause button now toggles the
player to stop playing as evidenced by another log
sThanks to our custom axis, the volume control changes
icon depending on the value of the range input

Different uses
for intention.js
The Intention blog
(bit.ly/19ZznD7) has
a number of examples
and more ways to use the
library, including a
helpful speed test.

001 measure: function () {


002
return webPlayer.playing();
003 },
004

11 Matcher method continued


The matcher is run each time respond() is called.
Its job is to check if a context should be applied by
returning true. Here were saying return true if the
context passed is the same as the playing state or false if
it doesnt. So if what the measure function returns is
true, then the icon-play context is in use.

001 matcher: function (measure, context)


{
002
return context.val === measure;
003 }

12 Public interface
Now that weve dealt with intention.js a fair bit,
next well build up our actual web player through the
imaginatively titled webPlayer. Itll be very simple so we
only have Play, Pause and Volume controls. The demo in
the online resource files (see link above) also has
seeking and a countdown if youd like to see how
those work.

156 Web Design Tips, Tricks, & Fixes

001 var webPlayer = (function () {


002
return {
003
playing: function () {
004
return playing;
005
},
006
play: play,
007
pause: pause,
008
volume: volume,
009
getVolume: getVolume
010
};
011 })();

13 Play function
The Play function sets the variable playing to
true and starts playing the <audio> element. We can
access our playing axis out of scope by using intent.
axes, which contains all of the axes that have been
added. Using this, we can force the playing axis to
re-evaluate itself and switch to the Pause class.

001 var play = function () {


002
playing = true;
003
setSong(currentSong);
004
player.play();
005
intent.axes.playing.respond();
006
return playing;
007 };

14 Pause function
We do the opposite with our Pause method;
set playing to false, invoke Pause on the player (the
<audio> element) and force the playing axis to
respond. This will measure the playing variable so as
its now false itll switch back to the Play icon. Pretty
simple stuff.

So weve got the Play and Pause buttons


working. Now well apply the axis pattern again,
except this time well deal with more than a simple
Boolean. To step it up a gear well measure against
three values to show a dynamic volume icon.
The order here is important as it goes from highest
to lowest.

001 var volume = intent.responsive({


002
ID: volume,
003
contexts: [{
004
name: icon-volume-up,
005
val: 0.5
006
}, {
007
name: icon-volume-down,
008
val: 0.01
009
}, {
010
name: icon-volume-off,
011
val: 0
012
}],
013 }).respond();

16 Volume matcher/measure
Matcher will iterate through each context and
see if its value (.val) is greater than or equal to the
measure (the current volume, as returned through
webPlayer). It will stop iterating when one of the
matchers returns true (which is why the order is
important). The measure function will get the current
value of the volume bar for you.

001
{
002
003
004
005
006

matcher: function (measure, context)


return measure >= context.val;
},
measure: function () {
return webPlayer.getVolume();
}

17 Intent events
You can also listen for events within Intention. An
intent is fired whenever a context returns true, context in
an axis returns true, or when a specific axis passes any
context. Below is an example of each note the colon to
differentiate between always returning true and passing
any context.

001 intent.on('volume', volume.respond);


002 intent.on('volume:icon-volume-up',
volume.respond);
003 intent.on('playing:', playing.
respond);

Create complex responsive sites with intention.js

<Far left>
sWhen in a mobile
context the volume
control is rotated, so it
is now vertical instead
of horizontally based
<Left>
s5IFSFTVMUPGPVSXPSL
and the final product;
intention.js controls the
appearance of our app
in response to player
events and widths

18 Set volume
volumeBar is a range input (<input type=range>)
and we can read its current value with .value. Once this
is set, we get the volume axis to re-evaluate with
respond(). This will cause the matcher to iterate through
the contexts and update the class name depending on
which context returns true first.

001 var volume = function () {


002
player.volume = volumeBar.value;
003
intent.axes.volume.respond();
004
return player.volume;
005 };

19 Get the volume


The getVolume method will be a simple wrapper
for returning the value of the volume from the player.
Unfortunately we cant use the volume() method
because this would cause an infinite loop of setting,
responding, returning a value and then responding
again. This is the method that the measure function of
the volume context will use.

001 var getVolume = function () {


002
return player.volume;
003 };

20 Volume markup
The HTML for the range input is mostly standard
but the attributes from data-intent onwards dictate how
this snippet of HTML should behave when within a
certain context (the mobile and tablet contexts). When
were in a mobile context, append the volume to volume
container, which will make it vertical and in tablet and up
put it outside (after) the volume container.

001 <input class=volume name=volume


type=range min=0
max=1
step=0.001 data-intent data-in-mobileappend=.
volume-container
data-in-tablet-after=.volume-container>

21 Before and prepend

when manipulating the DOM. The main bonus of


manipulating it this way is that Intention manages it for
you so you dont have to manually store the element in
different states.

Create a high-DPI image


handler with intention.js
One of the axis supplied in context.js is highres, this
adds a class of highres to an element if the device

001 <div class=time in-mobile-before=.


now-playing in- tablet-prepend=.playercontrols>
002
<span class=time-now></
span><span class=total- time></span>
003 </div>

22 Intent on simplicity
In this tutorial weve started to explore just how
adaptable intention.js can be by responding to events in
a music player as well as responding to different widths,
simply by adding HTML attributes to describe how it
should act. If youre looking for a simple solution,
especially on retro responsive builds, then this might be
the tool for you.

When were in a
mobile context,
append volume to
volume container
Adding
elements
after load
For apps that add markup
after loading, you can
manually add elements
with intent.add( element ).
This will add the element
to intentions
watch list.

pixel ratio is greater than one. To use it, you could


write something like the following:

001 //when in highres, load the


higher src image
002 <img data-intent data-in-highres:
data-in-highressrc=http://placekitten.com/800/800
src=http://
placekitten.
com/400/400>
001 //wait for load so all image
widths are correct
002 window.addEventListener(load,
function () {
003
//grab all images that are
children of highres
004
var images = document.
querySelectorAll(img.
highres);
005
for (var i = images.length 1; i >= 0; i--) {
006
var img = images[i],
007
//divide image width by
2 to get original
008
original = img.width /
2;
009
//set high dpi image to same
as original image
010
img.style.width = original
+ px;
011
}
012 });

As well as -after and -append there are sibling


commands -before and -prepend. Although these four
may sound limiting, they cover the majority of bases

Web Design Tips, Tricks, & Fixes 157

Make an
eCommerce
web element
with CSS3
Using CSS3, create a simple and
appealing shopping cart web
element that would be useful on
an eCommerce website

product. Firstly create a <div> with a class name of info


and then add in the product title, wrapped within a <h4>
header element. We then add in a little text describing
our product and then finish off with the price and a Buy
now button.

04 Star ratings

In the final bit of HTML, were going to add in a star


rating section that will be positioned at the very bottom of
our product block. We just simply add a <div> with a class
name of details and create an unordered list with a class
called rating. In a later step, were going to use a CSS sprite
to show a different-coloured star.

Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594

tools | tech | trends HTML, CSS

elling online provides the opportunity


for many businesses to reach out to
huge, untapped markets. When your
store can be open 24 hours a day and
you can reach a global market without
the costs of mailings and call centres, it
can provide a huge boost to your
business. But there are plenty of things
to consider when designing an
eCommerce site. Its not as simple as
throwing up some shopping cart
software and plopping products into a database. With the
power of CSS3, it is possible to create some very cool and
effective web elements that can just slot into place on any
eCommerce website.
The products that you or your client are selling need to
stand out and the all-important buttons such as Add to
Cart need to be prominent and stylish. It is essential to
think about the presentation of customer reviews, the price
and product description. All of these things need to be easy
to accomplish, and with CSS3, those things just got a whole
lot easier. So in this tutorial, we will look at how we can
create a fictional product and turn it into an appealing and
interactive web element using the power of CSS3 lets
get started!

01 Set everything up

First thing we need to do is create a new HTML5


document with a link to your stylesheet within the head.
Then within the <body> tag, we can create two <div>s with
a class name of container and then block, making sure
we comment the closing tags for better readability.

158 Web Design Tips, Tricks, & Fixes

001 <body>
002
003
<div class=container>
004
005
<div class=block>
006
007
</div><!-- END block -->
008
009 </div><!-- END container -->
010
011 </body>

02 Product image and buttons

Next were going to add in an image and some


buttons for our product. Firstly we create a <div> with a
class name of product. We then pull in our product image
and then add in two buttons. One of the buttons is a Add
to Cart button with a class name of buy and the other is a
View Item button with a class name of preview.

001
002
003
004
005
006
007
008
009

<div class=product>
<img src=images/placeholder.png>
<div class=buttons>
<a class=buy href=#>Add to cart</a>
<a class=preview href=#>View item</a>
</div>
</div><!-- END product -->

03 Product information

Now lets add in some information about our

001 <div class=details>


002 <span class=time>12 hours ago</span>
003 <ul class=rating>
004 <li class=rated></li>
005 <li class=rated></li>
006 <li class=rated></li>
007 <li class=rated></li>
008 <li></li>
009 <li></li>
010 </ul>
011 </div><!-- END details -->
012

05 The CSS

Open up a CSS file and start adding some styles.


First add in some default styles within the body selector.
Weve set our font to Arial and given it a light grey colour,
and well use a patterned background for the page. Finish
off by giving our container <div> some width and margin.

001 body {
002 font-family: Arial, sans-serif;
003 color: #aaaeb2;
004 background: #f1f1f1 url(../images/
bg.png);

005 }
006
007 .container {
008
009 width: 900px;
010 margin: 0 auto;
011 }

06 Style the block

Things are not looking that great, so lets start


shaping it all up. By targeting the block class, we can give
the body of our product information some shape and
some nice subtle effects by using the border-radius and
box-shadow properties. We do want to make sure that
the position is set to relative, as this will allow us to
absolutely position other elements within such as
the buttons.

001 .block {
002
margin: 30px 0;
003
display: block;

Make an eCommerce web element with CSS3

004
005
006
007
008

< Above>
s"EEJOHUIFQSPEVDUJNBHFIFSFIBTHJWFOVTTPNFUIJOHUPXPSLBSPVOE

< Above>
s5IF$44GPSUIFA"EEUP$BSUCVUUPOJTDPNQMFUF OPXXFNPWFPOUPUIFOFYUCVUUPO

< Above>
s4PNFPGUIFCBTJDTUZMJOHBEEFEUPUIFNBJOCVUUPOT A"EEUP$BSUBOEA7JFX*UFN
XJMMCF
WJFXBCMFPODFUIFQSPEVDUJNBHFJTNPVTFEPWFS

< Above>
s*OUIJTTUFQ XFSFKVTUBEEingBTJNQMFBDUJWFTUBUFPOUIFA7JFX*UFNCVUUPO

position: relative;
width: 300px;
border-radius: 5px;
background: #fff;
box-shadow: 0 3px 8px rgba(0, 0, 0,

.2);

009

07 Product image

Now lets set some styles for our product image.


Ensure the image is set to block and position is set to
relative. Then we can set the width to 100% so it drops into
the main product block. After that, we finish off by giving
the top corners the same radius as the block.

001
002
003
004
005
006
007
008
009
010

.product {
display: block;
position: relative;
}
.product img {
width: 100%;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}

08 Info and details

10 Button styles

Next we will give our product text and other


information some shape. Firstly lets target the info class,
which holds the product title and description. We then
separate the details section which is the star ratings by
adding a top border and then finish this off by giving it
some padding all around.

This is where we will start giving the buttons some


basic styling. Because we set the .product class to relative,
we can easily use absolute positioning to give ourselves
complete control of exactly where these buttons should
be. We can then give them some nice, rounded corners
and hide them by using opacity: 0.

001
002
003
004
005
006
007
008
009
010

001 .buttons a {
002
display: block;
003
position: absolute;
004
left: 50px;
005
width: 115px;
006
border-radius: 2px;
007
padding: 18px 10px 15px 65px;
008
font-family: Helvetica, sans-serif;
009
font-size: 14px;
010
font-weight: bold;
011
text-transform: uppercase;
012
color: #fff;
013
text-decoration: none;
014
opacity: 0;
015
text-align: center;
016 }
017

.info {
display: block;
position: relative;
padding: 20px;
}
.details {
border-top: 1px solid #e5e5e5;
padding: 18px 20px;
}

09 The large buttons

The buttons we are talking about here are the Add


to Cart and View Item buttons that we will position at the
centre of the product image. We then hide them until the
user mouses over the product image. We wont see much
in the way of buttons yet, but well tackle that soon.

Web Design Tips, Tricks, & Fixes 159

<Above left>
sThings are starting to take shape quite nicely now that some styling has been added to the product description
<Above right>
sThings are really starting to take shape now we have added some styles to our product price
<Top right>
sThe Buy Now button is the last step to finish off the product description section
<Bottom right>
sThe final element is the star rating section. It is here that the list elements are transformed into stars

11 Icon styling

Here we set some styling for the icons that will be


added in the next step to both of the large buttons. Make
sure the content is empty and then set a height and width.
Then, divide the area where the icon will be by adding a 1px
border to the right. Then add a subtle drop shadow.

001 .buttons a::after


002{
003
content: ;
004
display: block;
005
position: absolute;
006
height: 48px;
007
width: 50px;
008
border-right: 1px solid rgba(0, 0, 0,
.25);

009

box-shadow: 1px 0 0 rgba(255, 255, 255,

.17);

010
011
012
013 }

top: 0;
left: 0;
z-index: 1;

12 Add to Cart button

In this step, we focus on the Add to Cart button.


After positioning it 20% from the top, we can give it a dark
background colour. Then we can give it a subtle transition
and lower its opacity for when we hover over it. Lastly, we
will add in our icon that will be positioned to the left.

001 a.buy {
002
top: 20%;
003
background: #414141;

160 Web Design Tips, Tricks, & Fixes

004
005
006
007
008
009
010
011
012
013
014
015
016

Button icons

background: rgba(0, 0, 0, .85);


transition: background .2s ease-in;

Icons are a highly important


part of designing elements
for eCommerce sites, so
make sure that you use
them effectively.

}
.buy:hover {
background: #515151;
background: rgba(45, 45, 45, .85);
}
.buy::after {
background: url(../images/cart.png);
background-repeat: no-repeat;
background-position: 16px 18px;
}

13 View Item button

Next up will be to add the styles to our View Item


button that will sit underneath the Add to Cart button. We
are going to give this a blue colour and also give it a linear
gradient. Then, lets give it a subtle drop shadow and finish
up by giving it a two-second transition on hover.

001 a.preview {
002
bottom: 20%;
003
text-shadow: 0 -1px 1px rgba(0, 0, 0,

010
011
012

background-repeat: no-repeat;
box-shadow: 0 2px 0 #165181;
transition: background-position .2s

ease-in;

013 }
014 .preview:hover, .buy_now:hover {
015
background-position: 0 0;
016 }

14 Finish the buttons

In this step, well add a simple active state on the


View Item button. All we are going to do is move the
button down by two pixels using the translateY value of
the transform property when we click the button. In the
next rule, we add in the icon like we did previously.

.4);

004
005
006

background: #286398;
background: -webkit-lineargradient(bottom, #1d4970, #639ed3);
007
background: -moz-lineargradient(bottom, #286398, #639ed3);
008
background-position: 0 -15px;
009
background-size: 400px 80px;

001 .preview:active, .buy_now:active {


002
transform: translateY(2px);
003
box-shadow: none;
004 }
005
006 .preview::after {
007
background: url(../images/eye-icon.
png);

Make an eCommerce web element with CSS3

008
009
010 }

background-repeat: no-repeat;
background-position: 16px 17px;

15 Information arrow

Lets create the small arrow that we see pointing up


to the product image just above the products title. This is
going to be very simple. All we need to do is create a white
25 x 25px square, position it absolutely and rotate it by 45
degrees. Then we move it down using top -12px so all we
can see is one of the corners.

001 .info::after
{

002
003
004
005
006
007
008
009
010
011

display: block;
position: absolute;
top: -12px;
left: 23px;
content: ;
height: 25px;
background: #fff;
transform: rotate(45deg);
transform: rotate(45deg);

16 Product title

In this simple step, we will apply some styles to the


product title to give our product description some shape.
Start by setting the position to relative and giving it some
padding and margin. Then set the font family, font weight
and size. Finish up by pulling all the letters in slightly, using a
negative value to the letter spacing.

17 Product description

Everything is taking shape quite nicely now and the


next step is to think about the product description. First,
lets add a two-pixel blue line just underneath the title. The
good thing about doing lines like this is the ease at which
you can change the height. Then we give the product
description some styling.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019

.info h4::after {
display: block;
position: absolute;
bottom: 0px;
content: ;
width: 40px;
height: 2px;
background: #3b86c4;
}
.info .description {
display: block;
padding-bottom: 20px;
font-family: Arial, sans-serif;
font-size: 14px;
font-weight: 600;
color: #5f5f5f;
}

18 The price

Having now got a lot of the product description


done, there are only two things left to do, one of which is
simple: give the product price a little bit of much-needed
styling. Ensure that you have a play around with this;
sometimes a bigger font would look better, or perhaps
even a different colour would work well.

19 Buy Now button

The Buy Now button is the last step to finish off the
product description section. Were going to float this right
and use relative positioning in order to position it right
where we want it. Were then going to continue to give it
the same styling as our View Item button finishing up
with a nice transition and drop shadow.

The CSS transform property allows you to


visually manipulate an element, transforming its
appearance. There are many functions to the
transform property and one we used in this
tutorial (Step 14, for example) is called translate.

001 .buy_now {
002
float: right;
003
position: relative;
004
top: -5px;
005
display: block;
006
padding: 10px 10px;
007
border-radius: 3px;
008
009
font-family: Helvetica Neue,
Helvetica, Arial, sans-serif;
010
color: #fff;
011
font-weight: bold;
012
text-decoration: none;
013
font-size: 15px;
014
text-shadow: 0 -1px 1px rgba(0, 0, 0, .4)

015
016
017

background: #286398;
background: -webkit-lineargradient(bottom, #1d4970, #639ed3);
018
background: -moz-lineargradient(bottom, #286398, #639ed3);
019
background-position: 0 -15px;
020
background-size: 400px 80px;
021
background-repeat: no-repeat;
022
transition: background-position .2s
ease-in;

023
024
025 }

box-shadow: 0 2px 0 #165181;

20 The rating section

This is the last bit of the tutorial where we deal with


the star rating section. We position the unordered list over
to the right and zero out any default margin or padding.
Once we do this, the block will become shorter and our
bullet points will be overflowing. Lets sort that out next.

001 .rating {
002
position: relative;
003
top: 2px;
004
float: right;
005
margin: 0;
006
padding: 0;
007 }

transform: translateY(2px);
The translate(x, y) function is similar to relative
positioning, translating, or relocating an element
by x from the left, and y from the top. Its a handy
way to move elements as it gives you full control
of its positioning from using only one line of code.
transform: translate(2px, 10px);
To give us greater control, we can also use
negative values on either the x or y values. The
line of code below, for example, allows us to move
an element horizontally by 20 pixels.
transform: translateX(-20px)

21 Seeing stars

On this final CSS rule, we are going to add in our


stars. We have included a PNG file called stars.png in the
resource files that you can use. Were going to use this as a
CSS sprite and first position the green stars that have the
class name of .rated added to the <li> item.

001 .rating li {
002
float: left;
003
display: block;
004
height: 16px;
005
width: 16px;
006
margin-left: 5px;
007
background: url(../images/stars.png)
no-repeat 0 0;

008 }
009
010 .rating li.rated {
011
background-position: 0px -16px;
012 }
013

22 Final thoughts

eCommerce is forever growing on the web, and the


need to design cool and functional web elements is
becoming more and more achievable when using CSS3.
So, experiment with what youve learned throughout this
tutorial and see what you can produce!

Web Design Tips, Tricks, & Fixes 161

Customise
a map with
the Google
Maps API
Take Google Maps beyond the simple
embedded maps with the options in
the Google Maps API

03 Get the API Key

Your API key will be displayed on the following


page. This is essentially the dashboard for your API
projects. If you click on Edit Allowed referrers in the
right-hand column, you have the option to give individual
domains permission to use the key. Google will then block
any attempt by a disallowed domain to do so.

04 Prepare the document

First we need to declare the HTML5 page with


the DOCTYPE and include the viewport meta details. The
CSS gives both the body and HTML elements a height of
100 per cent. The ufo-map <div>, where our map will
ultimately display, also shares the same style. This
ensures the map will fill the browser window, although
this is optional by styling choices.

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends Google Maps API, Photoshop

verybody loves a Google Map. The


fact that Apple has struggled to match
them for sheer accessibility and
functionality is testament to how
Google has dominated the field for
years now. Most business websites will
feature a Google map displaying the
office location and, together with the
geo-location technology woven around
them, Google Maps is invaluable for finding your way
around unfamiliar locations.
Beyond the simple displaying of embedded maps,
however, is the wealth of possibilities available to
developers prepared to get to grips with the Google Maps
API. There really is no limit to what can be achieved by
using Googles JavaScript functionality. The API is split into
three distinct development packages; web applications, iOS
applications and Android applications. Google Maps lets
you integrate functional, feature-rich maps into your
webpages or applications, with options available for users
to manipulate content, position, zoom, and so on.
In this tutorial, well look at turning a basic Google Map
into an informational chart of great English UFO sightings,
complete with custom markers and styling, exploring some
other options along the way.

01 Get started

In order to use any of Googles API services, you


need an API key. This is particular to your account and is
included in any project in which you use Googles APIs.
You will need a Google account. Once youve got one,
head over to code.google.com/apis/console and click on
the Services link in the left-hand menu.

162 Web Design Tips, Tricks, & Fixes

02 Activate the API

At this point youll see an extensive list of Googles


available services and APIs. Scroll down to the various
map-related items for web, iPhone and Android. Were
focusing on building for the web in this tutorial, so click the
switch to turn Google Maps API v3 on. Agree to the terms
and then click on API Access.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023

<!DOCTYPE html>
<html>
<head>
<meta name=viewport content=
initial-scale=1.0, user-scalable=no
/> <style>
html {
height:100%
}
body {
height: 100%;
margin:0;
font-family: Open Sans, sans-serif;
}
#ufo-map {
height:100%;
}
</style>
</head>
<body>
<div id=ufo-map></div>
</body>
</html>

05 Begin scripting

In the head tag, below the CSS, include the


following JavaScript to assign your API key to the project
and call Googles API functions. Your unique API key should
be entered precisely into the appropriate area. Sensor can
be set to either true or false, and determines whether the
map should utilise GPS location services.

Customise a map with the Google Maps API

<Left>
The Google API is incredibly
adaptable to anyone who is
comfortable with JavaScript.
Not only are there the
various options that Google
has already supplied, but also
an impressive volume of
extra script enhancements
made available by
enterprising developers who
continue to push the API to
greater heights.

001

<script type=text/javascript
src=https://maps.googleapis.com/maps/api/
js?key=YOUR API KEY GOES HERE&sensor=true>
002
</script>

06 Map centre co-ordinates

The first thing we need to decide is where we want


the centre point of our map to be. The API needs
co-ordinates in order to fix the map. Since all our UFO
sightings take place in a large area around the Midlands,
well take Leicester as a handy mid-point. By loading
Leicester into Google Maps, we can find the co-ordinates
we need in the URL or embed code.

07 Display basic map

Insert the script from the resource files into the


head, below the API key, to display the Leicester-centred
map. The zoom option can be altered as required, with
values between 0 and 21, with the uppermost value
being the most zoomed in. Centre and Zoom are the
only mandatory options for a Google map.

More than a map


The key is to think of the API as
a base on which to build, rather
than the final project.
The possibilities
are endless.

001
002
003
004

<script type=text/javascript>
function initialize() {
var mapOptions = {
center: new google.maps.
LatLng(52.456009,-1.483154),
005
zoom: 8
006
};
007
var map = new google.maps.
Map(document.getElementById(ufo-map),
008
mapOptions);
009
}
010
google.maps.event.
addDomListener(window, load, initialize);
011
</script>

Web Design Tips, Tricks, & Fixes 163

08 Explore style options

You can change the look of the map to suit your


purposes by declaring this in the options. There four
different styles: Roadmap, Terrain, Satellite and Hybrid.
Roadmap is the default, Terrain can be seen in the image
below, Satellite is more like Google Earth and Hybrid fuses
Satellite with the Roadmap setting.

09 Insert first marker

By now, you should have collected the co-ordinates


for all your locations, just as we did with the centre point.
The following addition to the script will call a single location,
delineated by the default Google Maps marker and marked
by a hover-activated label but we want to add our own
custom-made marker instead.

The JSON Wizard


Anyone who has spent hours either changing styles in the browser tools, or simply changing the files and
continually uploading them to see how it looks, will know just how time-consuming and tedious that process
can be. Luckily, Google has taken your trials to heart and put together a Styled Maps Wizard, allowing you to test
all possible colour schemes, element visibility and any other changes that the API allows in a dynamic window.
All you have to do is experiment to your hearts content and, as soon as you are happy with your choices,
click the Show JSON button. Your styling code will then be displayed, ready for you to copy and paste into the
JavaScript in your file. This is a great feature, saving a lot of hand-coding and time!

Further options exist for declaring the anchor point and


shape of the marker, if desired. Numbering of each marker
allows z-indexes to be created for overlaps.

Be sure to visit bit.ly/MUhcF2


for a comprehensive list of
the APIs various features
as well as some handy
tutorials.

10 Add custom marker

Your custom marker can be any kind of image file.


We are using a PNG to mark out the first UFO hotspot. The
addition of a couple of lines to the options replaces the
default marker with our own. Make sure you call the image
from the appropriate place or folder.

14 Basic map styling

12 Simple marker animation

While the custom markers give the map an


individual look, we can embellish them a bit with some
animation. By placing the highlighted line into the option
fields of your markers, you can add a fun bit of movement.
As the page loads, they will drop into their positions from
roughly 50px above them and execute a single bounce.

13 Further animations

11 Multiple locations

Some changes are required for displaying multiple


locations. Labels are defined with the co-ordinates, in a list,
and the size of the custom marker must be declared.

164 Web Design Tips, Tricks, & Fixes

Googles API
reference

Alternatively, you can replace DROP with BOUNCE


in the animation function and have your marker bounce up
and down continually. This is actually really fun when
applied to little UFO markers, but may not be suitable for
the more serious map experience!

There are plenty of options within the API for giving


your map some custom styling. By using the built-in
selectors and setting styles for each, you are able to create
a really distinctive map, displaying only the features that
you want in the styles you design. For example, we start by
declaring our selectors and styles.

Customise a map with the Google Maps API

15 Basic styling continued

Having created our array of styles, we create a new


map object and name it -------. Then, we assign the map to
a map type control, with mapTypeControlOptions, which
will appear on the map and allow the user to switch
between our default Terrain style and the custom style.

Code library

The JavaScript (condensed)


Be sure to make the most of all the customisation options available to you with the Google
Maps API here we have delved into just a few of them

There is a variety of
options for styling and
arranging the controls,
from simple relocation to
advanced customisation

16 Basic control styling

Using the APIs map control selectors, you can


change the size, position and visibility. This example sets
the size of the zoom controls, presents the map styles as
a drop-down option and moves the location of the pan
control. There are also lots of advanced options for custom
styling the look of the controls.

001
002
003

mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.
DROPDOWN_MENU,
004 mapTypeIds: [google.maps.MapTypeId.
TERRAIN, map_style]
005 },
006 zoomControl: true,
007 zoomControlOptions: {
008 style: google.maps.
ZoomControlStyle.SMALL
009 },
010 panControl: true,
011 panControlOptions: {
012 position: google.maps.
ControlPosition.TOP_RIGHT
013 },
014 };

You can set a range of


different map styles for users
to choose from, and even
arrange extra layers

The map looks good, set to fill the browser, but it


could use a title. Well add a header, a title and subtitle, and
extra CSS. And thats it! This has only scratched the surface of
what you can dp why not see what else you can achieve?

014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034

Setting the labels for the


locations is easy, but
there is a more advanced
option for pop-up
information windows

17 Finish up

001
002
003
004
005
006
007
008
009
010
011
012
013

035
036
037
038
039
040
041
042
043
044
045
046

var styles = [
{
},{
featureType: landscape,
elementType: all,
stylers: [{ color:#c2c2c1 }]
},{
featureType: water,
elementType: all,
stylers: [{ color:#284489 }]
},{
featureType: road,
stylers: [{ hue:#9bfa68 },{ visibility:
simplified }]
},{
featureType: all,
elementType: labels,
stylers: [{ visibility: off }]
}];
var styledMap = new google.maps.StyledMapType(styles,
{name: Spooky Map});
var mapOptions = {
center: new google.maps.
LatLng(52.456009,-1.483154),
zoom: 8,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.
DROPDOWN_MENU,
mapTypeIds: [google.maps.MapTypeId.TERRAIN,
map
_style]},
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL},
panControl: true,
panControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT},};
var map = new google.maps.Map(document.getElementById
(ufo- map),
mapOptions);
map.mapTypes.set(map_style, styledMap);
map.setMapTypeId(map_style);
setMarkers(map, ufos);}
var ufos = [
[Rendlesham Forest, 1980, 52.091786,1.404618, 1],
[Bonsall, 2000, 53.128234,-1.675415, 2],
[Dudley, 2007-2013, 52.532096,-2.099075, 3],
[Ilkley Moor, 1987, 53.903081,-1.826917, 4],
[RAF Cosford, 1993, 52.640564,-2.295456, 5],
[Broad Haven, 1977, 51.844263,-5.111389, 6]];
function setMarkers(map, locations) {

Web Design Tips, Tricks, & Fixes 165

Automatically
test your
JavaScript
with Jasmine
Discover how easy it is to ensure code
quality by testing your program via the
Jasmine unit testing framework

aspect. This code snippet shows a basic comparison


that ensures a true value is really a true value.

001 describe(A suite, function() {


002
it(Tests something simple,
function() {
003
expect(true).toBe(true);
004
});
005 });
006

05 Code is code

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

tools | tech | trends JavaScript, Jasmine

omplex applications are like a cube


of jelly. Changing anything tends to
shake the entire system up, causing all
kinds of weird side effects. Unit testing
permits you to alleviate this problem
by outfitting the product with a variety
of self tests. These can then be run
automatically, pointing out areas that
were negatively affected by a recent change.
In the last few years, a large variety of test systems have
entered and left the market. Jasmine is still among the
most popular unit testing frameworks for JavaScript, as
its functioning does not require the presence of a DOM.
This means that you can use it to test both server and
client-side JavaScript code. Test cases are written in a
domain-specific language that is intended to be easy to
read for programmers and non-programmers alike.
A convenient runner website transforms your favourite
web browser into a powerful testing console waiting to
track and squish bugs in your program code. Ready?
Lets get started.

01 Download the framework


Jasmine can be downloaded by pointing your
browser to pivotal.github.io/jasmine. Scroll to the
bottom and click the link to standalone distributions in
order to get to a GitHub site offering you various zip
files. Select the one for version 2.0.0 in order to use the
most current edition of the framework currently
available. Click Raw to download it.

02 Test runner?
Jasmine tests usually are run via a file called
TestRunner.html. Open it in an HTML editor of choice in

166 Web Design Tips, Tricks, & Fixes

order to add the new test and source files at the


positions marked with comments. The initially provided
example engine and test case files can and should be
removed before adding actual code.

001 <!-- include source files here...


-->
002 <script type=text/javascript
src=src/Player.js></ script>
003 <script type=text/javascript
src=src/Song.js></
script>
004 <!-- include spec files here... -->
005 <script type=text/javascript
src=spec/SpecHelper.
js></script>
006 <script type=text/javascript
src=spec/PlayerSpec.
js></script>

03 Test suites
Unit tests should be grouped up for easier
management. This is done by creating suites via the
describe function. Its structure follows that of natural
language wherever possible; the first parameter explains
what must be tested, whereas the second one contains
a function that carries out the evaluation.

001 describe(Name of Suite, function()


002 {
003 //Test code goes here
004 });

04 The it command
Actual test work is performed in it() functions.
Each it function should be set up to test one specific

Before running our little example, we must clarify


that unit tests are made up of code written completely
by the developer of that particular solution. The
framework runs the test methods that you provide and
uses the results to determine between success and
failure. This can be proven by adding a call to alert() to
your test case.

06 Matchers compare...
Unit tests work by comparing the results of the
actual computation with the one intended to be
returned. Your expectations are passed into the
program via an expect() clause, which takes the actual
value produced by the routine under test. It can then be
compared to something else using a matcher.

001
it(Tests some numbers,
function()
002
{
003
expect(1234).toBe(return1234());
004
});
005

07 ...more than one thing


It is permissible to have more than one
expect()-Clause in a test case. During evaluation, the first
test to fail will not trigger the termination of the entire
routine (as it has failed). Most developers expect this
behaviour be aware that Jasmine does not shortcircuit
the evaluation of test code.

08 Is it something?
The simplest form of comparison works by
simply comparing the returned result with the intended
value. This can be achieved by using the toBe function,
which we first introduced a few steps ago. It fails
whenever the two values are not considered equal by a
=== comparison.

09 Analyse strings
Regular expressions tend to be very helpful
when dealing with textual data. Straight comparisons
can be done by invoking the toBe function. If the use of
a regular expression is desired, toMatch is better suited
to the task at hand. The syntax of the RegEx follows
JavaScript conventions.

001

it(Tests a regex, function()

Automatically test your JavaScript with Jasmine

<Above>
sClick the Raw button located on the right-hand side of the screen in order to start the
process of downloading

<Above>
sAn alert dialogue placed inside the test code will pop up as the Jasmine framework begins to
process the unit test

<Above>
sEven though the first comparison did not work out, the alert() dialog is still continues to
be displayed on screen

<Above>
sThe official documentation for Jasmine explicitly confirms that the toBe operator compares using
the === construct

002 {
003
var message = Hello to my
readers;
004
expect(message).toMatch(/my/);
005
});

10 Is it true?
When dealing with true and false values, a
simple comparison against true and false often is
not sufficient enough. toBeTruthy and toBeFalsy can be
used to remedy this problem. They work by performing
an internal compare against a value casted to bool,
thereby matching the normal JavaScript behaviour.

11 Undefined stuff
Generator methods might fail in a way that
causes the unit test code to halt with a null reference
error. This can be avoided by first checking whether an
object is defined or undefined. Use toBeDefined to
check for definedness, toBeUndefined checks whether
the element does not exist.

12 Array, taken apart


Figuring out whether an array contains a specific

value can be intimidating. Fortunately, Jasmine provides


you with the toContain matcher. This checks whether
the incoming array contains the element required at
any position, thereby saving you the effort of creating
and maintaining a loop in your unit test.

001
it(Tests whether an array
contains an element,
function()
002 {
003
var a = [a, b, c];
004
expect(a).toContain(c);
005
});
006

13 Numbers
Figuring out whether a number is larger or
smaller than another arbitrary value is usually achieved
via an if clause. This tends to enlarge the length of the
unit test. The toBeLessThan and toBeGreaterThan
clauses provided in Jasmine allow you to shorten all
numeric tests.

001
it(Tests Jasmines numeric
functions, function()

002 {
003
expect(2).toBeLessThan(3);
004
expect(2).toBeGreaterThan(1);
005
});

14 Negate matchers
Most matchers can be forced to work in inverted
mode. This means that a matcher will consider its test
successful only if the condition it is intended to analyse
is not met. For example, putting the .not. object in front
of toBeTruthy transforms the comparison into a lookalike
of toBeFalsy.

001
it(Tests whether an array
contains an element, function()
002 {
003
var a = [a, b, c];
004
expect(a).not.toContain(d);
005
});
006

15 Set up code
Some of the time, it is necessary for the engine
code to be reset to a predefined state before the tests

Web Design Tips, Tricks, & Fixes 167

<Above>
s5IFFYFDVUJPOPGBVOJUUFTUUBLFTQMBDFBDDPSEJOHUPUIFTUSVDUVSFPVUMJOFEJOUIFMPXDIBSU

<Above>
sUP#F5SVUIZDPOTJEFSTUIFTUSJOHAUSVFFRVJWBMFOUUPUIFCPPMFBOUSVFWBMVF

<Above>
s*OUIFXPSTUDBTF BOVOEFJOFEPCKFDUDBOIBMUUIFFYFDVUJPOPGUIFVOJUUFTUT6TFUP#F%FJOFE
UPDSFBUFSFTJMJFOUUFTUT

<Above>
s6TJOHYJUBOEYEFTDSJCFMFBETUPEJTBCMFETQFDTBOEUFTUDBTFT XIJDIXJMMOPUCFIBOEMFECZUIF
UFTUSVOOFS

can be run. This is achieved by providing the describe()


function with a beforeEach clause. The function
passed to beforeEach will be run before each of the it()
function payloads.

16 ...and tear it down


Similarly, the afterEach function will be executed
after each if() clause was processed. It can be used to
clear up leftovers caused by the test execution.
Alternatively, you can also use it to reset the engine to a
predefined state needed for the next test.

001 describe(A suite, function()


002 {
003
afterEach(function() {
004
window.valueStore = 0;
005
});

17 Global stuff
The body of the describe function is processed
linearly by the JavaScript interpreter. This means that
you can use it to perform any action that needs to be
handled before the actual unit tests can be run. Our
example declares a variable called valueStore before
running the first it() clause.

001
002
003
004

describe(A suite, function() {


var valueStore;
it(Uses valueStore, function()
{

168 Web Design Tips, Tricks, & Fixes

005

18 More It functions
The code snippets for the steps shown tend to
show more than one it() function per block. This is not a
problem. Jasmine permits you to have an almost
unlimited number of test cases nested into one describe
suite. Simply nest them below one another as shown.

001
it(Tests Jasmines numeric
functions, function()
002
{
003
expect(2).toBeLessThan(3);
004
});
005
it(Uses the not
qualifier,function()
006
{
007
008
});

19 It is not
As code matures, some unit tests become
unneeded. Removing them is not particularly smart, as
they might be needed again at some point in the future.
This problem can be addressed by using the nonworking xdescribe and xit functions. Their syntax is an
exact match of describe and it.

20 Harness the spy


Spies allow you to analyse how the code under

test interacts with one or more functions. Simply


initialise it and invoke the method just as you would do
normally. From the moment spyOn was called, the
invocations get absorbed by the Jasmine framework,
which tracks the calls.

001
it(Uses a spy,function()
002
{
003
spyOn(someObject,
functionName);
004
//Use someObject
005
});

21 Chained spying
Adding the andCallThrough command to the
declaration of the spy enables you to chain the
invocations and reduce the amount of impact on the
system. This means that Jasmine will analyse the callings
of the method, but will then proceed with forwarding
them to the actual implementation provided by the
system under test.

001 {
002
it(Uses a spy,function()
003
{
004
spyOn(someObject,
functionName).
andCallThrough();
005
//Use someObject
006
});

Automatically test your JavaScript with Jasmine

Create a custom matcher


Keeping your unit test code short and simple is
beneficial. Custom matchers allow you to keep
comparison logic out of the actual unit tests

001 describe(A suite, function()


002 {
Custom matchers are registered with Jasmine by
passing in a JSON array

001 var customMatchers =


002 {
003 toBeBisnovat: function(util,
customEqual)
004 {
<Above>
s5IFDPVOU
GVODUJPOSFUVSOTUIFOVNCFSPGDBMMTUIBU
XFSFSFHJTUFSFEJOUIFTQZEVSJOHUIFUFTUDBTFFYFDVUJPO

<Above>
s4QJFTDBONPEJGZUIFSFUVSOWBMVFPGUIFGVODUJPOBOBMZTFE*O
PVSDBTF BOFNQUZGVODUJPOJTPWFSXSJUUFO

This array contains a group of generator functions,


which return an object containing a compare
function

22 Was it invoked?
The most basic use case for a spy involves
finding out whether the method in question was
invoked during the execution of the test case. In our
case, the test will be successful only if the code masked
by the comment invokes the functionName method at
least once.

001 {
002
it(Uses a spy,function()
003
{
004
spyOn(someObject,
functionName).
andCallThrough();
005
//Use someObject
006
expect(someObject.
functionName). toHaveBeenCalled();
007
});
008

23 Parameters
Advanced testing requires the use of an artificial
spy. These can be generated by invoking the createSpy
function with a string identifying the name of the
function which you want to be shadowed. The
toHaveBeenCalledWith function permits you to
determine whether the parameter set in question was
actually passed in.

001
it(Uses an artificial
spy,function()
002
{
003
var whatAmI = jasmine.
createSpy(whatAmI);
004
whatAmI(Welcome);
005
whatAmI(I am unreal);
006
expect(whatAmI).
toHaveBeenCalledWith(Welcome);
007
});

24 How often was it called?


In some cases, the amount of invocations caused
during the execution of the test case can be interesting.
If an artificial spy is inserted, it can perform an analysis of
the call structure. Its results can then be used to
determine the number of times the method was called
during the execution of the test case.

25 With return values


Sometimes, modifying the value of a function
returned can be very helpful. This can be achieved by
adding the andReturn() clarifier to the creation of the
spy. From that moment onwards, all invocations of the
method managed will return the value passed in.

26 Control time
When attempting to debug time-based code,
compressing the wait cycles can help to reduce the total
execution time of the test battery. Invoking jasmine.
clock().install halts the flow of time in your program.
From then onwards, calling jasmine.clock().tick will allow
you to advance the time in a helpful step-by-step fashion.

27 Custom matcher
Even though Jasmine provides you with a large
selection of matchers, you might sometimes want to
add a new one to the roster. This can be achieved by
creating a so-called custom matcher. These are passed
in to the framework and can then be used like any other
matcher. See the code library (left).

28 Welcome to Node.js
Running your program from the browser can
become a nuisance. Fortunately, a Node.js-ready version
of the Jasmine framework is available via GitHub at
HJUIVCDPNNIFWFSZKBTNJOFOPEF. Once installed,
your tests can be run via the command line of your
system. Jasmine-Node even supports the Growl system
for sending out notifications through a variety of media.

001 return{
002 compare: function(actual,
expected)
003 {
004
var result=new Object();
005
if(actual.
isRocketName===Bisnovat)
006
{
007
result.pass=true;
008
}
009
else
010
{
Jasmine expects your code to return an object
containing a boolean pass value and a string
describing why a test failed.

001
result.pass=false;
002
result.message=Rocket is
not Bisnovat;
003
}
004
return result;
005 }
006 };
007 }
008 };
009
it(Uses a matcher,function()
010
{
Finally, call addMatchers on the generator array in
order to implement the matcher into the framework

001 jasmine.
addMatchers(customMatchers);
002 var aRocket=new Object();
003
aRocket.
isRocketName=Bisnovat;
004
expect(aRocket).
toBeBisnovat();
005
});
006 });

Web Design Tips, Tricks, & Fixes 169

Automate
development
processes
with Grunt.js
Alleviate the stress of repetitive tasks
and make the most of development
time with the Grunt.js task runner

Gruntfile.js (or Gruntfile.coffee) in the root directory of


your project. Inside of this add the wrapper function,
which is used by every Gruntfile and plug-in. This will
hold our configuration data.

001 module.exports = function(grunt) {


002 };

05 Install Grunt

Now its time for us to add our first plug-in


which is actually Grunt itself. With the Terminal window
open in the project directory, enter the command to
install the package from the manager. Here we are not
using the g flag to install them globally, but instead
choosing to save them locally and automatically add
them to the devDependencies section in the package.
json file.

Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594

01 Prerequisites

Grunt and the installation of any of its plug-ins is


managed through the Node.js package manager. As
such, your development machine must have Node.js
installed. If you have not already done so, make sure
you head over to nodejs.org/download and download
the installer.

170 Web Design Tips, Tricks, & Fixes

06 Dependency added

Once any npm install command has been run to


add a grunt plug-in with the --save-dev flag used, the
system knows that this should be added as a
dependency for development. It then adds the plug-in in
question to the devDependency configuration section
of the package.json file. Open the file in your editor to
see the updates.

tools | tech | trends Grunt.js, Adobe Edge Code

ts very rare when repetitive tasks are a


welcome addition to any part of our life,
personal or professional. More often than
not, during our development cycles and
processes we encounter more than one task
that is performed with glaring regularity.
With so much to develop, control and
manage, it can be a little daunting if you add
up the time spent on such tasks time that
could arguably be better spent elsewhere.
Enter Grunt.js, a free open source JavaScript task
runner powered by Node.js. Grunt aims to alleviate such
repetitive tasks by allowing you to create singular or
batched processes to manage these for you from the
command line. Written in JavaScript, anyone with basic
JS knowledge can get up and running with the Grunt
command line quickly. Its also an highly extensible
framework, with an ever-growing number of plug-ins
contributed by the development community.
In this tutorial well install the Grunt command line
interface tool, set up our local project environment to use
the library and install some useful plug-ins to assist us
with minifying and managing JavaScript and CSS files
ready for production use. Welcome to Grunt!

001 > npm install grunt --save-dev

02 Install Grunt CLI

With Node.js installed we have access to the


package manager via the command line. Open up a
Terminal or CMD window and run the following
command to install the Grunt CLI (Command Line
Interface). The g tag will install it globally, adding it to
your system path and making it accessible from any
directory on the machine.

001 > npm install g grunt-cli

03 Prepare your project

To set up Grunt processes within a new or


existing project directory, two specific files are required
both of which need to live in the root of the project
location. Create a new file in the root called package.
json. At the very least this must contain name and
version fields. Well also add in the devDependencies
field for later use.

001
002
003
004
005
006
007

{
name: my_grunt_project,
version: 0.0.1,
devDependencies: {
}
}

04 Create a Gruntfile

The second required file is the Gruntfile, which is


used to configure or define tasks and to load any Grunt
plug-ins we have requested within this project. Create

001 devDependencies: {
002 grunt: ~0.4.1
003 }

07 Uglify plug-in

Lets add another plug-in into the system. Once


again, open up your Terminal window within the project
directory and install a new plug-in, grunt-contrib-uglify.
Make sure to use the --save-dev flag again so that it is
added to the package.json file for you. This plug-in can
be used to minify files, which is perfect for any
JavaScript files we have.

001 > npm install grunt-contrib-uglify --savedev

08 Grunt config initialisation

Before we can add any tasks to our Gruntfile, we


first need to define the grunt.initConfig method, which
initialises a configuration object for the current project.
This sits directly within the wrapper function. Add this
code into the Gruntfile to declare the configuration
object. Our task definitions and configuration
information will go inside of this function.

001 grunt.config.init({
002
003 });

09 Uglify configuration

We can now add in our individual task

Automate development processes with Grunt.js

<Above>
s(SVOUSVOTPO/PEFKT*GZPVIBWFOUHPUUIJTJOTUBMMFE IFBEPWFSUPOPEFKTPSHEPXOMPBEUPEPXOMPBE
BOEJOTUBMMJU

<Above>
s5IFQBDLBHFKTPOJMFXJMMVQEBUFXJUIJOTUBMMFEQMVHJOTGPSMPDBMVTF UIBOLTUPUIF
TBWFEFWMBH

<Above>
s*OTUBMMJOHUIFHSVOUDMJQMVHJOJTJODSFEJCMZTJNQMFUIBOLTUPUIFOPEFQBDLBHFNBOBHFS

<Above>
s3VOOJOHUIFVHMJGZUBTLGSPNUIFDPNNBOEMJOF ZPVXJMMSFDFJWFTPNFJOGPSNBUJPO
BCPVUUIFTVDDFTTGVMCVJME

configuration. Each plug-in has its own config options,


which can normally be found on the Github or Grunt
plug-in pages. Define the uglify configuration. Set the
build option to reference the source directory where our
files reside, and the destination directory into which the
minified version will be placed.

001
002
003
004
005
006
007

uglify: {
build: {
src: src/js/script.js,
dest: dest/js/script.min.js
}
}

10 Automatic banners

When uglifying or processing any files, many


grunt plug-ins will let you define a banner, which can be
any block of text, and add it to the top of the processed
file for you. This is particularly great for the marking and

storing of dates or configuration data in the file. Add the


banner option as shown in the following code to the
uglify configuration.

same plug-in name used when you installed it via the


command line.

001 grunt.loadNpmTasks(grunt-contrib-uglify);
001 options: {
002 banner: /*! <%= grunt.template.
today(yyyy-mm-dd) %> */\n
003 },
004 build: {
005 src: src/js/script.js,
006 dest: dest/js/script.min.js
007 }

12 Run the task

Lets run the task. Open up the Terminal window


and navigate to within the project directory. To run a
task, we need to call Grunt followed by the name of the
task to run, which we configured in the Gruntfile. Once
complete, the Terminal window will give you a response
from the process.

008
001 > grunt uglify

11 Enable the plug-in

With the task config defined, it is now time for us


to load the task into the system so that Grunt knows
what to reference when a task is run. This is achieved
easily by adding in a method into the Gruntfile to load
the locally installed npm plug-ins. Simply define the

13 Minified JavaScript file

Our uglify task was set to minify (or uglify) a


specific JavaScript file in our source directory and place
the revised version into a destination directory ready for
production. Open up the dest/js/script.js file in a code

Web Design Tips, Tricks, & Fixes 171

Reference files
and directories
When creating your tasks
to watch or update a
selection of files, you can
specify individual files, or
choose all files within a
directory using a wildcard
(*). Grunt is highly
configurable.
<Above>
sThe minified JavaScript file
has been written, complete
with inserted banner text

002 options: {
003
banner: /*! CSS Build - <%= grunt.
template.today(yyyy-mmdd)
%> */\n
},
build: {
src: src/css/*.css,
dest: dest/css/combined.min.css
}
}

<Above>
sRunning a watch task to keep an eye on any file updates and changes is really useful

<Above>
sFollowing a file change, when saved, the specified tasks will run and Grunt will
continue to watch for you

004
005
006
007
008
009
010
011
<Below>
sRunning the default Grunt task,
two tasks have been processed
in order to save us some
valuable time and typing

// Load the task too (after the config


method)
012 grunt.loadNpmTasks(grunt-contrib-cssmin);

16 Combine tasks

With more than one task defined we would have


to run each task individually from the command line. We
can combine as many tasks as we wish and create a
default that will run when we write grunt or grunt
default in the command line. This new task will run each
task specified, saving time.

001 grunt.registerTask(default,
[uglify,cssmin]);

002
003 > grunt

editor. You should be able to see the minified code and


the inclusion of a date stamp at the top, provided by the
banner setting.

14 CSS minification

dev

002

15 Configure the task

Lets add a new plugin to our local project. With a


Terminal window open, install a new plug-in called
grunt-contrib-cssmin and save as a dev dependency to
update the package.json file. We want to keep our CSS
files as small as possible for production, and this plug-in
was written just for the task.

Open up Gruntfile.js in your editor. We can now


add in the task configuration for the freshly installed
plug-in. We can once more make use of the banner
setting to add in the date of the compilation. We are also
choosing to minify all CSS files within the selected
directory, renaming them as combined.min.css in the
output directory.

001 > npm install grunt-contrib-cssmin --save-

001 cssmin: {

172 Web Design Tips, Tricks, & Fixes

17 Watch files

While its incredibly powerful to be able to run


tasks as and when they are required, some developers
may find it beneficial to have the ability to perform tasks
on files when they have been added or updated. There
is a Grunt plug-in to manage this too, so lets install it in
the same way as we have installed all the others in this
tutorial.

001 > npm install grunt-contrib-watch --save-dev

18 Configure the watch

The watch plug-in can be configured, as with


many of the other plug-ins, to watch a specific directory

Automate development processes with Grunt.js

<Left>
s5IF(SVOU
EPDVNFOUBUJPOJT
EFUBJMFEBOE
JOGPSNBUJWF BOEJUTB
HSFBUQMBDFUPEJH
EFFQFSJOUPUIF
QPXFSGVMUPPM7JTJU
gruntjs.com/
getting-started GPS
NPSFJOGPSNBUJPO

Ensure teams are working


together with the package.
json configuration
Whether you are working as part of a team
or as a solo developer on your own projects,
version control is definitely your friend. Once
you have created your package.json file on your
development machine, it sits within the root of
your project. When committing your code to your
repository of choice, make sure that your Gruntfile
and package.json file are also committed. As a
result, any team member has access to the same
files created for the task runner to work. Likewise,
if you switch to a different machine, you will also
have access to the same files. Once Node.js is
installed on any new machine, you simply have to
run npm install from within your project directory
and it will install all of the dependencies from the
package.json file straight into your project.

or set of files in the project. Here we are watching for a


change to any of the JavaScript files within the src
directory. Once detected, we are running the uglify task
to process the minification of JS files. Make sure you
remember to load the task as well.

001
002
003
004
005
006
007
008
009
010

watch: {
scripts: {
files: [src/js/*.js],
tasks: [uglify],
options: {
spawn: false,
},
},
}
// Load the task too (after the config
method)
011 grunt.loadNpmTasks(grunt-contrib-watch);

20 Manage variables

We have referenced the src and dest directories


numerous times within the Gruntfile. While this is
acceptable, we can reduce the duplication of hardcoded
values and actually set these locations within our
package.json file. Add the following below the
devDependencies object. The package.json file is a
great place to set reusable values.

Trusted
plug-ins

001 srcDir: src/,


002 destDir: dest/

5IF(SVOUQMVHJO
SFQPTJUPSZJTGVMMPGGBOUBTUJD
QMVHJOTGSPNUIF
DPNNVOJUZ8IJMFZPVDBO
CFTVSFUIBUBMMPGUIFN
XPSL BQMVHJOQSFJYFE
XJUIAHSVOUDPOUSJCJT
UZQJDBMMZQSPWJEFECZUIF
DPSF(SVOUUFBN

21 Load JSON file

Open up Gruntfile.js in your code editor. We can


now replace instances of hardcoded directory paths to
use the variables in the package.json file. First, we need
to set a variable to hold the JSON contents of our .json
file using a built-in method from the grunt core file API.

012

19 Start watching

To start the watch task, open your Terminal


window within the project directory and call Grunt
watch. The output will let you know that it is waiting for
file changes. Once any are detected, the chosen task will
be run and the actions processed as defined in the task
configuration.

001 > grunt watch

001 grunt.config.init({
002 pkg: grunt.file.readJSON(package.json),
003 // The rest of the gruntfile...

22 Change path references

We can now change any references to our


directory paths. Find and replace all instances of src/
and replace it with <%= pkg.srcDir %> and dest/ can be
replaced with <%= pkg.destDir %>. When running our
tasks, the template strings will convert to the relative

paths set in the package.json file, reducing the amount


of repetition found within our code. TNow many of your
repetitive tasks will be taken care of!

001
002
003
004

build: {
src: <%= pkg.srcDir %>js/script.js,
dest: <%= pkg.destDir %>js/script.min.js
}

Web Design Tips, Tricks, & Fixes 173

tri Spe
al ci
of al
fe
r

Enjoyed
this book?

Exclusive offer for new

Try
3 issues
for just

* This offer entitles new UK direct debit subscribers to receive their first three issues for 5. After these issues, subscribers will then pay 25.15 every
six issues. Subscribers can cancel this subscription at any time. New subscriptions will start from the next available issue. Offer code ZGGZIN must be
quoted to receive this special subscriptions price. Direct debit guarantee available on request.
** This is a US subscription offer. The USA issue rate is based on an annual subscription price of 65 for 13 issues which is equivalent to $102 at the time
of writing compared with the newsstand price of $14.99 for 13 issues being $194.87. Your subscription will start from the next available issue.

About
the
mag

Uncover the secrets


of web design
Practical projects
Every issue is packed with step-by-step tutorials
for HTML5, CSS3, Photoshop and more

In-depth features
Discover the latest hot topics in the industry

Join the community


Get involved. Visit the website, submit a portfolio
and follow Web Designer on Twitter

subscribers to

Try 3 issues for 5 in the UK*


or just $7.85 per issue in the USA**
(saving 48% off the newsstand price)

For amazing offers please visit

www.imaginesubs.co.uk/wed
Quote code ZGGZIN
Or telephone UK 0844 848 8413 overseas 01795 592 878

YOUR FREE RESOURCES


Log in to filesilo.co.uk/bks-594 and download your great resources NOW!

EVERYTHING
YOU NEED
TO BUILD ON
THE AWESOME
SKILLS IN THIS
BOOKAZINE

ENHANCE YOUR WEB DESIGN SKILLS


Video workshops

Stock images

YOUR BONUS
RESOURCES
ON FILESILO WITH THIS
BOOKAZINE, FREE AND
EXCLUSIVE FOR WEB DESIGN
TIPS, TRICKS & FIXES READERS,
YOULL FIND A WEALTH OF
RESOURCES, INCLUDING

PACKED WITH BRILLIANT


DIGITAL CONTENT, AVAILABLE
ANY TIME, ON DEMAND

A walkthrough on creating a responsive


web game in HTML 5
An hour-long beginners guide to
typography in Photoshop
Ten premium fonts for you to use in your
web design projects
All the files and resources you need to
complete the tutorials in the book

Free fonts

filesilo.co.uk/bks-594
176 Web Design Tips, Tricks, & Fixes

FILESILO THE HOME OF PRO RESOURCES

Discover your free online assets


A rapidly growing library
Updated continually with cool resources
Lets you keep your downloads organised
Browse and access your content from anywhere
No more torn disc pages to ruin your magazines

No more broken discs


Print subscribers get all the content
Digital magazine owners get all the content too!
Each issues content is free with your magazine
Secure online access to your free resources
This is the new FileSilo site that replaces
your disc. Youll find it by visiting the link on
the following page
The first time you use FileSilo, youll need to
register. After that, you can use your email
address and password to log in

The most popular downloads are shown in


the carousel here, so check out what your
fellow readers are enjoying

If youre looking for a particular type of


content, like software or video tutorials,
use the filters here to refine your search

Whether its programming tutorials or


video workshops, categories make it easy
to identify the content youre looking for

See key details for each resource


including number of views and
downloads, and the community rating

Find out more about our online stores, and


useful FAQs, such as our cookie and
privacy policies and contact details

Discover our fantastic sister magazines


and the wealth of content and information
that they provide

Web Design Tips, Tricks, & Fixes 177

HOW TO USE
EVERYTHING YOU NEED TO KNOW ABOUT
ACCESSING YOUR NEW DIGITAL REPOSITORY

To access FileSilo, please visit filesilo.co.uk/bks-594

01

Follow the
on-screen
instructions to create an
account with our secure
FileSilo system, log in and
unlock the bookazine by
answering a
simple question
about it. You can
now access the
content for free
at any time.

02

Once you have


logged in, you are
free to explore the wealth of
content available on
FileSilo, from great video
tutorials and online guides
to superb downloadable
resources. And the more
bookazines you purchase,
the more your instantly
accessible collection of
digital content will grow.

03

You can access


FileSilo on any
desktop, tablet or
smartphone device using
any popular browser (such
as Safari, Firefox or Google
Chrome). However, we
recommend that you use a
desktop to download
content, as you may not be
able to download files to
your phone or tablet.

04

If you have any


problems with
accessing content on
FileSilo, or with the
registration process, take a
look at the FAQs online or
email filesilohelp@
imagine-publishing.co.uk.

NEED HELP WITH


THE TUTORIALS?
Having trouble with any of the techniques in this bookazines tutorials? Dont know
how to make the best use of your free resources? Want to have your work critiqued
by those in the know? Then why not visit the Web Designer and Imagine Bookazines
Facebook pages for all your questions, concerns and qualms. There is a friendly
community of fellow web design enthusiasts waiting to help you out, as well as
regular posts and updates from the team behind Web Designer magazine. Like us
today and start chatting!

facebook.com/ImagineBookazines
facebook.com/WebDesignerUK
178 Web Design Tips, Tricks, & Fixes

Get to grips with


the best tools,
techniques and
frameworks for
building fresh,
modern and
responsive sites

Add excitement
and interactivity to
your web pages
with dynamic
animation effects,
infographics and
3D elements

unlock the
potential of
web design
Enhance all
aspects of your
web design with a
range of solutions
for improving
code quality and
automating
key processes

FREE
ASSETS

ISSUE 03 REVISED EDITION

s Over 9 hours of expert


video tutorials
s Premium fonts to use
on your websites
s Professional responsive
CSS templates

You might also like