You are on page 1of 180

FREE RESOURCES

NEW

Includes fonts, templates and videos

Volume 3

HTML5
CSS3
The professional guide to programming
for web design and development

www.fullengineeringbook.net

#FCD905

Perfect responsive design Master animation Create apps

www.fullengineeringbook.net

A comprehensive masterclass in
becoming an instant expert

Welcome to
Making a website is something that just isnt possible without the aid of HTML. It is
the basic framework of the World Wide Web and we rely on CSS to make the styling
consistent and easier to manage. In this new volume we ofer you the tools you need
to become a web design master. Within these pages you will learn the art of
responsive design and how it will only serve to make your websites more user
friendly, therefore more efective. Add pop-up modal boxes, integrate payments and
incorporate a plethora of dynamic animations that will add extra pizazz to your
designs. Take inspiration from the experts and recreate some of their more ingenious
ideas and ind out what works for you and your designs. You also have access to
FileSilo, where there is a wealth of free content online, just waiting for you to
download and use, as well as hours of video tuition to aid you in your completion of
the tutorials inside. Enjoy the book!

www.fullengineeringbook.net

www.fullengineeringbook.net

HTML5

CSS3

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

www.fullengineeringbook.net
Publishing Director
Aaron Asadi
Head of Design
Ross Andrews

Edited by
Jen Neal & Fiona Hudson
Senior Art Editor
Greg Whitaker
Assistant Designer
Steve Dacombe
Printed by
William Gibbons, 26 Planetary Road, Willenhall, West Midlands, WV13 3XT
Distributed in the UK, Eire & the Rest of the World by
Marketforce, 5 Churchill Place, Canary Wharf, London, E14 5HU
Tel 0203 787 9060 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.
HTML5 & CSS3 Genius Guide Volume 3 2016 Imagine Publishing Ltd
ISBN 978 1785 462 603

Part of the

bookazine series

Contents
18

VR + THE WEB

92

Get to grips with how VR technology is revolutionising


the way we think about the future of the internet

Tips & Techniques

Front-end

10

52

20 HTML5 tools you need now

18 VR & the web


26 Integrate payments with the

Responsive design decoded

60 Is your content king?


66 Design aspect ratio-based layouts

www.fullengineeringbook.net

Stripe API

30 Master responsive image

with HTML and CSS

70 Make dynamic graphics with the

techniques

34

Create animated infographics with


Snap.svg

38 Build with AngularJS


42 Develop apps with Facebooks
React Native framework

46 Whats new with Modernizr?

26

34

6 HTML5
Mac OS&XCSS3
Genius
Genius
GuideGuide

74
76

88 Create an interactive mobile 3D


interface

p5.js library

92 Assemble full-screen navigation

Code 3D zoom effects with CSS

Developer

Form pop-up modal boxes with


pure CSS

80 Build offline web apps with


Service Workers

84 Model a unique mobile 3D


interface

70

98 Be a jQuery code master


106 25 pro plugins
116 Produce a picture gallery with
jQuery

HTML5 & CSS3

Genius Guide
132

60

120 Code validation into forms with

146 Create split-screen sliding panel

160 Code on-scroll image animations

www.fullengineeringbook.net
ngMessages

124 Make drums with the Web Audio


API

128 Get free web hosting with GitHub


Pages

132 Manage JS with asynchronous


tasks

effects

148 Animate an SVG with HTML and


CSS

150 Code animated sliding panels on


scroll

152 Make a resizable sliding panel for


your content

Special effects

154 Sync animations to audio and

138 HTML & CSS animation

158 Make a draggable fading effect

98

164

video with Popcorn.js

with CSS

162 Add slide-up titles on page load


using CSS

164 Animate typography and text


effects

168 Create a 3D navigation menu with


HTML

172 Make a screen shrink on scroll


174 Create scrolling text with colour
change

154

HTML5
Mac
& CSS3
OS X Genius Guide 7

Tips & Techniques

www.fullengineeringbook.net

8 HTML5 & CSS3 Genius Guide

10

20 HTML5 tools you need now


Master these essential APIs and specifications

18

VR & the web


Understand how VR is set to revolutionise the web

26

Integrate payments with the


Stripe API
Install a payment gateway for taking cash online

30

Master responsive image


techniques
Control image presentation across different clients

34

Create animated infographics


with Snap.svg
Use animations to display information visually

38

Build with AngularJS


Start building web apps with the framework

www.fullengineeringbook.net
42

Develop apps with Facebooks


React Native framework
Build an image catalogue app with
Facebook React

46

Whats new with Modernizr?


Learn about the features of the latest release

HTML5 & CSS3 Genius Guide 9

Tips & Techniques

20
www.fullengineeringbook.net

tools you
need now
Get learning with these essential APIs and
specifications for contemporary practices
10 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

Web Speech API

2 Text to
speech API

A TECHNOLOGY IN ITS INFANCY, BUT WITH THE POTENTIAL TO INTRODUCE


ENTIRELY NEW MODES OF EXPERIENCE TO THE WEB

WEB SPEECH APIS OTHER HALF

The Web Speech API is an experimental


onresult, onerror, and onend. Rather than try to explain
technology due to its ever-changing
the event-oriented nature of the API, here is a basic
specification, which brings voice dictation
example of it in action.
<textarea id="dict"></textarea>
software to the web. The underlying premise of the API
var recog = new window.
is to provide capacity for both brief input (think
SpeechRecognition();
commands) as well as continuous input (think classic
var dict = document.
dictation, allowing for pauses).
querySelector('#dict');
With a bit of imagination, this feature could begin
recog.continuous = true;
quite a change in the way that user interfaces are
recog.onresult = function(e) {
designed on the web. Google and Apple have already
e.results.forEach(function(r) {
been exploring speech to enhance particular aspects of
dict.textContent += r[0].transcript;
the user experience in their products with Okay
});
Google and Hey Siri. Such facilities on the web will
}
surely bring new and exciting opportunities.
recog.start();
The specification suggests more than a few
This code creates a new instance of
useful functions such as voice web search,
the SpeechRecognition interface. It
continuous recognition of open dialog,
Target
then configures the instance to
speech UI present when no visible UI
recognise continuous input, which
Audience
needs to be present and voice
This technology will be particularly
enables the speaker to pause. The
activity detection (dvcs.w3.org/hg/
useful for people with disabilities
instance is then started. When the
speech-api/raw-file/tip/
such as visual impairment, and
results are determined as the
webspeechapi.html#use_cases).
generally make the web an
speaker talks, the textarea is
Of course there will be some
even more accessible
appended to with the most likely
privacy concerns with any API that
place.
correct result.
potentially enables a device to capture
URL: bit.ly/1WsQh1u
and store local ambience for later. The
specification sets out two mandatory conditions
for vendors to follow, which paraphrased are: User
agents can only start recording speech with explicit and
VOICE WEB SEARCH
informed consent User agents must provide obvious
No doubt when this API becomes
indications when speech is being recorded. This
commonplace there will be clients requesting
interface element must also allow users to cancel the
their own version of Okay Google.
current speech session.
CONTINUOUS RECOGNITION OF
In terms of implementation, like most APIs of this
OPEN DIALOG
type, the interface is event-driven. SpeechRecognition
This one really depends on who is using it.
exposes four evented functions, which are: onstart,
Hook it up to an email client and send ten times
more email!

The flip side of speech-to-text is text-to-speech. It


really is just like the say command on any Mac OS
X machine. Of course because this API is a web
technology, it can and should be put to better use.
Most of the legwork is done by Web Speech APIs
SpeechSynthesis interface, which works in a similar
manner to SpeechRecognition, where evented
functions are exposed along with the speech
function aptly named speak. Check out a
stripped-down example of what it can look like in
action below:

var s = new SpeechSynthesisUtterance();


s.text = 'I like cat food';
s.lang = 'en-US';
window.speechSynthesis.speak(s);
A new instance of the SpeechSynthesisUtterance
interface is instantiated. The instance then has the
text defined the string the computer is going to
speak, along with a language. The final line passes
the configured instance to the speak function and
the computer begins to talk.
Unlike the SpeechRecognition API,
SpeechSynthesis is more widely supported, which
makes it a real option provided that the target
market is on iOSs Safari. This is quite handy for any
hands-free mobile applications, such as turn-by-turn
directions, or maybe even a step-by-step recipe app.

www.fullengineeringbook.net
Scenarios

Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

SPEECH UI PRESENT WHEN NO


VISIBLE UI NEEDS TO BE PRESENT
25+
44+
N/A
N/A
N/A
N/A

This technology could unlock an entirely new


market of even more minimal writing.

VOICE ACTIVITY DETECTION


There have got to be some interesting
opportunities when general voice activity
levels are paired with HTML5 Canvas.

Google and Apple have already been


exploring speech to enhance particular
aspects of the user experience

URL: bit.ly/1L5Hbpj

Scenarios
LISTENABLE BLOG POSTS
A great feature for the visually impaired, blog
posts that people can listen to would make
for a really compelling experience.

TURN-BY-TURN DIRECTIONS
Put your phone in your pocket and you can
then be audibly guided to your destination by
the browsers voice.

STEP-BY-STEP RECIPES
Sticky marks on touchscreens while weighing
out ingredients could be a thing of the past.

Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

43+
44+
N/A
8+
N/A
7.1+

HTML5 & CSS3 Genius Guide 11

Tips & Techniques

WebSockets API

CAPTURE VIDEO/AUDIO FROM DEVICES

FIRST THERE WAS HTTP, THEN ALONG CAME AJAX.


NOW, THERE IS WEBSOCKETS
WebSockets is a fundamentally diferent concept to
HTTP and AJAX. Instead of the client requesting
resources and the server responding with them, the
server and client agree to maintain a connection, called a
socket. At any time, the server and client can start
sending each other data across this socket, inherently
avoiding the overhead that comes with HTTP. The lean
nature of this protocol lends itself to latency-critical
applications and real-time experiences.
WebSocket-driven applications often require large
numbers of persistent connections, something that
traditional server-side technologies tend to be bad at
facilitating. Server-side architectures that allow for high
concurrency on a budget are often favoured like those
that are touted as non-blocking IO.

URL: mzl.la/1j9X55Q

Tools

Scenarios
REAL-TIME PROPERTY UPDATES
A forward-thinking estate agent implements
real-time property updates, providing an
ever-changing map of property to let.

MULTIPLAYER GAMING AND


COLLECTIVE EXPERIENCES
Any multiplayer game will require low-latency
communication between clients and the server.
This could apply to other group experiences as
well.

REAL-TIME CHAT
WebSockets could make a reasonable
replacement for the aging IRC, enabling richer
media to be used in discussion.

SOCKET.IO
SOCKET.IO

Browser Support

Real-time Node.js WebSocket architecture.

CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

GetUserMedia API

HTML5s getUserMedia API allows developers to


capture media streams from the device video, audio,
and both at the same time. This capability isnt that
exciting on its own, but it gets interesting when paired
with other HTML5 technologies. For example, the
video stream returned by getUserMedia can be
applied locally to a video element. That video element
can be drawn to HTML5 Canvas, which in turn can be
turned into a dataURL and then into a blob, ready to be
sent across a WebSocket to all other connected clients.
The nice thing about being able to bring the video
stream into HTML5 Canvas is it allows for manipulation
of the image before it gets sent to the server. It would
be very easy to scale the frames down, run filters over
them or even apply advanced efects such as blurring
and distortion.
GetUserMedia returns a stream of data that can be
used locally by HTML5s video element, like so:

<video autoplay></video>
var video = document.
querySelector('video');
navigator.getUserMedia({
video: true,
audio: true
}, function(s) {
video.src = window.URL.createObjectURL(s);
video.play();
});

www.fullengineeringbook.net

TORNADO
GITHUB.COM/TORNADOWEB/TORNADO
Python networking library and framework.

PLINK
DINAHMOELABS.COM/PLINK

31+
4.4 +
38+
8+
10+
7.1+

Real-time collaborative music-making experience.

History API

Link Prefetch API

SAVE STATES IN A SINGLE-PAGE WEB APP

PREFETCH NEXT STEPS IN KEY JOURNEYS

This API provides means to manipulate browser history


with JavaScript. This isnt limited to just forward,
backward and specific points, it also lets developers
add their history events with pushState.
History.pushState takes three values: an object
associated with the state, a title and then a page URL
which will be displayed in the browsers address bar.
The history API is very useful for single-page
applications that have diferent states or views that a
user may want to navigate between, but it still retains
the benefit of XHRs.

The HTML5 Prefetch API is a browser mechanism that


prefetches documents before a user manually requests
the ones that they are likely to visit in the near future.
Prefetching resources like this stop users having to waste
time waiting for server response the largest delay when
fetching new pages and assets.
Implementing prefetch cunningly can have a vast
efect on perceived performance, especially when users
are doing repetitive tasks.
Prefetching tags appear in the <head> of the page,
along with the other metadata relating to the site.

URL: mzl.la/1KzFuKx

URL: mzl.la/1VafzyW

Browser Support
CHROME
FIREFOX
SAFARI

12 HTML5 & CSS3 Genius Guide

CHROME
FIREFOX
SAFARI

URL: mzl.la/1iLRLWp

Parameters
CONSTRAINTS
Takes an object describing the stream constraints,
such as width, height, frame rate and more.

SUCCESSCALLBACK
If the request for a users media was successful, this
function is invoked and the stream is passed.

ERRORCALLBACK
If the request for media fails due to permissions, or
lack of sources, this function is invoked.

Browser Support

Browser Support
31+
38+
8+

The DOM is queried for the video element. The script


then requests permission to capture video and audio
streams via the getUserMedia API. Finally, the stream
returned is given to the video element, which begins
playback in the browser.

31+
38+
N/A

CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

31+
44+
38+
N/A
12+
N/A

HTML5 & CSS3

Genius Guide

The API that is


associated with media
elements allows for
separate media
controls in the DOM.
Although basic in this
example, the feature
does enable some
interesting aesthetics.

The API provides


access to a property
called currentTime.
This property controls
the playback of the
media but it will also
return the medias
current position.

The API also enables


basic properties of the
media to be controlled,
including playback
speed. Here the
developer has
implemented a
bespoke volume
control interface.

The MediaElement
interface allows the
developer to control
the playback of media.
Here the developer has
combined a play/pause
as one button rather
than having two
separate ones.

7
HTML
Media
API
www.fullengineeringbook.net

HTML5 VIDEO AND AUDIO HAVE PHASED OUT FLASH. ITS TIME
TO THINK ABOUT USING EMBEDDED MEDIA MORE CREATIVELY
The HTML5 Media API provides a standard JavaScript
API for interacting with the HTMLMediaElement
interface. HTMLVideoElement and HTMLAudioElement
are both children of the HTMLMediaElement and inherit
its properties.
Media Elements have properties for manipulating the
playback of media, including load, play and so on.
The scenarios for using this capability at first may
seem obvious. Any media that Flash would have been
used for before can now be done without browser
plugins but there are other benefits.
Its now easy to combine video and audio with other
HTML5 technologies such as Canvas for the production
of more engaging and grander interactive experiences.
Canvas lets developers manipulate video pixels and
apply bespoke efects.
Video thats more integrated with the surrounding
webpage is also now possible. The JavaScript interface
allows for play buttons to be separate from the traditional
video user interface, opening up brand new possibilities
for user experience designers to make use of.
Incorporating supporting animation to control
elements, such as expanding/revealing a video on a
button click, is now not only possible but also easy.

<video>
<source src="example.mp4" type="video/mp4"
/>
</video>

<button>Play</button>
var video = document.querySelector('video');
var button = document.
querySelector('button');
button.addEventListener('click', play,
false);
function play() {
if(video.paused) {
video.play();
} else {
video.pause();
}
}
First, DOM references are made to the video and button
elements. Then, a click handler called Play is then bound
to the button. The play function provides playing and
pausing functionality to the video by making use of the
HTMLMediaElement API interface.
Going on to build more advanced controls that
incorporate volume, seeking, playback speed and
tracking functions are all possible through the API. What
this means is that its much easier to bring a visual style
or brand to embedded media on the web than it ever
has been before.
Finally, the media element interface lets developers
create autoplaying media, giving rise to silent video as a
design element in a webpage or transparent media.

Scenarios
STANDARD VIDEO EMBED
Browser support for HTML5 media is so good
there really is no excuse for not using it as
standard for media embedding.

STANDARD AUDIO EMBED


Standard audio embedding is also preferred
over plugin-powered solutions, such as Flash or
Silverlight.

SILENT VIDEO
Use silent video instead of images to capture
human emotion and make emotional
connections with users.

HYPERREALITY
Shoot a video that contains very little
movement, but more than a photograph.
Hyperreal scenes can bring a page to life.

Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

31+
4.1+
38+
8+
9+
7.1+

URL: mzl.la/1NM0jYk

HTML5 & CSS3 Genius Guide 13

Tips & Techniques

Navigation
Timing API

SMART DECISIONS AND CONNECTIONS

PERFORM ANALYSIS ON LOAD TIMES OF WEB PAGES WITH THIS API


Ensuring pages are quick to load is crucial. The
Navigation Timing API can gather statistics on page-load
performance for developers to analyse. The statistics
allow for useful metrics such as the critical render path
and identification of slow images.
Use snippets in Chrome Developer Tools to store
useful functions for pulling metrics out of any page:

interactive, DOM content was loaded and the page had


finished loading. URL: mzl.la/1eUB4oS

function criticalRenderPath() {
var t = window.performance.timing;
// Converting to seconds
return {
interactiveAt: (t.domInteractive t.
domLoading) / 1000,
domContentLoaded:
(t.domContentLoadedEventStart t.
domLoading) / 1000,
complete: (t.domComplete t.domLoading) /
1000
}
}

Network
Information API

Scenarios
ANALYSIS OF ANY GIVEN PAGE
The navigation timing API should be used as a
quick reference to determine the critical render
path of any webpage.

COMPARATIVE ANALYSIS
Store the performance timing results when
conducting a series of improvements as a
benchmark for subsequent tests.

URL: mzl.la/1KAJcV4

Browser Support

Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

Long have developers wanted a definitive way to


determine what type of connection a user is on so
theyre better able to tailor experiences. The
Network Information API promises exactly this kind
of function capability.
This API will allow developers to make subtle but
important tweaks to experience, such as loading
standard-definition video when a user is on a mobile
data connection, as opposed to high definition when
theyre on Wi-Fi and are therefore able to load
high-quality content better.
This distinction can also be efectively used in
broader strokes, for example the user may want to
send less data to the client for standard XHRs and
this is especially useful if they are connected via a
mobile data connection.

31+
4.1+
38+
8+
9+
9+

CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

N/A
44+
N/A
N/A
N/A
N/A

www.fullengineeringbook.net

This references the performance.timing metrics, then


determines the metrics for each stage in the critical
render path to provide stats on when the page was

10 User Timing
API

11 Page Visibility
API

12 Battery

13 IndexedDB

Status API

STORE DATA IN THE BROWSER

BESPOKE CODE BENCHMARKS

FOR LOST FOCUS IN WEBPAGES

TAILOR FOR BATTERY

The User Timing API is an extension


window.performance, enabling
developers to mark points in their code
and make measurements. User Timing
can be used to identify areas of code
that are slower than desired.
Window.performance.mark lets
developers store a high resolution.
Window.performance.measure lets
developers calculate the elapsed time
between recorded marks.

Users often have a bunch of webpages


open at once, with only one in focus.
The Page Visibility API fires events
when a webpage loses focus or returns
into focus again, allowing developers to
get smart about the experiences on the
page that loses focus. This includes
pausing streaming media, as well as
avoiding unnecessary processing when
it comes to continuous animations and
even live media.

This API exposes useful battery


information. This includes charging, a
Boolean indicating whether the device
is currently charging; chargingTime,
which tells you how long until the
battery will be fully charged;
dischargingTime, which tells you how
long until the battery is depleted and
the device puts itself to sleep; and level,
which is the current battery level on a
scale between 0 and 1.0.

URL: bit.ly/1MIIXwN

URL: mzl.la/1Fu21wh

URL: mzl.la/UlVKw7

Browser Support

Browser Support
CHROME
FIREFOX
SAFARI

31+
38+
N/A

14 HTML5 & CSS3 Genius Guide

CHROME
FIREFOX
SAFARI

Browser Support
31+
38+
8+

CHROME
FIREFOX
SAFARI

IndexedDB provides developers a


low-level API to persistently store data
to a browser. Developers can store data
locally first and sync with the remote
server when a data connection is
available. This can be especially useful
when working with large datasets,
which should only be transferred over a
Wi-Fi connection. Like localStorage,
IndexedDB is subject to storage limits
and eviction criteria. The mechanisms
behind it are complex and vary with the
browser too. URL: mzl.la/1y2iyCj

Browser Support
43+
38+
N/A

CHROME
FIREFOX
SAFARI

31+
38+
8+

HTML5 & CSS3

Genius Guide

14 Drag & Drop API


USE DRAG AND DROP TO MAKE SORTING, REORDERING AND COLLECTING ITEMS A FAST AND EASY TASK
No longer do developers have to rely on third-party
}
function dragOver(e) {
JavaScript UI frameworks like jQuery to enable the
if (e.preventDefault) {
implementation of drag and drop. The HTML5
e.preventDefault();
drag-and-drop API provides evented functions and
}
HTML attributes, enabling most elements on any given
e.dataTransfer.dropEffect = 'move';
page to be made natively draggable. This means
return false;
developers can add cheap drag-and-drop functionality to
}
everyday tasks and applications; previously the
function dragEnter(e) {
overhead of libraries ensured it wasnt an
this.classList.add('dragging');
option. With a good implementation of
}
Colliding
drag and drop, it should be harder
function dragLeave(e) {
elements
than ever to distinguish web views
this.classList.
Its important for users to get
from native apps. There are seven
remove('dragging');
high-quality visual feedback from
events that cover the entire drag
}
drag-and-drop mechanisms. They
lifecycle. Just like mouse events,
function drop(e) {
should be confident of where
these can be bound to elements
if (e.stopPropagation) {
the item being dropped will
using addEventListener. A basic
e.stopPropagation();
be placed.
implementation of the drag life cycle
}
would look something like this:

<div class="item"
draggable=true></div>
function dragStart(e) {
this.style.opacity = '0.6';

return false;
}
function dragEnd(e) {
item.classList.remove('dragging');

}
var i = document.querySelectorAll('.
item');
i.addEventListener('dragstart',
dragStart, false);
i.addEventListener('dragenter',
dragEnter, false);
i.addEventListener('dragover', dragOver,
false);
i.addEventListener('dragleave',
dragLeave, false);
i.addEventListener('drop', drop, false);
i.addEventListener('dragend', dragEnd,
false);
First the various functions are set up to handle events.
DragStart() reduces the opacity of the dragged
element. DragEnter() and dragLeave() manage
classes used to style the item when its colliding with
another item. Drop() stops all of the current event
propagation. DragEnd() ensures the class used to
style collisions is removed.

www.fullengineeringbook.net
URL: mzl.la/1ENGVEq

Scenarios
MANAGING CALENDAR ENTRIES
Rather than editing specific times and dates
when managing a calendar, its much easier to
drag and drop appointments.

LIST SORTING
Sorting lists is better done with drag and drop
than the little arrow buttons that are sometimes
seen on older websites.

TASK PRIORITISATION
Prioritising tasks is an excellent use case for drag
and drop, which enables the swift reordering of
items.

IMAGE SORTING
Visual sorting is also useful. Being able to sort
images into two piles, such as suitable and
unsuitable, means that image organisation
could be vastly improved by drag and drop.

Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

31+
N/A
38+
8+
8+
N/A

HTML5 & CSS3 Genius Guide 15

Tips & Techniques


15 Web Workers

18 WebRTC Spec
CONNECTING DEVICES TO EACH OTHER

HAND COMPUTATIONALLY INTENSIVE TASKS TO BACKGROUND PROCESSES


Low concurrency CPU-intensive processing is something
that JavaScript in the browser has never been good at
due to its single-threaded nature. Operations that take a
long time block the thread and stop other things from
happening on the page.
The Web Workers API can enable background threads
to be spawned on the fly that can handle
computationally expensive tasks without there being any
detrimental efects to the main application thread. Web
Workers communicate with the main JavaScript thread
through an exposed function called postMessage. Heres
a basic example:

var worker = new Worker('worker.js');


worker.addEventListener('message',
function(e) {
console.log(e.data);
}, false);
worker.postMessage('I like cat food');
// worker.js
self.addEventListener('message',function(e){
self.postMessage(e.data);
}, false);

processing that would happen in the worker would be


kicked of in this function, but for now the example just
sends a message back to the main thread containing
identical data.

URL: mzl.la/1KAJDyK

Scenarios
SPREADSHEET APPLICATION
Spreadsheets can require an immense amount of
calculation if theyre large enough. Hand that
computation to another thread.

VIDEO ENCODING
Video encoding is an intensive computational
task and is not something that should be done in
the main thread.

Browser Support

The basic premise is to connect devices with each


other using a common platform where its easy to
craft rich experiences that leverage technologies
hence RTC (Real-Time Communications). The
three APIs that WebRTC implements are:
MediaStream (known as getUserMedia),
RTCPeerConnection and RTCDataChannel.
MediaStream provides access to streaming media
from a users device, like a camera and
microphone. RTCPeerConnection enables audio
and video calling as well as providing encryption
and bandwidth management capabilities.
RTCDataChannel is for peer-to-peer
communication of generic data.
The MediaStream aspects of WebRTC are
covered by the getUserMedia API section of this
feature. RTCPeerConnections job is to facilitate
streaming data between peers, but it doesnt
define any protocols to do so. Instead, developers
can choose any messaging protocol they desire,
such as XMPP, to handle the signaling required.
The signaling channel is used to exchange three
types of information between peers: media
abilities, the resolution and codecs supported by a
peers web browser; network information, a peers
external IP address and port; and Session control
for starting and closing communications as well as
error reporting.
WebRTC has a third API called RTCDataChannel,
which lets peers exchange miscellaneous data
with low latency. This makes WebRTC a contender
for low latency peer-to-peer applications or a
decentralised version of Web Sockets.

www.fullengineeringbook.net

There are two files here: the first is the main thread which
instantiates a worker from the other file, worker.js. The
main thread starts listening for data sent by the worker.
Then it sends data to the worker using postMessage, in
this case a simple string. Worker.js contains a function
that listens for data sent by the main thread. The

CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

31+
4.4+
38+
8+
10+
7.1+

17 Vibration API

16 Pointer Lock API

URL: webrtc.org

ENHANCE IMMERSIVE 3D EXPERIENCES

PROVIDE PHYSICAL FEEDBACK

The premise of the Pointer Lock API is to provide access


to raw mouse movement occurring beyond the
constraints of the browser window as well as hiding the
cursor. The API lends itself to first-person controls in
games, as well as other interactive first-person
experiences and experiences that require lots of mouse
movement such as 3D editing tools.
Before the Pointer Lock API, full-screen experiences
would run up against the edge of the browser window,
or worse go beyond it making it easy for users to be
taken out of the experience.

As smart devices become more common for interacting


with the web it makes sense to start taking advantage of
their unique abilities such as tactile feedback like that of
vibration. Most modern mobile devices have vibration
hardware. The vibration API ofers applications the ability
to access this hardware if it exists. The API is very
straightforward, as follows:

URL: mzl.la/1j9YZDr

URL: mzl.la/1MIJ77B

Browser Support
CHROME
FIREFOX
SAFARI

16 HTML5 & CSS3 Genius Guide

Scenarios

window.navigator.vibrate(250);
This line of code will cause the device to vibrate for 250
milliseconds. If an array is passed to vibrate, it will vibrate
and then pause for every other argument.

Browser Support
31+
38+
8+

CHROME
FIREFOX
SAFARI

31+
38+
N/A

DEVICE-AGNOSTIC VIDEO CHAT


WebRTC can bring video chat to almost any device
with a browser, camera and microphone.

PEER-TO-PEER GAMING
Games designed without a centralised server can
use WebRTC to connect peers with low latency.

PEER-TO-PEER FILE TRANSFER


WebRTC makes it possible to send large amounts
of data between peers.

Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

31+
44+
38+
N/A
N/A
N/A

HTML5 & CSS3

Genius Guide

19 Web Components

Scenarios
MULTISITE EVENTS WIDGET

USE WEB COMPONENTS TO PACKAGE HTML, CSS AND JAVASCRIPT


WIDGETS INTO REUSABLE, ISOLATED PACKAGES
Templates are similar to templates in other
Like WebRTC, the Web Components specification is a
third-party technologies like AngularJS. They enable
collection of several separate technologies. Web
Components are self-contained, reusable user interface markup to be defined, ready to be made use of later.
Shadow DOM is the specific technology that solves
widgets that leverage other open web technologies.
the DOM sandboxing issue, whereas
Using already public Web Components is
Custom Elements enable
something thats as easy as writing an
developers to create fully featured
import statement in an HTML page.
Remember it is
DOM elements. HTML Imports are
Web Components provide a way
not Polymer
to package widgets built with HTML,
similar to imports in other
Iolymer is a Google framework
CSS and JavaScript into reusable
languages, enabling the import of
based on Web Components
components theyre just as
entire Web Components, including
technologies and is not required
capable as anything else thats
their CSS and JavaScript.
to make effective use of Web
available out there.
While the four technologies in
Components.
For years, developers have worked
Web Components are supposed to
with widgets that arent sandboxed
be used in conjunction with one
from the rest of the DOM. The widgets
another, developers can select which
styling sat with the rest of the CSS, the JavaScript
parts of Web Components they need to use.
with the rest of the JavaScript. This lack of sandboxing The amount of things that can be achieved is broad.
made it hard to extend existing widgets without
When thinking about Web Components retrospectively
accidently regressing other parts of the code base. The against a recent project, they could be applied to any
four parts of Web Components that work to alleviate
self-contained feature of a webpage allowing that new
this problem are as follows: Templates, Shadow DOM,
component to be imported anywhere in the project.
URL: webcomponents.org
Custom Elements and HTML imports.

Develop an events widget that lists events from


an API dropped onto any site with one Import
statement and a Custom Element.

SEARCH WITH AUTOCOMPLETE


Take a search with autocomplete, such as
Googles Places, and then turn it into a reusable
component.

IMAGE CAROUSEL
Implement a carousel in a Web Component
and never write another carousel. Import the
old one that uses Custom Elements.

ACCORDION COMPONENT
You can turn any piece of markup into an
accordion by importing an accordion Web
Component and surrounding the item in a
Custom Element.

Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

www.fullengineeringbook.net
20 Shadow DOM

41+
44+
N/A
N/A
N/A
N/A

Parameters
ELEMENT.SHADOWROOT

ISOLATE PRESENTATION FROM CONTENT FOR MORE FLEXIBLE AND


ROBUST FRONT-END ARCHITECTURES
The Shadow DOM enables developers to encapsulate
DOM elements from the rest of the page. In conjunction
with templates, this enables the separation of concerns
with content and presentation. Before, a developer may
have written something like this when wanting to share
directions to their house:

<style>
.directions-widget { ... }
</style>
<article class="directions-widget">
<header>
<h2>Directions to my house</h2>
</header>
<p>Turn left</p>
</article>
But with Shadow DOM, they can write this:

<p id="directions">Turn left</p>


<template id="directionsTemplate>
<style>
...
</style>

<article class="directions-widget">
<header>
<h2>Directions to my house</h2>
</header>
<p class="directions">Turn left</p>
</article>
</template>
<script>
var s = document.
querySelector('#directions').
createShadowRoot(),
t = document.querySelector('#directionsTempl
ate'),
c = document.importNode(t.content, true);
s.appendChild(c);
</script>
The presentation code here is now inside a template, so
it wont be rendered by the browser. The script at the
bottom clones the template to the Shadow DOM, with
the presentation initially intended.

This is a read-only property that represents the


youngest shadow root that is hosted on the
element.

<CONTENT SELECT=>
The content element used inside of the
Shadow DOM is an insertion point, only to be
used in Web Components

<SHADOW>
Much like the <content>, the <shadow>
parameter is also an insertion point but it can
also be used for older shadow roots on the
same shadow host.

Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS

31+
4.4+
N/A
N/A
N/A
N/A

URL: bit.ly/1WsX3nM

HTML5 & CSS3 Genius Guide 17

Tips & Techniques

VR + THE WEB
THE NEXT GENERATION OF WEB DESIGN IS HERE. BUT HOW WILL THE RULES CHANGE AND
W H AT TO O LS A N D P LAT F O R M S W I L L B E A D E S I GN E R S F R I E N D ?

www.fullengineeringbook.net

18 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

How designing for the


web is changing
THERES A LOT TO CONTEMPLATE WHEN DESIGNING FOR THE WEB. ITS NOT EASY, AND IF YOURE READING THIS
YOU PROBABLY HAVE A GOOD IDEA OF WHAT WERE TALKING ABOUT
Consider that designing for the traditional web
some general guidelines to follow. Some of the best and
of today is still a two-dimensional medium. The
brightest minds are out on the front lines discovering the
audience scrolls up and down, sometimes left
sort of guidelines we need in this brave new world of
and right, on a two-dimensional plane. Your goal is to
user experience.
make those two dimensions convey meaning and
There are new guidelines to define and explore, but
order in a way that touches their hearts and
there are also many design principles with
minds. You want to give them an
which we are already familiar and stay the
WEB
experience that is both memorable
same. The basic way the human eye
REALITY
and meaningful, within the confines
works stays the same. Principles such
The prospect of designing for a
of two dimensions.
as contrast, colour, and pattern
new dimension is a very exciting
Now consider how you would
recognition are still valid tools. These
one. Check out the Catch the
accomplish the same goal in a
concepts can still be useful as the
Dragon site www.
three-dimensional medium. There
building blocks in our new virtual
catchthedragon.nl. This
are new factors to consider such as
medium. We may even be able to
combines and 360-degree
the users head angle and their
explore them further.
video and VR.
viewing radius. How do you make
But VR is just for videogamers, right?
elements touchable in a manner that is
you may think. Virtual reality has the
intuitive without the benefit of haptic
potential to change the web too, and there is
feedback? How do you deal with locomotion in a 3D
work happening in many arenas on just that. The idea of
space when a user is actually sitting or standing still?
the metaverse is not about a game, but a medium where
Does your UI move with the user or disappear
the virtual and the physical realities come together to
altogether? How do you use audio cues to get a users
form a new way of life, change it forever, and make it so
attention so that they turn their head? Were no longer
much better.
designing in a flat medium, but within all the space
As web designers and developers, we can be at the
around a person. It may seem like there are fewer
forefront of this new digital medium. We already are at
constraints and that can be freeing, but also scary. We
the forefront of the current prolific digital medium; the
know that with some form of constraints, or rules, that it
web. The bleeding edge is sharp, but we roll with it in
can be easier to work within those confines. It may seem
stride and push the boundaries of what is possible. This
like the skys the limit when designing for a threeis just another step into the unknown. We should do so
dimensional medium. But were finding that there are
with confidence and enthusiasm.

How VR and the


web can work
together
Education
The proliferation of online courses is just getting
started. Once you can immerse yourself into an online
classroom, the possibilities could be endless. Check
out Unimersiv.com for a glimpse into some of whats
already available.

www.fullengineeringbook.net

Your goal is to make those two


dimensions convey meaning and order in a
way that touches their hearts and minds

Jerad Bitner
Technical project manager
and VR enthusiast

VR is the next medium for the web


and should become a natural
transition for web developers and
designers. My recommendation is to
start studying architectural design
now so this can be applied to your
virtual worlds.

Socialising
Were already connected with each other through
Twitter, Google+, Facebook, and other social networks.
Imagine logging in and walking around in these sites
with their own architecture and content with your
friends. Check out Beloola.com to get an insight into
one companys vision.

Relaxation
Wouldnt it be great to re-visit your most relaxing
vacation spot anytime you wanted? With capture
devices becoming ubiquitous in the form of mobile
phones, and lately 360 cameras, you may be able to
visit wherever you like from the comfort of your home.

Creation
VR is rapidly becoming a new and exciting medium for
artists, both young and old. For examples, see this
video of a classic Disney animator drawing in VR
(vimeo.com/138790270), and check out this
augmented reality colouring book for children
(youtube.com/watch?v=SWzurBQ81CM).

Exploration
So many countries, so little time. With 360 videos
being taken worldwide of some of the most beautiful
and remote places, you can now fully immerse
yourself into these places to make you feel like you are
really there.

HTML5 & CSS3 Genius Guide 19

Tips & Techniques

5 VR
headsets
A LOOK AT SOME OF THE MAJOR
PLAYERS IN THE HMD MARKET
Virtual reality is currently nothing without a headset to
make the magic happen. There are various headsets in
various stages of development, but most are set to come
to the consumer in 2016. The big name in the world of
virtual reality is Oculus Rift, and Facebooks purchase of
Palmer Luckeys device means it will reach every corner
of the market. As with any new tech, the pleasure of
owning such a device will cost you dearly. But, the
budget option (less than 5) is already out there in the
shape of Google Cardboard. So go get your hands on
one now!

Oculus Rift

Samsung Gear VR

oculus.com/en-us/rift/

oculus.com/en-us/gear-vr/

Facebook bought Oculus for $2 billion (1.3 billion) to


get their hands on this one. The consumer version is
set to be available in July 2016 and is the default for
almost all VR software. Its to ship with hand controls.

A product of Samsung and Oculus, the Gear VR is a


wireless headset used with a Samsung phone. The
headset can be found for $99 (65), but the Samsung
phones are typically around $700 (464).

What are spatial memories?


Have you ever watched or read Dream Catcher? Well,
within the story, one of the main characters has what
he calls a memory warehouse. He can recall any given
memory, dragging it up from a virtual warehouse he
has built in his mind. He can walk around the building
and find any memory due to its relative position to
other memories. As such, he follows a path to locate a
particular memory.

This technique isnt quite as science fiction-esque.


The memory warehouse or memory palace is a system
of storing information in your brain by creating an
imaginary building and filling it with imagery of what
needs to be recalled. Learn how to build your own at
wikihow.com/Build-a-Memory-Palace.
Our brains were always meant to store information to
stay alive, like where you can find food and resources,

how to get home, and which plants are edible or


poisonous. This is most likely why we are so good at
remembering things visually and spatially.
By creating virtual worlds in which we can see and
hear, we are better able to create and recall memories
in the human brain, so its important that the
experience be a positive and even desirable one for
our users.

www.fullengineeringbook.net

By creating virtual worlds in which we can see and hear, we are


better able to create and recall memories in the human brain

How will VR affect UX?

VR COMES WITH A NEW SET OF EXPECTATIONS FROM USERS, AND TOOLS WITH WHICH WE
CAN CONNECT THEM TO OUR MEDIUM
Interfaces will no longer constrain themselves to
two-dimensional screens sitting on a desk. The screen
appears to disappear with a screen mounted to your
head. As you move your head there is new canvas
space available all around. The head-mounted display
gives a sense of depth and scale, and we can have
browsers and apps all around us.
Additionally we should consider how to organise
these apps in the space around us. Spatial organisation
of our UI components can help a user remember
where they can find things. Or it could degrade into the
nightmare desktop weve all seen with a massive clutter
of icons. But even then, our brains are capable of
making sense of that chaos.

20 HTML5 & CSS3 Genius Guide

Placing typical UI elements in such an environment


can be tricky. It can be hard to work out what is optimal
when the skys the limit. In order to get an idea of some
of the factors involved in finding the level, take a look at
some research conducted by Mike Alger, which is in
turn based on useful observations provided by Alex
Chu of Samsung. Algers research concludes that a
measurable area looking as follows is what is optimal
for user interface elements.
This conclusion is based on several factors, as
explained by Mike Alger in his paper. The first is the field
of view when a user is looking straight forward. This
distance is variable from device to device, but to give
you a good idea, the Oculus Rifts field of view is 94.2.

The second factor is the distance to which a user can


comfortably see. This distance is around 0.5 to 1 meter
from the user as a result of how the eyes attempt to
focus more and the strain caused after this distance.
Oculus recently recommended a distance of 0.75
meters to developers. The third factor is the head
rotation of a user.
Horizontally the comfort zone is about 30 from the
centre with a maximum distance of 55 to the side.
The fourth is head pitch, or the distance up and down
that is comfortable for a user to position their head.
Upwards this is comfortable up to 20 with a
maximum of 60. Downwards this is comfortably 12
with a maximum of 40.

HTML5 & CSS3

Genius Guide

Google Cardboard

HTC Vive

Razer OSVR

google.com/get/cardboard/

htcvr.com

razerzone.com/osvr

A much cheaper version of using your phone as a


head-mounted display, the Cardboard is actual
cardboard and works with many phones. The
Cardboard app is available on Android and iOS.

HTC and Valve have partnered on this headset which


comes with hand controllers and multiple light sensors
for room-scale VR applications. It is due to be
available in April 2016.

This is a little diferent in that it is the first open source


virtual reality headset. The goals of the project are to
make the parts available for you to build and upgrade
over time.

Creating memorable
experiences

Scale can be a powerful tool

Another useful tool to consider is how scale can afect


One side efect of experiencing virtual reality through a
the user. Creating a small model of something like a
head-mounted display is the direct impact on your
robot can make the user feel powerful, as though the
memory due to the feeling of being inside a new
robot were a cute toy. But scale the robot up to three or
environment rather than watching it on a screen.
four times the original size and its now far more
Feeling as though youre a part of it all creates
menacing. Depending on the memory youre trying to
memories of the experience, not just retention of
create, scale can be useful in shaping the experience
what we learned through reading. Engaging
of the user.
a user and creating memories on a level
where they can almost forget that
Steady
what they are experiencing is virtual
Horizons
When you are creating
Visually stunning scenery can afect
is what we refer to as immersion.
immersive
environments,
the immersion experience as well.
Immersion is at the heart of VR
make sure you keep your
A beautiful sunset, or a star-filled
applications. It being a core goal of
horizon nice and steady for your
night sky can give the user an
the VR experience, we should try
users in order to avoid inducing
the all-too-often experienced
environment to which they can
to understand the factors involved
VR sickness.
relate. Relating to known places and
and the techniques that are
scenes is an efective means of
becoming best practices in the
creating memorable experiences. Its a
creation of an immersive experience.
means of triggering other similar memories
and feelings and then building on those with the
Positional audio is a way of seeing with your ears.
direction you are trying to take the user. An immersed
Ingrained in us from early evolution, our brains have
user may have been there before, but now there is a
attuned themselves to figuring out exactly where a
new experience to remember.
sound comes from in relation to ourselves. A
recognisable sound that is behind you and to your left
Teaching someone a new and wonderful thing can also
can quickly trigger not only an image of what made the
be a useful memory trigger. Do you remember where
sound, but we can approximate where that sound came
you were when you first learned of HTML, or
from. It also triggers feelings within us. We might feel a
Photoshop? The knowledge that tends to stick out the
measure of fear or soothing depending on what our
most to us can trigger pretty powerful images and the
brain relates this sound to and how close it is to us. As
feelings that we memorised in those movements.
in real life, so it is in VR. We can use positional audio as
Heralded by some to be an important catalyst in
cues to gain a users attention, or to give them
changing how we learn, VR has the potential to
information that is not presented visually. Remembering
revolutionise education. Indeed we are better able to
a time when you were in VR and a sudden loud sound
create memories through the use of VR, and what
scared the pants of of you can immediately recall a
better memories than those of learning new and
memory of everything else you were experiencing at
interesting things?
the time.

A new shopping
experience

www.fullengineeringbook.net
Create beautiful
scenes

Use sound to draw attention

Make learning memorable

Advertising in VR is a whole new field, and


companies are just starting to wrap their minds
around the possibilities of connecting with their
intended audiences in a whole new way.
Advertisers and marketers have been trying
new ways of selling products for ages. One of the
basic principles of selling or marketing is making
the consumer identify on a personal level with a
product in order for them to want to buy it. Many
tactics are engineered and employed to get
people to buy things, but almost all of them come
down to this one over-arching goal of having a
person identify with the product.
VR could be a huge catalyst for achieving this
goal. Visiting a shop in virtual reality where you
can walk around the wares, see their size and
shape, hold them up with your virtual hands to
really identify the products dimensions, and even
obtain additional information through a display of
information attached to the product all of these
are possible. Or perhaps youre taken to a whole
new place when you pick up the object to
experience the use and operation of the product.
All of these are additional ways that a person can
identify with a product on a deeper level than a
two-dimensional representation allows.
There are some great examples of how VR is
being used in the commercial space. Trillenium
(trillenium.com) is just one of the many. They are
looking to bring the retail experience to shoppers
by creating virtual stores that allows users to
browse through shops as in real life.

HTML5 & CSS3 Genius Guide 21

Tips & Techniques

WEBVR in
action
STANDARD EXAMPLES OF USING WEBVR FOR
CREATING VIRTUAL ENVIRONMENTS

Chrome Experiments for VR


vr.chromeexperiments.com
Utilises WebGL and Three.js to create a virtual
environment compatible with your smartphone and
Google Cardboard.

What tools are developers using?


WE INVESTIGATE SOME OF THE TOOLS AND PLATFORMS DEVELOPERS ARE USING TO BUILD,
DISPLAY, AND COLLABORATE ON THEIR WORK

Unity 3D

3ds Max & Maya

website are very useful, not only teaching the basics of


the software, but also giving introductory lessons to
basic 3D modelling concepts. You can quickly learn the
basics of modelling with SketchUp and then move onto
more advanced tools like Blender if you desire. Its really
great for modelling, quickly learning the lingo, and then
moving onto bigger and better things. You can grab a
free trial version of the software at sketchup.com.

www.fullengineeringbook.net

Unity is one of the most ubiquitous of tools used today


These are Autodesk products for modelling, animation,
for in the development of VR technology. At its heart its
lighting and VFX. They dont have VR support by default
a game engine. It has a direct VR mode to preview your
but through pricey plugins instead. AutoCAD and 3ds
work in an HMD, which can really boost productivity by
Max are long-time standards in the architectural design
designing for VR almost within a virtual environment.
industry and have some of the most precise tools in their
Unity is quickly becoming the default tool for VR
UI. Like almost all GUIs for building 3D environments and
development due to its ease of use and the ability it
drawings, these tend to be quite massive UIs with a lot of
afords for quickly making prototype VR applications
tools hidden behind menus, submenus, and toolbars.
with it. Theres a huge community around this
Learn more about 3ds Max, Maya and other
tool and so there are a plethora of
Autodesk products at autodesk.com/
WebVR
resources and documentation to learn
products/maya/overview.
Standards
from. Whats more, a market of 3D
When you are looking to
assets can get you up and running
Blender is quickly becoming a
develop for the web and VR, take
in just a short amount of time. If
favourite modeller for VR
a look at the WebVR standard
youre familiar with C++ or
developers. Its free and open
drafted by Mozilla and Google:
JavaScript, you can get into the
source software written in Python.
mozvr.github.io/webvr-spec/
scripting pretty easily as well. All
Theres a huge community of people
webvr.html
major HMDs are supported and its
devoted to this software and its use.
cross platform. You can even export to
Many websites provide tutorial videos,
WebGL. Unity can be found by visiting
forums, and documentation. The softwares oficial
unity3d.com.
documentation is also quite impressive. Mainly for
modelling, UV mapping, lighting, rigging, and animation,
One of the main competitors of Unity 3D, Unreal Engine
you can export your models to a multitude of formats
is another gaming engine with VR integrations, an asset
that can then be used with many other tools. Theres
store, and it also has great documentation. The graphics
even a great plugin for exporting your creations into
are more advanced and realistic by default, and the
JanusVR with a free open source plugin at github.com/
learning curve is not dissimilar to Unity. Many of the VR
void4/FireVR. You can download Blender and use it for
demos built with UE4 are much more life-like and
free at blender.org.
smoother to navigation within. It provides great
performance with the conveniences of a modern editing
Googles SketchUp is a basic modelling application with a
environment. UE4 itself is also cross platform, but it
very low learning curve that can get anyone up and
exports to slightly fewer platforms than Unity does. Find
running in a short amount of time. The tutorials on the
out more about UE4 by visiting unrealengine.com.

Blender

Unreal Engine (UE4)

SketchUp

22 HTML5 & CSS3 Genius Guide

GearVRf
The GearVR framework (GearVRf) is an open source VR
rendering library for application development on
VR-supported Android devices. While many of the other
tools can export Android or iOS applications to use with
your phone, this is an Android native framework for
developing VR applications. You can dig into this one
more at gearvrf.org.

Three.js
This is a JavaScript library which works as a layer on top
of WebGL. It has many helpers and abstractions that
make working with WebGL much easier than the WebGL
API alone. WebGL is an OpenGL implementation within
modern browsers such as Chrome, Firefox, and Safari.
There are some excellent applications being developed
with Three.js which utilise 3D design to create anything
from fun demos, to multiplayer worlds and games.
Most WebVR implementations are built using Three.js
due to its ease of use and in part due to how popular
JavaScript has become. Doing 3D graphics in the
browser is hardly done without Three.js. Check out
github.com/borismus/webvr-boilerplate to get started.
Most browsers are still struggling with headset device
support, but theyre getting much closer to being
included in the main builds of modern browsers like

HTML5 & CSS3

Genius Guide

SceneVR
scenevr.com
With multiuser support, this metaverse is built on Three.js
and NodeJS, with its own HTML-like markup.

Sharing the VR
experience
Many apps are built with VR in mind anything
from video games, increasingly implementing VR
support, to desktop apps that enable you to have
a VR desktop. While much of the UX and usability
side of VR is being explored, many of these
applications are already extremely compelling.
A great place to start is the Oculus Share site,
with hundreds of games and demos for VR already
in the making, and thats just for the Oculus Rift.
There are many more being created for your
browser in WebVR, and for Android and iOS
devices in their respective app stores.
You can also check out some exploration into
journalism with VR. Theres a great piece created
for LA Times on graphics.latimes.com/marsgale-crater-how-we-did-it/ which was created in
WebGL for WebVR. You can experience this in VR
using your phone and Google Cardboard, or
simply go to the website graphics.latimes.com/
mars-gale-crater-vr.

www.fullengineeringbook.net

INSPIRIT

Quake 3

mozvr.com/projects/inspirit

media.tojicode.com/q3bsp

Based on Three.js, built in Blender, and utilising the Web


Audio API, this example of virtual reality will knock your
socks of.

This is a working version and level rendered of the game


Quake 3 in WebVR. You can check out its source here:
github.com/toji/webgl-quake3.

Chrome and Firefox. However, most phones can be


detected with github.com/borismus/webvr-polyfill and
if turned sideways, they can be switched to a dual display
mode that you can use with Google Cardboard,
Samsung VR, or other headsets that are built to be used
in conjunction with a smartphone.

JavaScript, and a subset CSS. This approach makes it


quicker for the web development community to get
involved and familiar with designing for VR. You can
create games like Puck-man (scenevr.com/ws/puckman.
scenevr.hosting/game.xml), or just import a model and
show it of to your friends.
Virtual environments built using SceneVR are even
somewhat compatible with our next tool, JanusVR. Try it
out at scenevr.com or, to read more, head over to docs.
scenevr.com.

Vizor.io
Vizor is an interesting take on a WebVR editor in your
browser built with NodeJS and Three.js. Its a visual
programming environment for WebGL, WebVR and
other HTML5 APIs. It features live preview, data flow
visualisation, network communication, publishing,
unlimited undo, and presets that can be used as modular
building blocks. Complex logic can be nested in
subgraphs and they can be rendered directly to a
specific render target, or simply used as a texture. Loops
are modelled as nested graphs that are evaluated once
per loop iteration. All within your browser. To give it a try,
head to vizor.io.

SceneVR
Scene is an open source platform built using WebGL and
Three.js for the client and NodeJS for the server side and
multiplayer component. With Scene you can create
virtual reality scenes using a simple HTML-like markup,

JanusVR
Janus is more like an actual web browser for VR than a
development tool. Its a platform in the way that SceneVR
is a platform, and while the client is closed source and
built in QT5, the server-side component is open source
and written in NodeJS. Janus has full Oculus Rift support
with avatars and some hand control via the leapmotion.
com Leap Motion controller. Virtual environments are
written in much the same way as a more traditional
website is created. An HTML-like syntax is used to set up
rooms with basic JavaScript support. As virtual
environments are just websites in Janus, you can serve
them up like a traditional site, using whatever server you
like, hosting it anywhere. Its distributed just like the web
of today.

Within Janus you can hit tab to create a portal to a


new website, in much the same way you enter an
address into your usual web browser. Click the portal and
walk through to a new website, or room. You can even
place the Janus markup inside a traditional website
within comment tags so that when you view the site with
a typical browser, you see your regular website with
parsed HTML, and Janus sees the 3D version. Janus lets
you edit the code of the room from directly within Janus,
and save.
This is one feature making Janus a popular option for
web developers to start the transition to building VR. It
even has built-in multi-user support so you can walk
around the internet with your friends, and talk to them
via the built-in voice chat support. Its a lot of fun and has
a very low learning curve, especially if youre already
familiar with web technologies.

HTML5 & CSS3 Genius Guide 23

Tips & Techniques


Creating a
mixed reality
HOW VR & AR COULD JOIN
FORCES FOR A NEW REALITY
Virtual reality consists of creating new worlds in which to
immerse yourself and others within. It replaces the real
world you see and feel around you with one created for
you. There are inherent problems with this when it
comes to locomotion its best experienced standing in
one place or sitting in a swivel chair so that the user is
not getting tangled in the cords, or bumping into
real-world objects. Most VR applications do not take into
account the actual physical surroundings of the user.
Augmented reality deals with creating overlays onto
the real world in order to enhance it in some way. AR
takes into account the world around you, letting you see
it and navigate within it but also changes it in ways to
JOSH CARPENTER (PRODUCT DESIGN LEAD ON THE MOZVR TEAM)
make it more useful or provide new experiences while
REVEALS HOW MOZILLA ARE BUILDING THE NEXT-GEN OPEN WEB
you interact with it. You can walk around with AR devices
untethered by cables. Theres typically a camera which
Q . What is the MozVR mission?
much more accessible for developers, thanks to new
you may see through, or perhaps light is projected
To help build the next great generation of the open web
developer tools like A-Frame and Vizor.
directly onto the retina to create pixels that appear to
by upgrading it for high-performance virtual
the user to be in the real world. This is the
reality and all forms of immersive
Firefox Nightly currently ofers support for Android.
area that products like MagicLeap
Liv
computing beyond. We believe it is the
Are there any plans to add iOS to the list?
(magicleap.com) are turning their
Erickson @
imperative of those of us who love the
Firefox for iOS is very new so its too soon to say how it
focus on.
misslivirose
open web to be proactive about
will evolve, but our team would love to see WebVR
Theyre fairly independent
This is the account for a VR & AR
extending it early into promising
running inside it eventually, as is the case with Firefox for
concepts but already were
developer at Microsoft who often
frontiers like VR, so that it is present
Android. In the meantime, the great thing about WebVR
looking for ways to make them
writes a lot about teaching VR &
for developers and users from day
is that it runs wherever WebGL is available. With WebGL
converge. Imagine a device that
AR as well as sharing her
one, and awesome.
could let you see and interact
experiences as she learns
with the real world until you want
more herself.
Who works on the MozVR team, how
to watch a movie with your friends
did it come together and how is it being
in VR. At that point it would simply take
funded?
up your entire field of view and provide a
Were a group of designers, engineers, and researchers
more virtual experience rather than augmented.
working from the ofice of the CTO, an organisation
The web is a concept that works with both, either by
WEBGL IS HARD. A-FRAME IS
within Mozilla that works to invent the next generation of
re-imaging webpages as virtual places you can interact
GOING TO CHANGE THAT
the web platform. Our team includes both full-time
with, or by overlaying information from the web onto
members such as myself and Vlad Vukicevic (co-creator
existing real world objects. The point is that the
of WebGL), and passionate volunteers who just want to
underlying network of the internet itself can be applied
WebGL is the backbone of todays WebVR. It has
work on something they believe in deeply. It was two of
to and can support both mediums in very useful ways.
amazing 3D performance and broad adoption. And
us to start with, and weve been expanding the team in
its going to get much faster in the coming year,
response to positive feedback.
thanks to new tech like WebGL 2 and shared
memory. That said, we love the accessibility of
For WebVR, designers, and developers need to
HTML and CSS. Its critical for the growth of WebVR
download the latest Firefox Nightly and Add-on. At
that as many people as possible can create VR
what stage of development is it currently at?
experiences, and HTML and CSS are much more
Setting the table. In 2015 our focus was establishing
widely known than WebGL. To make it easier for
critical baselines for performance and ease of use. By the
more people to create VR content, weve built
end of the year WebVR will be plug-and-play in Nightly
A-Frame, a library of building blocks for the VR
channels of Firefox desktop and Android. It will fully
Web that enable developers to create responsive
support the Oculus SDK. It will run at the native refresh
VR experiences with simple markup, no WebGL
rate of VR headsets, eliminating previous performance
knowledge required. Were very excited to ship it
Magic Leap is a company bringing the VR and AR
ceilings. It will be based on a new version of the WebVR
by the end of the year.
experience together
API that will enable link traversal in VR. And it will be

The countdown
to WebVR

www.fullengineeringbook.net
The easy way to
create for VR

24 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

Virtual reality consists of creating new


worlds in which to immerse yourself and
others within

enabled by default in iOS since version 8, developers can


create VR experiences for iPhones using solutions like
the WebVR Polyfill from Google engineer Boris Smus.
Which VR hardware is getting you excited?
All of it! Theres so much to choose from. Multiple
companies approaching the market from very diferent
angles means we have an amazing array of hardware
coming, from low-cost mobile solutions to high-end
room-scale rigs. I personally have a soft spot for the
Vives full-positional tracking and motion control. Mice
and keyboards are wonderfully eficient input devices,
but theyre kinesthetically constrained. I want to design
like how Jiro makes sushi, with fluid motion and freedom
of movement. The hardware for that is going be a reality
soon, and I cannot wait.

Finally, we are only at the beginning of what is a very


exciting future for the web. Where do you think
WebVR will be in 12 months time?
Youll put on your headset, and surf the web. Gliding from
link to link, into experiences that are worlds, not sites.
These experiences will satisfy new jobs to be done,
emphasising what is uniquely awesome about VR: awe,
immediacy, empathy, and so on. Youll still use your
phone and your laptop to book a flight. But youll preview
the destination in VR. Meanwhile, native VR will be
amazing, but WebVR will add an essential
complementary parallel. Lower friction, more content,
and truly connected with the rest of the digital world, not
just the other handful of people who own the same
headset as you. Were extremely excited about the next
12 months. Its going to get very, very interesting.

Essential VR
Resources
A COLLECTION THAT WILL
MAKE YOUR VR BETTER

Cardboard Design Lab


bit.ly/1X2cpU7
A set of intrinsic rules that you need to know
to be able to respect physiologically and
treat your users carefully. Google has
regrouped some of these principles in an
app so you can learn through this great
immersive experience.

WebVR Information
webvr.info
This is a convenient website that has lots of
links to information regarding the WebVR
specification, how to try it out, and how to
contribute to its formation. Its a great quick
stop for getting into the nitty gritty of the
idea behind WebVR and why.

www.fullengineeringbook.net

James
Deeley
Creative strategy director at Amaze
Virtual Reality has attracted a lot of excitement and
buzz recently. Yet, for it to be around for the long
term, brands are going to have to start getting
smarter in how they use it, particularly if it is to avoid
being another gimmick. We all expect VR to have a
big future in gaming, and in immersive brand and
retail experiences, but to reach the everyday it will
also need to ofer something for the home and
contribute to the way in which we live our lives today,
and also tomorrow.
The smart approach is to see VR as a part of a
wider technology evolution, all built around the

individual, connecting to an ecosystem of devices, cloud


platforms and intelligent spaces.
This mixed reality will blend virtual reality with
augmented reality, ambient and in-store technology and
wearable devices.
We know that the next wave will move VR on from
being just a headset experience and extend it into the
wider environment. This might be via the use of gloves,
sensors and connected devices, afecting the way we
interact and control our involvement, and that
development has a real purpose beyond just the wow
factor.
The next leap forward will be to make the VR
world live using it to experience live events, to control
perspectives and go deep inside stories and experiences.
Then finally, VR will make it into the home. Like all truly
vital technology, for VR to grow and become part of our
everyday it needs to start to disappear, to be so simple to
use and so beneficial that we dont think twice about it.

3D User Interfaces: Theory


and Practice
bit.ly/1T3aBV7
This book addresses the critical area of 3D
user interface design a field that seeks to
answer detailed questions that make the
difference between a 3D system that is
usable and efficient and conversely, one that
causes user frustration, errors, and even
physical discomfort.

Oculus Developer Center


developer.oculus.com
Signing up for an account here can give you
access to the developer forums which
contain tons of nuggets of information and
discussion about VR, best practices, and
shared experiences by other VR developers.

HTML5 & CSS3 Genius Guide 25

Tips & Techniques

Integrate payments
with the Stripe API
Learn how to develop a custom Stripe form into
an online web store and handle the Stripe API
with Node.js
E-Commerce is huge, and everywhere, no
retailer from before the time of the web hasnt
either felt its impact or been gobbled up by
web-born goliaths that have adopted their business
models for the internet era. E-commerce is also hard,
sure, you pay for things online all of the time, but the
credit card details arent going straight from us to the
service youre paying, often a payment gateway service is
used somewhere along the line to process your credit
card and pass along the information to the retailer that
you just made a purchase from.
If youre the owner of a small web store, or just want to
take payments for some reason or another on your own
website, integrating with one of these payment gateways
can be tough and complicated.
Fortunately for us, theres Stripe, a simple but powerful
API that allows us to process and receive monies from
card payments without too much hassle. In this tutorial,
youre going to take a demo web-store and implement
Stripe.js and the Stripe API into it.

the project resources. Enter code/start and then


run npm install to begin installing the Stripe
Node.js library

1. Get a Stripe account

5. A home for the JavaScript

Before you kick this project of, youre going to need to


get ourselves a Stripe account. Head on over to
dashboard.stripe.com/register and follow the on-screen
instructions in order to get a Stripe account set up. Once
youve received a confirmation email from Stripe come
back here.

All of the code that the store uses to keep a track of an


order is in the storeUI.js file in the scripts folder. You dont
need to do anything with this, its a helper library for the
store, but you do need to initialise it, and you need a
place to do that from. Add the following just after where
you import the storeUI.js file into index.html and then
open core.js for editing.

4. Get the Stripe JS library


Using Stripe has been made even simpler by the
lovely developers over at Stripe who have put
together a ton of neat libraries for us to use. Youre
going to grab the Stripe.js library that will let us
build whats known as a custom forms which is a
form like any other, but with Stripe integrated into it.
Open index.html and just after where you import jQuery
at the bottom of the HTML document add:

www.fullengineeringbook.net
<script src="https://code.jquery.com/
jquery-1.11.3.min.js"></script>
<!-- Add this -->
<script type="text/javascript" src="https://
js.stripe.com/v2/"></script>
<!-- -->
<script src="scripts/storeUI.js"></script>

7. Find the publishable Stripe key

In order to interact with the Stripe API, you need to get


whats called the publishable key. By including this key
with each request you make to Stripe, the API can
identify us and handle payments appropriately. You can
find your publishable keys at dashboard.stripe.com/
account/apikeys. Use the TEST key for this tutorial and
never share your secret keys with anyone.

8. Back to core.js

2. Grab the project resources


Were not going to build a web store from scratch
because thats not what this tutorial is about. In the
FileSilo resources for this project, there is a prebuilt web
store with all of the things you need to handle a basic
ordering process. Download the demo files and move
them into a folder of your choosing, keeping the
directory structure intact.

3. Install Node.js dependancies


Now go ahead and open up terminal (or command
prompt if youre on Windows) and you will need to
change directory to the location where you just stored all

26 HTML5 & CSS3 Genius Guide

Once youve got your TEST publishable Stripe key, head


back to core.js and just after where you initialised the
store events, add Stripe.setPublishableKey();

function init(){
store = new store_events;
Stripe.setPublishableKey('YOUR_TEST_
PUBLISHABLE_STRIPE_KEY');
}

<script src="scripts/core.js"></script

9. Create a card payment form


6. Initialise the store
Our demo store is made up of a couple of forms and
inventory items. You dont want to concern ourselves
with binding events and handling callbacks in core.js, so
all of the logic is in storeUI.js - but it hasnt been initialised
yet. In the init() function of your core.js file add the
following code:

function init(){
store = new store_events;
}
This will create all of the event listeners youll need.

You may have noticed that although you have some


code to make a shopping cart, you dont have any
markup to take the users card details when they try to
checkout. Lets do that now. In index.html, just after the
<button> element with the id of false_purchase add the
following markup to your code:

<div id="card_creds" data-display="false">


<div class="container">
<h3>Please enter your card details</h3>

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

<label>
<span>Card Number</span>
<input type="text" size="20" />
</label>
<label>
<span>CVC</span>
<input type="text" size="4" />
</label>
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" />
<span> / </span>
<input type="text" size="4" />
</label>
<input type="submit" value="Pay" />
</div>
</div>

</label>
<label>
<span>CVC</span>
<input type="text" size="4" datastripe="cvc"/>
</label>
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" datastripe="exp-month"/>
<span> / </span>
<input type="text" size="4" datastripe="exp-year"/>
</label>
<input type="submit" value="Pay" />
</div>
</div>

10. Work with data-stripe


Right now, the #card_creds form doesnt do anything
special with Stripe. In order to make Stripe recognise the
form, you need to add data-stripe attributes to the
elements that contain specific parts of the cards details
so that they can be passed on to Stripe.
For the credit card number you add datastripe=number to the input where you expect the user
to add the card number, for the CVC (3 numbers on the
back of the card) you add data-stripe=cvc and so on
and so forth.

11. Set users security and liability


Using the data-stripe attributes allows Stripe to strip out
all sensitive data about the user before it ever hits the
server. Cyber-crime is on the rise and you cant all aford
to have a security team working to ensure that all of the
servers are impenetrable. By allowing Stripe to take
sensitive payment data of of our hands before it ever
hits the server, you never have to worry about the
security of the users or the liability if ever you were to
have a data breach.

processed. Once those details have been validated a


one-time-use token will be returned to us. To test the
code out, you can use any of the card details from stripe.
com/docs/testing, so long as youre using the TEST
publishable API key.

order_form.addEventListener('submit',
function(){
Stripe.card.createToken(order_form,
function(status, res){
if(status !== 200){
alert("Something went wrong. Sorry");
order_form.reset();
}
else
{
submitOrder(res.id, function(response){
store.closeForm();
store.showReceipt
(response.thingsBought);
});
}
});
});

13. The order token


We dont want the users card details to go anywhere
near the server because that opens up to a world of
potential trouble (see the Why tokens? boxout), but how
is a payment processed? Simple, you can use the token
you just received in the response from the Stripe API.
Along with the customers order, you send the order

www.fullengineeringbook.net
<div id="card_creds" data-display="false">

12. Test the cart


<div class="container">
<h3>Please enter your card details</h3>
<label>
<span>Card Number</span>
<input type="text" size="20" datastripe="number"/>

Right now, if you add some items to the cart and enter
your card details into the form, the page will reload. you
need to prevent the submit event and work some AJAX
magic with Stripe to get the card details of in a usable
way. Add the following code to the addEvents function
of core.js. Using the Stripe.js library, send of the card
details the user has entered to the Stripe API to be

Store keys
Instead of switching keys every time you want to
deploy to your production environment, save
them as environment variables. One for your
development and one for your live platforms.

Left

Once our order has completed and our payment


accepted, our store will generate an itemised receipt for
our customer
Top left

We dont want to build a whole store, we wouldnt have


enough time to talk about Stripe! This tutorial comes with
a demo store to get us on our feet quickly
Top right

The Stripe API gives us a bunch of keys to use when


accessing its API. You use the test key in this example so it
doesnt cost us any money, but you have to switch it over
when you go live!

HTML5 & CSS3 Genius Guide 27

Tips & Techniques


token to the own server, where you can request Stripe
deduct a credit from the users balance. Before you do
that, you need to sort out the customers order.

product-id'),
price : thisItem.getAttribute('data-price')
});

14. Tally up the order

payload.total += parseInt(thisItem.
getAttribute('data-price'));
}}

item purchased by the customer and returns an


organised list.

17. Parse the request


Before you send to the order to the server, you need to
create a payload describing what they actually ordered
that you can process server-side. In the empty
submitOrder function of core.js add the following. First, it
takes all of the items out of the cart and puts them into
an array, then it gets the price of those items and creates
a total in pence (assuming youre using GBP) which you
will ultimately charge to the user. This isnt the most
tamper-proof way of calculating price, but its good for
demoing the power of Stripe.

function submitOrder(){
if(token === undefined){ throw "No Stripe
card token has been passed"; }
var items = document.
getElementById('purchase_list').
getElementsByTagName('li');
payload = { items : [], total : 0 };
for(var g = 0; g < items.length; g += 1){
var thisItem = items[g];

15. Send the order to the server


Now that you have the payload containing the total price
and the items in the cart, as well as the stripe token weve
acquired, its time to send it to the server. you can do this
using a good ol fashioned jQuery AJAX request. Add the
following code just after the last bit of code you added to
submitOrder();

jQuery.ajax({
type : "POST",
url : window.location.origin + "/order",
data : {
order : payload,
stripe_token : token
},
success : callback,
error : function(err){
console.log(err);
},
dataType : "json"
}
)
;

On lines 71 and 72 of stripeServer.js,, parse the body of


the AJAX request sent to the server to retrieve the order
payload and Stripe token for the customer. Now that you
have a Stripe token, you can charge the customers card
(stored on the Stripe servers) using this token. you do
this with stripe.charges.create(); This function takes two
arguments. An option argument, which needs to contain
the amount of monies being charged (in pennies, a
currency and a payment source (our card token). The
second argument is a callback to handle the response
from the Stripe API.

stripe.charges.create
({
amount: price,
currency: "gbp",
source: card_token,
description: "Customer cheese order"
}, ...

18. Handle the Stripe response


If something goes wrong, Stripe will pass an error back to
the server, but if there is no error, everything has gone
great, youve been paid! (although it may take up to 7
days for you to receive the money); Now you need to
inform the user, which you do here with res.json. Its at
this point that you would write logic to set up a delivery
or store the order in a database somewhere or maybe
send a confirmation email, but that implementation is up
to you and your (or your customers) needs.

www.fullengineeringbook.net

payload.items.push({
productID : thisItem.getAttribute('data-

All in the platform

16. Receive the order

If you want put your store in an app, you dont


have to change much. Stripe has libraries for iOS
and Android. If youre running a Cordova app,
use the same process, but whitelist stripe.com.

In the root of your project folder, open stripeServer.js. On


lines 69-100 define a single endpoint, /order. This is
where you will handle the data that has been sent from
the demo store. On lines 37-67 you will have the
sortOrder function which tallies up the amount of each

Top left

Each item in the cart has data-attributes on the element


that keep a track of that items price and product
reference. When you send this information, it would be
prudent to check that the total sent is equivalent to the
produce selected
Top right

Once the order has been processed, send the client an


object that contains an itemised list of the products you
bought. This lets you know for certain the exact quantity
of produce purchased by the server
Right

When youre testing the code out, you dont want to be


using actual card details, what if you charge yourself
1,000,000 by accident. Stripe provides test details that
will work with your test publishable key

28 HTML5 & CSS3 Genius Guide

... function(err, charge)


{
if (err && err.type === 'StripeCardError')
{

HTML5 & CSS3

Genius Guide

Why tokens?
So why are you using tokens
instead of just handling card
details ourselves? Surely you can
better look after our own
customers data? Well, no.
Security is hard, no matter how
hard you, as an individual try, its
unlike youll ever be able to
match the strength of security
ofered by an enterprise-level
payments platform. Stripes job
is to keep their API running and
their data safe, your job is to sell
delicious cheeses. Let these
guys take on the card stuf, its
what theyre really good at. On a
side note, say you do store card
details on your service and you
get hacked, youre liable for that
datas security, not only does it
suck being hacked, but if the
data was stored poorly, you may
be subject to legal action from
your customers. Ouch. Is it
worth it?

res.set(500);
res.json({
status : "ERR",
message : "Something has gone horribly
wrong"
});
}
else
{
res.json({
status : "OK",
thingsBought : itemisedItems
});
}
});

confirmed by Stripe the Node server sends a JSONencoded itemised list in its response. the helper library
thats been handling all of the store logic kicks in here
again. Once that the confirmation has finally been
received, it will reset and close the card details overlay
and if you pass the itemised list that the server sends
back, then it will generate a receipt to show the customer
what they have ordered. This will happen in the callback
you passed as part of the submitOrder function call, as
we have shown below:

Detecting fraud
Stripe uses machine learning algorithms to
detect potential fraudulent purchases. If you
know a payment was genuine you can tell Stripe
and theyll process the payment.

www.fullengineeringbook.net
submitOrder(res.id, function(response)
{
store.closeForm();
store.showReceipt(response.thingsBought);

20. Square one


19. Generate a receipt
On the client-side, the form will still be waiting for a
response from the server. Once payment has been

So thats the order process complete. Now you can show


the customer what theyve ordered and then you can let
them continue on their way. In this case, you can now

reset everything when they close the receipt dialog, but


on a real store, we would let them browse around the
website or you can even view all of their orders in a
dashboard somewhere if thats what you want.

21. Prime time


When youre ready to take your new web store live, dont
forget to change the TEST publishable API key to the
LIVE one. Otherwise, all of the orders that you end up
taking wont actually charge the people for any of the
purchases that they make, regardless of the validity of
their payment method.

Remembering your
customers
In this tutorial, you generate a token for
each purchase you want to make, and
seeing as the tokens are single-use only, it
means that wed have to get the user to
enter their card details every single time
they want to buy something. That is going
to become a frustration for them very
quickly. So, how do you store card details
for the customer without storing card
details? The Stripe API allows you to create a
Customer object that you can associate
with card details by passing in the charge
token before you process a payment.
Though you can only use this token once to
make a charge, you can access the
customer any time you like and make a
charge to them without them ever having to
make a payment.

HTML5 & CSS3 Genius Guide 29

Tips & Techniques

Master responsive
image techniques
Learn how to use <picture> and srcset, and bring art direction
to responsive images

www.fullengineeringbook.net

30 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Ever since responsive web design became a


thing designers and developers have been
looking for better tools to manage imagery
across many diferent clients and viewports. With the
advent of the srcset attribute and picture elements, this is
now achievable in modern browsers and responsive
images are even starting to become possible on mobile
devices, with Android 4.4.4 ofering good native support.
For aging browsers, Scott Jehls picturefill JavaScript
polyfill can be used to plaster over the cracks although
network performance will still be an issue.
The pinnacle of this new feature set from HTML5 is the
picture element, enabling creative teams finite control of
how images are presented to their web browser
creative teams are finally able to give art direction on a
per-client basis. This can be something that works as
simple as serving diferent aspect ratios to mobile
devices, to serving entirely diferent image compositions
for diferent viewports.
This tutorial will walk you through the process of
crafting flexible images the old way, image swapping
using srcset for diferent viewports and display
capabilities, fully responsive images using picture, using
picturefill the right way, and finally bringing all of these
components together to produce an interactive demo
that exploits the best that a picture has to ofer. Maximise
your online real estate now.

2. Basic responsive images


Responsive images will need to shrink with their
containers. The code that were using below is a bit
counter-intuitive because it suggests that it just limits the
width of the image, but in efect it implies the image
should be flexible in its width. These images are really
flexible rather than responsive.

img
{
max-width: 100%;
}

3. Change resolutions with srcset


Modern browsers can make use of the srcset attribute
that enables the browser to make a decision with regards
to what image to actually display. The width specified
after each additional image path corresponds to the
width of the image.

<img src="small.jpg"
alt="text for screen readers"
srcset="medium.jpg 600w,
large.jpg 1200w" />

4. See srcset in action


Heres a basic implementation of srcset on jsfiddle as a
live demo (jsfiddle.net/aqx9aoat). The browser has
chosen to display the 500px width image rather than the
initial 1000px one. The browser is choosing which image
to pick by itself here.

<img src="small.jpg"
alt="text for screen readers"
srcset="medium.jpg 500w,
large.jpg 800w"
sizes="66vw" />

6. Responsive srcset behavior


The sizes attribute also takes media queries, which allows
developers to change the behaviour of images
depending on the viewport. Here, 66vw is used
whenever the viewport is wider than 499px, otherwise
the image will display with 100vw.

<img src="small.jpg"
alt="text for screen readers"
srcset="medium.jpg 600w,
large.jpg 1200w"
sizes="(min-width: 500px) 66vw,
100vw"
/>

7. Retina support with srcset


Srcset enables developers to specify the use of hi-DPI
imagery via the x descriptor. Unfortunately though,
images with the x descriptor are fixed-width only (not
flexible), which limits their usefulness. This is something
that prove to be handy for making hi-res cropped
background efects, however.

www.fullengineeringbook.net

1. Basic image markup

Marking up a standard image hasnt changed for a long


time. The src attribute specifies the location of the image.
The alt attribute is for supporting text that should be
useful if the image cant be found, or for the visually
impaired who use screen readers.

<img src="image.jpg"
alt="text for screen readers" />

5. Control srcset behaviour

Use calc in sizes

The sizes attribute can enable developers to control the


amount of screen real estate the image will take up. The
example code shown specifies that the image will take
up 66 per cent of the viewport width as opposed to the
preset value of 100vw.

The sizes attribute allows for using calc() just like


CSS. This enables us to have finite control that
wouldnt be possible otherwise, like calc(100vw
40px). Its handy for keeping gutters on images.

Top left

When the user increases the width of their viewport, the


browser loads the 800px version as itll be less stretched
Top right

The browser has to decide which image to display based


on the information provided which, in this example, is just
the width descriptor
Left

Due to the small viewport on page load the browser has


chosen to load the 500px wide image, as its smaller in
dimensions and file size

HTML5 & CSS3 Genius Guide 31

Tips & Techniques


<img src="image.jpg"
alt="alt text"
srcset="imageRetina.jpg 2x,
hiDPI.jpg 3x"
/>

8. Responsive art direction


The picture element enables developers to specify
multiple source elements and a fallback img, enabling
media queries to be applied to each. The code shown
below swaps out widescreen images for square ones
as this will be a better aspect ratio for mobile at a
499px wide viewport.

<picture>
<source
media="(min-width: 500px)"
srcset="wideLarge.jpg 800w,
wideMedium.jpg 500w" />
<source
srcset="squareLarge.jpg 800w,
squareMedium.jpg 500w" />
<img src="fallback.jpg" alt="" />
</picture>

9. Style picture elements


This may also appear to be counter-intuitive, but the
picture element cant exactly be styled in the same way

as an image. The picture simply wraps an image, passing


the right image path for any given media to the image
element. Flexible images are also possible within picture
elements, but they will first need to be marked up like the
code as shown below:

picture img
{
max-width: 100%;
}

10. Starting markup


Earlier on, this tutorial briefly covered Retina image
support using srcset and explained that Retina support
only worked for fixed-width images. Picture can provide
us with a way around that problem by making use of the
media attribute. As you can see in the code below:
catering for wide devices first, the fallback.jpg file will now
be replaced with wide1200.png.

<picture class="album">
<source
media="(min-width: 801px)"
srcset="wide1200.png 1200w" />
<!-- ... -->
<img src="fallback.jpg" alt="" />
</picture>

11. Responsive Retina images

wide800-2x.jpg 2x" />

12. Markup for responsive


This final source caters for the smallest viewports and
implements the same technique as the one in Step 11.
The downside to using this approach is that a lot of
markup is needed for one responsive image each
version will require its own source tag as well as a set of
media queries.

<source
media="(max-width: 500px)"
srcset="square500.png 500w,
square500-2x.jpg 2x" />

13. Style picture elements


Picture elements are essentially glorified spans a
display:block later and youre able to add whatever styles
that you want. The code shown below uses calc and
margin to add gutters to the picture, as well as show a
nice box shadow.

.album {
display: block;
width: calc(100% 40px);
margin: 0 auto;
box-shadow: #A39A9A 0 0 30px;
position: relative;
}

www.fullengineeringbook.net

Comment sources
With so many diferent sources required for each
responsive image being implemented, it pays
dividends to write HTML comments to help keep
track of the images being sourced.

Top left

This client gets the wide image. We could have supplied a


2x variant as part of this step as a lot of modern clients
are on 2x plus displays
Top right

Widescreen images on mobile viewports can get very


small when scaled proportionately. The picture element
allows us to serve a cropped image
Right

The medium Retina image should be served to higher-end


tablet devices with Retina or hi-DPI displays, like Apples
iPad, when they eventually support it

32 HTML5 & CSS3 Genius Guide

In this additional source the media attribute specifies that


these images are only to apply to viewports between
501px and 800px. Srcset will then load the image that is
found to be the most suitable to the client with either the
1x or 2x versions of wide800.

<source
media="(max-width: 800px) and (minwidth:501px)"
srcset="wide800.png 800w,

14. Extended picture styling

Because the picture element behaves like a regular span,


the element can be extended with :before and :after in
CSS to apply efects over the top of images. Below this, a
gradient is overlaid the image. View the full source of this
demo on FileSilo.

.album:before
{

HTML5 & CSS3

Genius Guide

Picture explained
The ultimate goal behind
using things like srcset,
picture, sizes, source, and
media is to enable
designers and developers
to deliver the best possible
image for a given
environment, rather than
have a one-size-fits-all
image that scales
proportionately but will
look completely terrible at
the extreme ends of
viewport sizes.
Picture allows the build
team finite control over
what, how, and when any
given variant of an image
displays. Each source can
have a media attribute. Its
the media attribute that
controls when a source
should be used via a media
query. The srcset attribute
is then left to simply list out
the available variants for
the image in question
either in width descriptors
(eg 250w) or DPI
descriptors (eg 2x).

The ultimate goal is [...] to deliver the best


www.fullengineeringbook.net
possible image for a given environment
content: '';
position: absolute;
width: 100%;
height: 100%;
background:linear-gradient(...);
}

15. Image styling


Picture essentially progressively enhances img elements.
CSS can still target the image, just as if its inside a regular
container. Images inside picture elements are available
for styling just like any other image.

picture img {
border-radius: 3px;
}
picture {
border-radius: 3px;
}

16. Add interactions


The process of adding interactions to picture elements is
slightly diferent. Binding hover to the picture element
ensures the hover will work as intended. However, the
visual feedback still needs to happen on the image, so
thats where styles should be applied.

picture:hover img {
opacity: 0.5;
cursor: pointer;
}

17. Add filters


With filters coming to CSS, developers are able to apply
filter efects to DOM elements this includes picture

element images. The contrast of the image is slightly


bumped with this filter. Naturally these filters can be
applied on a per-media-query basis.

picture img {
-webkit-filter: contrast(1.25);
}

{
display: flex;
align-items: center;
justify-content: center;
}

20. Picture polyfill


18. Centre everything
The first part of centring the image is to have the
container (in this case, the page body) fill the entire
viewport. This is easily achieved using absolute
positioning and resetting any margins/padding to 0.

body
{
margin: 0;
padding:0;
position: absolute;
height: 100%;
width: 100%;
background-color: #E1E4E2;
}

19. Vertical centre


Flexbox can easily be used to vertically centre content of
variable height. Align-items will vertically centre child
elements, and justify-content horizontally will centre
them. Try playing around with these in dev tools to see
how they behave.

body

Scott Jehl has led the development of a polyfill for the


Picture element called picturefill. Why not head over to
GitHub (github.com/scottjehl/picturefill/releases) right
now, in order to download the latest release and try it out
for yourself.

21. Use picturefill


Like most polyfills, using picturefill is very straightforward.
First, make sure that you reference the script in the head
of the page the async attribute is optional but its
beneficial for performance. Also you should create the
element for any browsers that dont support HTML5
but bare in mind that this isnt a required step if HTML5
shiv is already present.

<head>
<script>
// Picture element HTML5 shiv
document.createElement( "picture" );
</script>
<script src="picturefill.js" async>
</script>
</head>

HTML5 & CSS3 Genius Guide 33

Tips & Techniques

Create animated
infographics with
Snap.svg

Take a static graphic and add


interactivity and animation to create an
exploded-view infographic

www.fullengineeringbook.net

34 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

In the new responsive web world that


designers have to inhabit, sizing graphics is of
the utmost importance to us as web designers.
Getting crisp graphics on both a phone and on a huge
cinema display monitor is not just desirable, but essential.
To that end most of us have switched to using SVG
images for our icons and line art drawings, which are
always crisp on every display. Not only that but the file
size is often much smaller than a PNG image. When it
comes to creating animated images or interaction with
graphically rich content we will need a solution that can
help us do this too. Thankfully Snap.svg comes to the
rescue because it lets us use crisp SVG graphics but also
adds the polish that clients have come to love for their
shiny web apps.
In this tutorial we are going to use Snap.svg to create
one of those exploded-view images that you would find
in Haynes car manuals but were going to dissect a
mobile app. Well take a regular SVG created in Illustrator
and add animations to this, then make some of the
buttons on the interface work. These will drop pins onto a
map and slide an of-canvas menu onto the screen. This
provides a great introduction into how you can make
your own graphically rich applications using Snap.svg.

centred on the page and a background image is placed


in there so that all the vector lines and shapes have a
background to stand out against.

<style>
svg{
display: block;
margin: 0 auto;
background-image: url(bg.jpg);
}
</style>

3. Start up Snap.svg
After the CSS styling in the head section, script tags are
added with an onload function that detects if the page
has finished loading. Once the page has been loaded up,
two variables will be declared. One of these variables will
hold a timer that waits a fraction of a second before
starting the animation and another variable holds the
Snap SVG file.

<script>
window.onload = function () {
var timer;
var s = Snap(1280, 800);
};
</script>

1. Start the project


4. Load an SVG file

5. Reference individual graphics


Once the scene has finished loading up, we will need to
do an important part of the tutorial we need to
reference individual graphic elements so that they can
be animated or interacted with on the page. Here the
variables will reference unique IDs and these IDs are the
ones that youd find on any regular HTML tag. They will
be stored in a variable to be used later on.

var menu = f.select("#menu"),


pin = f.select("#pin"),
chatPin = f.select("#chatPin"),
thumb = f.select("#thumb"),
disc = f.select("#disc"),

6. More references
Notice that each line of the code shown below has the
variable that is then followed by the letter f. If you take a
look at Step 4s code, you will notice that the f included
there appears inside the brackets of the function, and all
of this code is in that function. The letter f simply stands
for file and it is a reference to the SVG file that we had set
to load from before.

header = f.select("#header"),
icons = f.select("#icons"),
base = f.select("#base"),
baseText = f.select("#baseText"),

www.fullengineeringbook.net

To start of the project, take the tutorial files from FileSilo


and open the Start folder in a code editor such as
Brackets. In the head section of the index.html page add
a link as shown to the Snap.svg library. You can also
download the library from snapsvg.io for reference.

<script src="js/snap.svg-min.js"></script>

2. Style the SVG element


Just after the Snap code library has been imported, the
CSS styling for the SVG element is set. This is displayed,

Before the closing bracket of the onload function in the


previous step, add the code shown here. This tells snap
to load the scene.svg file. Notice the comment that states
the tutorial code goes here this is where the rest of the
tutorial code will go. Because once the SVG is loaded, the
code between the curly brackets is called.

Coding Snap.svg
Snap.svg uses JavaScript to manipulate the still
SVG images that you import into it. The code
adds animation and interactivity to the graphics
for a rich user experience.

Snap.load("scene.svg", function(f) {
//TUTORIAL CODE GOES HERE
});

Left

In Illustrator you can see all of the graphics named in the


layers panel, so make sure that you open up the layer to
see the names In the background of the SVG element, a
background image has been added through CSS
Top left

In the background of the SVG element, a background


image has been added through CSS
Top right

After loading the graphic it is displayed over the top of the


background image, but still needs a little work

HTML5 & CSS3 Genius Guide 35

Tips & Techniques


7. Last graphic references
Here the last references are stored in variables and you
may be wondering where exactly these names came
from or how they got in the SVG file. When graphics are
grouped together in Illustrator, they can be named in the
layer panel, these names are applied as IDs when
exported into SVG.

map = f.select("#map"),
people = f.select("#peopleBtn"),
chat = f.select("#chatBtn"),
burger = f.select("#burgerBtn");

8. Display the SVG on the page


The next line of code is quite an important line because
this line displays the graphic on the screen. If you
remember that s is the Snap reference, then append
means to add to that, so we use the reference of f which
is the SVG file. Save the page now and hit the live
preview in Brackets or view the page from a server to
see the graphic.

s.append(f);

9. Clean up the graphic


At present there are some pins floating in space and a
menu that is obstructing the way of the main graphic.
These will be important to us later but for now lets make
them invisible. Place the code here, just before the line

we added in Step 8 as this efect should be applied


before the image is displayed.

menu.attr({ opacity:0 });


pin.attr({ opacity:0 });
chatPin.attr({ opacity:0 });

10. Hide hit areas of buttons


You can refresh the browser now and see the updates to
the graphic from the previous step. There are some hit
areas for buttons to hide the button icons, so those will
need to be made invisible as well. Add this code that
weve provided below immediately after the code from
the last step.

people.attr({ opacity:0 });


chat.attr({ opacity:0 });
burger.attr({ opacity:0 });

11. Leave a pause


Once the graphic is on the screen, the animation is ready
to be applied but it should wait a little before starting
this is so that the user can see the graphic, then see it as
it moves into position. Add the code here after the s.
append(f); from Step 8. This code will set a timer to wait
for 300 milliseconds.

timer = setTimeout(designIn, 300);


function designIn() {
clearTimeout(timer);

thumb.animate( {transform: "t0,-160"},1500,


mina.backout );
disc.animate({transform: "t0,-150"},1100,
mina.backout);
header.animate({transform: "t0,-130"},850,
mina.backout);
icons.animate({transform: "t0,-100"},550,
mina.backout);
}

13. More animation


The graphics that are at the bottom of the app will also
need to be animated, and so does the map in the
background. Add the following lines of code before the
closing bracket that we showed you in the previous step.
Now just save the file and view it in your browser to see
all the elements animate into position on the screen.

baseText.animate({transform: "t0,-130"},850,
mina.backout);
base.animate({transform: "t0,-100"},550,
mina.backout);
map.animate({transform: "t0,-70"},450, mina.
backout);

14. Move the thumb icon


As it stands, the animation stops moving but it would be
good if we could make the thumb continuously bob
about in the graphic. Go back to the code added in Step
12 and amend the thumb code as shown. This will call
another function thumbUp when it has finished.

www.fullengineeringbook.net
12. Animate the graphics

Animating scale
If you want to animate the scale of an image,
then SVG is the perfect graphic to scale as it is a
vector and it can be blown up in size without any
loss of quality.

Top left

A little tidy up is required as some graphics arent needed


until animation is applied to other elements
Top right

The first graphic elements are animated into position,


showing an exploded view of an app
Right

Interactivity is added to the other icon but there needs to


be a way to reset this so the icon goes away again

36 HTML5 & CSS3 Genius Guide

Add the code to finish the function from the previous


step. These graphics are animated with a slight bounce
to get them into the position we want. The t inside the
transform means that they are transformed relatively
from their current position. The timing of each is placed
after this. Then just hit Save and view it in the browser to
see the animation.

thumb.animate( {transform: "t0,-160"},1600,


mina.backout, function(){thumbUp()} );

15. Move the thumb up


The thumbUp function is added here and it needs to go
just below the closing bracket of the designIn function.

HTML5 & CSS3

Genius Guide

Other ways to use


Snap.svg
Snap.svg is great at
manipulating pre-made
SVG images but it is also
great at creating content
from scratch, perfect for
making basic geometric
shapes like circles or
rectangles. There is a
great tutorial on this at the
Snap.svg site snapsvg.io,
but there are also some
other great examples at
websites like svg.dabbles.
info that help to fill in
some blanks in working
with Snap.svg. Of course
the perfect match for
graphics is to create some
graphics in your favourite
vector illustration
program, then add to it by
creating dynamic masks
with shapes in Snap.svg.
An excellent example of
this is the Cofee Maker
demo that comes when
you download the source
code of Snap.svg, but bare
in mind that this is a very
advanced application!

www.fullengineeringbook.net

This thumbUp function is called after the thumb has


moved into position and it moves it up a little higher with
easing so that it slowly builds up speed and then
subsequently slows down again.

function thumbUp()
{
thumb.animate( {transform: "t0,-210"},800,
mina.easeinout, function() {thumbDown()} );

into the graphic and bounce onto the map. The pin was
made invisible in Step 9. Save your code and view it in a
browser to test the click.

popcorn.cue( 17.2, people.click(function ()


{
pin.animate({opacity:1, transform:
"t0,280"},900, mina.backout);
});

16. Move back again


Once the thumb has moved up, it calls the function
thumbDown so now we will add that function below.
Again this moves the thumb down and calls the
thumbUp function that keeps the thumb bobbing up
and down in a loop. Now just save this and view it in the
browser, as we have done previously, to see the
animation in action.

function thumbDown()
{
thumb.animate( {transform: "t0,-160"},800,
mina.easeinout, function(){thumbUp()} );
}

Similar to the previous step, if the user clicks on the chat


icon, the chat pin should drop onto the map and show
the location of the chat. The code adds this on-click
animation, and once this is done you can save the page
and view it in a browser to test that the click is working.

chat.click(function () {
chatPin.animate({opacity:1, transform:
"t0,280"},900, mina.backout);
});

Right back at the start there was a menu that was made
invisible. Now lets make the burger icon a button that
can be clicked and this will bring the of-canvas menu
into the app. Add this code below, which will animate this
onto the screen. Then save this and try clicking the icon
in the browser.

burger.click(function () {
menu.animate({opacity:1, transform:
"t150,-70"},900, mina.backout);
});

19. Reset the pins


When the user clicks either of the icons and the pins
drop into position, they will stay there. Its possible to only
show one at a time by making the first pin animate back
of when the other icon is pressed. Just add this line of
code to the click function of Step 17 to do exactly that.

chatPin.animate({opacity:0, transform:
"t0,0"},900, mina.backin);

17. Add interactivity


Its time to make the graphic interactive now. Adding the
next set of code will make the icon of the person a
button. Clicking on this button will make the pin animate

pin.animate({opacity:0, transform:
"t0,0"},900, mina.backin);

21. Bring in the menu


18. Click the chat icon

disappear when the other icon has been clicked. This is a


simple solution for what we wanted to achieve so save
this, then just test this in the browser and only one pin
will display at a time.

20. Adjust the second pin


As in the previous step, the code here needs adding to
the click function in Step 19. This will make the first pin

22. Remove the menu


To get rid of the menu, it is as easy as letting the user
click on the actual menu itself. Adding the following code
will animate it back to the original position, while also
taking the opacity down and making the menu invisible.
Save this and view again in the browser to see and test
all the functionality.

menu.click(function () {
menu.animate({opacity:0, transform:
"t0,0"},900, mina.backin);
});

HTML5 & CSS3 Genius Guide 37

Tips & Techniques

Build with
AngularJS

5 best
libraries
and tools

Learn everything you need to know to start building


web apps with the framework
Lodash

Start building
START WITH THE DATA, FIND APIS, READ THE DATA THAT THEY PROVIDE
AND THATLL GIVE YOU IDEAS

Structuring your app


Package managers can simplify the finding,
Organising an app is tricky in the beginning. AngularJS
downloading and updating process of app
allows for complete flexibility which also means that you
dependencies, and theres no good reason not
have to figure out the best way. Think about it as
to use them. You can install AngularJS with NPM, the
something organic that can be modified down the line
Node package manager, or with the help of Bower.
and grow and change with your app.
You might find that some packages that you want are
Start of by putting all your files in the main directory
not on NPM however it is the most reliable manager for
and create a new subdirectory to group files together as
you to use. Bower can be slightly less reliable but it does
you progress.
benefit from there being more front-end packages
Its better to structure your app in folders by feature
available, as well as its use of a flat dependency tree, so
rather than by type (for example as services, controllers,
you are probably better of with using it as a manager
templates and so on). That way its easier to locate your
over NPM.
code quickly, keep a flat structure, and stay DRY
Remember to save all your dependencies in
(dont repeat yourself). It might feel
your package file regardless of the package
To Follow
counterintuitive initially, but as
manager that you use, so your app is
Adventures In Angular
applications grow over a certain size,
easy to share or reinstall.
@angularpodcast
its quite dificult to find things if files
Build
Adventures in Angular is a weekly
are organised by type. Its very likely
In AngularJS, modularity is a key
podcast dedicated to all matters
that code is going to be repeated so
principle and youll soon find out that
of the framework. Guests from
try to avoid that as much as you can.
there are many small files that you
Ionic and GSAP have both
Choose a naming convention and
want to load. Its not a good idea to
appeared on the podcast
make sure that you stick to using it.
manually load the small files in your page
recently.
You are going to end up with a lot of files;
not to mention the performance issues that
even small apps have quite a few files. If you
could come up if your app ends up in production
ensure that you organise your app in folders by
looking like that. For these reasons its better to use a
feature, it will help you a lot if you add a type sufix to the
task runner or tool, like Grunt or Gulp, to help you run
names such as example.controller.js.
some tasks and optimise your workflow.
Modularity is also quite important, although its not a
requirement. You could potentially have everything
The key tasks that you are going to want in your build
under the main app module and it would work okay. But
script will include:
it would be easier to read and makes for a much
Diferent environments for development
better structure if you just create one main module and
and production
then other modules to be shared across the app and
Watch files for change
modules by feature.
Concatenate, mangle and minify
The main benefit of this type of structure shines
Create source maps for easier debugging
through on big apps; also its good to note that by having
Linting (especially for teams)
this level of modularity, its very easy to reuse modules
Run tests
on diferent apps.

lodash.com
Lodash is a very useful utility library. It has an
extensive documentation and it does all sorts of
things for you. Lodash is focused on performance
so its a good idea to use it instead of some slower
AngularJS methods.

Angular UI
angular-ui.github.io
AngularUI is an amazing set of tools, frameworks
and even directives to help you build your Angular
apps faster.

www.fullengineeringbook.net

38 HTML5 & CSS3 Genius Guide

UI Router
github.com/angular-ui/ui-router
UI Router is part of Angular UI and has become
the de facto routing framework that everyone
uses. Its much more powerful than ngRoute the
one provided by Angular. It allows you to manage
your applications interface by states bound to
named, nested and parallel views, providing a lot
of flexibility.

UI Bootstrap
angular-ui.github.io/bootstrap/
Another component of Angular UI is UI Bootstrap,
a very useful set of AngularJS directives that
mimics Bootstrap components. If you use
Foundation theres an unoficial port of UI
Bootstrap called Angular Foundation.

John Papas Angular Styleguide


github.com/johnpapa/angular-styleguide/
blob/master/README.md
John Papa wrote an amazingly thorough and very
opinionated style guide that has been improved
upon by a good number of contributions. This is
highly recommended reading.

HTML5 & CSS3

Genius Guide

Bootstrapping
ANGULARJS IS NOT BASED ON CONVENTIONS LIKE OTHER FRAMEWORKS

Rafa Garcia-Lepper
Lead front-end engineer

AngularJS is an amazing
framework for creating
data-driven SPAs. Working
with it is a lot of fun and I love
that it encourages me to
write better code.

Its not a steep learning curve for developers wanting to


set it by passing an array as a second argument to the
get to know Angular, but it becomes more challenging
module method in the angular object angular.
when an app grows over a certain size. For this
module(exampleApp,[]);. You can then get this
reason its better to stick to a series of
module by omitting the second argument
To Follow
conventions. In AngularJS the best way of
angular.module(exampleApp);.
Joe Eames
working is by creating single
Configuration
@josepheames
responsibility modules that will work
In a configuration block you set
Joe is a panelist in the JS Jabber
together with other modules to
elements like routes, exception
and Adventures in AngularJS
create an app, which is in itself a
handlers, providers and constants
podcasts and a great developer
module. Then you just inject the
which need to be there before the
to follow. He is the organiser of
services that the diferent modules
app starts.
ngConf, and active in
provide, keeping your code tidy.
sharing tips and advice.
To bootstrap an app, all you need to
Run block
do is to declare a module, give it a name
In a run block, you trigger logic that needs to
and then declare all the other modules on
happen when the app is starting. Things like
which it depends. Then in the HTML you can load the
authentication, translation or analytics, for example, will
app in any element you want; AngularJS will replace
belong in here. Its better to not write the logic code
anything inside it with the views of your app.
inside the run block for testing. Rather, create factory
A module is a collection of configuration and run
services with the logic, inject them in the run block and
blocks although you dont actually need either. It sounds
then invoke the required methods from it.
confusing but to create a module all you need to do is to

www.fullengineeringbook.net
To bootstrap an app declare a module, give it a name and then

declare all the other modules on which it depends

Performance
IT CAN BE EASY TO MESS UP THE DIGEST CYCLE
Every model in AngularJS is represented as a $scope
object and these will make use of an array called
$$watchers, which can then be utilised to store
functions. Every single time that $watch is called or a
value is bound from the DOM (using ng-repeat, ng-class,
ng-show and so on) a
new function will be
stored in $$watchers.
Every single time that
one of these values in the
$scope object is modified,
the digest cycle will go
through the $$watchers
array and it will then run
all of the functions in it.
If any of the functions
in the array changes any
watched value in the
scope, then the cycle will
run again.

Its important for you to be aware of this issue and so,


you should make sure that you avoid any of the
unnecessary cycles by minimising the number of
watched values. Filters can be a performance problem
too because they are run twice with every digest cycle
and because they only
hide the filtered items
using CSS, which means
that the collection will
stay in memory. Try not
to use filters unless you
really have to.
Also, youll find that its
faster to work with simple
objects, especially with
the data that comes from
the backend. Try to make
sure that the object has
only the keys that are
really necessary.

Security
ANGULARJS INTRODUCES SOME
RISKS WORTH NOTING

Avoid mixing server and the


client templates
In AngularJS, templates are just HTML files, but you can
call a server-side file which will be processed and sent as
HTML. The risk is clear as you are exposing some code
that will be executed on the server, potentially
introducing some unintended XSS vectors.

CSRF
If theres a cookie called XSRF-TOKEN, AngularJS will
recognise it and automatically convert it into a request
header X-XSRF-TOKEN. This will be sent on every request
sent by $http for the server to validate the token.

The ngSanitize module


This module changes how AngularJS encodes the
output and creates a list of allowable HTML elements,
stripping everything else out.

HTML5 & CSS3 Genius Guide 39

Tips & Techniques

Using a data-service
ABSTRACT CRUD OPERATIONS INTO SERVICES SO THEY CAN BE ACCESSED

Inject the service in


the controller, then
in the activation
function call the
getExample function
for the example
data and wait for
the promise.

To communicate with
the backend, use a
factory, inject $http
and return an object
exposing all the
public methods.

Create a function
getExample to call
the service for the
data and wait for the
promise; next, set
the data and resolve
the promise.

Use $http to make a


request to the API
and use then and
catch. Try to avoid
anonymous
functions to improve
code readability.

www.fullengineeringbook.net

Communicating with the backend


When making requests to the backend, its tempting to
do it from the controller, but its better not to do it and
keep a separation of concerns. Otherwise your controller
will become bloated very quickly and it will be dificult to
test and maintain.
You want to create a service that can be reused from
other parts of the app. This is the best way to work with
AngularJS in general, but its particularly useful when
interacting with the backend so data can be cached and
reused this will make your app feel faster.
Use a factory where you inject $http and create an
object literal where you expose pointers to private
functions and properties, similar to the revealing module
pattern. Then use $http in the private functions for the
CRUD operations and return it. This way the controllers
remain oblivious to the logic. A controller or any other
consumer will only need to know what service to get

data from and its interface. If you require some data in a


controller for a view to work, load it in the resolve
member of the state, and then inject it into the controller.
Again if you have a factory you can inject it in the resolve
and use all the exposed methods.

Work with directives


Directives are reusable self-contained components
created to add bits of enhanced HTML functionality that
are used from the views. They can have a controller and
a template and can be invoked from the HTML in four
diferent ways: by custom element, attribute, class or by
comment. Create one directive per file, and name the file
after the directive; if it has a template file, put them
together in a folder of the same name so its easy to find
and maintain.
Directives inherit their parent scope by default, so its
probably a good idea to isolate the scope but dont do

Use element directives when they are a


component, when you are actually creating
a new HTML tag
40 HTML5 & CSS3 Genius Guide

it blindly. Make sure you learn about scopes in AngularJS


first. If you need to manipulate the DOM at all, you need
to do it from a directive inside the linking function.
Angular also works nicely with jQuery. It comes with
jqLite, so out of the box youll have a subset of the most
common jQuery functionality available, but if you load
jQuery it will overwrite and become available instead.
Avoid invoking directives as classes or comments. Use
element directives when they are a component, when
you are actually creating a new HTML tag. Use attribute
directives when they modify or add some behaviour to
an existing element.
The name of a directive should be in CamelCase
exampleDIrective in JavaScript when you declare it, and
it needs to be dash separated when invoked in the HTML
<example-directive></example-directive>.
To get values into the directive isolated $scope, you
can use custom HTML attributes and bind them to the
scope object in the directive definition object. The keys
of the scope object will be the HTML custom attributes
using the same CamelCase to dash rule. You can bind
them as strings by making use of @, or to an expression
using &. You can also use = to create a two-way data
bound object.

HTML5 & CSS3

Genius Guide

Models, controllers
and views
IF YOU ARE NOT FAMILIAR WITH THE MVC PATTERN THIS MIGHT BE
CONFUSING AT FIRST, BUT ITS A LOT EASIER THAN IT LOOKS
AngularJS is structured around data which should
bloating the controller by using $scope methods
come from services and you want to display
that would be better of in a factory.
your data in the views, so what you do is
If you do this, dont forget to capture
Avoid
use a controller. A controller is bound
this
into a variable like vm, which
ng-controller
to a view and the data model is
stands for View Model, so it doesnt
Ng-controller doesnt
represented as the $scope object.
change by context.
enforce one-to-one coupling,
The $scope object is accessible from
In the HTML you can display the
its not reusable and its not
the view so you can have any data
elements
in the model ($scope or
flexible. Attach a controller
by adding it to $scope.
vm), all by using double curly braces
to a template using a route
Its a good idea to avoid the $scope
like this {{vm.example}}. If you decide
definition or a directive.
you dont want to bother with the
object though and to use controllerAs
controllerAs syntax, $scope is implicit so that
syntax instead. ControllerAs binds this to
the $scope object which will help you to avoid
you can just use {{example}}.

Services
LEARNING TO USE SERVICES IS
KEY TO MASTERING ANGULAR
In AngularJS there are services, providers,
factories and constants that create a lot of
confusion as they are all diferent types of
services. They are all singletons, so just use
factories, forget about the rest. One exception is in
the config block, where only providers are
allowed. Other than that, stick to factories.
Put in services any logic that could be shared
across the app. Then all you need to do when you
need some functionality is to inject it.
Dependency injection is a key feature of
AngularJS and its really nice to work with.
Make multiple small factories with one
responsibility each. Services can be injected into
other services so any functionality can be reused.
This is a really nice way of working; it will keep
your code clean and clearly defines the diferent
parts of your app.

Register
functions
www.fullengineeringbook.net

EXECUTE ASYNCHRONOUS OPERATIONS WITH PROMISES, CHOOSE THE


MOST APPROPRIATE TEST TOOL AND FIND OUT HOW TO ROUTE

Promises

Unit tests

AngularJS has a promise implementation by default


exposed as the $q service, its also implicit as part of
the $http service. It might be confusing at first. The
basic way you use it is by creating a deferred object
using $q.defer();, which you then use inside an
asynchronous operation to resolve or reject the
deferred object. Then you can return deferred as a
promise. There are very few times when you are going
to need to use $q.defer(). Mainly it will be when you
need to wrap a jQuery plugin to work in Angular and
you need to start a promise to replace the callbacks.
Promises in $http are a bit diferent, but youll be safe
just using then() and by remembering to always catch()
rejected promises.

Jasmine is the most common testing framework for


running unit tests in AngularJS. Its the one used by the
AngularJS core team, although you can use Mocha if you
prefer it.
To run tests with AngularJS you will need angularmocks.js, which is a tool provided by the AngularJS that is
designed to create replicas of the objects called mocks.
This makes it easier for you to decouple components
and inject and mock AngularJS services in your tests by
making use of ngMock.

Tests & tools


Keep ESLint running in your code editor and keep a lint
config file in the repository too, so that everyone in
your team writes code in the same style. Its also a
good idea to lint your code as a build task, and even
better to do it as a pre-commit Git hook to ensure a
baseline of code sanity before running tests.

End to end
Unit tests alone arent enough. If you really want to
minimise risks you will need to run end-to-end tests in
actual browsers. The AngularJS team provides a useful
NodeJS program called Protractor to run end-to-end
tests. It uses WebDriver for controlling web browsers and
simulating user interactions.

Running tests
Karma is framework agnostic and very configurable tool
provided by the AngularJS team to run tests. It works well

with Grunt and Gulp, so its easy to run tests as part of


your build process.
If you want to learn more about testing in Angular,
then wed recommend you to read the book AngularJS
Testing Cookbook by Simon Bailey, which gives you
easy-to-follow recipes for testing out the diferent parts of
your application.

Routing
Ideally your app should be organised by feature
modules, and every single module that needs a route will
also have its own module. When you are working with a
UI router, you will need to declare states instead of routes
a state may or may not have a route and you can also
nest states.
Declare the routes in the config block of each of your
modules and then inject $stateProvider and
$urlRouterProvider.
Use $stateProvider to declare the diferent states, and
$urlRouterProvider to declare the route alternatives. Give
a name to the state and pass an object with the diferent
parameters for it.
If you find that you need to do things in-between the
routes, then you can make use of the run block. You can
also create links to states in your HTML by first utilising
ui-sref as an attribute.
Use $stateParams if you need to access the
parameters of the routes, but keep in mind they are not
inherited by nested routes.

Its also a good idea to lint your code as a build task, and even
better to do it as a pre-commit Git hook

HTML5 & CSS3 Genius Guide 41

Tips & Techniques

Develop apps with


Facebooks React
Native framework
Create a JavaScript-powered native cataloguing image app
with the React library

www.fullengineeringbook.net

42 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

So, youve been writing JavaScript for a little


while now, youd say youve become quite
good at it, youve made websites, a couple of
small libraries and even a few web apps. The thing is, no
matter how awesome the web is (and it is fully awesome)
the call of the native platform still beckons. You decide to
give it a crack, but youve never written anything with
Objective-C before sure, theres this new Swift thing that
looks familiar, but the process of building an app is still
foreign to you. We could try some transpilers, that is, write
some apps in JavaScript and then have something like
Titanium figure out what your code is trying to do, but
thats a painful process to get right. We could try out
PhoneGap thats nice and familiar and you can get great
results after some tweaking, but JavaScript optimisation is
hard especially when its inside a native wrapper. What
are we to do? Wouldnt it be great if we could write apps
in JavaScript with our favourite IDE but have everything
in our views be native wouldnt that be ideal? Well, thats
React Native a supercool framework from Facebook
that lets you write your app logic in familiar React.js
syntax and then renders all of the view using native iOS/
Android elements. Its not transpiling or reinterpreting
your JavaScript code, its running it separately in the
background. In this tutorial, were going to be making a
catalogue app, that is, an app that shows us cats (see
what we did there?), so lets get to it!

Hit play and the app should run. The iOS simulator might
throw an error so select iOS simulator in the menubar
and click reset content and settings and hit play again.

6. Our bare-bones app


In our iOS simulator, our app will now be open. Go back
to the catalogue folder we created and open index.ios.js
in your favourite IDE. This is the main entry point for
React Native to run our app from. Were using the virtual
DOM to create elements, but instead of DOM elements,
were using equivalent iOS elements.

var styles = StyleSheet.create({


container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
// alignItems: 'center',
backgroundColor: 'white',
},
});
AppRegistry.registerComponent('catalogue',
() => catalogue);

7. Clear the house

10. Create list.js

This React Native project has one view, but we need two
views for this tutorial: one for listing our categories, and
another for viewing the photos in that category. Delete
everything in index.ios.js and insert the following in its
place to import the required modules for our project.

In index.ios.js we defined the List component as our first


view. Create the file list.js in our project folder and a file
called catViewing.js. Import the following modules:

'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
Image,
ListView,
TouchableHighlight,
NavigatorIOS,
View,
} = React;
var CatViewing = require('./catViewing');
var List = require("./list")

'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
Image,
ListView,
TouchableHighlight,
View,
} = React;
var cats = require("./cats"),
thumbCats = [];
var CatViewing = require('./catViewing');

www.fullengineeringbook.net

1. Get React installed

React Native is a complicated piece of kit, so there are


quite a few dependancies but thanks to homebrew, NPM
and Node.js setting up React Native is simple. To install
just run these commands in a terminal window:

brew install watchman


npm install -g react-native-cli

2. Create a new project


Now we have the React Native CLI tools installed, CD to a
directory that you want to create your React Native
project in and run react-native init catalogue. This will
create a bare-bones project with everything we need.

3. Fix Xcode project/iOS simulator


For some, the Xcode project might not work out of the
box, Xcode can fix that for us. Open the Cat-alogue.
xcodeproj file inside the folder you just created. Xcode
will open. Click on the project tab on the left and select
8.0 from the Deployment Target drop-down menu.

4. Select device
Look at the play button in the top left of Xcode, just to
the right of it there should be a small icon with iPhone 4s
or something similar, click it and select iPhone 5s or
iPhone 6 (depending on your version of Xcode) from the
dropdown that appears and hit play.

5. Fix errors
If you get errors, the fix is simple. Click on the tabs
showing the error and select the first fix thats suggested.

8. Create a starting point


We now have everything we need except for a view. Add
the following code to index.ios.js, it uses the NavigatorIOS
module to let us create views, this means we get a lot of
things like back buttons and animations between views
for free. The initialRoute property determines where our
app should find the code for our first view.

var catalogue = React.createClass({


render: function() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'Cat-Alogue',
component: List,
}}
/>
);
}
});

9. Stylings
Lets create a simple stylesheet. React doesnt use CSS, it
uses a JavaScript polyfill to emulate a limited subset CSS
with native components, and as such we define styles
like so. AppRegistery exposes our React class to our
native code, its our true entry point to the application.

just after that, were going to create the List class and all
of the functions that it will use to build our view:

var list = React.createClass({


getInitialState : function(){
},
renderCatThumb : function(cat){
},
loadCat_egory : function(category){
},
render: function() {
},
});

11. Find the cats module


If we run our code, we get an error, this is because it cant
find the cats module we defined earlier. You can grab
cats.js from FileSilo and add it to our project folder, its a

Learn once,
write everywhere
Weve all heard of write once, deploy
everywhere but theres rarely an instance where
that actually works out. Facebooks suggested
philosophy is learn once, write everywhere.
Once youve learned React, you can write it for
any platform, rather than maintaining one
codebase that has to accommodate everything.

HTML5 & CSS3 Genius Guide 43

Tips & Techniques


really simple JavaScript module that contains URLs for
the cat images well be using.

12. Set our initial state


We need to help React make sense of our data for iOS so
we use a ListView to list categories and a ListView will
only accept a DataSource object as an argument. Inside
of getInitialState, add the following code to create an
object for each of our categories for making a tab:

...
for(var key in cats){
thumbCats.push({
image : cats[key][0],
title : key
});
}

render items, were going to need a function to define


what each list item should look and how it works. We can
do this in the renderThumbCat function. Here, were
using React Natives iOS analogous virtual DOM to
express how the list elements should be laid out.

renderCatThumb : function(cat){
return (
<TouchableHighlight onPress={() => {this.
loadCat_egory(cat.title)}} underlayColor="rg
ba(0,0,0,0.1)">
<View style={styles.cell} >
<Image source={{uri : cat.image}}
style={styles.thumbnail} />

<ListView dataSource={this.state.dataSource}
renderRow={this.renderCatThumb}
style={styles.listView} />
</View>
);
},

15. JsCSS stylings


Add some stylings or everything will be clumped
together. We can do this with Stylesheet.create(). This is
not CSS, but what Facebook calls JsCSS, a subset of CSS
expressed as objects. Each object in styles can be
thought of as a class name and each property is a
styling. A key diference is that we separate stylings with
a comma, not a semicolon.

<View style={styles.rightContainer}>

16. Rendering
var ds = new ListView.
DataSource({rowHasChanged: (r1, r2) => r1
!== r2});
return { dataSource: ds.
cloneWithRows(thumbCats),
};
...

<Text style={styles.title}>{cat.title}
Cats</Text>
</View>
</View>
</TouchableHighlight>
);
},

13. Render the thumb cats


14. The first render

Head over to the iOS simulator and hit Cmd/Ctr+R on


your keyboard to render. We dont need to recompile the
app, because were using JavaScript to determine our
views, we can rerender on-the-fly. If your keyboard did
nothing you need to go to Hardware>Keyboard>Connect
Hardware Keyboard in your iOS Simulator Menu bar.

17. Push a view to the stack


Now we have a scrollable list of categories, but when we
tap them, they highlight, but nothing happens. If we want
to see the images in the category, we need to push a
new view to our stack and pass the relevant images to it
for loading. Add the following code to loadCat_egory()
and then create the file catViewing.js in our project folder:

www.fullengineeringbook.net

Now that we have a data source our ListView can use to

Is it honestly native?
Yes! Facebook have yanked out the JavaScript
engine from the WebViews and run it in a separate
thread. Your app logic runs in JS but everything
you see on the screen is completely native.

Top left

Historically, error messages have been obfuscated noise


that are rarely any help. Fortunately, thats not so much
the case these days. The fix Xcode prescribes is spot on
in this case
Top right

Facebook doesnt want your code to fail silently. It wants


to get up in your face so you write better code, so here is
what theyve dubbed the Red Screen of Death
Right

This is how our app should look so far. Our categories for
our ListView are being dynamically generated in
JavaScript and then rendered with iOS native components

44 HTML5 & CSS3 Genius Guide

Weve not had much to look at so far, but thats about to


change. We now have almost enough code to render
our first view. Once every React Module has been
loaded, the render function is the last function called and
it will render the view. Now change your render function
to the following:

render: function() {
return (
<View style={styles.container}>

...
var catsToView = cats[category];
this.props.navigator.push({
title: category + " Cats",
component: CatViewing,

HTML5 & CSS3

Genius Guide

JsCSS WAT?
Aligning objects on a
screen is a tough business,
just ask any iOS developer
whos done a lot of manual
positioning, it can be a
nightmare. Facebook
looked around for a
solution to aligning things
intuitively and it found
one, CSS! Problem is,
implementing CSS for iOS
was not a prospect they
fancied much, instead,
they opted to create a
JavaScript subset of CSS
styles that could be used
to position native iOS
elements in and around
native iOS views so it has
all the goodness of CSS
and JavaScript and full
speed of a native. One of
the coolest things about
JsCSS? It has Flexbox, not
the full Flexbox, but
something very close and
easy to use. Check out the
Facebook Developers
YouTube channel for more
information on React
Native bit.ly/1AK9zmZ.

www.fullengineeringbook.net
passProps: {catsToView},
});
...

18. catViewing.js
With loadCategory() weve passed everything we need
to render our images, but where did we pass it to? What
about the CatViewing class were about to create in
catViewing.js? CatViewing works just the same as our list
class worked, except instead of being a ListView, were
using a ScrollView which gives us a little more flexibility
when it comes to how we lay content out. Add the
following code to catViewing.js to get started:

'use strict';
var React = require('react-native');
var
{
Image,
PixelRatio,
ScrollView,
StyleSheet,
Text,
View,
} = React;
var CatViewing = React.createClass({
render: function() {
},
});
module.exports = CatViewing;

19. Get our list of cats


The first thing we want to do is get a reference for our list

of cats that we passed to the view from our List class.


Each React class has a props object which we can
access by using this. We dont need many functions
here for our CatViewing class, in fact we only really need
one and that is a render(). So ammend render() to look
like the following:

render: function() {
var catsToShow = this.props.catsToView;
return (
<ScrollView contentContainerStyle={styles.
contentContainer}>
{catsToShow.map(createThumbRow)}
</ScrollView>
);
},

20. Map our cats


In our scrollView, we have mapped catsToShow to
createThumbRow, but we havent written that yet! So the
actual making of the createThumbRow is a very simple
process for each image we pass to it, it will create an
instance of the Picture class were about to create. Picture
is a very simple class, so its very similar to CatViewing in
that sense, it only has a render function and all it does is
take a wrap for an image in a view and then it will grab
that images source. Just think of it as if you are wrapping
an <img> in a <div> and then setting the src attribute
over in HTML.

var createThumbRow = (uri, i) => <Picture


key={i} uri={uri} />;
var Picture = React.createClass({

render: function() {
return (
<View style={styles.centering}>
<Image style={styles.imageHolder}
source={{uri:this.props.uri}} />
</View>
);
}
});

21. Finish up
Were almost ready to view all of our cats. If you refresh
the iOS simulator, we get a nice big error (we might even
crash Xcode!) because we havent added styles for the
Picture or CatViewing classes. But, thats simple, if we just
add the following after our Picture class closes, were all
done. Now we can take our Cat-alogue, and put it
wherever we want it to be.

var styles = StyleSheet.create({


contentContainer: {
padding: 10,
},
centering : {
alignItems : "center"
},
imageHolder : {
width : 280,
height : 280,
marginBottom : 5
}
});

HTML5 & CSS3 Genius Guide 45

Tips & Techniques

Whats new with

Modernizr?
AFTER YEARS WITHOUT A MAJOR RELEASE, MODERNIZR 3 WAS PUBLISHED IN
SEPTEMBER 2015, JAM-PACKED WITH NEW FEATURES AND IMPROVEMENTS

www.fullengineeringbook.net

Why you need Modernizr


THE SECOND MOST USED JAVASCRIPT LIBRARY ON THE WEB, AND WITH GOOD REASON, MODERNIZR HELPS YOU
CREATE GREAT WEBSITES FOR BROWSERS OLD AND NEW
If you have worked on a website in the last
five years, you have undoubtedly run into
Modernizr. Browsers add new features to the
web all the time, but unless you are just making demos
you probably arent that comfortable using them for
quite a while. It can feel dificult to know when if ever
you are actually able to deploy them into production
and count on them to work. Modernizr takes the stress
out of that decision by giving you an incredibly simple
API to hundreds of diferent battle-tested feature
detects. Cant you just send a diferent site to basic
browsers? In a few cases that makes perfect sense, but
it adds a ton of work and headaches. If you assume
that the client isnt capable enough to render your
latest and greatest simply because it happened to be
made by Microsoft or Mozilla, prepare for a world of
hurt. Those assumptions will inevitably come back to
bite you once the browser has been updated. You
need to actively check each and every new version of

46 HTML5 & CSS3 Genius Guide

every browser to make sure it hasnt added or


removed something you inferred was there just
because of its name, company, or version. Yuck. A
much simpler method is to use Modernizr. It checks
for the actual HTML, CSS, or JavaScript feature you
care about, and gives you a simple true or false result.
The code you wrote to use the new and shiny will start
working as soon as the feature is added to your users
browsers, with no changes needed on your part.
So feature detections are the way to go, but why
should you use Modernizr instead of just rolling your
own? Quite a few of the things Modernizr checks for
seems very simple to test for yourself, but due to the
fact that humans create our web browsers, there is an
endless amount of quirks and oddities between them.
Modernizr acts to clear house of these idiosyncrasies,
collecting and sharing the issues so that you get tons
of bug fixes for free! You dont have to find out that
Internet Explorer 11 parses preserve-3d but never

actually applies it, or that Chrome throws an exception


for WebSQL only inside of Incognito Mode. You just
get to write a simple if/else, and focus on the code you
actually want to be writing. On top of that, Modernizr is
100 per cent open source. You can view the code for
every feature detection on GitHub, complete with
comments and explanation for why each part was
added. Modernizr 3 builds on top of all of this, with
dozens of new feature detections, reduced file size,
custom builds, and much, much more.
As well as the large selection of new features in
Modernizr 3, the website has been given a revamp.
This makes it easier to find the detects users need to
add to their builds.
The new site also allows for real-time search for
detects on the download page and each detect now
has a special comment with useful information
including polyfills and links. Total browser support just
got a whole lot easier.

HTML5 & CSS3

Genius Guide

Whats new?
THE LATEST VERSION IS BIGGER AND BETTER. HERES WHY

Lean and mean feature detection machine


From its inception Modernizr has had a core monolithic
suite of feature detects. It turns out this is a terrible idea!
Most websites never use a majority of the detects that
were included. Even though it is a relatively small file, all
those extra bytes add up, slowing down the load time for
your site and making for some sad users. Modernizr 3
has done away with this by modularising every single

detect, allowing for 100 per cent custom builds tailored


to your specific website. That means an even smaller file
to include and faster loading site for all of your users. The
downside of this is that there is no longer that single
monolithic file to use when you are building your site, but
keep reading to see how the Modernizr team has made
it making your own custom build of version 3 a doddle.

Hundreds of new detects


Between the last incarnation of version 2 and the new
By adding a Service Worker and AppCache detect,
3.0, Modernizr comes with over 100 new
you can check to see what the best way to
feature detects, complete with
make your website work ofline would be,
Changes to
documentation and polyfill information!
make your touch interactions work
detects
While a full list is available at modernizr.
properly across all browsers by
A few detects have been
com/download, some of the
checking Touch and Pointer Events, or
renamed since version 2. Make
highlights include the industrys most
maybe reduce your @font-face
sure to read the changelog on
robust Flash (and Flash blocking)
download size by checking out
modernizr.com to see if your
detect, functional tests for video and
unicode-range. There are many more
code will actually require
audio autoplay (that means proper
great features that have been added, so
any updates.
results even on mobile!) and nearly a
make sure to checkout the Modernizr
dozen detects for new image, audio, and
download page to read the documentation
video formats and codecs.
on all of them.

Patrick Kettner
Lead Modernizr developer

Modernizr 3 takes away of the


guesswork of browser support, and
lets me concentrate on writing
code for the problems I actually
want to be solving.

Choosing the right


build for your site

www.fullengineeringbook.net

A perfect fit for the


modern build toolchain
MODERNIZR 3 INTRODUCES A NUMBER OF NEW WAYS TO INTEGRATE
QUICKLY AND EASILY INTO YOUR EXISTING TOOLCHAIN
Visiting the oficial website has always been the default
way to get your copy of Modernizr, and with version 3.0
it is stronger and better looking than ever.
The new site includes a number of improvements to
make generating your custom Modernizr faster and
easier. Powering the Download page, a new Universal
Builder creates the exact same code as any of the other
tools you can use to create your Modernizr. That means
better consistency and fewer chances for bugs to creep
in. The new site automatically creates a build for you
every single time you change an option. That means that
by the time you are ready to build, it has already been
built for you. This process is kept snappy by using a
Service Worker to cache all of the modules as you select
them. That means that your build time actually speeds

up the more you use it, and keeps it working even if you
are ofline! The constant build also gives you the ability to
check on just how much bloat (or lack thereof) your build
has, with the compressed and uncompressed file size
listed on the left-hand side of the page at all times.
Remember that every byte you add, every single one of
your users has to download. Be kind to your network and
theirs keep it as small as possible. The site even has a
fully responsive design, allowing you to generate your
build or check the documentation on your mobile.
But having to go to the site to recreate the build every
single time you want to make a small change can quickly
become tedious and boring. Its 2015 robots should be
doing boring junk like this. That is why version 3 has
added new ways to integrate Modernizr into your build.

CUSTOM BUILDS SPEED THINGS


UP AND MAKE USERS HAPPIER

It is super simple to create a custom build of


Modernizr. Once you have a feature to detect (and
not before adding dependencies to your site
before theyre needed is a sure-fire way to bog
the site down) head on over to modernizr.com/
download. From there you can search for and
select any feature you want. You do not need to
know the exact Modernizr term for what you are
looking for, as the search box will scour
documentation, caniuse, and many other sources
in order to make it simple to find everything.
Tapping on the detect will pop up its
documentation, including a short description of
the feature, any polyfills that are available, as well
as links to in-depth resources like dedicated blog
posts and specifications. Once you have selected
everything you want, tap on the BUILD button to
get a list of various ways to get the code. As we
will explain later on, Modernizr 3 fits well into your
modern build toolchain, so there are a number of
options available. The Build option gives you the
raw Modernizr file. Command Line Config will
produce a JSON file thats used to power the
Modernizr CLI tool. A Grunt Config can be
downloaded as well to automate your Gruntmodernizr setup. Finally, if you want to test
Modernizr results in the various browsers you
support, try it out on CodePen. You may not even
need to test for that feature any more!

HTML5 & CSS3 Genius Guide 47

Tips & Techniques


Whether you Grunt your site or
Gulp it, Modernizr can help

Jam with the console cowboys in


cyberspace

Once upon a time, when dinosaurs roamed the earth,


websites were written in notepad, uploaded to your FTP
server and you were done. But the web has grown up
quite a bit since the Jurassic period, and with it so has
the way that sites are built.
Ben Almans GruntJS was the first really popular
JavaScript build system, and Eric Contra Schofstalls
Gulp quickly became extremely popular as well. There
are a number of ideological diferences between the two,
but the Modernizr team thinks both are great and has
created tools to easily integrate it into either of them.
Created by Modernizr team member Richard Herrera,
both Grunt-modernizr and gulp-modernizr will search
your code base for references to Modernizrs feature
detects and automatically generate a customised build
with only the features you actually use. Rather than
manually creating a new build every time you want to
add something new, you just have to write your code as
though it was there already and your build system will
take care of the rest! You get all of the great benefits of
developing with the gigantic full version of Modernizr
with none of the performance concerns.
Full documentation is available on npm and GitHub
for both modules, but they are both very simple to add
to an existing project. Here is an example of a Grunt
configuration you can add to your existing Gruntfile:

Almost all of the tools that Modernizr 3 introduces are


built upon the its npm package. It even powers the
Modernizr website! The straightforward command line
interface can take a JSON configuration file as input, and
uses it to create your custom build.

npm install https://modernizr.com/


download?promises-unicoderange --save
bower install https://modernizr.com/
download?promises-unicoderange --save

Thats it! Every time you run Bower or npm update, it will
check to ensure you have the latest and greatest version
modernizr --config config.json --dest
of Modernizr, complete with all bug fixes and
custom_modernizr.min.js
performance improvements. The only caveat to using
the download service is that if you ever want to add or
You dont have to generate the configuration by hand
remove detects from your build, you will need to either
grabbing the build URL that is included by default
update or remove the existing entry in your package/
in the header of all builds of Modernizr (like
bower.json. Since the new dependencies
modernizr.com/download?emoji) will
would mean you are using a diferent
Keep an eye
take you to a version with all of your
URL, you would end up with duplicate
detects, already checked. From there
on file size
versions of Modernizr in your project.
Its all too easy to bloat your
you can tap on the BUILD button
Code it forward
build by adding too many new
and grab the generated Command
So you have created your build of
features always remember to
Line Config. Using the above URL,
Modernizr, but now you have
keep an eye on the overall file
you get the following JSON file:
{
discovered that, horror of horrors, it
size to make sure your
"minify": true,
doesnt detect something you need!
website stays fast.
"feature-detects": [
How can you remedy that situation? The
"test/emoji"
Modernizr team has thought of this too, and
]
created generator-modernizr-detect. Yet another
}
nodejs package, generator-modernizr-detect is a plugin
for the popular Yeoman tool. It will ask you a few
The tool works in Windows, Linux, and OS X, and can be
questions to generate all of the scafolding you need to
integrated into any system that has the ability to call
...
create a new feature detect. Once you have created and
modernizr: {
command line programs.
added it to your site, go ahead and create a Pull Request
"parseFiles": true,
But maybe your builds dont ever change. Or maybe
on GitHub to share your discoveries with the rest of the
"customTests": [],
you just dont want to have you entire team install (or
Modernizr community. Most of the detects that are
"outputFile": "/my/awesome/project/
know how to use) the CLI tool. Cant there just be a way
maintained were contributed by folks outside of the
modernizr-output.js",
to download the prebuilt file? With Modernizr 3, there is!
project, many with little to no open source experience. It
"tests": [
is a great way to show of your research and knowledge
"emoji"
Npm and Bower, at your service
to a kind and caring community that helps power a huge
],
The days of downloading a script from a random place
chunk of the web.
"uglify": true
on the web have long since passed. We have proper
} ...
dependency management in the JavaScript world
Looking forward
Version 3 is far from the end. Since its release in
thanks to the likes of Bower and npm.
Since Grunt/gulp-modernizr searches for
September 2015, there have already been dozens of
One of the most frequent requests the Modernizr
references to the Modernizr detects, you
improvements, with many more to come. One of the
team has received is the ability to treat it like
almost never need to actually include
things that is quickly becoming the most requested is
any other JavaScript dependency, and be
the tests portion. If you ever want
support for new module syntaxes. Between npm, ES7s
installable via one of these package
Modernizr.on
to force the inclusion of certain
managers. But, due to its highly
Modernizr 3 adds the idea of
detects, you can always add them
modular nature, it was simply not
asynchronous feature detects.
to that array.
possible (let alone practical) to
Check out the Modernizr.on API to
If you really like the idea of the
publish every possible
react to feature detects that take
Grunt and gulp versions, but use
combination. It would require
some extra time.
one of the other build systems,
nearly a centillion individual
such as Broccoli, Brunch or Mimosa,
packages! That didnt stop the
you can get the same results by
Modernizr team instead of registering
creating a wrapper around the customizr
and maintaining that number of modules, it
npm package.
has created a Bower and npm download service.
Also created by Herrera, customizr is the abstracted
As a result, what this means is that, rather than
crawl-and-build mechanism that powers the Grunt and
install a hosted package from Bower or npm like you
gulp packages. If you prefer getting closer to the metal,
normally would do (eg bower install modernizr), you
and want to eschew the built-in automation of Grunt and
can go ahead and install directly from the same
gulp, Modernizr now includes a command line tool to
The new modernizr.com has a brand new look,
custom URL that is included by default in the header
help get stuf done.
and a ton of new features
of every Modernizr build.

www.fullengineeringbook.net

48 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

JavaScript modules, and tools like Browserify and


Webpack, modularity has become a huge part of the
JavaScript landscape. Modernizrs internal modules will
soon be updated to be compatible with these other
syntaxes. This means that someday soon you wont even
have to build the bundled Modernizr file any longer. You
will be able to just import or require each individual
detect as you need them, like you would any other
standard module.
In a perfect world, all browsers will implement features
as they are created, and tools like Modernizr will no
longer need to be used in order to figure out what and

when you can use them. But today is not that day, and
tomorrow likely wont be either. Adding the latest version
of Modernizr to your project can save hours trying to
research and debug diferent ways to handle tiered
browsing experiences. Version 3 has added a ton of new
ways to easily integrate an updated version to your
existing toolchain. Whether you grab it from the website
as you always have, generate it via Grunt or Gulp, or
download a prebuilt version through npm or Bower via
the download service, Modernizr wants to make it as
easy as possible to stop worrying about cross-browser
issues, and start making the next amazing website.

Working with CSS


MODERNIZR IS STILL THE SIMPLEST
WAY TO STYLE YOUR SITE
Since the very beginning, Modernizr has been a
fantastic way to add functional if statements to your
CSS. Rather than worrying about selector hacks or
specificity bugs to make sure that browsers purvey
the styles you intended, Modernizr adds a class for
every feature detect to the root element. This means
that you write clear and self-documenting CSS.

.cssgradients .header {
background-image: lineargradient(cornflowerblue, rebeccapurple);
}
.no-cssgradients .header {
background: url("images/glossybutton.
png");
}

Working with JS
QUICKLY QUERY THE RESULTS OF ANY FEATURE DETECTS
if (Modernizr.awesomeNewFeature) {
showOffAwesomeNewFeature();
} else {
getTheOldLameExperience();
}
Version 3 adds a few of new APIs that you can leverage
on your code. Modernizr.on was added as a way to hook
into all of the new asyncronous feature detects. Since the
code you write may execute before the results of the
detect are known, you can register a callback to run once
Modernizr has finished.

Modernizr.atRule lets you check support for both


prefixed and unprefixed @rules (e.g. @font-face, @
keyframes, etc).

if ( !(Modernizr.atRule(keyframes) ) {
// load JS powered animation lib
}
Modernizr.prefixedCSS is similar to the older Modernizr.
prefixed, but will return the (possibly) prefixed version of
a value in kebab-case rather than prefixeds camelCase

Sometimes Modernizr can clash with CSS you have


created, or perhaps some included in a framework
being used. That is why Modernizr has the
classPrefix option. This can can be added or
configured in any of the tools mentioned in this
article, like so:

www.fullengineeringbook.net
Modernizr.on(videoautoplay,
function(supportsAutoplay) {
if (supportsAutoplay) {
//replace static image with video
}
});

Modernizr.prefixed(backfaceVisibility)
webkitBackfaceVisibility
Modernizr.prefixedCSS(backfaceVisibility)
-webkit-backface-visibility

{
"classPrefix": "webdesignermag-",
"feature-detects": ["css/gradients"]
}

Now, rather than this

There are a few more, and some updates to older APIs as


well. Check out the complete changelog on modernizr.
com to see all of the changes.

Its also a good idea to lint your code as a


build task, and even better to do it as a
pre-commit Git hook

Five tools & resources

<html class=cssgradients>
you get this

<html class=webdesignermag-cssgradients>
One final change with the CSS in Modernizr 3 is the
no-js class. Previously, Modernizr would remove the
no-js class from the root element if it existed, and
then always add a js class. As of version 3, it will
continue to remove the no-js class unless the
enableJSClass option is false in your config. It will
also only add the JS class if a no-js class is found.
This lets you decide on whether or not a client has
enough JavaScript to really say it supports it.

Ryan Seddons guide to


Modernizr 3

Building Resilient Web


Apps NPM blog

Modernizr GitHub
source code

customizr

bit.ly/1IegIzt

bit.ly/1P6HFgh

bit.ly/1SikoG0

This short course in Modernizr 3


willl take you through the
fundamentals in JS and CSS.

Patrick Kettner lays out the


fundamental tools for keeping
Modernizr compatible.

The entire library is available


here on the GitHub repository,
free for you to dip into.

You can try customising your


own Modernizr build and
exporting it without having to
worry about optimisation.

bit.ly/1LxUIzM

How to use Modernizr


Responsibly
bit.ly/1GYl7Gh
Discover how a responsible
approach to Modernizr can
improve user experience.

HTML5 & CSS3 Genius Guide 49

Front-end

www.fullengineeringbook.net

50 HTML5 & CSS3 Genius Guide

52

Responsive design decoded


Learn to build with the new Foundation 6

60

Is your content king?


Make sure your design is content-led

66

Design aspect ratio-based


layouts with HTML and CSS
Build tile-based layouts to maximise your content

70

Make dynamic graphics with the


p5.js library
Create stunning visuals for interactive designs

74

Code 3D zoom effects with CSS


Revamp the tired parallax scrolling feature

76

Form pop-up modal boxes with


pure CSS
Find new ways to present info on one page

www.fullengineeringbook.net
80

Build offline web apps with


Service Workers

Create offline applications using Service Workers

84

Model a unique mobile 3D


interface
Integrate a bespoke browsing experience

88

Create an interactive mobile


3D interface
Add interactivity to your orientation controls

92

Assemble full-screen navigation


Create menu systems for websites and web apps

HTML5 & CSS3 Genius Guide 51

Front-end

www.fullengineeringbook.net

52 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

5 new F6 features

New look

CHECK SOME OF THE EXCITING NEW ADDITIONS TO FOUNDATION

THE CREW BEHIND FOUNDATION 6


TELL US HOW IT ALL GOT STARTED

Half the filesize

The newest version of Foundation is here and,


according to ZURB, the team behind the build
itself, its a whole lot more than just a visual
iteration, code restructure or even a simple change in
version number. ZURB had tons of phone calls,
conversations at meetups, and even sent staf on the
ZURB World Tour to hear how people were using the
past versions.
From New York to Hong Kong to Ontario and Sydney
people spoke about their love of rapidly prototyping with
Foundation and their interest in how ZURB used it for
production sites. From these conversations the teams
goals for the next version of Foundation would rely on
getting people producing faster prototypes, so they can
iterate quickly, and then taking those prototypes to
production code thats leaner and more maintainable.
The biggest and most noticeable diference for
Foundation 6 is that its now half the filesize of
Foundation 5. Weighing in at 60KB CSS & 84KB JS the
Foundation team has put tons of care and energy into
producing a framework thats as light as possible while
still being a powerful foundation for any website. The
ability to pare down the components to the ones youll
use and a larger emphasis on more powerful Sass
functions will help users decrease file size even more. A
lean site will lead to a faster site which in turn will allow
for more success for the Foundation community.
The Foundation team made a big push for a more
a11y-friendly framework in Foundation 5.5 and are
continuing that work by re-coding every component
with accessibility in the forefront of their minds. Every
Foundation component uses accessibility standards and
the team has been working with some killer a11y
advocates to make sure theyre hitting the mark. All code
snippets will come with attributes and roles along with
instructions on how/why these things need to be used.
This will help ensure that every website built on
Foundation 6 will be able to be seen anywhere, on any
device, by anyone.
Foundation has always been very careful about the
styles added to the framework with the goal that the
base styles are to act as a wireframe rather than a final
design. The team is doubling down on that efort and
pulling more styles from components, so users can more
easily style them to fit the brand of their work. The styles
can be updated with variables in the Sass, but the team is
standing firm that not every selector with every
declaration gets a variable. What this means is that users
will be able to write their own CSS and not just be
hunting down and modifying theme variables for every
style the aim is styles and variables where they make
sense, while avoiding abstractions.
In Foundation 6, mixins with Sass have been made
stronger to allow devs to build custom rows with any

More flexible Sass

The total filesize of every component and


In Foundation 6 customisation is what it is
class in Foundation 6 now weighs in at
all about. The Sass mixins have been
Use fewer divs
60KB CSS and 84KB JS, with plenty
made stronger to allow devs to build
for the grid
of room to make them even smaller
even more customised rows with
Combine rows and columns in a
when selectively removing any
any number of columns they need.
single div for a maxwidth centered
unused components.
So, if a designer or developer
column, by using the following
wants to use a four-column grid
code example:
inside a five-column grid inside a
All code snippets will come with
<div class=row
twelve they can. This means that
attributes and roles along with
column> </div>.
almost any grid can be created. But,
instructions on how and why these
dont get too overexcited, a grid still
elements need to be used. This will help
needs to functional.
ensure that every website built on Foundation 6 will
be able to be seen anywhere, on any device,
Foundation 6 will be ofering not only
by anyone.
Right to left
the CSS versions and the regular Sass
compatible
versions of Foundation, but a
Not everyone reads from left to
souped-up stack complete with a
right. Add the following for sites
With the goal that the base styles
custom static site generator
that need it. Add dir=rtl to the
are to act as a wireframe rather
named Panini to help flatten files
HTML tag and $globaltextthan a final design, the team pulled
into single HTML documents.
direction: rtl; in the settings to
more and more styles from
Panini is a Gulp-powered build
components, so users can more
make your site flip for rtl
system that can do a lot. It can
languages.
easily style them to fit the brand of their
compile Sass to CSS, combine JS into
production work.
one file and create production-ready code.

A11y friendly

Starter projects

Styled for ultimate


simplicity

www.fullengineeringbook.net

The biggest and most noticeable


difference for Foundation 6 is that its now
half the filesize of Foundation 5

HTML5 & CSS3 Genius Guide 53

Front-end
stronger to allow devs to build custom rows with any
number of columns they need. If a design needs a
four-column grid inside a five-column grid inside a
twelve, new mixins will make that super quick and easy.
Users can still use the mixins for almost every
component and rename the classes to match their
necessary names. This means developers can convert
presentational classes from prototypes to semantic
markup and not need to import those classes into their
final code. This has always been a great part about
Foundation with Sass, but the team is taking care to
make it even more powerful.
Finally, Foundation 6 will be ofering not only the CSS
versions and the regular Sass versions, but a souped-up
stack complete with a custom static site generator
named Panini to help flatten files into single HTML
documents. Devs can spin up a browser sync server
with tons of ways to optimise code with UNCSS and
UglifyJS. This is the same stack ZURB uses to build for
their client work and they are making it available for the
first time to the Foundation community.

New desktop companion app


Spin up projects with a single mouse click
Foundation for Sites 6 comes with a new companion
app, Yeti Launch (foundation.zurb.com/develop/
yeti-launch.html), that makes it dead simple to spin up
Sass projects, compile them and upload them to
Notable Code where you can get feedback directly on
the site.

Modular JavaScript utilities


Create your own JS plugins
The utility libraries are publicly accessible so users can
make their own amazing plugins.

Quick project starts


Collaborate on responsive
design prototypes

Spin up projects faster than


ever before

Upload your responsive design web


pages to easily get contextual feedback on
any breakpoint

The new command-line tool (CLI) enables users to set


up blank Foundation for Sites, Apps, or Emails
projects with fewer dependencies than ever before.
Users can also choose to install through NPM, Bower,
Meteor, or Composer.

Stakeholders and collaborators can annotate and


review coded webpages on any device. Take your
Foundation projects from prototype to production with
Notable (foundation.zurb.com/responsive-designcode-review).

50 building blocks and 15 new


templates
A growing library of resources

Flexible navigation patterns


Customisable and modular navigation

Motion UI

Theres a new menu system that is completely


customisable and modular.

Pop these premade components into your projects and


save time and resources.

work with any JavaScript animation library.


details of an efect, from what direction an
Need more
So what can the Motion UI library do for
element slides, to how far it spins, to
designers and developers? The most
components?
how intensely it shakes. Motion UI also
A the bottom of every
important thing is that it will make
includes a large number of premade
component, hidden away in the
prototyping easy. When moving to a
CSS classes in order to help you get
documentation, you can find a
production environment, the library
up and running quickly.
selection of building blocks that
gives users total control over how
It is worth noting that the library
expand on that particular
efects work.
was designed specifically for use with
components functionality
At the very core of the library is a
the Foundation frameworks, but it can
or style.
set of powerful transition and animation
also be adapted to work with any
Sass mixins, which work to give users
frameworks animation library, such as
complete freedom and absolute control over the
Angular or React.

www.fullengineeringbook.net

EASILY CREATE ANIMATIONS


AND TRANSITIONS

This Sass library includes more than two dozen


diferent built-in transition and animation classes for
you to make the most of. Originally part of the
Foundation for Apps code, ZURB has decided to make it
its very own library. The updated version includes
significantly more robust transition options, an animation
queueing system, and flexible CSS patterns that can

54 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

Whos using Foundation?


THE POWER OF THE FRAMEWORKS HAS ATTRACTED SOME BIG NAMES. HERES WHAT THEY HAD TO SAY

Imran Oozeerally

Doug Macklin

Nick Pettit

Barclays

Golden State Warriors

Team Treehouse

It was decided early on that the new site would be

I have been using Foundation for several years now,


not because Im content to stick with what I know, but
because it remains the best framework of its kind by a
long shot. The ease of customisation and hassle-free
setup it provides are unparalleled.
The Foundation framework has not only helped me
cut down my workflow time, but more importantly it
inspired me to grow as a web developer. I studied
Computer Science in college, but knew hardly
anything about front-end web development prior to
working in my current position. When I discovered
Foundation, it made me want to improve my workflow
and get up to speed with the changing landscape.

I personally prefer using Foundation because of its

mobile-first responsive. I did an assessment of the


front-end frameworks available at that time and
decided to use Foundation. I particularly liked
Foundations grid system and general philosophy.
The front-end was completed on schedule,
integrated into CQ5, and released with great success. I
believe that Foundations robustness was a big factor
to the success of the project. In fact the modules built
for the dotcom website are being used across various
other Barclays projects.
Thanks for producing this great framework, and
keep up the good work!

more robust grid system. When I design new web


projects, I always start by thinking about the mobile
experience before I move on to larger screen sizes,
and I personally feel like Foundation has an edge with
block grids and collapsible rows.

www.fullengineeringbook.net
The hassle-free

Prototype to production
THE TENETS OF FOUNDATION 6
Foundation for Sites 6 is aimed at helping people get
their projects from prototype to production. To make
sure every decision was working towards that goal, the
Foundation team came up with specific tenets that
include the following:
Prototyping in Foundation 6 should...
s Get me running with minimal dependencies, but
give me tools that modern sites need.
s Be able to rapidly produce a proof of concept in
code with easily readable presentational classes.
s)BWFBCBTFTUZMFUIBUJTBTVOPQJOJPOBUFEBTUIF
wireframes were replacing them with.
s(JWFNFBDPNNPOSBOHFPGQMVHJOTUIBUDBOCF
easily configured without writing JavaScript.
Production in Foundation 6 should...
sBe able to easily streamline code by using Sass
mixins to create semantic classes.
s-FUNFRVJDLMZQBSFEPXOUIFTUSFBNMJOFEJMFTJ[F
by selectively importing the components I used.
s#FTUZMFEUPNBUDINZDVTUPNEFTJHOTXJUIPVUUIF
need to override code or change tons of variables.

Yeti launch

setup it provides is
unparalleled

Once a site, app or email is uploaded to Notable


Code, users can receive contextual feedback on
SPIN UP FOUNDATION PROJECTS
JOEJWJEVBMFMFNFOUTBUBMMEJFSFOUTDSFFOTJ[FT5IJT
WITH THE PUSH OF A BUTTON
hopefully means plenty of feedback from clients and
Working with Sass and build systems is awesome, but
stakeholders on actual elements and not just vague
setting up a machine to work with them can be
notes about pieces of a website.
daunting. Some users really like the increased
The app itself was created using Foundation for
benefits a full web stack brings, but are
Apps and wrapped with an Electron shell.
simply not up for the challenge of
This allowed the ZURB team to use web
JS knows
hopping into command line to set up
technologies to rapidly prototype and
breakpoints
an entire build system.
then take those straight to a native
You can easily use JS to expose
Thats why along with the launch
app-like experience.
the breakpoint of the current
of Foundation for Sites 6, ZURB has
Future versions will include the
device by using the Foundation
released a free Mac app (also
ability to spin up templates and
MediaQuery object:
coming to Windows soon) to spin
selectively import components, and
Foundation.MediaQuery.
up any Foundation website, email or
in the very near future the
current.
app. This installs a new instance and
app will be expanded to Windows. Yeti
runs a build system to compile Sass,
-BVODIXJMMCFQFSGFDUGPSOFXVTFSTUP
Concatenate JS and even compress images.
TQJOVQQSPKFDUTRVJDLMZBOEFWFOGPSNPSF
Then it lets users take those projects and upload
BEWBODFEVTFSTXIPXBOUUPRVJDLMZBOEFBTJMZ
them into Notable Code, a new service to upload
create a prototype and share it for instant feedback.
prototypes and get contextual feedback straight on the
(SBC:FUJ-BVODIBUhttp://foundation.zurb.com/
coded pages.
develop/yeti-launch.html.

HTML5 & CSS3 Genius Guide 55

Front-end

Build your own JS plugin


DISCOVER THE TECHNIQUES NEEDED TO CODE A CUSTOM ADD-ON
Anyone who has ever needed to make a custom plugin
for a web design knows it can be a pain. Even if you
utilise a framework, there hasnt been a lot of built-in
support for layering over the top of it and creating
whatever doodads and whizbangs you might want.
Foundation 6 has solved this problem by ofering a
plethora of public APIs to make it faster and simpler to
integrate your own custom plugins. Part of the 50 per
cent code reduction is due to separating out these
common functions and these utilities. Were going to
show you how.
What were doing:
s Setting up a custom trigger for our element to fire,
based on the users input.
sGrabbing the index of the current card, well need
that going forward.
sCalling on our Foundation.Motion library and
animating the card out. For this demo, we used
slideOut(Left/Right) for swipe events and
scaleOutDown for button clicks.
sOnce our animation is complete, fire our custom
trigger and remove the card from the view as we dont
need it anymore.
Finally, if we opted for modals, (we did), lets invoke
that modals destroy method and clean up our DOM
structure a bit. Put it all together, and youve got yourself
a custom-built plugin that works seamlessly within the
Foundation framework. We save you time by providing
utility functions. There are a quite a few we didnt go over
in this article, but information about how to use them can
be found on our docs page. Weve given designers a set
of power tools to build their own plugins and
functionality, and we cant wait to see what you do with it.
The JS utilities in Foundation 6 save you time and
efort. Separating out the common functions into smaller
utilities saves code and gives you power tools for your
production. Foundation not only has very useful popular
plugins for you to develop with, but also tons of tools to
help you build your own.
To view the full code for this plugin, follow this link:
github.com/zurb/foundation-sites-6/blob/tutorial/
testing/js/swipin.js.

utilise this with:

$element.on('swipe swiperight swipeleft');


Foundation.util.motion.j is the file that is the JavaScript
behind the Motion-UI library. It adds custom classes to
add transitions to elements and move them ofscreen.
We will utilise this with:

Foundation.Motion.animateOut($element,
animationClass, function(){
//optional callback
//do stuff
});
This file is dependent on another helper file: foundation.
util.animationFrame.js,
which has one function to utilise hardware acceleration
to improve animation efects. This will be called with:

};
Plugin.prototype._events = function(){
//add event listeners
};
//add logic functions here \/...
Plugin.prototype.destroy = function(){
//remove event listeners
//remove elements from the DOM
Foundation.unregisterPlugin(this);
};
Foundation.plugin(Plugin);
These are the non-optional methods for each plugin, and
naming conventions should be followed (otherwise
Foundation._reflow() wont work!). Everything else is
completely up to you.
Now that we know how to start a plugin, we can build
our Tind...er, Card Swiping plugin, for succinctness and
humour, were going to call it Swipin. We know how to
build the skeleton of a plugin already, so lets look at the
_init function in detail.

Swipin.prototype._init = function(firstTime)
{
this.$element.addClass(this.options.
containerClass);
this.$cards = this.$element.find('.' +
Foundation.util.triggers.js is an event listener/
this.options.cardClass);
emitter helper file. This listens for click
if(this.options.hasDetail &&
firstTime){
Custom
events on:
[datathis._makeModals();
columns
close="idOfThingToClose"],
}
You can use the gridcolumn
[dataif(this.$element.find('.' +
function in order to create a
open="idOfThingToOpen"],
this.options.
column class with a custom size:
[databtnContainerClass).length){
@include gridtoggle="idOfThingToToggle"]
this.options.hasBtns = true;
column(4 of 5) makes an
as well as listening for any other events
}
80%wide column.
if(!Foundation.MediaQuery.
you may want to tap into.
atLeast(this.options.unstackOn)){
Next up is foundation.reveal.js. We want
this._stack();
details for our little image-filled cards, so lets
}
programmatically create some modals that will open
this._events();
when we click or tap on our cards. Reveal has its own
};
dependencies as well, including foundation.util.
Foundation.Move(timeOfAnimationInMS,
$element, function(){
//apply animations/transitions here.
});

www.fullengineeringbook.net

Build a responsive card swiper


Well start with some of the utility functions and existing
plugins were going to want:

Foundation.MediaQuery
This utility library has a few helper functions such as

Foundation.MediaQuery.
atLeast('breakpointString');
as well as an event emitter that triggers when a
breakpoint is hit.
Foundation.util.swipe.js is a file in the JS folder that
adds a swipe event emitter to jQuery elements. We will

56 HTML5 & CSS3 Genius Guide

sizeAndCollision.js, to properly size modal frames, detect


collision events, and set the ofsets of the modal element.
Were going to create these on the fly with:

new Foundation.Reveal($element);
and add a few elements within them.
That covers the basic components were going to
need, so lets see how a plugin is built. The basic
structure of each and every JS-based plugin is this:

function Plugin(element, options){


this.$element = element;
this.options = $.extend({}, Plugin.defaults,
this.$element.data(), options);
this._init();
Foundation.registerPlugin(this);
}
Plugin.defaults = {};
Plugin.prototype._init = function(){
//do stuff
this._events();

A few things that we did:


sAdd the container class to the root $element for
easy styling.
sCreate a jQuery collection of our individual cards.
s$IFDLBCPPMFBOUPTFFJGXFOFFEUPNBLFPVS
modals, the firstTime argument is passed from the
constructor functions call to _init(), we dont want to
make more modals when we reflow this plugin.
sCheck the markup for a button container, if we
have buttons, then well need that boolean in our event
handler.
sCheck the size of the screen, if its below our
unstackOn threshold, well stack our cards and add the
swipe event listener.
So we know we can programmatically create plugins
with our JS, lets see what that looks like.

Swipin.prototype._makeModals = function(){
var _this = this,

HTML5 & CSS3

Genius Guide

New Foundation for Sites


6 JS Plugins
Stick anything, anywhere (nearly)
Make sticky sidebars that fix position as the page
scrolls and can unstick when they hit other elements,
or a sticky topbar navigation that follows users down
the page. Items can stick to the top, bottom, left or
right and anchor to any other element on the page.
Simply add the .sticky class and [datasticky] to an
element to create something that sticks. Sticky
elements must be wrapped in a container, which will
determine your sizing and grid layout, with [datasticky-container].

$modals = $modals.add(reveal.$element); //
modal = '<div class="reveal" data-reveal></
we dont need the elements, so $modals is
div>', //declare our reveal markup
a temporary variable
closeBtn = '<button class="close-button"
});
aria-label="Close alert"
$(document.body).append($modals);// attach
type="button"><span>&times;</span></
them to the DOM all at once.
button>', //utilize a Foundation helper CSS
};
class close-button
lorem = '<p>This is just some lorem ipsum
Now we have our modals, they are attached to the
for this tutorial</p>'; //and generate some
DOM, and they have open and close triggers applied to
generic text for the sake of this lesson.
them, thanks to our handy triggers library. Next, check
var $modals = $(); //create an empty jQuery
out the _events function. It manages triggers from
collection, well need that in a minute
media query changes and applies event listeners to our
this.reveals = []; //save our shiny new
cards. It will need to delegate some tasks to helper
modals to our current plugin, we need that
functions, but well leave those out for brevity.
too!
Swipin.prototype._events = function(){
this.$cards.each(function(){ //iterate
var _this = this;
through all our cards
$(window).on('changed.zf.mediaquery',
var $card = $(this),
function(){
imgSrc = $card.find('img').attr('src'), //
_this._handleMQChange();
since each card has an image, grab the src
});
attr
if(this.stacked){
id = this.id || Foundation.
this._addSwipe();
GetYoDigits(6, 'card-detail'), //
}
we need an id for our triggers
this.$cards.off('click.zf.swipin
Responsive
utility functions, so lets
tap.zf.swipin')
typography
make one. GetYoDigits gives
.on('click.zf.swipin tap.zf.
Change the values in the
you a psuedo-random string.
swipin', function(e){
$headersizes variable in
reveal = new Foundation.
_this._handleClick(e,
order to create responsive
Reveal($(modal).attr('id',
$(this));
typographic scales that change
id)),//generate our modal
});
to adapt themselves to a
for this card
};
variety of diferent
$closeBtn = $(closeBtn).
Here, were applying a listener to the
screen sizes.
attr('data-close', id); and
window, for media query events, and
update our close button with the
adding the click handler for our cards. Since
data-close attr for our triggers utility
we only add the swipe listener when the cards are
$card.attr('data-open', id);
stacked, lets take a look at our card markup, CSS, and
reveal.$element.append($closeBtn, '<img
stacking logic.
src=" + imgSrc + "/>' + lorem);//append
The markup:
our elements to the modal we just created
<div class="row medium-up-3" data-swipin>
_this.reveals.push(reveal); // and save our
<!-- this data attribute is what foundation
new modals to their proper place
looks for to initialize your plugin -->

<divclass="columnssmall 6right"data sticky


container>
<divclass="sticky"data sticky>
<imgsrc="assets/img/interchange/small.jpg">
</div>
</div>

Toggler add and remove classes


without writing JS
Quickly prototype interactions by toggling classes
onto any element using simple data attributes. To
setup a class toggle, start by adding the attribute
datatoggler to an element. The value of datatoggler is
the class you want to toggle. Also give the element a
unique ID so it can be targeted. Then, add datatoggle
to any element, with the ID of the target as the value of
the attribute. Now, any time you click on this element,
the class will toggle on and of on the target.

www.fullengineeringbook.net

<ulclass="menu"id="menuBar"data toggler=".
expanded">
<li><ahref="#">One</a></li>
<li><ahref="#">Two</a></li>
<li><ahref="#">Three</a></li>
<li><ahref="#">Four</a></li>
</ul>
<p><adata-toggle="menuBar">Expand!</a></p>
<div class="column card"> <!-- repeat as
many of these as you like -->
<div class="thumbnail">
<img src="http://placehold.it/450x650">
<div class="button-group expanded">
<a class="button tiny alert">No Thanks</a>
<a class="button tiny success">Yes Please</
a>
</div>
</div>
</div>
</div>
The Sass:

.swipin {
position: relative;
top: 50px;
.thumbnail .button-group {
margin-bottom: 0;
margin-top: .25em;

HTML5 & CSS3 Genius Guide 57

Front-end
.button {
border: 1px solid #FEFEFE;
border-radius: 0px;
}
}
}
.is-stacked .column {
position: absolute;
left: 0;
width: auto;
transition: transform .5s ease;
transform: scale(0.6) translate(0px, -30%);
}
.is-stacked .column:first-child {
transform: scale(1) translate(0px, 0);
}
.is-stacked .column:nth-child(2) {
transform: scale(0.9) translate(0px, -10%);
}
.is-stacked .column:nth-child(3) {
transform: scale(0.8) translate(0px, -20%);;
}
.is-stacked .column:nth-child(4) {
transform: scale(0.7) translate(0px, -30%);
}

$(this).css('z-index', '')
.find('.' + _this.options.btnClass).show();
});
this.$element.removeClass('is-stacked')
.trigger('unstacked.zf.swipin');
this.stacked = false;
};
While our cards are unstacked we get:

};
Because the whole card has an event listener, we
need to see if one of the buttons was clicked, and if it is
then we will stop propagation so our event doesnt
bubble to our [data-open] listener and open our modal. If
it wasnt a button though, lets allow that modal to open.
Our swipe listener will look like this:

this.$cards.off('swiperight.zf.swipin
swipeleft.zf.swipin')
.on('swiperight.zf.swipin', function(e){
e.preventDefault();
_this._swipe($(this), 'Right');
}).on('swipeleft.zf.swipin', function(e){
e.preventDefault();
_this._swipe($(this), 'Left');
});
Which calls this:

Which, when stacked gives us:

The stack is simple, merely adding a class to the main


element, setting a z-index so the cards stack correctly,
and hiding buttons as well be swiping now:

Swipin.prototype._swipe = function($card,
dir){
var isYes = dir === 'Right';
this.dismissCard($card, isYes, 'slideOut' +
dir);
};
And this dismisses our card with the slideout animation
to the left or right. This function, is the bread and butter
of this whole plugin. We wanted to make two common
user interactions, click buttons and swiping right or left,
and combine them in a responsive way with a
recognisable layout.

www.fullengineeringbook.net

Swipin.prototype._stack = function(){
var counter = this.$cards.length,
_this = this;
this.$cards.each(function(){
$(this).css('z-index', counter)
.find('.' + _this.options.btnClass).hide();
counter--;
});
this.$element.addClass('is-stacked')
.trigger('stacked.zf.swipin');
this.stacked = true;
};
The _unstack function is pretty similar:

Swipin.prototype._unstack = function(){
var _this = this;
this.$cards.each(function(){

How to build with the


Motion UI
CHECK OUT FOUNDATIONS SASSBASED ANIMATION LIBRARY
Motion UI ships with over two dozen premade CSS
transition classes, which we used in the tutorial.
However, if you want to streamline your CSS output,
and create more fine-tuned efects, you can use
Motion UIs Sass mixins.
First, comment out

@import motion-ui-transitions in app.scss


to remove the pre-built classes.
Next, add this code to your Sass file. Well replace our

58 HTML5 & CSS3 Genius Guide

Now were getting somewhere! Of course, though we


have our cards and they stack nicely, we have to be able
to do something with them. Lets look at our click and
swipe handlers

Swipin.prototype._handleClick = function(e,
$card){
var $target = $(e.target),
isBtn = $target.hasClass(this.options.
btnClass);
if(isBtn){
e.stopImmediatePropagation();
var isYes = $target.hasClass(this.options.
yesClass);
this.dismissCard($card, isYes, this.options.
animOut);
}

basic slide with a custom hinge.

.hinge-in {
@include mui-hinge(
$from: right,
$fade: true,
$duration: 0.25s,
$timing: easeInOut
);
}
.hinge-out {
@include mui-hinge(
$state: in,
$from: right,
$fade: true,

Swipin.prototype.dismissCard =
function($card, isYes, animOut){
var trigger = (isYes ? 'yesplease' :
'nothanks') + '.zf.card',
idx = this.$cards.index($card),
_this = this;
Foundation.Motion.animateOut($card, animOut,
function(){
$card.trigger(trigger, [$card]).remove();
if(_this.options.hasDetail){
_this.reveals[idx].destroy();
}
});
};

$duration: 0.25s,
$timing: easeInOut
);
}
Lastly, in

plugin.js
, replace the references to

slide-in and slide-out with hinge-in and


hinge-out
When you refresh the page and use the plugin, youll
see the new efects in place. You can refer to Motion
UIs full documentation (at https://github.com/zurb/
motion-ui) to learn more about making use of the
custom efects.

HTML5 & CSS3

Genius Guide

A look ahead at Foundation


for Apps 2
WHAT DOES THE FUTURE HOLD FOR ZURBS WEB APP FRAMEWORK?
Last year ZURB launched Foundation for Apps, an
Angular-powered framework that was primarily
focused on creating fully responsive web apps. It
includes a flexbox-powered grid built for flexible,
responsive app layouts, in addition to a series of Angular
directives for creating of-canvas panels, modals,
notifications, and more.
Foundation for Apps was created as a brand new
framework, because the team at ZURB felt like
Foundation 5, while an amazing tool for building
websites, was not as great when it came to building web
apps. Further, there were no existing solutions in the
open source world for building fully-responsive web apps
designed specifically for the browser. Much like how
Foundation for Emails (previously known as Ink) is
designed specifically for HTML email, Foundation for
Apps is designed specifically with HTML apps in mind.
The framework borrows fairly heavily from existing
ideas in Foundation for Sites, but it also includes many
unique components specifically designed for responsive
web apps, including a flexbox-powered app grid,
collapsible panels, flexible menu patterns, and responsive
action sheets. The frameworks JavaScript is built on the

Angular framework, so its specifically designed with


single-page apps in mind. Foundation for Apps also
shipped with a small plugin called Front Router, which
allows for the creation of Angular routes (URLs) directly
within the HTML of each page.
Version 1.0 of Foundation for Apps launched in
December of 2014, and the Foundation team is already
hard at work on Foundation for Apps 2, which is going to
be powered by version 2.0 of the Angular framework.
Foundation for Apps 2 features even more robust
responsive layout options, a greatly improved visual style,
and more powerful Angular components. Many ideas
developed in Foundation for Sites 6 will also be ported to
Foundation for Apps 2, ensuring it features all the latest
improvements.
Angular 2 is a drastic departure from Angular 1, so the
JavaScript codebase will be overhauled to fit Angular 2s
new design patterns. The code will also be written in
TypeScript, a new superset of JavaScript designed by
Microsoft its also the oficial language of Angular 2.
Angular 2 is due to launch next year, and ZURB will be at
the forefront of Angular 2 development with Foundation
for Apps 2.

where theyre opened. Sone of the features in 2.0 include:


s"GVMMZMFYJCMFHSJE even on small screens! That
means you can create any number of columns and have
a fully flexible small grid.
s#VJMUXJUI4BTT This means you can wield the
powers that come packaged with Sass including
variables, mixins and partials!
s/FXUFNQMBUJOHMBOHVBHFn*OLZ Say goodbye to
sifting through hundreds of pesky table tags. With Inky
you can write tags like <row and <columns> to spit out
the six table tags needed to just get the skeleton of your
email together.
s)FMQGVM6*DPNQPOFOUT Row, Columns, Callouts,
Inline Lists, Vertical Lists, Block Grid and Thumbnails.
s*OMJOFBMMPGUIFTUZMFT Theres a handy Gulp task
that inlines all your CSS from a remote stylesheet.
s)BOEMFCBSTUPLFFQZPVPOUSBDL Weve included
the support of Handlebars templates to keep you from
repeating yourself! Things like the header and footer of
your email can stay the same, allowing you to change
only the content that matters!
Weve also packaged up a handful of battle-tested
templates to get you up and running with Foundation for
Emails 2.0! Were really excited to share the workflow
improvements with the world, and cant wait to see what
you can do with it.

www.fullengineeringbook.net

Angular 2 is due to launch next year,


and ZURB will be at the forefront of
Angular 2 development

Responsive emails
GET ALL-SCREEN FRIENDLY

Brandon Arnold
Foundation Lead, ZURB
We wanted to learn how people actually used
Foundation, so we travelled around the world and
hopped on hundreds of calls to actually watch how the
community used the Framework and discussed what
they needed from it. It was amazing!

Responsive email design has been growing steadily in


popularity, and its no surprise as to why: 47 per cent
of email opens are actioned on a mobile device
(litmus.com/blog/mobile-opens-hit-record-highof-47), and some brands see upwards of 70 per cent of
their emails opened on mobile. Ensuring that emails
looked good on any device was imperative, therefore
ZURB created Foundation for Emails, formerly known as
Ink, for our own emails. This was then later released to
the general public as open source software.
Foundation for Emails helps people build responsive
emails that look great on all major email clients,
especially Outlook! We took on the significant workload
of figuring out all the diferent quirks in all the most
popular email clients and devices in order to provide a
framework for creating emails that just work, no matter

&YBNQMFDPEF

<row>
<columns large=8 small=4>
</columns>
<columns large=4 small=8>
</columns>
</row>
A better solution than this:

<table class="row">
<tr>
<td class="wrapper">
<table class="six columns">
<tr>
<td class="expander">
</td>
</tr>
</table>
</td>
<td class="wrapper last">
<table class="six columns">
<tr>
<td class="expander">
</td>
</tr>
</table>
</td>
</tr>
</table>
<row>
<columns large='6' small='12'>
</columns>
<columns large='6' small='12'>
</columns> </row>

HTML5 & CSS3 Genius Guide 59

Front-end

Is your
content
king?

www.fullengineeringbook.net

Content-led design is the future. Get ready for


your brand to succeed with a seven-step plan

60 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

Why do you need


content strategy?
STOP! DONT DESIGN A THING UNTIL YOUR
CONTENT STRATEGY IS SOLID
Design is content. Content is design; its time to get over the old
designers-dont-do-words story. Its time to get intimate with
content, and embrace it as the first fundamental part of any design
journey. But before we begin, lets start by defining what a content strategy is.
There are so many versions of this answer, but really every single one boils
down to this: a content strategy is a road map.
To make better design decisions, you need to know what content is
needed for the business to fulfil its promise. For example, if your client wants
to be the best online pet store, youll need to know what content the
customers will be expecting and demanding from such a proposition first.
Otherwise, anything you produce will fall on deaf ears or worse, itll bug
them so much, theyll start spouting bad press about your brand. It really
does happen, for something so seemingly small.
So why do you need content strategy? It grounds you. It saves time. It
saves money. It saves your sanity. When you start talking to your client about
their business vision and the content they need to fulfil that promise
authentically, you can start to have a conversation about the experience
youre creating, not simply whether the logo is in the right place or the right
size. Imagine, a client/designer relationship where youre both focused on the
nuts and bolts of the content first, where the client doesnt simply say they
love it, like it, dislike it or hate it they can articulate why it does or doesnt fit.
Its time for some new thinking. And if youre someone whos serious about
solving problems with your design, this is really, truly the new way to work.

Natasha Spice
Designer at Folk
@natashalindblum

Starting a project off with a


content strategy means I can solve
problems for real people. Designs
can look and feel fantastic, whilst
leaving the client and the end-user
feeling empowered

www.fullengineeringbook.net

Five masters of content cartography


THESE ORIENTEERS REALLY KNOW THEIR WAY AROUND THEIR BRAND VISIONS

airbnb airbnb.co.uk
Airbnbs content courses through the site. Belonging is everything, so
customers feel at home anywhere in the world.
Warby Parker warbyparker.com
Everything feels like part of a whole. Consumer empowerment, the
cool but not over-the-top previews. Shame theyre stateside though.
Hatchet + Bear hatchetandbear.co.uk
Homely, rustic, unique Hatchet + Bear know themselves. They
understand consistency of personality, which is why theyre always
out of stock.
Go Pro gopro.com
Go Pros genius hinges on cleverly showcasing its users footage
throughout the site experience its marketing that makes itself.
General Electric ge.com
By creating content linked to vision, the story General Electric tells
goes from boring to brilliant, fostering genuine community and
action around a greater cause.
HTML5 & CSS3 Genius Guide 61

Front-end

Getting
started
THE BASICS OF A KILLER CONTENT
STRATEGY, IN LINE WITH YOUR
BRAND VISION
So, youre about to design a website. Hold it. First, we
need to hail back to the old school and draw up a
scenario to really think about the process.

Case study

ASOS

asos.com

Most people are at least aware of ASOS in some


capacity, even if they dont fall into their
20-something demographic. Its an online fashion
superstore, fundamentally. But they are so incredibly
good at seamlessly incorporating their content into
design, product and messaging that it would be rude
to leave them out of this feature. Flawless user
experience and targeting means that their customers
have literally no reason not to buy again, again and
again. Everything is spot on, and laser-focused.

Lets say Mr and Mrs Customer saunter up to you and


say, Hi, Id like to buy a car.
And you say, Sure, what kind of car do you want?
Any will be fine, they reply. Four wheels and a
chassis. You nod. You head over to the garage, and after
a few minutes, you pull up in a shiny new hatchback.
They look plain-faced for a second.

Theyre great at weaving stories through their


products and collections, but notice that its never
ever contrived; think the Festival Chic theme that
takes control of their Womens section. This is, once
again, something that their customers genuinely
want; its a style that meets their needs and ambitions
at the current time in context with whats happening
in their customers worlds. Its also a theme that is
bound to be a big product seller for the company too.

www.fullengineeringbook.net

Thats not going to work, Mrs Customer says. Where


will our five children sit?
Dont clench your fists in fury just yet. You could have
predicted this.

The user journey

Theyre exceptional at picking partnership


opportunities which feel on-brand like Britains Next
Top Model for example, and a variety of festivals
right now ASOS are working on connecting clientele
with Glastonbury. Like their content, this is
down to good old-fashioned research. The
time, the place; the connection. These
Every page is
partnerships are tailored to the
a landing page
consumers needs to a hairs width.

What does a typical user want to do? What


are their goals in life, their gains and their
pains? Put yourself in their shoes for a
second. They might want to spend
People wont just be landing
more time with the kids. They might
on your homepage. Think about
want to succeed in their job, or
the multitude of ways a customer
attain the perfect work-life balance.
can come to the site. Each page
Whatever it is, you need to find this
think of. This is bigger than business.
should be self-contained,
goal out, and articulate exactly how
The answers here will be more honest,
self-explanatory and
you can help them achieve it with your
and more valuable than a dozen surveys.
unconfusing.
website. If content is king, then the
Sure they might not be as representative as
customer is the supreme overlord of the
a 10,000 strong body of consumer data, but its
universe. You want them to provide the clicks.
more specific. Its real.
But how do you get the kind of information to make
All you need is a trend of five or six, and you can start
this specificity happen? Everyone knows how annoying it
to get a feel for a customer type and then following on
can be to have some anonymous organisation cram a
from this you can start to sense the kinds of content that
survey down their throats for the chance to win x or y.
might help them to achieve what the clients actually
The problem here lies in the approach. Hell, were already
want to achieve. Another benefit that can be gained here
kicking it old school, so lets just hang around for a while;
is that you can gain useful, precise feedback on ideas
the best way to find this information is to physically talk
roaming uncharted territory.
to people, face to face. Talk to your friends, neighbours,
Its a good idea to evaluate any existing content once
family members, clients, and anyone you happen to be
youve done this. This includes anything you or your
chatting to through sheer serendipity.
client may have already, but focuses more specifically on
Ask them what makes them happy, sad; ask them
your competitors.
what would be their proudest moment if they had the
Get a big list brands whose products are similar,
opportunity. Ask them what grinds their gears, and what
whose audience is similar, whose mantras are similar
theyd like to have done as a kid. Everything you can

62 HTML5 & CSS3 Genius Guide

and pick them apart. Youll usually find a hairs width


angle in the market thats untapped by anyone. Learn it,
own it, master it. This is yours. Write the user and
competitor analyses down. Stick them on the wall.
Theyre your bible now.

Sitemapping
Before you start writing any content, or drawing up any
designs, youll need a comprehensive map of the pages
you need, an idea of what theyll contain, and how theyll
interact with each other.
A logical sitemap enables you to maximise your user
experience; to see the bigger picture ahead. It also
makes it infinitely easier to delegate content generation
tasks to freelancers when youve got every item of detail
listed out. Moreover, the impact of call to actions can be
clearly distinguished for an excellent site journey with
admirable click-rates. This same concept is true when it
comes to actually designing each page and page

HTML5 & CSS3

Genius Guide

Mobile and desktop are one thing, but when


youre ASOS, youve got a dragons wealth of
content to deliver. And people want to read it.
Thats why they span multiple channels
digital and analogue ofering things like the
ASOS magazine, which you get for free with
ASOS Premium.

ASOS are adept in knowing their customer.


This knowledge allows them to create content
that is always relevant, useful, interesting and
truly resonates culturally with their
customers. This makes users want to ofer
things like their phone number as they know
itll be used to enhance their experience.

www.fullengineeringbook.net

ASOS live and breathe omnichannel. The


symbiotic relationship between content and
design is wholly consistent everywhere from
the website to email messaging, to social
media, and even their postal slips. This means
that you always know where you are, and this
builds excellent trust and usability.

component when the contents in place. Heres the


slightly tricky part though. How can you design a website
that melds seamlessly with its content if you dont have
the content itself, using just lorem ipsum to fill in the
spaces? And how can you write excellent content when
youre unsure of its design context? The answer is simple:
mock up the content yourself.
It might not seem like its in your remit, and as far as
finished products go, its not. But lorem ipsum is the
mortal enemy of a content-first approach. If its an events
page youre drawing up, throw in the date, a title and a
description. It doesnt have to be good content; it doesnt
even have to be grammatically correct but its better

than using a placeholder when you have no idea what


the finished product will actually look like.
Leave the writing of any of the fancy stuf to your
copywriter. This extra distance will make it easier for
clients to see the whole picture, and get a better feel for
the site in the lead-up to sign-of. It makes it a hell of a lot
easier for your content writer to populate too. And finally,
it makes it so much easier for you to design a site whose
essence is there already.
Another point is an important dont. Dont ever,
under any circumstances allow the luxuriousness of a
brand to influence the readability of its content. Heres an
example. Lets say your sites a piece of high-shooting

A logical sitemap enables you to


maximise your user experience; to see the
bigger picture ahead

Plot an effective
analysis
You need a solid understanding of a number of
things in your competitor analysis. This ranges
from homepage meta descriptions and tone of
voice, to content themes, objectives, and how
efective these appear to be. When youre
confident in this, you can plot it and put this to use.
Youll need to select two scales, set against axes,
eg in a cross-section of cosmetics brands,
sustainability/technology vs. fun/professional. Put
an X for each brand studied according to how they
fare on these scales. Once youve plotted eight to
12 Xs, youll notice a significant gap in this
spectrum. Thats the flavour your content needs to
have to secure a space in the market.

HTML5 & CSS3 Genius Guide 63

Front-end

Finisterreuk.com is pretty minimal.


Notice that only the boldest CTAs
are present on mobile

www.fullengineeringbook.net
Dont fall into the content dump trap. If its an
important CTA, hero it on your homepage, even
on mobile devices

Youll
never get it
straightaway

contemporary art. It sells high-price-point goods to


high-net-worth customers. The first temptation for many
is to put on airs with the content. But if its a luxury
product, surely its got to sound luxury, right?
Wrong. Kind of. If your product or service is what your
customers are looking for, dont put them of with
verbosity. Often, youll lose traction in your attempts to
be descriptive. Keep sentences simple, and try to include
just one concept in each. Use the active voice, and write
as if you were having a conversation with your customer.

Start as close to the end as


possible, and dont waste your
readers time
The legendary American writer, Kurt Vonnegut, said to
remember these two points. Ultimately, it boils down to a

Learning your customer takes


time. Youll need to use analytics to
check how theyre interacting with
few things. Research your customer
content. You need to take this
With this information to hand, next
extensively. The more you know about
information and constantly
youll need a sitemap. As mentioned
the customer, the greater clarity youll
tweak and improve.
earlier, this gives you a pragmatic
have on the direction, themes and purpose
knowledge of every pathway, every step,
of your content.
every call to action, and every goal within your
Know their desires, their fears, their ambitions, their
site. It naturally gives you a comprehensive list of every
habits, their favourite brands, and more. Research these
page too, so itll keep you and any content delegates
brands and other competitors extensively. This
sane and ordered when it comes to designing and
includes any content youve done before. The more you
populating the site. Remember that dropping in some
know about them, the more likely it is that your content
rough working copy gives the work some vibrancy.
will find a home in the marketplace.
With your themes and content/design relationship
Looking at your own past content will assist you in
bubbling along nicely, dont neglect to check your
identifying why things may not have worked so well
readability. You can do test this out by using a number of
previously, and might highlight ways you can specifically
online sources just look up Flesch-Kincaid, and aim for
improve. This research stage is crucial, as itll define the
a score of 65 in its Reading Ease results. Note that the
parameters for your content to sit within.
higher the score, the easier it can be understood and
vice versa. Texts like Time magazine for example have a
score of about 52 whereas the BBC News website comes
up as 67.4 (bit.ly/1Hq0pmd). Remember: even the most
elite, technical or hard-to-find products need to be
accessible to an online reader. Okay. Now you can move
past content strategy and start designing again.

With your themes and content/design


relationship bubbling along nicely, dont
neglect to check your readability
64 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

to
Desktop vs mobile Nine
Follow
SHOULD CONTENT DIFFER FROM DESKTOP TO MOBILE? YES. ABSOLUTELY

If your customer is looking for of-the-cuf, pass-the-time


accommodate users stubby fingers. Similarly, but more to
content say theyre commuting on the Tube then its
do with software and download speed restrictions, there
unlikely theyll be viewing it on their PC device. Say
are far fewer large graphics on a mobile site. Its kind of
theyre conducting some in-depth research
like the distinction between a corner shop and
Dont
for a paper: they wont be doing it on
a supermarket; ones a little more
forget buttons
their smartphone. This kind of
expensive, with a smaller range of
Ban Submit from your
distinction is especially true for
products available, but its super easy
dictionary. Use CTAs which grab
features like store finders.
and requires much less efort. For the
user attention and are relevant to
Chances are, people are more
other, the opposite is true. Both play
what you want them to do. If youre
likely to use a smartphone for
an important role in our lives
ofering something for free, use
viewing content when theyre on the
Credibility or bust
get. If you want to inspire
go so bringing it to the forefront for
People online are sceptical about
a purchase, say
mobile is important. If you want to take
everything, so make sure to include trust
purchase.
it one step further, great integration with
indicators in your designs. And while you dont
map software means your customers will
have to state them in your copy, just keep your trust
know youve thought
promises at the front of your mind. Place any trust
about their journey.
indicators somewhere that follows the eye so they feel
Next, and unsurprisingly, mobile should be as minimal
natural and unobtrusive.
as possible. Its pretty obvious that when youre designing
for 320 x 480, you cant include half the stuf you would
Where does site traffic come from?
for 1920 x 1080 without sacrificing a scary chunk of
usability. This is when your user journey from before
comes in handy. Think back to their pains and gains.
What content do they want? Boil every last speck of your
site content down to the essence that drives your
customer, and minimalism wont be a problem.
On a related note, theres a lot less floating hypertext
content on a mobile site, but thats not because the links
arent there. Youll typically see a greater number of
Source Shopify, August 2014
buttons and bars which serve this linking function, to

THE ALL-IMPORTANT ACCOUNTS

Alistapart
@alistapart
For people who make websites some fantastic
resources and authors.

Ian Lurie
@portentint
Ian provides great tips for optimising everything to do
with web and design.

Jonathon Colman
@jcolman
The content strategist at Facebook shares his
thoughts and insights about everything you do.

Kristina Halvorson
@halvorson

www.fullengineeringbook.net
50.3%

49.7%

Content Strategy
for the Web
contentstrategy.com
@BrainTraffic
Written by Kristina Halvorson and Melissa Rach,
this is one of the best books about content
strategy available today. It gives so much
information and many tips to make what could be
a complicated process very simple, and it gives
some totally solid reasons to share with clients
about why its best to get the content parts sorted
first above all else. Its a manual that provides you
with the knowledge to deliver meaningful and
efective content when and where its most
relevant to your clientele. It also helps you
understand processes, teaches you to make better
decisions and plan for the long term.

Author of one of the most useful books on content


strategy, Content Strategy for the Web, Christina
knows her stuf.

The Content Marketing


Institute
@CMIContent
As the name suggests, this Twitter account is more
focused on content marketing, but still has some
great resources and insights.

Melissa Rach
@melissarach
The co-author of Content Strategy for the Web,
regularly posts about the latest content case studies.
Melissa describes herself as a content nerd.

Contents magazine
@contents
A digital magazine dedicated to the art of content
strategy & online publishing. It hasnt been updated
since 2013 but still divulges some must-know topics.

We Live Content
@welivecontent
This account shares timely and useful resources for
content marketers and content strategy professionals.
Something new appears daily.

Karen McGrane
@karenmcgrane
Karen is an experienced content strategist who on a
good day makes the web more awesome. She is also
the author of Content Strategy for Mobile.

HTML5 & CSS3 Genius Guide 65

Front-end

Design aspect ratiobased layouts with


HTML and CSS
Building tile-based UIs can be complex. Discover how to make
this process easy and create responsive aspect ratio layouts

www.fullengineeringbook.net

66 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Traditional web builds assume content is


flexible and likely content managed. Boxes
change in height as the page resizes because
theyre defined by a percentage width and their content.
But this flexibility isnt always an absolute requirement.
We can craft more interesting layouts when content is
well defined.
Aspect ratio-based layouts prioritise proportion over
content. In this sense the process is much more like
editorial with all of its pros and cons. The aspect ratio
approach gives us more design control but its much
more labour intensive to produce a good experience. If
your client does not want to engage in editorial processes
or requires flexible systems then steer clear!
This approach is fantastic for scenarios where data is
well defined or can be truncated without issue or where
iconography is more important than text. Dashboard
pages, widget collections and even some web
applications are all digital experiences that could benefit
from this approach.
Here were going to cover how to semantically build
aspect ratio-based layouts, approaches for dealing with
overflowing content, and overcoming the issues with
making aspect ratios work responsively.

1. Download files

3. Style aspect ratios


Were using the ratio data attribute we created as a
selector (supported by IE9 and up). Set the height to 0
and control the size of the box with padding only. As
were creating a square, the padding is equal to the width.
We also hide any child content if it were to overflow.

.aspect[data-ratio="1:1"] {
max-width: 100%;
height: 0;
padding-bottom: 100%;
overflow:hidden;
background: rgb(211, 22, 22);
color: #fff;
}

.aspect-content {
margin: 20px;
}

6. Add imagery
Working with images in aspect ratios is tricky. We want
the image to scale, but we dont want to distort it. With
this in mind, we will need to write markup that enables us
to crop it if necessary.

<div class="aspect" data-ratio="2:1">


<img src="./img/floor-3.jpg" alt="" />
<div class="aspect-content">
<h4 class="headline">Directions</h2>
</div>
</div>

4. Harder ratios
Using 4:3 is a little more complicated because we have to
do some maths to figure out this ratio. The way to
calculate how much padding you need to give an
element is by dividing the height by the width and
multiplying by 100. So for example we would use in this
case: 3 / 4 = 0.75 * 100 = 75.

.aspect[data-ratio="4:3"] {
max-width: 100%;
height: 0;
padding-bottom: 75%;
background: rgb(223, 28, 66);
overflow: hidden;
color: #fff;
}

7. Style the image


Here we position the image absolutely, relative to its
parent container. We also tell it to fit its parent container
with the max-width property and have it crop from the
bottom right. We also want this image to sit behind
everything, so give it a z-index of 0.

.aspect {
position: relative;
}
.aspect img {
max-width: 100%;

www.fullengineeringbook.net

The ZIP file provided on FileSilo for this tutorial contains


all the assets that we will be using along with a basic
boilerplate setup. Were going to use an npm package
called http-server to serve our files.

2. Mark up aspect ratios

5. Style aspect content

The aspect ratio boxes dont have any semantic value in


this tutorial, so weve used <div> tags. They could be
<section> tags if appropriate. Were also using data
attributes to semantically describe our aspect element.

The content inside any given aspect box will look bad if it
sits flush against the edges of the box. We can get
around this by giving a margin to the .aspect-content div,
which should wrap all written content in a given box.

Compress images
The images provided in this tutorial are
uncompressed they weigh 4MBs each. Images
can be compressed in Photoshop with the save
for web dialog or an npm module like imagemin.

Left

The image weve put in is far too large. Lets make it fit
our page better
Top left

This is the aspect-ratio technique. The rest of the tutorial


focuses on working with other ratios and content
Top right

This is what you should see when serving the files from
the start-here folder

HTML5 & CSS3 Genius Guide 67

Front-end
position: absolute;
right: 0;
bottom: 0;
z-index: 0;
}

8. Content to the front


We need to bring the content to the front so were giving
it a higher z-index than the absolutely positioned image
and we give it the lowest possible z-index for this efect.

.aspect-content {
z-index: 1;
position: relative;
}

9. Link the boxes to other pages


Here we take the 2:1 box and wrap it in an anchor
element. In HTML5 this is valid so long as there isnt an
anchor within an anchor. We also give this anchor a class,
which we will use to change styles specifically to this box.

10. Style directions


Were overriding the normal .aspect-content styles so the
content area fills the box and resets margins. Flexbox
brings the content to a vertical and horizontal centre.

.directions .aspect-content {
width: 100%;

height: 100%;
margin: 0;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}

11. Animate hover on directions


We want the hover state to change the entire tile as the
area is clicked. Weve created a cubic-bezier transition for
a nicer animation and all attributes that change between
normal and :hover states will animate using this.

.directions .aspect-content {
color: rgb(55, 55, 55);
background-color: rgba(255, 255, 255, 0.83);
transition: all .5s cubic-bezier(0, 1.14, 1,
1);
}
.directions:hover .aspect-content {
background-color: rgba(47, 47, 47, 0.8);
color: #fff;
}

12. Animate the image hover


Fading the image out on hover will pull focus to the text
and therefore the action of the box. We use the same
animation and timing as the other hover efects on this
element. The short duration is important because were
used to state changing instantly on hover. Animations
over .5s feel sluggish.

opacity:.5;
}

13. Bring it together


Now weve got the diferent aspect ratios and some
styles together we need to pull it together. Because the
aspect boxes are fully responsive we can simply wrap
them inside a div that limits their width.

<div class="one-half">
<a href="#directions" title="Directions to
event" class="directions">
<div class="aspect" data-ratio="2:1">
<!-- -->
</div>
</a>
</div>

14. One half and one quarter


The one-half class limits the width of its child elements to
50% and will try and float itself along side other content.
It works for siblings like other grid systems, but you also
nest them to get quarters.

.one-half {
width: 50%;
float: left;
}
<!-- Nesting to get quarters! -->
<div class=one-half>
<div class=one-half>
</div>
</div>

www.fullengineeringbook.net

Avoid styling
Large images with CSS styles on (like opacity)
can take longer to render which makes
animations slow. Try avoid applying styles to
images and instead animate simpler elements.

Top left

Positioning the content over the image required both


z-index and position-relative properties
Top right

Flexbox works across evergreen browsers. For older


browsers the text will just be aligned top left
Right

Instead of modifying the image we simply use transparent


backgrounds and animate the content that sits on top of it

68 HTML5 & CSS3 Genius Guide

.directions img {
transition: opacity .5s cubic-bezier(0,
1.14, 1, 1);
}
.directions:hover img {

15. Going responsive


Where we go responsive will depend entirely on the
content you wish to place in the boxes and how you
structured the one-half markup. You will have to resize

HTML5 & CSS3

Genius Guide

Changing aspect
ratio sizes
Unfortunately, aspect
ratios dont work across all
screen resolutions so
when we go responsive
we may actually end up
with a bad looking UI.
There are a few options
available to us to fix this
problem: write JavaScript
to group the elements
diferently under diferent
.one-half boxes, write
JavaScript to modify the
data-ratio attribute as
required or write CSS to
change up the aspect
ratios themselves.
These diferent
approaches all have pros
and cons. The upside of
using this pure CSS
solution is that it performs
really well across all
devices, but it also means
that you have elements
which say that they are 1:1
but in reality they will have
many diferent aspect
ratios as and when the
page resizes.

www.fullengineeringbook.net

your window and see where things break. In the build


example provided there were adjustments needed to the
one-half class at 1000px.

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


.one-half {width:100%;}
.one-half .one-half {width:50%;}
}

16. 420px and below


We also had to bring the nested halves back to 100% at
420px and below so all the content remained visible. In
the build example there are 1:1 boxes inside the nested
halves, so were still able to see two boxes in a portrait
view on a mobile device.

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


.one-half .one-half {width: 100%;}
}

17. Changing aspect ratio


There was also a need in the example to modify the
aspect ratios as the browser got smaller. This was
because they became too large when the halves
stacked. It feels counterintuitive to have a ratio of 1:1 look
like 2:1, but this is the best performing solution.

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


/* Make 1:1 become 2:1 */
.aspect[data-ratio="1:1"] {
padding-bottom:50%;}
/* Make 2:1 become 4:1 */
.aspect[data-ratio="2:1"] {
padding-bottom:25%;
}}

18. Aspect at tablet

The square aspect ratio had a lot of issues in the tablet/


large phone area of screen sizes. Similar to the above
weve had to take it down to 3:2 at 850px and below and
then bring it back to 1:1 at 600px and below.

@media screen and (max-width:850px)


.aspect[data-ratio="1:1"] { /* Make
become 3:2 */
padding-bottom:66.6%}
}
@media screen and (max-width:600px)
.aspect[data-ratio="1:1"] { /* Make
become 1:1 again */
padding-bottom:100%}
}

{
1:1

21. Finishing touches styles


{
1:1

19. Aspect at mobile


At 420px and below, the 2:1 box (which was 4:1 at tablet)
was looking a bit thin, even though all the content fit fine
with the ratio. After some trial and error, we found that
the 2:1 ratio worked better and it being the original ratio
was an added bonus!

20. Finishing touches markup


Add another call-to-action tile to see how it works with
your other tiles in the layout. In the example it sits within
a nested one-half container. This is a fairly straightforward
CTA as there isnt much content here, it should just work
with the responsive styles that have already been written.

<div class="one-half">
<a href="#sponsors" title="Sponsors"
class="sponsors">

<div class="aspect" data-ratio="1:1">


<div class="aspect-content">
<h4 class="headline">Sponsors</h4>
<p>View our list of sponsors</p>
</div>
</div>
</a>
</div>

Here were using the :after pseudo element to place an


image after our tile. Then we absolutely position it over
the top. We need to make it clear that these tiles are
CTAs on a web platform where users arent used to
seeing them in action.

.sponsors .aspect:after {
content: '';
width:13px;
height:20px;
background-image:url('./img/arrow.png');
position:absolute;
right:20px;
bottom:20px;
transition: right .5s cubic-bezier(0, 1.14,
1, 1); }

22. Finishing touches animation


To make the hover state a bit more obvious we can
change the right property which we set up a transition
for in the previous step. Its fairly subtle but reinforces the
notion that the user is interacting with an element that
will take them somewhere.

HTML5 & CSS3 Genius Guide 69

Front-end

Make dynamic
graphics with
the p5.js library
Create interactive drawings with HTML5 Canvas and p5.js, a
JavaScript port of the popular open source Processing library

www.fullengineeringbook.net

70 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/nks-887

HTML5 & CSS3

Genius Guide

Since the early 2000s, the Processing library


has been used by designers and artists as a
creative coding environment to create
stunning visuals with very few lines of code. The
Processing library is actually a Java library and this is
useful for creating interactive installations and prints. The
p5.js project is a new initiative to bring the ease of
Processing to the web by enabling designers and
developers the same easy controls to draw to the Canvas
element in HTML5. This means that live, interactive
visuals can easily be created for just about any HTML5
capable browser, which is almost any browser from the
last three or four years.
The screenshots for this project do not do it justice as
the project has to be interacted with in order to see it
work properly. We are going to be creating an organic
shape that is drawn pretty similar to an old spirograph,
but its going to morph, change size, shape and colour
based on the users mouse input. As the user moves
their mouse, the shape ripples and changes to create a
stunning interactive shape-shifting visual. With a little
manipulation this could easily become a music visualiser!

1. Start the project


Open up your web browser, type in p5js.org, click
Download and then choose Complete Library. Once it
has finished downloading, open the folder emptyexample and copy the file p5.min.js into it. Open index.
html in your code editor and change the script file to use
the minified version.

bare-bones template ready for us to start with the coding


process. Open this up in your code editor and you will
see that there are two functions here. The first function,
setup, is used to set all the things at the start of the
project like background colour and size. The draw
function is called every frame.

function setup() {
// put setup code here
}
function draw() {
// put drawing code here
}

3. Edit the setup function


In the setup function add the code that is presented
below. This creates a new Canvas element to draw into
and set this up to be the current width and height of the
browser window. The background of the Canvas is set to
black, and the Canvas itself is set to smooth, or antialias.
This will ensure that the lines are crisp but not jagged at
the edges.

createCanvas(windowWidth, windowHeight);
background(0);
smooth();

4. A new function

stroke(255, 255, 255, 28);


ellipse(0, 0, 120, 80);
}

5. Start the draw function


Now inside the draw function, add the first line in the
code below, which is the same as in the setup, for
making the background a black colour. The diference
here is that it is called every frame and therefore
removes any drawing from the previous frame so that
we end up with a new drawing every frame. The
translate line moves the drawing point to the middle of
the browser window.

background(0);
translate(windowWidth/2, windowHeight/2);

6. Draw around a circle


A for loop is added here to create 720 ellipses. The for
loop increases by 0.5 every loop so it will draw 720
instances. The push line enables the drawing to rotate
around the middle of the screen. The drawing position is
then pushed out 200 pixels on the y axis.

for (var i=0; i<360; i += 0.5) {


push();
rotate(radians(i));
translate(0, 200);

www.fullengineeringbook.net
<script language="javascript" type="text/
javascript" src="p5.min.js"></script>

2. Open sketch.js
After installation, the app is usually extracted. The main
code for our project will be found in sketch.js this is a

In between the setup and draw function, add a new


function as we have shown in this step. This code is
called to draw an ellipse on the screen and we will be
drawing a large number of ellipses later using this. The fill
colour is turned of and the stroke is white but with a low
opacity that is just over 10 per cent visible. The ellipse is
drawn from 0, 0 pixels to 120, and 80 pixels on the x and
y axis respectively.

Adding colour in p5.js


Colour in p5.js follows a pattern of 0-255 to give
256 colours for each colour channel and this in
turn will give around 16 million diferent colours!
To get random colours, a random number in that
scale can be created.

function drawEllipse() {
noFill();

Left

The p5.js library can be downloaded from p5js.org where


all documentation can also be found as well as some very
useful example files to introduce you to some concepts.
Also look out for the p5.js editor, available on Mac OS X
and coming soon to Windows and Linux
Top left

Once the core code is in place it can be run and you will
see a circular pattern appear on the screen. Next we will
make this modulate and change based on mouse position
so that it is interactive with the user
Top right

By adding some minimum and maximum values to the


waves undulating around the shape, we can start to affect
the interaction of the graphic in much more detail than we
were able to previously

HTML5 & CSS3 Genius Guide 71

Front-end
7. Rotate again
Now as the drawing point is 200 pixels out from the
centre of the screen, p5 will draw an orbit around that
point but first it will rotate again here. The whole drawing
will be scaled but it will also be based on a sine wave
that modulates between 1 and 1 so that the result is a
very organic shape.

rotate(radians(i*3));
scale(map(sin(radians(i*6)), 1, 1, 0.5,
1), map(sin(radians(i*3)), 1, 1, 0.5,
1));

numbers that draw the shape. Here the variables are


added just above the setup function so that we can call
them from any function that we want. The names are
fairly self-explanatory, and you will also see them in
action in the coming steps.

var
var
var
var
var
var

scaleX;
scaleY;
min;
max;
radius;
r, g, b;

8. Draw the ellipse

10. Scale based on position

Now as the drawing point is at the right place, the ellipse


is drawn and the pop command places the drawing
point back to the centre of the document. Save the file
and view the index.html page in the browser to see the
drawing of the organic shape in action. Now we are
going to change the shape interactively based on the
mouse movement of the user.

In the draw function add the following code at the top,


and this code will set the values of scaleX to take the
mouses x position. As it moves 0 pixels to the right-hand
side of the screen, those values will be mapped onto a
range of values from 1.5 to 11.5. The same thing will then
happen with the y position of the mouse and the
window height as well.

drawEllipse();
pop();
}

scaleX = map(mouseX, 0, windowWidth, 1.5,


11.5);
scaleY = map(mouseY, 0, windowHeight, 1.5,
11.5);

12. Map other values


Just below the code that was added in Step 10, add the
code that we have included below. It looks very similar to
our other pieces of code, but whats diferent is that this
time the position of the mouse on the x axis is mapped
onto a range of numbers from just 0.1 to 0.5 and the y
mouse is mapped onto 0.8 to 1.8. These positions will
provide some subtle diferences in the drawing when
they are applied in the next step.

min = map(mouseX, 0, windowWidth, 0.1,


0.5);
max = map(mouseY, 0, windowHeight, 0.8,
1.8);

13. Scale again


Just like we did in Step 12, locate the scale line of code
inside the for loop. Here the min and max variables are
added. Save this and view it in the browser to see how it
adjusts the drawing on the screen. Remember that these
numbers will be adjusted as the mouse moves around
on the screen.

scale(map(sin(radians(i*scaleX)), 1, 1,
min, max), map(sin(radians(i*scaleY)), 1,
1, min, max));

9. Add some variables


In order to add interactivity to the screen, we will need
some variables to dynamically control some of the

11. Amend the for scale

14. Change colours

www.fullengineeringbook.net

The nature of code


Because p5.js is a port of Processing, most
Processing code can quickly be adapted. Check
out Dan Shifmans eBook The Nature of Code
(natureofcode.com/book) for more information.

Top left

A random colour is generated each time the browser is


refreshed, this works well at setting an initial colour but
what we really want to do is give the user a little more
control over the colour that appears rather than giving
them sporadic choices
Top right

The colour is now adjusted so the height of the mouse in


each third of the screen controls either red, green or blue
and this provides a way of adding slightly more control
over the colour on the screen
Right

Now the radius of the overall shape has been changed so


that it is affected by the mouse position on the y axis. The
top of the screen makes the object smaller while the
bottom of the screen makes it larger

72 HTML5 & CSS3 Genius Guide

Look inside the for loop, further down in the draw


function. Here you will see a line of code beginning with
scale. Change the numbers from 6 and 3 to scaleX and
scaleY as we have shown here. This means that the code
will now take the mouse position for how the shape will
be drawn. Save this now and try it out in your browser to
see it in action.

scale(map(sin(radians(i*scaleX)), 1, 1,
0.5, 1), map(sin(radians(i*scaleY)), 1, 1,
0.5, 1));

In much the same way as the shape of our graphic can


be altered based on where the mouse is, as we have
shown in the previous steps, it is also possible to
dynamically change the colour. In the setup function add
these random numbers for the red, green and blue
values. The colour values are measured from 0 (for
darkest) to 255 (the brightest).

r = random(255);
g = random(255);
b = random(255);

HTML5 & CSS3

Genius Guide

Getting to know
hello p5.js
Starting with a new library
can take a little getting
used to and a lot of
programming languages
seem to start with a simple
hello world. Taking this
idea further, p5.js created
a site called hello p5.js
(hello.p5js.org), which
introduces the basic ideas
in a very simple interactive
video format. Live code
can be seen running
alongside the video as the
presenters introduce the
video. The video itself
even has its green screen
around the presenters
removed live by code in
the browser so that the
power of what is available
through p5.js can be
clearly demonstrated. In
the video you will see how
a particle system is
created, a flocking
behaviour is added to it
and then live windspeed
data from New York
afects the flocking!

www.fullengineeringbook.net

15. Use the colour

In order to get those random colours working add the


letters r, g and b to the stroke line which is located in the
drawEllipse function. This means that when it draws the
ellipse it will also make use of the random values. Save
this now and test it in the browser to see how it works
and looks. Each time you refresh the page a new colour
will be used.

stroke(r, g, b, 28);

16. Colourful mouse moves


Having to refresh the screen to change the mouse colour
is okay, but we may also want to update the colour based
on the screen position of the mouse. This colour efect is
possible via an if statement as we have shown in the
code below, which divides the screen into three
horizontal strips for RGB colour. In this step we have
started of with the first third and mapped it to the red,
giving it a random colour.

function mouseMoved() {
if (mouseX < (windowWidth/3)){
r = random(255);
//r = map(mouseY, 0, windowHeight, 0, 255);
}

the screen. Keep in mind though that each third will


afect a diferent colour.

else if (mouseX > ((windowWidth/3)windowWidth)){


b = random(255);
//b = map(mouseY, 0, windowHeight, 0, 255);
} else {
g = random(255);
//g = map(mouseY, 0, windowHeight, 0, 255);
}
}

Continuing on from what weve learned in the previous


step, we can use the if statement to take the last third of
the screen and map that to a random blue colour. Then,
we can also do the same for the green in the middle.
Save all of this now and test it in the browser to see all of
the random colours as the mouse moves around, all over

radius = map(mouseY, 0, windowHeight, 100,


350);

21. Set the radius


18. Slight change to the colour
The random colour changes have worked well so far, but
now we can specify that the colour now changes
specifically based on how far down the page the mouse
is. To do that we will need to revisit the if statements that
we have already used in Steps 16 and 17. First, comment
out the random line and uncomment the line afterwards.
Then, save this and test this change in the browser to see
it all working.

//r = random(255);
r = map(mouseY, 0, windowHeight, 0, 255);

19. Change the drawing radius


17. Green and blue changes

20. Update the radius

Now in the mouseMoved function, add the following line


just before the closing bracket of the function. The y
position of the mouse will decide how large the radius of
the circle will be. Note that this will never be smaller than
100 pixels and never larger than 350 pixels, but you can
change these values if you want them to be slightly
larger or smaller.

Now we go back to the shape itself, it is possible to


change how large the circle is drawn around the centre
point. In the setup function add the radius value as
shown here. This started of the project with an initial
value of 150 pixels as the radius from the centre of the
screen, but this can now be updated.

radius = 150;

In order for these radius values to actually be used, look


inside the draw function and inside the for loop is a
translate line. Update the value of 200 to the radius
variable. Now you can save the file and then refresh in
the browser to see this in action. There will be a lot of
changes now to the shape, size and colour.

translate(0, radius);

22. Fade out


Finally it is possible to fade out the drawing from all of
the previous frames. In the draw function, comment out
the background colour. So now we want to set the fill
colour to black with a low opacity of around 10 per cent.
Then, a rectangle is drawn over previous frames with the
low opacity on top and this will cause the previous
frames to fade out. Save and test this now to see the final
efects in all their glory.

background(0);
fill(0, 25);
rect(0, 0, windowWidth, windowHeight);

HTML5 & CSS3 Genius Guide 73

Front-end

Code 3D zoom
effects with CSS
As seen on scholzandfriends.ch/de

Menu overlay
The burger icon will
reveal the menu. Clicking
this brings a full-screen
overlay so that the menu
can be navigated.

Zooming 3D effect
As the images move at
different speeds, they
create an effective effect
that looks as though the
camera is moving.

www.fullengineeringbook.net

Image slider
The initial content that
covers the browser is a
giant slider to move
through projects with
animated image effects.

74 HTML5 & CSS3 Genius Guide

Animated image

Full homepage

The background image is


made of two images and
move at different speeds
towards the viewer for a
parallax effect.

The homepage itself is


much larger than shown
here as it can be scrolled
down to bring more
content to the user.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Parallax scrolling on sites is getting to the point


of being overdone; as soon as every site starts
to have the same features its time to start
looking to add a touch more originality into the design
process. The Scholz & Friends site has taken the familiar
paradigm of the parallax efect on images, but has done
this with a diferent take.
Parallax is usually done with images or content
moving at diferent speeds as the user scrolls down the
page, this was original and novel five years ago. Instead
of doing it this way, the parallax efect on Scholz &
Friends is actually a zooming efect, which gives the

impression that a camera is moving closer to the


content. Not only that, but this also helps the user to
focus on specific content, as the image is brought into
the foreground.
This gives a very unique look to the content and it
provides a freshness that makes a subtle change from
the scrolling efects that other sites employ.
When content that you design looks just diferent
enough from the competition it helps you to stand out as
a designer and helps your clients stand out and every
designer needs to remember that the success of their
clients is ultimately a reflection of their own success.

Fresh paint on a familiar style


<comment>
What our
experts think
of the site

Producing content for the image slider in the site requires a fresh approach,
almost every site on the web has featured content displayed at the top of the
site. To show off Scholz & Friends, a zooming effect was used on the images to
freshen up the dated parallax look.
Mark Shufflebottom, professor of Interaction Design

Technique
1. Creating 3D zoom effects
To create some of the 3D zoom efects found on the
Scholz & Friends site, create a new HTML document and
add this code to the body. This will display two images on
the webpage.

image is just scaled up slightly so that it looks like the


camera is zooming in on the image.

@-webkit-keyframes back {
from {transform: scale(1);}
to {transform: scale(1.2);}
}

EXPERT ADVICE
Controlling CSS keyframes
As the 3D zooming parallax efect is the focus of this
site it can be reproduced using HTML and CSS alone
without any JavaScript. This is down to the use of CSS
keyframes, which enable us to specify how something
will look on frame one and in the final frame of
animation. The duration is also controlled in seconds
as opposed to milliseconds in JavaScript.
CSS keyframes normally loop, so in the workshop
the animation takes place over six seconds and the
default would be for it to start again and loop through.
There are some commands that enable us to control
exactly what happens with the keyframes and they can
be set to play in reverse, play just once, loop a certain
number of times or play back and forth.
Using the animation fill mode, the keyframes can be
set to forward, meaning they play once and hold on the
final frame of animation. Set this to backward and they
will play in reverse order. Change this to both and it will
double the duration, playing it forward and backwards.
Using the animation iteration count, the amount of
times it loops can be controlled. This will reset on the
first frame of animation so be careful of your content
jumping back to the start.

animation-name: fore;
animation-duration: 6s;
animation-fill-mode: forwards;
}

www.fullengineeringbook.net
<div id="wrapper">
<img src="img/bg.jpg" id="bg">
<img src="img/fg.png" id="fg">
</div>

2. Wrap them up
Now create style tags in the head section of the
document and add the CSS rule for the wrapper. This
holds both images and centres them on the page. As the
images zoom in, the overflow is set to hidden.

5. No prefix code

Newer browsers that dont require the vendor prefix


should also be catered for, so here is the code for those.
Its slightly smaller because it doesnt have -webkit- in
front. Notice the keyframes have the label back which is
picked up in Step 3s code.

@keyframes back {
from {transform: scale(1);}
to {transform: scale(1.2);}
}

3. Position the background

6. Foreground image

The background image needs to be positioned


absolutely so that each image can be overlaid on top of
each other. The animation is going to be stored in
keyframes with the title back. This should hold on the
last frame of animation so the forward animation fill
mode is used.

The foreground image isnt currently visible because the


overflow is hidden. Adding this rule for it will position the
foreground over the top of the background image and it
aligns to the bottom of the background image, while
being 100 pixels in from the left.

#bg {
position: absolute;
-webkit-animation-name: back;
-webkit-animation-duration: 6s;
-webkit-animation-fill-mode: forwards;
animation-name: back;
animation-duration: 6s;
animation-fill-mode: forwards;
}

4. Add keyframes
Safari, Chrome and Opera use the webkit prefix on CSS
so here the keyframes are added. As you can see the

#fg {
position: absolute;
bottom: 0;
left: 100px;

7. Finishing the foreground


As with the background image this is also being
animated to zoom in. The remaining code for the
foreground CSS rule sets up to run on keyframes that are
labelled fore. It takes six seconds to run and will pause
on the last frame of the animation like the background.

-webkit-animation-name: fore;
-webkit-animation-duration: 6s;
-webkit-animation-fill-mode: forwards;

8. First keyframes

The foreground keyframes animate two diferent


properties at once. They increase the scale and move the
image slightly to the left, this helps to give a 3D efect as
this zooms in more than the background to make it look
like its in front.

@-webkit-keyframes fore {
from {
transform: scale(1);
left: 100px;
}
to {
transform: scale(1.4);
left: 40px;
}
}

9. Final keyframes
Add the last keyframes to the CSS and then save the
document. Opening this in your web browser will show
you the efect running over six seconds and you will see
the foreground and background moving separately to
complete this 3D zoom efect.

@keyframes fore {
from {
transform: scale(1);
left: 100px;
}
to {
transform: scale(1.4);
left: 40px;
}
}

HTML5 & CSS3 Genius Guide 75

Front-end

Form pop-up
modal boxes
with pure CSS
Show new information in a modal box along with animation
effects without loading a new page

www.fullengineeringbook.net

76 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Good design is always about presenting


information in a way that is simple to
understand. And yet, sometimes the amount of
information causes a conflict with the need to present
information in a way that is easy to comprehend and
where the information is still complete. One option would
be to separate content onto diferent pages, but this
causes scope for unnecessary page loading and poor
usability, especially where users are accessing the
webpage through a slow internet connection such as via
mobile data with poor reception.
Modal boxes ofer a perfect solution to the problem by
enabling additional information to appear on the page
when they are clicked without the need to load a new
page. Furthermore, modal boxes can be closed again in
order to return the user to the original content without
the need to reload.
This tutorial looks at several options for how modal
boxes can be developed with CSS to provide highly
usable designs for websites and web apps that are easy
to adapt for diferent types of content you may want to
present. The functionality of these modal boxes will focus
on easy access in a way that enhances the user
experience of the webpage.

1. Get started

page. This will provide information needed by the reader


to identify whether they want to read further.

3. Option navigation
Next insert the available options that will provide the user
with access to additional information. These options will
be regular <a> links contained inside a <nav> container.
Unlike regular <a> tags that use their href to link to
external pages, these <a> links will link to ID components
on this page using a # symbol in their href attribute
preceding the ID name being linked to.

<nav>
<a href="#alpha">Alpha</a>
<a href="#bravo">Bravo</a>
<a href="#charlie">Charlie</a>
<a href="#delta">Delta</a>
<a href="#echo">Echo</a>
</nav>

4. Add modal boxes


The modal boxes will all use <article> as their container
element and will have an optional attribute of datatransition to specify the type of transition they will use to
appear and disappear, providing a high degree of
flexibility for individual sections.

<article id="alpha">
</article>
<article id="bravo" data-transition="left">
</article>
<article id="charlie" datatransition="right">
</article>
<article id="delta" data-transition="zoom">
</article>
<article id="echo" data-transition="fade">
</article>

5. Modal box content


Insert content into each of the <article> containers. Each
modal box will need the ability to be closed, which will be
triggered by an <a> tag linking to a blank ID using just #
for its href. We also want to give this closing button a
data-button=close attribute so we can style it later.

<article id="bravo" data-transition="left">


<a href="#" data-button="close">x</a>
<img src="img/photo1.jpg" alt="Coastline" />
<h2>Bravo</h2>
<p>Lorem ipsum dolor sit amet.</p>
</article>

6. Initiate CSS styling


The main HTML template content is now complete, but
the additional CSS stylesheet resource file is still required
to add the styling. Create a text file called styles.css,
making sure that your text editor does not add .txt as a
file extension. These also need attaching from the
<head> section of HTML document.

7. Style HTML body


Dont forget that the <html> and <body> elements on a
webpage are set to a height of just one line by default,
hence causing problems if we want to create a container
that has a full webpage height. Solve this by setting the
<html> and <body> elements to be full height in the CSS.

www.fullengineeringbook.net

First, declare the main HTML page structure, including


the head and body section within the HTML page. We
will need a content container made from a div element
with an ID called container to control page content flow.

2. Content overview
With the main layout elements in place, we can insert the
main content inside the container element. The page will
have a descriptive title and introduction text to provide
the main overview of the information contained on the

Multiple transitions
Use data attributes to enable multiple transitions
to be defined that can be easily added to
individual modal boxes without having to
overcomplicate your CSS.

Left

The navigation container and its options are now styled


to appear separate from the main content and
identifiable as buttons
Top left

HTML elements in place with content added to article


sections, but no styling yet
Top right

Article sections acting as the modal box containers look


like this without their styling

HTML5 & CSS3 Genius Guide 77

Front-end
9. Options container

html,body{
display: block;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}

We want the options to stand out from any standard


content on the page. You can do by styling the options
container that was created with the <nav> tag. This will
be styled with a distinctive border and margin spacing to
ensure it appears separate from surrounding content.

8. Style the container


The container needs to be styled in a way so that it will
stand out. This can be done by changing the main page
background colour and positioning the container in the
centre of the page. To do this, we need to update the
<head>, <body> and container sections.

html,body{
font-family: "Trebuchet MS", Helvetica,
sans-serif;
background: rgb(21, 34, 47);
}
#container{
display: block;
width: 1000px;
height: 100%;
background: #ccc;
margin: 0 auto 0 auto;
padding: 1em;
}

nav{
display: block;
padding: 1em;
border: 3px solid #000;
margin: 2em 0 2em 0;
}

10. Option styles


The option navigation elements need to appear like
buttons, even though they are just <a> link tags. This can
be done through CSS by making these elements display
as an inline-block, which enables us to apply sizing and
padding to make them appear like buttons.

nav
a {
display: inline-block;
padding: 1em;
margin-left: 1em;
font-size: 1.5em;
border: 3px solid #fff;
background: #333;
color: #fff;
}

nav
a:hover{
border-color: #333;
background: #fff;
color: #333;
}

12. Define modal boxes


The modal boxes all use <article> elements as their
containers, hence we can use CSS to define their default
styles for width, height and positing. We want these
elements to appear at pixel-specific locations on the
screen so we use absolute positioning to allow attributes
for top, left and z-index.

article{
display: block;
position: fixed;
z-index: 9999;
left: 25%;
top: 100%;
width: 40%;
height: 50%;
padding: 2em 5% 0 5%;
border-radius: 1em;
background: #000;
color: #fff;
overflow: auto;
}

www.fullengineeringbook.net

Make full use of


visual information
without
compromising on
presentation

Top left

Define the style of the modal box to make it clearly stand


out from the main page content
Top right

Modal boxes can also use transitions to slide in from the


side when links to their associated ID are clicked
Right

Alternatively, the modal boxes will now fade into view


using transition animations

78 HTML5 & CSS3 Genius Guide

13. Set transitions

11. Option hover

Good usability will make it easy for users to know which


option they will select if they are to press on their
trackpad or mouse button. We can apply the :hover
property to the options so that they change colour when
the users mouse pointer is placed over them, indicating
which option is about to be selected.

Modal boxes need to be able to show transition from


one CSS property state to another for the animation to
be visible. To keep our CSS simple, set all properties to
be eligible for transition animations. You can add other
properties later to trigger their animation sequence.

article{
padding-bottom: 1em;

HTML5 & CSS3

Genius Guide

-webkit-transition: all 2s;


transition: all 2s;
}

14. Target selector


Now apply the target selector to define the CSS states
for elements that are selected via their ID. Elements will
transition to this state when they are clicked on ie this is
the state that all modal boxes will appear as. The
!important element ensures that these styles overwrite
the previously defined styles for <article> elements.

:target {
visibility: visible !important;
left: 25% !important;
top: 25% !important;
width: 40% !important;
height: 50% !important;
opacity: 1 !important;
}

15. Transition: fade


Now that the modal boxes have the ability to transition
from the default <article> settings to the :target settings,
we can apply rules that will overwrite the default <article>
settings through the data-transition attribute. Our first
rule will let the modal box fade in and out of view.

Modal box usage in UX design


Visual information often needs to take up a large amount of space in order to be fully useful. Check out Twitter, which
uses modal boxes to display basic information about a persons profile that are triggered when you click on a Twitter
handle. Using text or thumbnails to trigger the presentation of the full image or video when clicked provides a way to
make full use of visual information without compromising the presentation of the main page content. Forms can also
provide users with complementary functionality such as search, registration and account logins. Or, modal boxes can
be used with alerts and notices automated appearances of information can be provided to show important
information that the user must see. Similarly, modal boxes for tips are presented as a clickable options for requesting
additional information useful for enabling users to access more information when they want it.

www.fullengineeringbook.net
[data-transition="fade"]{
left: 25%;
top: 25%;
opacity: 0;
visibility: hidden;
}

16. Transition: left


The next transition we want to use is to let the modal box
slide in from the left by placing the default position of the
modal box as fully of the screen to the left. This means
that it will move from this position to the centred position
set in the :target when this element is selected for display.

[data-transition="left"]{
left: -100%;
top: 25%;
}

17. Transition: right


We also want a transition efect to make the modal box
slide in from the right by placing the default position of
the modal box as fully of the screen to the right ie 100
per cent of the screen width from the left.

[data-transition="right"]{
left: 100%;
top: 25%;
}

[data-transition="zoom"]{
visibility: hidden;
left: 50%;
top: 50%;
width: 0;
height: 0;
opacity: 0;
}

19. Style close buttons


The modal boxes have an an element with an attribute of
data-button=close used to close the modal box. We will
style this to appear in the top-right corner as a red circle
achieved by setting the border radius to be curved and
for the element to float to the right.

article [data-button="close"]{
display: block;
float: right;
background: #c00;
color: #fff;
border: 3px solid #fff;
border-radius: 1em;
padding: 1em;
text-decoration: none;
}

18. Transition: zoom


The final transition to add is the ability for a modal box to
zoom in and out from the screen centre. This transition
requires the default style to be of zero width and height.
Well also add an opacity of zero so that the modal box
will fade in and out of view as it sizes up or down.

20. Style images


Now we change the colour of the close button by
applying styles through the :hover selector that will
trigger the change when the user hovers their mouse
pointer over the close button.

article [data-button="close"]:hover{
background: #fff;
color: #c00;
border: 3px solid #c00;
}

21. Image spacing


Our modal box design makes use of an image to be
displayed at the left of the text content. This image
should be the height of the modal box we can use CSS
to set the image as 100 per cent of the modal box article

img{
display: block;
float: left;
height: 100%;
}

22. Place a margin


Make sure that there is a margin of one text character to
the right of the image so the text isnt too close to the
image. Place a margin to the right of the image, so that
the positioning of all elements in the modal box will take
this into account.

article img{
margin-right: 1em;
}
article img{
display: block;
float: left;
height: 100%;
}

HTML5 & CSS3 Genius Guide 79

Front-end

Build offline web apps


with Service Workers
Use the Service Workers API to create rich offline applications that were previously
only possible with native code

www.fullengineeringbook.net

80 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Unless you have been under a rock (or at least


of of Twitter for a while) you are likely to have
heard that the hot new thing in web
development is progressive web apps. Already being
implemented by major websites like Flipkart, Facebook
and Google, Progressive web apps basically mean a
collection of new APIs that have very recently been
added to some browsers that allow for authors to create
rich, native-like experiences. The key bit that ties
together most of these new browser APIs is Service
Workers, and it will radically change the way that you go
on to make websites in future.
Introduced in Chrome version 40, Service Workers
are a new type of web worker that act as a kind of proxy
between your website and the network. That means
with a little bit of JavaScript we will be able to intercept,
modify and even respond to requests from our site
without ever hitting the network! By using Service
Workers, we can make web apps work 100 per cent
ofline, allow for content sites to have fun and enjoyable
ofline fallbacks, and supercharge the responsiveness of
our site for everyone else.
In this tutorial we will update an HTML5 podcasting
app by adding a Service Worker to our site, include
some tips to make your own upgrades easier and
explain the common pitfalls that you can avoid.

file at the root of the site called sw.js (eg example.com/


sw.js) The location of the file is important (we will go
over why thats the case in Step 5).

navigator.serviceWorker.register('/sw.js')
// .register() is async, and it
// returns a promise
.then(registration => {
// we're installed!
}).catch(err => {
// there was some kind of error
})

5. Pick a place to save


Where the sw.js is loaded from is very important, and it
should probably be /. That is because what the SW is
able to control (and therefore make work ofline) is
limited to its scope. That means that if you register
example.com/js/sw.js, it will only be able to control any
URLs that begin with example.com/js.

// control everything on the domain


navigator.serviceWorker.register('/sw.js')
// control everything served from /js
navigator.serviceWorker.register('/js/sw.
js')

3. Use Promises
Service Workers are completely asyncronous, and so
they use Promises everywhere. Promises are a new-ish
browser API that makes it easier to reason about async
code. If you havent brushed up on them before now, it
would be a great time to do so all new async APIs will
be based on them.

functionReturningAPromise()
.then((result) => {
// All Promises have a `then` method
// where can do something with the
// result of the function
}).catch((e) => {
// Always make sure to define a catch
// on your promise, otherwise you
// won't know if there was an err
})

6. Listen for fetch


Now well add some functionality by listening for the
fetch event (fired for any network activity covered by
the SWs scope and this will include XHR, CSS and
more). It will respond with data stored via the new
Cache API if it exists. If it isnt cached, thats fine, we will
just fire of a new fetch call.

self.addEventListener('fetch', ev => {
ev.respondWith(
caches.match(ev.request)
.then(response => {
return response || fetch(ev.request)
})
)};

www.fullengineeringbook.net

1. Get support

Service Workers arent supported everywhere yet, and


wont be for a while. So the first step whenever dealing
with new APIs is to do an existence check. Tools like
Modernizr make this easy for trickier APIs, but Service
Workers are quite simple to check for without it

2. Create a Service Worker


Lets add a Service Worker. To start, we create a blank

4. HTTPS only

Lets encrypt!

You can only register a Service Worker if the site is


connected to HTTPS (or accessed via localhost). This is
going to be true for most new browser APIs, so if you
havent gotten a SSL cert for your site, now is a great
time to do so,

LetsEncrypt.org is a safe and free new way to


get and automatically renew SSL certificates,
which are required for new browser APIs like
Service Workers.

Left

For securitys sake, browsers will only let you register a


Service Worker if the site is connected to over HTTPS
Top left

Chromes internet connection error message shows up


when the user is offline and no Service Worker has been
registered. Our users cant do anything in this case
Top right

By using a fallback image we are able to ensure that even


when resources arent cached or available, our users still
get a visually pleasing experience

HTML5 & CSS3 Genius Guide 81

Front-end
7. Add responses
You may have noticed that we never actually added to
the Cache. Since Cache is not the same as the
browsers HTTP cache we have to manually add the
responses as they come in. You may only want to do
this for only certain items, though, otherwise none of
your REST calls would ever update!

let request = ev.request


caches.match(request)
.then(response => {
return response || fetch(request)
.then(response => {
// only add JPGs to the Cache
if (request.url.match('/jpg$') {
cache.add(request);
}

8. Prime the cache


In addition to fetch, we can listen for the install event in
order to fire some set-up code. This lets us prime the
cache with a few entries for things we know are going
to be requested, as well as any fallback content we may
want to load later on.

self.addEventListener('install', event => {


event.waitUntil(
caches.open('cache-v1').then(cache => {

11. Disable for offline functions

return cache.addAll([
'/logo.svg',
'/fallback.jpg',
])
});
)
})

Our app relies on audio files from outside sources. We


cant really presync every podcast ever, so when we go
ofline we want to disable some functionality to prevent
user confusion. In this case, we will hide the search
button when we get an ofline event.

9. Fallbacks failing
In our app, we are going to load a number of images,
and on slow connections, they may take a long time to
load. We can add a fallback to the fetch call that we just
made, so that we can show our default image rather
than an empty spot.

return fetch(ev.request)
.then(response => {
cache.add(ev.request);
}).catch(err => {
// reply with the precached image
return cache.match('/fallback.jpg')
})

let cL = document.body.classList
let toggle = () => {
// add the class hideSearch to the
// body tag when nav.onLine is false
cL.toggle('hideSearch', !navigator.onLine)
}
window.addEventListener('online', toggle);
window.addEventListener('offline', toggle);

12. Alternate experiences


One thing we are all trying to avoid is the dreaded user
bounce rate. If the site is ofline, its more or less useless
to the user. You can use Service Workers in creative ways
to serve temporary content if a user navigates to a page
that is not cache. For example, The Guardian s website
displays a crossword!

10. Keep our users in the loop


Even though we are creating a great ofline experience,
there are going to be some things that wont work.
Therefore, we want to make sure our users know that
the app has gone ofline, in case they are unaware. Just
how you show that information is up to you, the
browser provides an easy way to check.

caches.match(request)
.then(response => {
if (response) return response;
if (request.url.match('/article/') &&
!navigator.onLine) {
// if the request isn't cached and we
// are offline, serve this instead
cache.match('/crossword.html')
}
)})

www.fullengineeringbook.net

The UpUp API


Hit the ground running with UpUp (talater.com/
upup) a great library that provides a simple API
for a lot of Service Workers as well as more
common use cases.

let updateStatus = (event) => {


// inform user of offline status
}
window.addEventListener('online',
updateStatus);
window.addEventListener('offline',
updateStatus);

13. Communication is key


Service Workers are like other web workers in that they
have no access to the DOM, and run in a separate

Top left

Hiding features that will not work while users are ofline
can reduce the frustration they feel during use. Just
make it clear why the functionality disappeared!
Top right

You can leverage Service Workers to delight users even


when you cant give them the content they wanted. The
Guardian s site shows a crossword when offline!
Right

Service Worker support is limited to the latest Chrome,


Opera and Firefox versions. App cache, on the other hand,
works almost everywhere

source: caniuse.com

82 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

App cache fallback


If you are just using Service
Workers to cache content, you
can fallback to app cache. After
checking that Service Workers
arent supported, check for app
cache:

if ("applicationCache"
in window) {...
Here is the tricky bit app
cache is added through the
manifest attribute on a
HTML element:

<html manifest="cache.
appcache">
But you cant add the manifest
attribute via JS it has to be
there on page load. We get
around this by creating a blank
page that only has the
manifest, then add it here via
an iframe:

let iframe = document.


createElement(iframe)
iframe.src = "/cache.
html"
iframe.style.display =
"none"
document.body.
appendChild(iframe)

www.fullengineeringbook.net

thread to the rest of your code. That means that in


order to communicate between your worker and your
site, you need to use the postMessage API.

// sw.js
self.onmessage = (message) => {
// the string passed to the worker
// exists on the `data` prop
let msg = message.data;
console.log('msg from the DOM ' + msg)
}
// index.js
navigator.serviceWorker
.controller.postMessage('HELLO WORLD!')

14. Share actions


If you have a site open in multiple tabs, you can use
the Service Worker to share actions across all of them
through postMessage. This keeps our app in a
consistent state across tabs, even if the user is only
interacting with a single one.

let url = request.url;


if (url.match(\/delete\/\d+)) {
fetch(request).then(() => {
self.clients.matchAll()
.then(all => all.map(c => {
c.postMessage("{delete:"+url+"}")
));
})
})
}

15. Update caches

Eventually our cached content will be stale. When that


happens, you will probably want to delete the old
caches in order to let the server give us the updates.
This is usually best done in the activate event, where
you can register a function just like we did before for
the fetch or install events.

event.waitUntil(
caches.keys().then((names) => {
return Promise.all(
names.map((name) => {
caches.delete(name);
})
);
})
);

})

17. Update the Service Worker


The process for updating your Service Worker is pretty
simple, just change the file. When your site registers the
Service Worker, the browser will always attempt to
download it. If it has a single byte of diference from
what it got last time, it will start using the new version
after the page reloads thats unless you tell it
otherwise.

self.addEventListener('install', (ev) => {


// you can take control from the old
// service worker immediately by
// calling skipWaiting on install
ev.waitUntil(self.skipWaiting());
});

16. Solve multiple issues

18. Debug your Workers

Lets say we update our sites layout and we want to


delete the HTML and CSS, but we dont want to lose
any audio cached for playback. In this case, we should
register multiple caches one for the code and
another for audio. Then we can invalidate them one at
a time.

Since theyre so new, the tooling around Service


Workers is not great yet. A lot of errors are often
swallowed in ways that are pretty opaque. In Chrome,
you have the ability to go to chrome://serviceworkerinternals to see more advanced options. The devtools
team is working hard to make this better!

let whitelist = ['audio-cache']


caches.keys().then((names) => {
return Promise.all(
cacheNames.map((name) => {
if (whitelist.indexOf(name) === -1) {
return caches.delete(name);
}
})

19. Future support


Supporting ofline is just the beginning for Service
Workers. Background sync, which is used to update
your app without the user even having it open; push
notifications, which provides the ability to get the same
native alerts apps have had for years; and much more
is on the horizon and will soon be expected by users!

HTML5 & CSS3 Genius Guide 83

Front-end

Model a unique
mobile 3D interface
Build an augmented menu that hooks into the mobiles device orientation
controls to create a bespoke browsing experience with three.js

www.fullengineeringbook.net

84 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Creating compelling web experiences for


mobile devices has come a long way, there are
a whole raft of phone functions that designers
can plug in to and access without the need for
packaging up the mobile site as an app. In this tutorial
what is being achieved with the native mobile web would
have been pretty hard to conceive as an app going back
just a few years, but now this is running purely as a
mobile optimised website.
The site itself will be in 3D and rendered by three.js but
instead of this being rendered with the WebGL renderer,
the scene will be rendered using the CSS3 renderer,
giving us maximum compatibility with devices. Having 3D
as part of the design is going to be an important part of
the interface. In order to browse around the interface the
user will need to rotate their phone and the display will
update, placing them in the centre of an augmented
interface. Moving the phone around becomes like
moving a camera in the interface to explore the links that
are on ofer to the user. This is made possible through the
Device Orientation Controls that come bundled with
three.js and can turn our phone into something similar to
an Oculus Rift.
This is part of a two-part tutorial; creating the interface
and get the device orientation working, we will focus on
the interaction with the menu in the following pages.

<script src="js/CSS3DRenderer.js"></script>
<script>
var camera, scene, renderer;
var circle1, circle2;

position: [ 0, 512, 0 ],
rotation: [ Math.PI / 2, 0, Math.PI ]
},{

4. Add each side


2. Set the scene
The code now adds the init function, used to initialise the
scene. A camera is created, the control system is initiated
to run on the device orientation controls. The scene is
created now that the camera and control system can
work with. The final code starts an array and this
contains an object.

function init() {
camera = new THREE.PerspectiveCamera( 75,
window.innerWidth / window.innerHeight, 1,
1000 );
controls = new THREE.
DeviceOrientationControls( camera );
scene = new THREE.Scene();
var sides = [{
url: 'img/scene-right.jpg',
position: [ -512, 0, 0 ],
rotation: [ 0, Math.PI / 2, 0 ]
},{

3. Create the background

Each side has to be added so in total there will be six


sides for this. If you wanted to create your own
background, an image with a 90-degree field of view
horizontally and vertically has to be taken that points at
all six sides. Its easier to create this with a 3D application
as the rotation and field of view can be exact.

url: 'img/scene-base.jpg',
position: [ 0, -512, 0 ],
rotation: [ Math.PI / 2, 0, Math.PI ]
},{
url: 'img/scene-front.jpg',
position: [ 0, 0, 512 ],
rotation: [ 0, Math.PI, 0 ]
},{

5. Set up the cube


Now as all six sides have been referenced in the array, a
cube is created by making a new 3D object and this is
added into the scene. A for loop is created to iterate
through each position in the array and this will be used
to display the images in the scene as a box.

www.fullengineeringbook.net

1. Link the libraries

Open the start folder in a code editor such as Brackets.


In the body of the document, add the following code to
link up the libraries. This uses the three.js library available
from threejs.org. Following this is an opening script tag
with some global variables that are needed in the project.

<script src="js/three.min.js"></script>
<script src="js/DeviceOrientationControls.
js"></script>

To create the background for the 3D scene a skybox will


be created, which is a large cube placed on the outside
of all other objects. The code here is holding a reference
to each of the sides, their individual position and rotation
within the 3D scene in order to view the box correctly.

Overlapping sides

The skybox cube is really 1024 pixels by 1024


pixels but it has been set to display at 1026 by
1026 so that there is a slight overlap in all of the
sides, as CSS 3D transformations are not as
accurate as WebGL.

url: 'img/scene-left.jpg',
position: [ 512, 0, 0 ],
rotation: [ 0, -Math.PI / 2, 0 ]
},{
url: 'img/scene-top.jpg',

Left

The tutorial uses the CSS3D renderer as part of three.js.


This renders the display using standard CSS3D transforms,
not WebGL, and ensures maximum device compatibility
Top left

Adding the background images to the cube makes a 3D


environment as the user moves their device around them
Top right

Looking towards the floor shows the area that will contain
an interactive Google Map later in the tutorial

HTML5 & CSS3 Genius Guide 85

Front-end
url: 'img/scene-back.jpg',
position: [ 0, 0, -512 ],
rotation: [ 0, 0, 0 ]
}];
var cube = new THREE.Object3D();
scene.add( cube );
for ( var i = 0; i < sides.length; i ++ ) {

6. Set each side


Information from each array position is stored in the
variable side. A new image element is created and given
a specific width. A CSS3DObject is created and added.

var side = sides[ i ];


var element = document.createElement( 'img'
);
element.width = 1026;
element.src = side.url;
var object = new THREE.CSS3DObject( element
);
object.position.fromArray( side.position );
object.rotation.fromArray
( side.rotation );
cube.add( object ); }

7. Icon images
Now that the background is in place, our attention will
turn to creating icons that will sit in front of that. Another

array is created, but this time round there is much less


information than before and thats because the image
needs to be stored for each of the icons that will be
placed on the screen.

8. Iterate the icons


Again a for loop is created to iterate through the images.
A div element is created to hold each image within. The
image is added using the JavaScript innerHTML
command to create content inside of it. The image is
given a unique id and the class of pic that is used to
style it later in the CSS. The source image is also added
for the icon.

9. Handle the interaction


A click handler is added for the picture and at the
moment this simply returns the value of the id to the
console log. In the second part of the tutorial, we will
learn how this calls the correct content to load for each
of the icons. The image is then added to a CSS3DObject
for placing in the scene. Then the position of the icon is
calculated around the camera.

pic.addEventListener( 'click', function (


event ) {
console.log(event.target.id);
}, false );
var object = new THREE.CSS3DObject( pic );
var phi = (Math.PI*2) / menu.length;
phi = phi * i;

11. Add to the scene


The final step is to tell the object to look at the vector
position setup, then the icon is added into the scene. The
closing bracket will now finish of the for loop. This will
mean that all of the code that is inside of the for loop is
applied to each image icon so that they are all positioned
to orbit the camera.

object.lookAt( vector );
scene.add( object );
}

12. Interactive map


This next block of code is to add an interactive Google
Map to the page. Visit Google Maps and find a location
youd like to show, then click the menu button and from
the slide-out panel, click the share button. In the popup
grab the embed code and paste the iframe into the third
line of code shown here.

element = document.createElement( 'div' );


element.className = 'mapped';
element.innerHTML = embed code here;
var elementWidth = 600;
var elementHeight = 600;

13. Position the map


There is a large red square on the floor of the 3D scene,
which is part of the background images added earlier on.
We are positioning the map to be 600 by 600 pixels so,
in the embed code added from Google, change the
width and height to 600 for both. The map is positioned
further down away from the camera and then rotated
toward the camera.

www.fullengineeringbook.net

3D CSS transforms
Anything can be displayed in the 3D scene that
can be displayed on a regular webpage, such as
video, maps, text and images, because the scene
is all controlled with CSS 3D transforms.

Top left

Point the device towards the floor to reveal an interactive


Google Map that shows the location of the event
Top right

A circle is added to the scene and placed above the


camera and can be seen by tilting the device upwards
Right

Another circle is added and animation sets these circles to


rotate around. If the aspect changes to landscape the
scene automatically resets to fit the device window

86 HTML5 & CSS3 Genius Guide

10. Position the icon


Using the code from the previous section each icon is
positioned at equal positions around the camera. The
350 relates to the radius of the circle or how far from the
camera the icons will appear. Once in position each icon
is rotated to face the camera in the centre of the scene.

element.style.width = elementWidth + "px";


element.style.height = elementHeight + "px";
var cssObject = new THREE.CSS3DObject(
element );

HTML5 & CSS3

Genius Guide

Know your three.js


renderer
Three.js is a 3D library that
is more used for creating
interactive WebGL
experiences but it also
comes with one or two
extra renderers that ofer
3D interactive experiences
for browsers that cant
display WebGL scenes.
This list is small but some
Android phone vendors
such as Samsung have
spotty support for WebGL
across their product line,
so its safer to use three.js
renderer. This limits the
development to creating
content that is essentially
just mapped onto flat
planes, but with a little
creativity this can still be
very efective. Other
renderers available
include SVG and the
Canvas renderer. SVG
doesnt really ofer any
improvement over CSS but
Canvas allows for 3D
model formats to be
loaded and displayed.

www.fullengineeringbook.net
cssObject.position.y = -400;
cssObject.rotation.x = -Math.PI/2;
scene.add(cssObject);

animate();
}

init();
</script>

17. Update the screen display

20. CSS Body

The next element that is being added is a transparent


PNG image with circular lines on it. This is added into the
3D scene and positioned above the camera while being
rotated towards the camera. This will be animated to spin
later on to provide some animation within the scene.

If the phone or tablet device is rotated from portrait to


landscape or vice versa, the browser changes
dimensions. In order to capture this, the onWindowResize
function updates the aspect ratio of both the camera
and the renderer so this will work on any size device with
any size display.

Open the project.css file from the css folder on FileSilo.


This is empty of all code, so add the code shown here for
the body tag styling. This sets the background colour to
white and sets the margins to zero, so that the scene fills
the full browser display. The overflow is hidden and the
font set to Helvetica or Arial.

15. A second circle

18. Animate the scene

Another circle is added and you will notice the pattern


that a div element is created, inside here an image is
placed. The div needs to be added as a CSS3DObject,
this can be positioned and rotated to display correctly.
Finally add the object to the scene to be displayed.

The animate function updates the screens display using


the browsers requestAnimationFrame command to
update the screen at 60 frames per second, or as fast as
the device can render it. The circles are rotated on the
screen, the controls update and the scene is rendered or
updated to display the view.

14. Add animated elements

16. Display the 3D scene


The way the scene is to be updated is now set. Normally
with three.js scenes this is the WebGL renderer but in this
tutorial the CSS3D renderer is being used, for maximum
compatibility. An event handler is registered to call the
onWindowResize function if the screen changes and the
animate function is used to update the screen.

renderer = new THREE.CSS3DRenderer();


renderer.setSize( window.innerWidth, window.
innerHeight );
document.body.appendChild( renderer.
domElement );
window.addEventListener( 'resize',
onWindowResize, false );

function animate() {
requestAnimationFrame( animate );
circle1.rotation.z += 0.001;
circle2.rotation.z -= 0.002;
controls.update();
renderer.render( scene, camera );
}

body {
background-color: #ffffff;
margin: 0;
cursor: move;
overflow: hidden;
font-family: helvetica, arial, sans-serif;
}

21. The menu items


The next CSS rule sets the image icons that are
displaying as the menu. This just sets the cursor to a
pointer if the user has a cursor on rollover. This wont be
necessary for the majority of browsers as mobile and
tablets dont usually have mouse pointers!

22. Finish and save


19. Set it all up
As we come to the end of the JavaScript code, the init()
function is called which sets the scene up, placing
everything in there and calling the scene to start
rendering. After this the script tag is closed. Save this
page now as all of theJavaScript code is added in here.

The size of the pictures is set here using the width and
height properties. Without this the image icons are just
too big on the screen, but its useful to have the images a
little bigger as most mobiles and tablets have high-pixel
resolution screens. Save the file and place on a server
then connect with your mobile device.

HTML5 & CSS3 Genius Guide 87

Front-end

Create an interactive
mobile 3D interface
Part two of our tutorial takes an augmented menu that uses the mobiles device
orientation controls and adds interaction to create a fully working site experience

www.fullengineeringbook.net

88 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

In part one of this tutorial (starting on page 84),


a unique mobile augmented website menu was
created. The site was created with the help of the
three.js library and was rendered using the CSS3 renderer
rather than the WebGL renderer to give maximum
compatibility with devices. The 3D was an integrated part
of the design as the user had to rotate their phone
around them to display the interface, augmenting the site
around them. This placed the user in the centre of the
interface. The movement of the phone was created using
the Device Orientation Controls that come bundled with
three.js and this sort of turned our phone into something
similar to an Oculus Rift.
Now, in this final part of the tutorial, the interface will be
given some content so that it actually becomes useful.
This content will be hidden from the user until they click
on the appropriate icon in 3D space, at which point a 2D
panel will slide in over the top of the existing 3D menu
system. The animation in the panels,will be powered by
the Animate.CSS library, which will slide on the new
content. This gives us access to a quick way to create
animated elements.
Each panel will be colour-coordinated to match the
icon that has been clicked and then the panel can be
removed again by clicking a burger menu icon in the top
left to take the user back to the experimental menu.

2. Content panels
There are going to be four content panels in the project
these will appear when the user clicks on one of the
icons in the menu inside the 3D scene. Add the code as
weve below to the body of the page just above the script
tags. This creates a top bar section and an area for text.

<div id="info1" class="panel hidden


animated">
<div class="head">
<a href="#" onclick="fade1();">&#9776;</a>
<h2>Chat</h2>
</div>
<p>Text here </p>
<p>Text here </p>
</div>

3. Panel details
You can fill the text with your own content or even
images. You may notice that there is a strange code in
the link tag, this is actually the code to create the three
lines of the burger icon for the menu button. This will
take the users back to the 3D menu screen.

<div id="info2" class="panel hidden


animated">
<div class="head">
<a href="#" onclick="fade2();">&#9776;</a>
<h2>Arriving</h2>
</div>
<p>Text here </p>
<p>Text here</p>
</div>

appropriate icon the panel will slide in from the left.


Clicking the burger icon will make it slide back to the left.

<div id="info3" class="panel hidden animated


weather">
<div class="head">
<a href="#" onclick="fade3();">&#9776;</a>
<h2>Weather</h2>
</div>
<p>Text here</p>
<p>Text here</p>
</div>

5. Five into four


Each panel will be styled up to match the colour of the
icon using CSS code the colour will be used to reinforce
the selection made by the user. There are five icons and
but only four panels. One icon is the logo of the website
so that will not link anywhere, but it will orientate the user.

<div id="info4" class="panel hidden


animated">
<div class="head">
<a href="#" onclick="fade4();">&#9776;</a>
<h2>Events</h2>
</div>
<p>Text here</p>
<p>Text here </p>
</div>

www.fullengineeringbook.net

1. Pick up from part one

This tutorial picks up directly where it was left of at the


end of part one (see page 87). First link up the animate.
css library, available from daneden.github.io/animate.
css, which weve already downloaded and put in the CSS
folder. This will power the sliding on of popover content
later on.

<link rel="stylesheet" href="css/animate.css"


/>

Positioning above
The new panels added in this tutorial are
positioned on a z plane above the background
CSS panels so that they appear in front of the 3D
scene as 2D panels.

4. Panel power
The panels are constructed from regular HTML elements
and will be hidden from the site using CSS. Then linking
up the CSS Animate code when the user selects the

Left

The Animate.CSS library is used to create transitions in the


app and slide the appropriate content over the top of the
existing menu
Top left

The HTML for the panel is created that forms the structure
of the overlaid content that appears above the interface
when the appropriate icon is clicked
Top right

In the CSS the panels are styled to have individual looks so


that each icon slides content over the interface in a similar
colour scheme. This content hasnt quite fully fallen into
place in the image

HTML5 & CSS3 Genius Guide 89

Front-end
6. Responsive srcset behaviour
Save the HTML document for now and open the project.
css file from the CSS folder. Add on the code in the next
few steps to style the content in the panels appropriately.
The first content merely creates the generic style for all
of the panels that place this above the other content on
the page.

7. Hide and seek


When the App starts up the menu should be visible and
nothing else. The hidden class is used to hide all the
panels when the App first launches and then only as the
user taps the device screen should it be visible to the
user. The visible class was actually used during testing
but is not used in the final site.

.hidden{
display: none;
}
.visible{
display: block;
}

allows for the head section to have the right height for
both of those elements.

.head{
height: 45px;
}

9. Position the menu


The link in the head section of the panels is the burger
menu icon and here the code is floating that icon to the
left of the screen. Its given a slight padding around the
top and left so it isnt too close to the sides. The text
decoration is set to none and ensures that the underline
doesnt appear below this.

.head a {
display: inline-block;
float: left;
width: 10%;
padding: 10px 0 0 10px;
text-decoration: none;
}

10. Lay out the heading


8. Break down the parts
After the panel is styled up, each panel will have a head
section that has a burger menu button to take users
back to the menu and a heading so that they know they
are seeing the right content on the screen. This CSS just

Now, turn your attention to the h2 heading tag, which is


made to float to the right of the menu icon. The padding
on this reflects the slightly diferent shape of the text and
the icon, with there being less top padding on the text.
The text is also aligned to the right so that the menu and
heading are on opposite sides of the screen.

11. Paragraph settings


Below the heading there is just a couple of paragraphs,
but if this was your own design this could contain a
variety of content, from images, videos or anything else
you wish to display on a HTML page. As there is only text
in the example there is just a 5 pixel padding for the top
and bottom and 10 pixels for left and right.

p{
padding: 5px 10px;
}

12. Individual style


Each panel shares the same generic styling that has
been applied in the previous six steps. Now you need to
concentrate on giving each panel a colour scheme that
fits with the initial icon that it represents. Here the panel
is given a light green background with dark green text
and header.

13. Blue section


As in the previous step, the styling is now looking at the
individual panels. The second panel will be styled up with
a light blue background, giving a darker blue colour for
the text. The header panel of this is the reverse of that
styling with a dark blue background and lighter text.

14. Third panel

www.fullengineeringbook.net

Know your code


HTML is the content of your website while CSS
provides the way those elements are rendered
by the browser giving a unique design. The
JavaScript part of the site provides functionality.

Top left

The Animate.CSS library is used here, and this slides the


content onto the screen with a bounce. Here the content
is just about to bounce into final position
Top right

As the weather icon is clicked you can see the panel just
beginning to be animated into position and its
transparency is just fading in here as well
Right

When the user clicks on the burger menu in the top left of
the panel the content slides back off the screen to the left
as shown in this image. This allows the menu to be
accessed again

90 HTML5 & CSS3 Genius Guide

.head h2{
display: inline-block;
width: 70%;
margin: 0;
padding: 7px 10px 0 0 ;
float: right;
text-align: right;
}

The third panel takes on purple characteristics for the


colour scheme with lighter styling for the background
and a darker header section on this panel. The colours
help to reinforce to the user the icon that theyve just
clicked on to give them a way to orientate themselves in
the mobile web site.

#info3.panel{ background-color: #d1b3ce ; }


#info3 .head{
color: #eed8ec;

HTML5 & CSS3

Genius Guide

Using Animate CSS


The Animate CSS library is
a relatively lightweight
library with the smaller
version weighing in at only
52KB. This consists of one
CSS file that has
keyframes built for various
CSS movement and
animation. This saves us
the time in the tutorial of
having to put these
together and it is always
worth your while as a web
designer to build on the
shoulder of other libraries.
When you can, dont
reinvent the wheel!
To use the library, all
that needs to happen is
that the library is linked to
your page, which we did in
Step 1. Then, any content
that needs to be animated
must have the class
animated applied to it.
Finally, an animation style
should be applied as a
class, such as
bounceInLeft. This will
immediately call the
animation into efect.

www.fullengineeringbook.net
background: #714c6e;
}
#info3 .head a{ color: #eed8ec; }
#info3 p{ color: #584356; }

15. Final panel colours


The final panel that is being styled up again reflects the
colours of the icon used to access it from the original 3D
menu created in part one of this project. This time the
colour scheme is given an orange theme with light tints
and dark shades used to create the panel. Save the CSS
file and close it.

#info4.panel{ background-color: #f5c5a7 ; }


#info4 .head{
color: #f5c5a7;
background: #b65212;
}
#info4 .head a{ color: #f5c5a7; }
#info4 p{ color: #b65212; }

16. Start the JavaScript


All of the requisite elements are now in place for the
design and content of the panels. Its just a case of
adding the desired functionality to make these panels
work. In the JavaScript code locate the global variables
on lines 56 and 57, then add this function below it. This is
called into efect when the menu burger icon is pressed
on the first panel.

function fade1(){
var change = document.getElementById(
'info1' );
change.classList.remove('bounceInLeft');

change.classList.add('bounceOutLeft');
}

17. Bounce around


The next code is for the second panel and these series
of functions take the ID of the relevant info panel then
remove the class that has made them bounce onto the
screen from the left. Once this is removed the code to
make them leave is added and the elements bounce
back out to the left.

function fade2(){
var change = document.getElementById(
'info2' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');
}

18. Use Animate CSS


The CSS styles that are being added and removed for
these sections have not been created here instead they
are from the Animate.CSS library that was hooked up to
our page in the first step of this tutorial. You can visit
daneden.github.io/animate.css to see more styles.

function fade3(){
var change = document.getElementById(
'info3' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');}

19. Customise the animation


If you visit Dan Edens Animate.CSS site you can try out
diferent animation styles before applying them to your

content. Find styles that work together and make sense


with your functionality rather than choosing the most
attention grabbing animation that you see.

function fade4(){
var change = document.getElementById(
'info4' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');
}

20. Grab the link


Following this youll need to scroll down through the
code until you find the code that has the click function
event listener on the pic variable. Inside this function, add
the two lines of code in bold shown below. These lines
check that the icon that has been clicked on is not the
first icon, and if so it stores the current icons ID in the
change variable.

pic.addEventListener( 'click', function (


event ) {
console.log(event.target.id);
if(event.target.id != "0"){
var change = document.getElementById(
'info'+event.target.id );

21. Finish the code


Now continue with the following code that turns of the
hidden property, and if it has been clicked on previously
it removes the bounce out CSS. The bounce in animation
is added to bring the panel onto the screen. Save this,
upload it to a server and connect using your phones
browser to see it all working.

HTML5 & CSS3 Genius Guide 91

Front-end

Assemble fullscreen navigation


Use the full-screen features of CSS and JavaScript to create
menu systems for websites and web apps

www.fullengineeringbook.net

92 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

The web has transformed from a platform for


the delivery of information and content to also
being capable of delivering software
applications. Web-based software applications have
often been labelled as not as good as their native
counterparts an attribute that is now more of an
incorrect stereotype with the modern browsers now
supporting HTML5.
A big part of the problem that web applications face in
their accusation of being a poorer equivalent of their
native counterparts is based on psychology people who
make such accusations are often unaware that many
apps theyve download from their app store account are
merely web apps wrapped by a native web view element.
One of the features of HTML5 that can be used to
condition users to take your web app more seriously is to
display content in fullscreen this is more relevant to the
desktop where windows can clutter the screen, but are
also relevant to mobile smartphones and tablets.
Our example will create a menu page that provides the
user with the option to access content in full-screen
mode. A useful element for full-screen applications is the
use of iframes, which are a good solution for the limitation
of the browser exiting full-screen mode as soon as the
user visits a new URL; iframe elements enable page
changing without changing the current URL.

this to load the CSS stylesheet and JS code. This lets the
resources to be reused by other pages if required.

<link rel="stylesheet" type="text/css"


href="styles.css" />
<script src="controls.js" type="text/
javascript"></script>

3. Page container
Use the <body> section to contain the visible content. We
start this by placing the <main> page container inside the
body; this will be used to allow the controlled layout of
the content. Your page title and introduction content will
go inside this.

4. Fullscreen: controls
The controls to access the full-screen elements are
placed as content inside the <main> container element.
Each of these items have a [data-screen] attribute that
stores the element ID of the item to open.

ability to contain these elements inside a container that


has controls, such as to exit full-screen mode and/or
switch to viewing other elements.

<div id="screen3" class="fullscreen">


<span action="exit">close</span>
<iframe src="http://www.monkey-x.com"></
iframe>
</div>

7. JavaScript selector functions


With all of the HTML elements on the page, the next step
is to start building functionality with JavaScript. Create a
file called controls.js and add the following functions to
allow easy selection of HTML page elements.

$ = function(cssRule){
return document.querySelector(cssRule);
}
$$ = function(cssRule){
return document.querySelectorAll(cssRule);
}

5. Fullscreen: elements
Some elements will be displayed directly in full-page
mode. These elements are to be added to the content
inside the <main> container. We add a selection of
images that will be selectable, as well as a number of
iframe pages with class=fullscreen to be called on later.

8. JS full-screen activation
Our example will use a single function to activate any of
the full-screen presentation of the elements passed to it.
This allows the control of full-screen requests to be
managed from one place, with it being easy to upgrade
later if this is required.

www.fullengineeringbook.net

1. Initiate HTML page

As with any webpage, there is a requirement to define the


pages HTML, head and body structure. Use the head
section to contain any meta data such as the page title
for SEO and accessibility that you may need.

<iframe id="screen1" class="fullscreen"


src="http://www.nextpoint.co.uk"></iframe>
<iframe id="screen2" class="fullscreen"
src="http://www.blitzbasic.com"></iframe>
<img id="screen4" class="fullscreen"
src="img/guy.jpg" />

2. Load resources

6. Fullscreen: containers

The HTML <head> section should contain the links to


any resources you are using for the page. Were using

In addition, providing the ability to make elements


directly display in full-screen mode, we also have the

Use iframe apps


A problem with full-screen mode is that it closes
when the user visits a new URL this is solved by
using iframes, enabling you to show diferent
webpages without changing the URL.

Left

The HTML elements are on page, but without any styling


to make the effect work hence the content of other
pages being visible
Top left

The navigation screen has now been styled, complete with


the hiding of elements that are to be opened for
full-screen display
Top right

Full-screen options are now added as buttons it is their


[data-screen] attribute that defines them as the controls to
be searched for

HTML5 & CSS3 Genius Guide 93

Front-end
function fullscreen(element){
if(element.requestFullscreen) {
element.requestFullscreen();
} else if(element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if(element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if(element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}

9. Controls: exit fullscreen


There is a need to allow the user to exit full-screen mode
from within the webpage. This is performed in a similar
way to opening full-screen mode, but instead referencing
the main documents exitFullScreen() function.

function fullscreen_exit(){
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();

}
}

});

12. Initialise styling


10. JS action listeners
Controls that are responsible for activating full-screen
presentation of other elements require their JavaScript
listener to behave slightly diferently instead of
activating themselves, we use the [data-screen] attribute
to reference the ID of the element to activate the
full-screen presentation.

window.addEventListener("load",function(){
var screenTriggers = $$('[data-screen]');
for(var i=0; i<screenTriggers.length; i++){
screenTriggers[i].addEventListener("click",f
unction(){
fullscreen( $('#'+this.getAttribute("datascreen")) );
});
}
});

11. Attach fullscreen_exit()


Looking back at Step 6, there are elements used as
containers for presentation complete with controls.
Attach the previously created fullscreen_exit() function to
elements with a [data-action=exit] attribute when
clicked, in order for the user to exit full-screen mode..

Now that the JavaScript functionality is complete, the


next stage is to start the definitions for the visual
presentations. Create a file called main.css and then
insert the following CSS formatting for the main HTML
and body containers.

html,body{
background: #000;
padding: 0;
margin: 0;
font-family: monospace;
height: 100%;
}

13. Content container


The content is contained inside the <main> element,
which positions the content in the centre of the screen.
We achieve this positioning by setting the left and right
margins of <main> to auto, which will balance the margin
spacing between both sides.

main{
display: block;
width: 75%;
margin: 10% auto 0 auto;
background: silver;
padding: 1em;
}

www.fullengineeringbook.net
About the exit plan
Browsers provide a way to exit full-screen mode,
but users will forget any notice they are shown.
Make sure to add an on-page exit button to make
it easy for users to exit fullscreen when they
want to do so.

Top left

Other types of elements, such as video, can be made


fullscreen if required
Top right

Another website being shown in fullscreen through an


iframe, enabling navigation without having to change the
current URL
Right

A website in full-screen display with the exit button bar


placed at the top of the screen

94 HTML5 & CSS3 Genius Guide

window.addEventListener("load",function(){
var screenTriggers = $$('[dataaction="exit"]');
for(var i=0; i<screenTriggers.length; i++){
screenTriggers[i].addEventListener("click",f
unction(){
fullscreen_exit();
});
}

14. Navigation styling

The full-screen options all have the [data-screen]


attribute, hence why we use this in order to reference
them; enabling us to change their element type from
button if needed. Also apply colour, padding and
transition properties.

HTML5 & CSS3

Genius Guide

Why fullscreen?
The ability to ofer your
website and web
application users the
option to view content in
fullscreen allows your
design to access
maximum space for better
usability. It could also
provide focus on a single
element on your page, for
example with picture,
video or content section.
For web apps, it also
has the psychological
advantage of persuading
users to think of your
creation as an app, rather
than as a website. This will
then enables users to take
your software more
seriously as an app that
they would actually want
to use. With the latest
features of HTML5
supporting ofline
functionality and ofline
data storage, the
diference between the
capabilities of native and
web apps have become
very blurred.

www.fullengineeringbook.net
[data-screen]{
display: inline-block;
padding 1em;
font-size: 2em;
background: #333;
color: #fff;
transition: background-color 1s;
-webkit-transition: background-color 1s;
}

15. Navigation hover effect


In order to make sure that users can clearly identify that
navigation elements can be interacted with, we will place
an efect on each of the navigation items to slightly
change their appearance when the mouse pointer is
hovering over them. Changing the colour to become a
lighter shade when it is hovered over gives the
appearance of it lighting up.

[data-screen]:hover{
background-color: #777;
}

16. Exit style


Elements that have [data-action=exit] will need to have
this displayed as a visible control. We will make this
appear as a full-size red bar with white text that stretches
across the full width of the screen. This element will also
be 5% of the height of the full screen.

.fullscreen [data-action="exit"]{
display: block;
width: 100%;
height: 5%;

background: #c00;
color: #fff;
transition: background-color 1s;
-webkit-transition: background-color 1s;
}

17. Exit hover


The exit option will also change appearance when the
user hovers over it. This is achieved by using the :hover
selector, in which we will change the background and
text colours. With the background-color property being
set as a transition in the previous step, the colour change
will animate when the element is hovered over.

.fullscreen [data-action="exit"]:hover{
background-color: #fff;
color: #c00;
}

18. The iframe styling


Container elements that contain an iframe element will
be displayed to show them at full size. This needs to take
into account the five per cent height of the exit option,
hence the height of the iframe will be 95%.

.fullscreen iframe{
display: block;
width: 100%;
height: 95%;
}

19. Hiding full-screen elements


Full-screen elements use the class name fullscreen and
are hidden by default. Properties to ensure 100 per cent

width and height are set for when the elements are later
displayed in full-screen mode avoiding the need to
repeatedly define this under the diferent browser vendor
full-screen selectors.

.fullscreen{
display: none;
width: 100%;
height: 100%;
}

20. Full-screen visibility


Items that have been hidden from normal view need to
become visible when the browser enters full-screen
mode. This is achieved by using :fullscreen selector
although take note that diferent browser vendors use
diferent versions and spellings for this selector.

.fullscreen:-webkit-full-screen{display:
block;}
.fullscreen:-moz-full-screen{display:
block;}
.fullscreen:-ms-fullscreen{display: block;}
.fullscreen:full-screen{display: block;}
.fullscreen:fullscreen{display: block;}

21. Finishing touch


With everything complete, you are now free to make any
additional styling required for your version of the
full-screen menu tool. In this example, we add an
underline style to the h1 element used as the visible
page title.

h1{
text-decoration: underline;}

HTML5 & CSS3 Genius Guide 95

Developer

www.fullengineeringbook.net

96 HTML5 & CSS3 Genius Guide

98

Be a jQuery code master


Grasp the core tricks and techniques of jQuery

106 25 pro plugins


Boost your website or app with these top add-ons

116

Produce a picture gallery


with jQuery
Manage user interactions for visual presentation

120 Code validation into forms with


ngMessages
Learn to create a form with reactive user feedback

124 Make drums with the Web


Audio API
Integrate a responsive drum kit with Web Audio

128 Get free web hosting with


GitHub Pages
Sign up and reap the benefits of GitHub hosting

www.fullengineeringbook.net
132 Manage JS with
asynchronous tasks

Reduce JavaScript bloat in one fell swoop

HTML5 & CSS3 Genius Guide 97

Developer

be a
www.fullengineeringbook.net

code master
We reveal the core techniques for the library, integration
with ES6 and cheat sheets for easy referencing

98 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

The current state of jQuery


ITS BEEN TEN YEARS SINCE INITIAL RELEASE, BUT WEB DEVELOPERS STILL NEED TO KEEP AN EYE ON JQUERY
Falling victim of its own success in recent
years, jQuery can sometimes be described as
not-cool especially when used in the same
sentence as libraries like Angular or React. JQuery
doesnt include a templating language or follow a MV*
pattern, yet its still an incredibly useful library in the
modern developers toolset.
JQuerys gentle learning curve can be a great
introduction to JavaScript and since conception its
become the go-to for a first taste of JavaScript a
language that is leaving its browser only roots behind.
The library enables complex topics to be introduced
sooner and in bite-size chunks. The more experienced
developer should remind themselves of jQuerys own
slogan which is write less, do more. This ease of use
can, in the real world of fast-paced deadline-driven
development, be a lifesaver. How many of us can
remember how to efectively traverse the DOM in
vanilla JavaScript?
Simplicity shouldnt be a negative, the library is in use
in over 65 per cent of the top one million websites
(libscore.com/#jQuery) and this isnt a coincidence.
The librarys core is well-thought-out and the jQuery
team has an incredibly methodical process to
implementing new features features that are
introduced to improve the library with each release.
Being designed from day one with extensibility in
mind has meant that in the last ten or so years,
thousands of plugins have been developed by a huge
open source-based community; there is a jQuery plugin
for almost all use cases now. Unfortunately though,
some of these plugins that have been created may also
generate some bad press due to the poor-performing
and underdeveloped code involved. The saying A poor
workman blames his tools is true for all of these terribly
written plugins and the developers that decide to
actually use them. Knowledge within the open source
community allows the cream to rise to the top and the
jQuery community has published guidelines on
extending the library.
We have to thank jQuerys popularity for kick-starting
the vibrant JavaScript community we have today. There
have been of-spin projects such as jQuery Mobile,
which is an extension of the library to produce mobile
and tablet-ready interfaces. Web developers can use an
existing skillset to make advanced interfaces for the
newest devices devices that didnt exist when it was
initially released.

The library has enabled developers to work with the


DOM API to build a far richer web than we had ten
years ago improving the end users experience, which
should ultimately be the most important goal of any
web project.
The library will be a whopping ten years old in
August 2016, making it the great grandfather of
JavaScript frameworks a proven and stable platform
that has enhanced millions of websites. There was a
time when people believed Facebook would start losing
users as its popularity increased this never happened
because the platform worked whilst serving a purpose,
like jQuery.
Understanding, when enhancing an interface to
improve the end users experience, is key and jQuery
has been successfully doing this for nearly ten years.
Newer libraries may introduce new features and
paradigms; it may not be faster than its native
counterpart functionality, yet jQuerys dependable core
and widespread knowledge base ensure that it stays
production ready.

Whats up with v3?


LEARN MORE ABOUT THE FIRST
MAJOR RELEASE IN TWO YEARS
Version 3 alpha is now out in the wild and
comes in two flavours; much like the release
of version 2 it drops support for Internet
Explorer below version 9. There is however a
compat version if you want to support older
browsers and utilise new features for your
more up-to-date users. The only caveat here
being that the compat version will be of a
larger file size as well as being slower in
real-use performance.
When developers release a major version of
any framework there is usually a queue of
people complaining about breaking changes,
and the jQuery team has worked hard to
ensure this isnt the case almost all code
should continue to work with zero changes.
There are, however, changes that are a step
in the right direction. In previous releases any
jQuery methods that hide/show content (.
hide(),.show(), .slideIn()) applied display
properties directly to the element, sometimes
adding display:block to elements and
overriding display properties that should have
been display:inline this can cause a lot of
layout issues. This is no longer the case and
jQuery recommends to hide/show content
using CSS classes with methods such as .
toggleClass(). This increases performance by
ensuring the change is rendered by the CSS
render engine.
Performance seems to be high on the
agenda and whilst reworking the internals of
custom attribute selectors (:visible, :hidden)
theyve noted speed increases of up to 17 times
faster in execution. The underlying animation
engine now utilises requestAnimationFrame
meaning smoother animations, less CPU time
and reduced battery drain on mobile devices
great if youre using jQuery in PhoneGap or a
Cordova application.
Version 3.0 goes some way to
futureproofing the library, ensuring that its
keeping up with the latest standards (.
deferred() is now Promises/A+ compliant for
example). Along with the increase in
performance, and when combined with the
removal of deprecated functionality, jQuery v3
is another step forwards.

www.fullengineeringbook.net

Daniel Jenkins
Development lead

JQuerys easy-to-understand
syntax allows me to introduce
experience-enhancing features on
websites quickly and efficiently that
work across multiple web browsers
and devices.

The library is well-thought-out and the


jQuery team has an incredibly methodical
process to implementing new features

HTML5 & CSS3 Genius Guide 99

Developer

Whats in the core API?


REMEMBERING THE CORE METHODS IS A BIG UNDERTAKING, SO HERES A LIST OF WHAT YOU SHOULD KNOW

selectors
$(selector)

Attributes
& CSS

.attr()

api.jquery.com/all-selector/

api.jquery.com/attr/

Selects all elements.

Gets the attribute for the first


selected element.

api.jquery.com/innerHeight/
Gets the height of first matched
element, This will include the
padding as well but does not
include the border.

.innerWidth()

.class

Browser
Events

.innerHeight()

.resize()
api.jquery.com/resize/
Binds event handler on resizing.

event
preventDefault()

api.jquery.com/class-selector/

.data()

api.jquery.com/innerWidth/

Selects all elements with the


given class.

api.jquery.com/data/
Store data associated with
matched element or return the
first matched elements.

Gets the width of first matched


element. This will include the
padding as well but does not
include the border.

.prop()

.outerHeight()

api.jquery.com/prop/

api.jquery.com/outerHeight/

.scroll()

Gets the value of a property for


the first matched element or sets a
property on matched elements.

Gets the height of first matched


element. This will include the
padding, border and optionally
the margin.

api.jquery.com/scroll/

#id
api.jquery.com/id-selector/
Selects a single element with the
given id.

selector1, selector2,
selector3

api.jquery.com/event.
preventDefault/
If this method is called, then the
default action of the event will not
be triggered.

Binds event handler upon


element scrolling.

www.fullengineeringbook.net

bit.ly/1Cs2xEX

Selects the combined results of all


the specified selectors.

.load()

.val()

api.jquery.com/val/

.outerWidth()

api.jquery.com/load/

api.jquery.com/outerWidth/

Binds event handler to JavaScript


load event.

bit.ly/207g9md

Gets the value of the first matched


element or sets a value on the
matched elements.

Selects all elements with the given


tag name.

.addClass()

element

Gets the width of the first matched


element. This includes padding,
border and optionally the margin.

api.jquery/ready/

api.jquery.com/addClass/

.width()
api.jquery.com/width/

bit.ly/207gbdS

Adds specified class to the


matched elements.

Selects all direct child elements


specified by parent

.css()

parent > child

ancestor descendant
bit.ly/1PPT039

api.jquery.com/css/

Gets the current computed width


(in px) of the first matched
element, or it will set the width on
all of the matched elements.

Adds specified style property to


the matched elements.

.offsetParent()

.on()
api.jquery.com/on/
Attaches an event handler for one
or more events.

.trigger()

Gets the closest ancestor element


that is positioned.

api.jquery.com/trigger/

Determines if any matched


elements are assigned to a
specific class.

.position()

.blur()

api.jquery.com/position/

api.jquery.com/blur/
Binds to the form Blur event.

.removeClass()

.hasClass()

:first

api.jquery.com/hasClass/

Selects the first matched element.

:last

api.jquery.com/removeClass/

Gets the current coordinates of


the first matched element, relative
to the ofset parent.

api.jquery.com/last-selector/

Removes specified class from


matched elements.

.scrollLeft()

Selects the last matched element.

Specify function to run when DOM


load is complete

api.jquery.com/offsetParent/

Selects all of the elements


that are the descendants of the
ancestor element.

api.jquery.com/first-selector/

.ready()

Executes matched events.

.change()
api.jquery.com/change/
Binds to the change event handler.

api.jquery.com/scrollLeft/

:first-child

.toggleClass()

bit.ly/1LXfv4A

api.jquery.com/toggleClass/

Selects all elements that are the


first child of their parent.

Adds or removes a specific class


from matched elements.

100 HTML5 & CSS3 Genius Guide

The current horizontal position of


the scrollbar for the first matched
element or sets horizontal position
of the scrollbar for elements.

.focus()
api.jquery.com/focus/
Binds or triggers to the form
Focus event.

HTML5 & CSS3

Genius Guide

runtime can continue while waiting on asynchronous


tasks to complete. ES6 introduces the fetch() API, an
extension of the XHR standard and it look similar to
jQuerys syntax:

fetch('/script.php')
.then(function(data){
console.log(data)
}).catch(function(){
console.log('error')
})
There is the potential for future releases of jQuery to
enable the fetch() API in browsers that support it.
ES6 allows developers to work with JavaScript files as
modules. On a website where jQuery is only required
on one of the webpages, ES6 modules can help.
Libraries such as RequireJS help to do this but incur
browser load and performance penalties for the end
user. Theoretically jQuery could be extended in ES6
when you do it like this:

jQuery and ES6

//script.js
<module>
import * as $ from 'jquery';
</module>
//jquery.js
module.exports = {
$ : jQuery()
}

www.fullengineeringbook.net

TAKE A LOOK AT THESE ES6 FEATURES AND HOW JQUERY CAN USE THEM

ECMAScript 6 or ES6 is the name for the


JavaScript wrote by developers utilising v1 of
latest version of JavaScript, oficially
the library works with the latest version of
Extending
launched in June 2015, its going to
todays browsers, and vice versa with
take browsers a considerable
jQuery
code written in v2 and older
You can make use of jQuery.fn.
amount of time to implement all of
browsers. This is no mean feat its
extend() ($.fn) to extend the
the new features. Developers
one of the main reasons the jQuery
jQuery prototype and provide
wishing to implement the code
library still exists and has a massive
yourself with new methods that
now will need to use a compiler
user base, a lot of logic happens
can be chained of the jQuery()
from ES6 into ES5 such as babel
behind the scenes. As newer
function.
(babeljs.io) to ensure backwards
features are introduced, jQuery takes
compatibility. The current version of
a logical approach to supporting them
JavaScript (ES5) can turn developers with a
with a good forewarning on sunsetting
back-end mindset blue in the face with its lack of
older functionality.
certain language features. The release of ES6 is
Asynchronous functionality is notoriously hard to
designed to move JavaScript as a language towards a
understand and recent versions have introduced the
platform for building more complex applications; the
latest standard of Promises. Many developers rely on
creation of platforms like Node.js and PhoneGap have
the library to send/receive data to the server, from the
proven that JavaScript is an extensive language no
browser using the $.ajax() wrapper.
var request = $.ajax({
longer existing in just the traditional web browser
url: "script.php",
context. Smart TVs, mobile applications, websites,
method: "POST",
servers and many other platforms now depend on
});
JavaScript, thus updating the language needs to be
request.done(function( msg ) {
controlled and ES6 goes a long way to becoming
console.log(msg);
backwards compatible.
});
ES6 may not be production-ready today unless the
request.fail(function( jqXHR, textStatus ) {
exact platform specifications are known, yet it contains
console.log(error);
features the modern web developer will want to be
});
aware of. Languages evolve and the technology that
supports them does too, jQuery has a proven track
JQuerys recent implementation of Promises enables
record of helping developers build interfaces for the
developers to efectively ensure that the JavaScript
widest level of support available. The majority of

This module pattern would enable jQuery to remove


the method $.fn.extend() and allow plugin developers to
still hook into the jQuery core.
ES6 controversially introduces classes, constructors
and extend into the language something back-end
developers will rejoice about. Regardless of opinion the
new inheritance model could be put to good use with
jQuery becoming class-based, with plugins extending
the base jQuery class.

class pictureSlider extends jQuery {


constructor() {
this.slideSpeed = 5;
this.touchEnabled = true;
}
//plugin code
}
There isnt currently an ES6 implementation of the
jQuery library, but as popularity increases the library will
look to support it. A large community built on plugins
using the current $.fn.extend() prototype makes picking
one of the previous two examples for extending the
library a logical move once browser support is ready.
ES6 introduces many native APIs that jQuery has
included workarounds for in previous releases such as
new iterators (for + of) and common data-structures
(.map). You can read more at ecma-international.org/
ecma-262/6.0/) for a full list of all the new ES6 features.
ES6 will make a lighter and faster jQuery, ensuring that
developers using the library can focus on writing code
that is doing less behind the scenes and more for the
end user.

HTML5 & CSS3 Genius Guide 101

Developer

JQuery provides a
multitude of helpful
functions, that should have
been included in JavaScript
from day one

A pros guide to the


www.fullengineeringbook.net
benefits
of jQuery
JQUERY HAS THE POTENTIAL TO TURN A GOOD DEVELOPER INTO AN EXPERT FIND OUT HOW

Matt Leach
Head of development, Thinking Juice

Using jQuery was the first time I


saw the web as more than a flat
interface and a place to create
experiences for users and
customers, every time I use the
library I learn something new.

102 HTML5 & CSS3 Genius Guide

When looking to use web technologies for a project


there are many factors involved in the decision-making
process to consider, such as how long until the project
needs to be delivered. Does the project need to
support the latest browsers? Or even worse support the
oldest of browsers? Does the project have to withstand
being production-ready, bug-free and dependable?
Multiple factors play a part, some that may not even be
considered by the developer when embarking on a
new project.
Working with HTML and CSS can, for many, be an
easy choice when it comes to building interfaces, yet
the sheer number of JavaScript frameworks to choose
from can be bewildering. Syntax aside, choosing the
right framework takes a large amount of consideration.
Its the wider thought process of the entire project and
the impact of decisions made early on that makes a
good developer, great. Knowledge like this isnt gained
over night but practising, experimenting, making
mistakes, learning and talking to peers can reduce the
headaches along the way of mastering development.

Progressive enhancements
JQuery was initially introduced to enhance the world of
web development and, like all open source eforts, to
enhance the framework users experience. In the real
world these enhancements can be measured by trivial

elements such as allowing new features to be added to


a website within tight timescales or ensuring a student
can complete a task they set out to do. Take for
example the blue chip world, a world that has inherently
slow IT upgrade schedules with the majority of these
users using much older versions of Internet Explorer,
picking the right library helps to ease the pain of
building features that are cross-browser compliant.
Trying to write vanilla JavaScript for even basic use
cases can be painful, taking the blue chip world for
example try adding a class in jQuery:

$(#contact).addClass(sent);
The jQuery method has enabled this functionality in
minimal code for working across multiple browsers.
Now try writing that in native JavaScript:

document.getElementById(contact).
classList.add("sent");
Now this is nearly double the length and works in
modern browsers, looking back to older versions of IE
this would cause an error. To ensure cross-browser
compliance look at this code (and its length):

var d = document.getElementById("contact");
d.className = d.className + " sent";
One line of code may sufice if the project only uses
JavaScript for this single action loading in a library

HTML5 & CSS3

Genius Guide

5 jQuery features
you need to know
METHODS THAT ARE WELL
WORTH USING

.promise()
You can use this method to
return a Promise object to
observe when all actions of a
certain type that are bound to the
collection, regardless of whether
it is queued or not, have
finished.

.ajaxSetup()
api.jquery.com/jQuery.ajaxSetup/
This little-known method allows variables to be
predefined for all AJAX requests. For example
using a defined URL route for all requests in an
application could be set via:

$.ajaxSetup({
url : /requestMe
})

.grep()
api.jquery.com/jQuery.grep/
Grep is a Unix command and jQuery provides
this as a helper that is great for searching
through arrays for specific values.
would then be overkill. JQuery gives developers a set of
tools that keeps all levels focused on the end goal.

Deadline-driven development

repeated more than once there is probably a way of


automating that process.
DRY (dont repeat yourself) principles are abundant
when it comes to writing eficient, human-readable
code. Look at this code for changing an elements state
once interacted with:

var data = [0,1,2];


var filteredData = $.grep( [ 0, 1, 2
], function( n, i ) {
return n > 0;
}, true );

www.fullengineeringbook.net

Deadlines, much like taxes, are unavoidable in most


walks of life, and a day-to-day occurrence. Known for
causing many a grey hair, working smart can make the
approach much more bearable. Its all too common to
see more junior developers looking at a current project
or application and then announce Hey, we should
rewrite that in this cool framework. This doesnt mean
they are incorrect and their enthusiasm shouldnt be
rewarded, but taking on board a new library has to be
carefully considered. It needs to ensure a return on
investment whether thats personal or financial. There
will be companies pushing products live with a new
library, built by a freelance resource that their internal
developers cant support. In a development team, at
crunch time, everyone will be expected to help and
chances are nine out of ten developers in the team will
be able to help iterate on any code wrote in jQuery. If
written in the cool framework the resource pool may
be slightly smaller. When starting any project be aware
that at some point in the future, other developers will
have to support it.

How do the pros really use it?


A skilful developer is someone that has not only
mastered the art of writing code and logical thinking
but the understanding that if something has to be

$(.btn).addClass(in-use);
$(.btn).attr(disabled, true);
$(.btn).data(used, true);

JQuery provides a smart developer the ability to chain


these methods, using the prototype inheritance model (a
paradigm widely used JavaScript):

$(.btn).addClass(in-use).
attr(disabled, true).data(used,true);

The variable filteredData is now an array of any


values greater than 0;.

.closest()
api.jquery.com/closest/
This method traverses upwards from the
current DOM element to a documents root
element. It accepts a jQuery object as an
argument and if included when traversing,
jQuery returns the first matching element.

.holdReady()
JQuery provides a multitude of helpful functions, that
should have been included in JavaScript from day one.
Replicating functionality that other languages contain
from the outset, a lot of very similar libraries exist purely
to fulfil these tasks. Many JQuery utility methods are a
secret toolset that a lot of developers dont mention
frequently.
The jQuery library may not be the fastest or the
lightest but a community of thousands can continue
producing interfaces in an ever-changing world of
technology. Being a good developer isnt about being
an early adopter its about writing well-formed code that
works when required, whilst knowing the tools to get
the best out of the platform.

Taking on board a new library has to be


carefully considered. It needs to ensure a
return on investment

api.jquery.com/jQuery.holdReady/
This is a relatively unknown method that holds
or releases the .ready() function. Use cases for
this may seem far-fetched, but there can be
times where the DOM is ready but other
functionality should happen first.

$.holdReady( true );
$.getScript( "myplugin.js", function()
{
$.holdReady( false );
});

$.merge()
api.jquery.com/jQuery.merge
Developers used to PHP (array_merge) will
recognise this as a fast way of merging two
arrays this neat helper provides functionality
that native JavaScript doesnt provide.

var new_array = $.merge( [ 0, 1, 2 ],


[ 2, 3, 4 ] )

HTML5 & CSS3 Genius Guide 103

Developer

Advanced jQuery
REGARDLESS OF EXPERIENCE, THESE ADVANCED METHODS OF ARE DEFINITELY WORTH CHECKING OUT

Filters

Utilities

Deferred
Object

AJAX

.eq()

inArray()

api.jquery.com/eq/

bit.ly/1MgB8c6

deferred.always()

api.jquery.com/jQuery.ajax/

Reduces the set of matched


elements to the one at the
specified index.

Searches for a specified value in


an array and returns its index.

api.jquery.com/deferred.
always/

Performs an asynchronous HTTP


(AJAX) request.

jQuery.isArray()

jQuery.ajaxSetup()

jQuery.ajax()

.filter()

bit.ly/1GvAzz8

Adds handlers to be called when


the deferred object is either
resolved or rejected.

api.jquery.com/filter/

Determines whether the argument


is an array.

deferred.done()

Reduces the set of matched


elements to those that have
matched the selector or pass the
functions test.

.jQuery.
isEmptyObject()
bit.ly/1Nyv0zh

.first()

Adds handlers to be called when


the Deferred object is resolved.

Checks to see if an object is empty.

api.jquery.com/first/
Reduces the set of matched
elements to the first one that is in
the set.

api.jquery.com/deferred.
done/

jQuery.isFunction()
api.jquery.com/jQuery.
isFunction/

api.jquery.com/jQuery.
ajaxSetup/
Sets default values for any future
AJAX requests.

jQuery.get()
api.jquery.com/jQuery.get/

deferred.notify()

Loads data from the server using a


HTTP GET request.

api.jquery.com/deferred.
notify/

jQuery.getJSON()

www.fullengineeringbook.net

.has()

jQuery.isNumeric()

deferred.progress()

api.jquery.com/jQuery.
isNumeric/

api.jquery.com/deferred.
progress/

jQuery.getScript()

Determines whether its argument


is a number.

Specifies a function to run when


DOM load is complete.

api.jquery.com/has/
Reduces the set of matched
elements to those that have a
descendant that matches the
selector or DOM element.

api.jquery.com/is/

jQuery.makeArray()

Adds the handlers that will be


called when the deferred object
goes on to generate the
progress notifications.

Checks against a selector and


return true if at least one of these
elements matches the selector.

api.jquery.com/jQuery.
makeArray/

deferred.reject()

.is()

Converts an array-like object into


a true JavaScript array.

bit.ly/1GIgIMT

api.jquery.com/last/

jQuery.merge()

Reduces the set of matched


elements to the final one in the set.

api.jquery.com/jQuery.
merge/

deferred.resolve()

.map()

Merges the contents of two arrays


together into the first array.

api.jquery.com/deferred.
resolve/

Parses each element in the current


matched set, producing a new
jQuery object containing the
return values.

jQuery.now()

Rejects a deferred object and calls


any failCallbacks with the given
arguments.

.slice()

jQuery.parseHTML()

api.jquery.com/slice/

api.jquery.com/jQuery.
parseHTML/

api.jquery.com/map/

104 HTML5 & CSS3 Genius Guide

api.jquery.com/jQuery.now/
Returns a number representing
the current time.

Parses a string into an array of


DOM nodes.

Loads JSON data from the server


with a GET HTTP request.

bit.ly/1RdOJVI

.on()
api.jquery.com/on/

Rejects a deferred object and


calls any failCallbacks with
specified arguments.

.last()

Reduces the set of matched


elements to a subset specified by
a range of indices.

api.jquery.com/jQuery.
getJSON/

Checks if the argument passed is a


JavaScript function object.

Calls the progressCallbacks on a


deferred object along with the
given arguments.

Attaches an event handler for one


or more events.

.trigger()
api.jquery.com/jQuery.
getScript/
Loads a JavaScript file from the
server using a GET HTTP request,
then executes it.

.load()
api.jquery.com/jQuery.load/

deferred.
resolveWith()

Loads data from the server and


places the returned HTML into the
matched element.

api.jquery.com/deferred.
resolveWith/

jQuery.post()

Resolves a deferred object and


calls any doneCallbacks with the
given context and args.

api.jquery.com/jQuery.post/
Loads data from the server using a
HTTP POST request.

HTML5 & CSS3

Genius Guide

5 common mistakes to avoid


A LITTLE KNOWLEDGE OF THE COMMON MISTAKES EVERYONE MAKES CAN HELP TO PRODUCE BETTER CODE

1. Relying on $(document).ready(); the browsers cache, which would reduce bandwidth and
Including JavaScript in the <head></head> tags and then
page-load time.
waiting for jQuery to run when the DOM is fully loaded
3. Faster selectors
can cause the end user a headache-inducing wait.
With the introduction of CSS preprocessors, its become
Executing JavaScript code when the browser has loaded
a bit of an issue with overly specific CSS declarations yet
the complete DOM is in itself inherently dificult and
with jQuery we find the opposite happening. Look at
troublesome. Each browser tells JavaScript when the
this navigation code:
DOM is ready at a diferent time and jQuery has a
<ul id="navigation">
helpful method .ready() that does a
<li><a class="nav-item"
The
multitude of things in the background to
href='#home'>Home</a></li>
$var syntax
ensure the DOM is loaded before firing.
<li><a class="nav-item"
Use the dollar $var syntax to
JavaScript is a blocking script
href='#about'>about</a></li>
let others know its a jQuery
meaning when the browser finds
<li><a class="nav-item"
object. If the variable is in the
the <script> tag it wont do anything
href='#contact'>contact</a></
correct scope, then jQuery will be
else until that code has loaded in.
li>
able to access the element
Any assets, photos, CSS and other
</ul>
without having to search for
JavaScript files, wont execute until
<script>
the DOM again.
this file is loaded. Its considered best
$('.nav-item').click(function(){
practice to place all JavaScript assets in
//code to scroll to location
the footer as JavaScript should enhance a
})
page, not build the UI. If code is required to execute
</script>
when all assets in the webpage are ready, it would be
The lack of specificity here means that jQuery has to
convenient to do this:
traverse the whole DOM to find .nav-item on big pages
The code doesnt get executed until the whole DOM is
this can reduce performance greatly. Its like going
ready large images slow down the time from page load
shopping and having to look at every item in the shop to
to the JavaScript firing.
//code//
find a specific item. You can increase performance by
(function($) {
increasing selector specificity:

$('#navigation').addClass('visible');
//execute other code
$('#navigation').removeClass('visible');
Every time jQuery wants to alter the navigations class
attributes, it has to traverse the whole DOM and find the
element with the id #navigation, alter its class then
continue processing the next line of JavaScript. Each
time the $(selector) is used, jQuery has to look for this
element in the DOM. Assign the jQuery $(selector)
object to a variable increases performance, as a
reference to that element is now available in memory.

var $navigation = $('#navigation');


$navigation.addClass('visible');
//execute other code
$navigation.removeClass(visible');

5. Animating with jQuery


When jQuery was initially released, its internal animation
engine was one of the most ground-breaking features
since then browsers and CSS have moved considerably
forward. Take this example of animating an elements
height for example:

www.fullengineeringbook.net
//fire code
})(jQuery);

Initialising any functions this way enables the JavaScript


to execute when its possible. The end user will see the
page being usable sooner perceiving a faster load time.
If specific code needs to ensure a certain element is
completely loaded before being executed, use .load():

$(img).load(function(){
//execute code
})

2. Hosting jQuery yourself


When building a website that utilises jQuery its all too
easy to download a copy of the library, place it in a local
directory then load it in to the pages required.

<head>
<script src='/jQuery.js'></script>
</head>
For every new visitor to a website they have to download
this file from the server, which slows down the initial page
load and introduces an extra drain on bandwidth.
Reference jQuery from a CDN and the chances are that
when someone visits the website, they will previously
have visited a website that hosts jQuery with that CDN
(Google for example) and already have jQuery stored in

<ul id="navigation">
<li><a class="nav-item"
href='#home'>Home</a></li>
<li><a class="nav-item"
href='#about'>about</a></li>
<li><a class="nav-item"
href='#contact'>contact</
a></li>
</ul>
<script>
$('#navigation .nav-item').
click(function(){
//code to scroll to location
})
</script>

$('.changeHeight').animate({
'height' : 250
}, 650);

JQuery internally calculates the elements height, then


changes the height up to 60 times a second, causing the
browser to redraw the DOM every single time its
changed (60fps). CSS animations in modern
browsers are handled using hardware
Smooth
acceleration and are processed by the
auto heights
GPU ensuring a faster experience over
Adding the class .open to the
CPU tasks like rerendering the DOM
element will cause the GPU to
for example.
<style>
redraw the elements properties
.changeHeight{
without having to do any of the
-webkit-transition: all 0.65s
complex JavaScript calculations
ease-in-out;
that will be running.

Now when traversing the DOM, jQuery looks for the


parent id (#navigation) and then looks for its child
element with the class declared. Going back to the shop
analogy, the aisle would now be known as (#id), thus
searching for the specific item would take much less
time than before.

4. Not caching DOM elements


Here is a simple script for adding a class to a websites
navigation, then removing that class after executing
other logic:

-moz-transition: all 0.65s


ease-in-out;
-o-transition: all 0.65s ease-in-out;
transition: all 0.65s ease-in-out;
overflow:hidden;
height:auto;
max-height:0;
display:block;
}
.open{
max-height:250px;
}
</style>
<script>
$('.changeHeight').addClass('open');
</script>

HTML5 & CSS3 Genius Guide 105

Developer

www.fullengineeringbook.net
discove
r the top jquery add - ons for
m ak i
ng you
ience
r websites and apps A bet ter exper

Expert speaks
Tam Hanna works with Symbian
software products and a variety of
coding languages. He reveals the best
plugins for powering up jQuery

106 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

Tweak Photos
<body>
<div id="editor-window"></div>
<script type="text/javascript">
$("#editor-window").imageEditor({
'source': '/img/demo.jpg',
"maxWidth": 500,
"onClose": function () {
}
});
</script>
</body>

Plugin: Image Editor


bit.ly/1hIv6c1
Category: Photo editing
Users love to edit uploaded pictures on the
web. Image Editor provides a svelte little GUI
wrapper around the Camanjs filter library: it
saves you from the hassle of coding a set of
sliders, buttons and symbols which come
together to make up a little editor.

Manage UIs
bit.ly/1GK1Ub7
Tree views provide a way to manage complex user
interfaces: if options are grouped up, the UI
appears less daunting at first glance. EasyJSTrees
tree structures start out as a group of list tags,
which are then spruced up by invoking the
easytree() method on the mother element.

Getting started with the Image Editor plugin


requires the embedding of four libraries and a
picture box. Our test harness starts like this:

OnClose is invoked if the user clicks the close button


below the image: you can use the various methods
found in Canvas in order to obtain the results of the
editing operation. Image Editors Save button
<head>
compresses the picture into a file which is then served
<script src="dependencies/jquery.min.js"></
via the download utility.
script>
Other initialisation options include maxHeight, for the
<script src="dependencies/jquery-ui.js"></
maximum height of the image; maxWidth, for the
script>
maximum width of the image; remoteSave, where the
<script src="dependencies/bootstrap.min.
default save method is browser; remoteURL, for where
js"></script>
you want to send the image to; blockEnable,
<script src="dependencies/caman.
which should only be enabled if jQuery
full.js"></script>
Required
BLOCKUI is enabled; blockMessage, a
<script src="js/boostrapdependencies
message that will be displayed in the
image-editor.min.js"></
Image Editor will need these
blockUI; and saveCallBack, the
script>
libraries: the latest jQuery, jQuery
callback after the save event.
<link href="dependencies/
UI, Camanjs and Bootstrap.
The actual editing is handled by
jquery-ui.min.css"
Camanjs is very easy to extend,
the plugin no callbacks are
rel="stylesheet">
with a constantly growing
provided to inform you about the
<link href="dependencies/
number of image editing
individual steps taken. Image Editor
css/bootstrap.css"
capabilities.
should not be used to process large files:
rel="stylesheet">
most browsers pop up an alert dialog about
<link href="css/boostrap-image-editor.
unresponsive scripts if an operation takes too long.
css" rel="stylesheet">
In practice, images smaller than XGA tend to work well
</head>
keep in mind that Firefox is not multithreaded, which
leads to resource competition between tabs.
Keep in mind that the download is not complete and
thats because each of the libraries also expects its
OTHER AUTHOR PLUGINS:
resources to be in place for the GUI to work. This can be
Ritchy Chen
accomplished by extracting the individual archives
rithychhen.com
contents into the /dependencies folder.
Plugin 1: Scrollbar Indicator
Image Editor does its magic in a <div> tag, which is
bit.ly/1LxgHeR
populated at runtime via the imageEditor function. Our
Plugin 2: Birthday Picker
example loads the editing tools during page load in
bit.ly/1hIvnvy
practical applications, starting the editor on demand
might be more eficient:

Pop-up dialogs
bit.ly/1MWNFGr
Palm OS graced developers with the popup: a
complex modal dialog which could be invoked to
get a result. Prompt21 obviously was inspired by
the golden oldie. Invoke the popup after calling the
var p = $(.popup).prompt21(); method on it, and
feast your eyes on a JSON object containing the
values entered in the dialogs widgets.

www.fullengineeringbook.net

Image Editor does its magic in a <div> tag,


which is populated at runtime via the
imageEditor function

Tab bars
bit.ly/1OHWpjG
Tab bars are a classic: if theres little screen real
estate, multiply it by introducing some tabbing.
TurboTabs expects you to feed it with a structure
of <ul> and <div> elements alongside a
configuration object that can be set up via a tool
on the plugins website. Your input will then be
transformed into a svelte-looking and nicely
animated tab bar.

Sticky cursors
bit.ly/1RMbaSs
Making a widget stick to the cursor is helpful when
a drag-and-drop-like interface is to be
implemented. ObeyCursor transforms this task
into a no-brainer: simply configure a <div> tag of
choice, and configure it with a call to the
obeyCursor method:

<script type="text/javascript">
$(function() {
$("#slave").obeyCursor(opts);
});
</script>

HTML5 & CSS3 Genius Guide 107

Developer

Web Windows manager


Our web app has been
rendered in a little
pop-up window. You
can spruce up its looks
by deploying your
chosen GUI framework.

Users are free to


change the desktop
background to an
image as they see fit.

Deskibles start menu


will remind users of
classic versions of
Windows 95 to 7. The
default items in our
screenshot can be
removed if desired.

A small clock located


in the bottom-right
corner of the screen
can help your users to
keep track of time.

www.fullengineeringbook.net
Plugin: Deskible
bit.ly/1PwPvyu
Category: Window manager
Ever found yourself sufering from MDI envy
while working on a web app? This proof of
concept creates a relatively full-featured
Window Manager based on your favourite web
technologies. It helps developers to create and
manage a number of dynamic windows inside
their web applications.

First download Deskible from GitHub. This must be done


via the command line to satisfy the dependencies. Next,
open index.html for the correct operation. As of this
writing, the log-in window is not implemented just click
Login to move into the desktop environment. Start menu
content is configured by startMenu array content
declared in app.js. One example looks like this:

startMenu: [{
icon: 'book',
label: 'Documentation',
sub: [{
icon: 'wrench',

108 HTML5 & CSS3 Genius Guide

id: 'docu-setup',
label: 'Setup and Layout',
options: {
tabs: false,
content: {
url: 'apps/documentation/setup.html'
} } }, {
Higher-level folders are created as simple array elements,
while their subelement contains the actual content.
Looking at /apps/examples/irc.html reveals that the IRC
client consists of but the following line:

<iframe type="text/html" width="100%"


height="100%" src="https://kiwiirc.com/
client" frameborder="0"/>
Complex content is best created via an iframe: Deskible
will load it as if it were found in a website, displaying
content in the area decorated by the window managers
widgets. A custom installation of Deskible starts by
removing unneeded elements: for most applications, a
YouTube player and an IRC client are overkill. Proceed to
an iFrame-hostable web apps in the apps folder:

<p>
<script>

function tmgnBtnClicked()
{alert ("Hello World!");}
</script>
R: <input type="text" name="r" ><br>
U: <input type="text" name="u" ><br>
I: <input type="text" name="i" ><br>
<button onclick="tmgnBtnClicked()">Calcula
te</button>
</p>
Next, add the relevant entry to the start menu. Our
resistance calculating widget will sit in Tamoggemon ->
OhmCalc, accomplished via the following snippet:

startMenu: [{
icon: 'book',
label: 'Tamoggemon',
sub: [{
icon: 'wrench',
id: 'ohmcalc',
label: 'OhmCalc',
options: {
tabs: false,
content: {
url: 'apps/ohmcalc.html'
} } },]}

HTML5 & CSS3

Genius Guide

Telephonic enforcer
bit.ly/1VVXt3V
Users hate sharing their phone number with
random websites. This library contains a set of
validation routines aimed at catching miscreants
red-handed. Please keep in mind that
MobilePhoneNumber does not check whether the
user really owns the phone in question it merely
keeps honest people honest by not allowing them
to enter malformed numbers.

Manage Cookies
Plugin: CookieBar and js-cookie
bit.ly/1LdDLxR and bit.ly/1av6HUb
Category: Cookie management
EU regulations have made cookie management
dificult: as Google recently decided to require
EU compliance in its AdSense program,
developers need to conform to the regulations.
Fortunately, a combination of these two cookie
plugins makes compliance and data handling
really, really easy!

Achieving compliance in itself is really easy: cookieBar is


shipped with a stylesheet that contains the logic for a
basic cookie bar that is easily dismissable by the user.
Best of all, you dont have to use any markup either! Start
of by including the JS and the CSS file along with the
main jQuery library:

with one provided by your legal department, and can


also modify the styling to make the cookie bar blend in
better or stand out more.
In the next step, it is now time for us to actually persist
some data. First of all, the cookies library must be
included in the header:

<script src="js.cookie.js"></script>
JQuerys js-cookie plugin provides a bunch of helper
methods for implementing a basic KV store reading
data from it can be accomplished like this:

$(document).ready(function() {
if(Cookies.get('imagineCookie')===undefined)
{
alert("No cookie there yet");
}
else
{
alert("Found: " + Cookies.
get('imagineCookie'));
}
});

<html>
<head>
<script src="jquery-2.1.4.js"></
script>
<script src="jquery.cookieBar.
Js-Cookie
js"></script>
For some quickfire
<link rel="stylesheet"
information on js-cookie, make
type="text/css"
sure you check out the Wiki
href="cookieBar.css">
github.com/js-cookie/js-cookie. It
</head>
is written by one of the authors,

www.fullengineeringbook.net
Protect your images
bit.ly/1LdEGy9
Image theft happens more than you think. This
little utility uses the HTML5 Canvas editing
capabilities to stamp images with a watermark on
the clients browser a feature which can also be
used to frame images, thereby strengthening your
websites corporate identity. As with all other
client-side security systems, be aware that
sophisticated attackers are able to work around it
with the most minimal of efort.

Saving data is then done via the set


method. Cookies do not limit
themselves to basic types: you can
also persist JSON objects by passing
them in.

Fagner Brack, and includes


$(document).ready(function() {
Displaying the actual bar can then be
details on integration
if(Cookies.get('imagineCookie')===
accomplished by invoking the
with Angular.
undefined)
cookieBar() method. The plugin contains the
{
necessary logic to keep state: the user will not see
alert("No cookie there yet");
the bar twice if he does not delete the cookie:

Cookies.set('imagineCookie', "Hello
Cookie");
}

<body>
<script type="text/javascript">
$(document).ready(function() {
$.cookieBar();
});
</script>
</body>
</html>

AUTHOR BOX:
Carl Woodhouse

github.com/carlwoodhouse

Klaus Hartl

github.com/carhartl

Fagner Brack
CookieBar provides a variety of methods to aid in the
customisation process: you can replace the default text

github.com/FagnerMartinsBrack

JQuerys js-cookie plugin provides a


bunch of helper methods for implementing
a basic KV store

HTML5 & CSS3 Genius Guide 109

Developer

Break and merge


images

Find faces
Plugin: Face detection

Plugin: ChunkIt
bit.ly/1GK5ims
Category: Image manager
Breaking images down along rectangular
patterns has always been popular the Pet
Shop Boys teaser for Love Etc in 2009 brought
the design pattern to public attention. This
plugin takes an image, renders it into a Canvas
and then chops it down into tiny pieces which
you can arrange to create psychedelic
wallpaper designs.

ChunkIt does its magic by creating a structure of li tags


contained in a ul tag: each one of them contains an
<img> tag which, in turn, contains its picture data as an
inline image.
Since browsers decorate list tags with all kinds of
objects by default, we start out by declaring an
embedded stylesheet which aims to calm these
tendencies down.

<script src="jquery-2.1.4.js"></script>
<script src="jquery.chunkIt.js"></script>
<script>
$( document ).ready(function() {
$('#gridHouse').chunkIt({ imgURL :
'flowers.jpg' , cellsInRow:5,
cellsInColum:5, shuffle:true});
});
</script>
The chunkIt() method takes a JSON object which
configures the actual behaviour of the tiling engine.
ImgURL is a URL to the image, while cellsInRow and
CellsInColum decide the size of the result. Setting
shufle to false arranges the <li> tags in line you can
always perform a correlation between their ID and the
part of the image contained within.
In the case of our example, the structure generated
looks like this:

bit.ly/1jGT3BR
Category: Image analysis
Finding faces in pictures is important for
multiple reasons: when digital cameras with
the feature were first introduced, getting
perfectly exposed portraits became so
much easier. This plugin allows you to look
for faces in image files provided by your
users or a server of choice.
Face detection is relatively accepting of older jQuery
versions the plugins author specifies it with jQuery
1.11.1. Weve used a recent edition for brevity reasons:

<!DocType html>
<html>
<head>
<script src="jquery-2.1.4.js"></script>
<script src="ccv.js"></script>
<script src="cascade.js"></script>
<script src="jquery.facedetection.js"></
script>
</head>

www.fullengineeringbook.net

<!DocType html>
<html>
<head>
<style>
ul.grid {
padding: 0px;
}
ul.grid li {
list-style: none;
display: block;
border: 0px solid #CCC;
float: left;
line-height: 0px;
}
</style>
In the next step, the actual
instantiation of the plugin takes place.
The invocation of chunkIt() does the
actual work expect the browser to stall
for a bit of time:

<body>

<div id="gridHouse">
<ul class="grid" style="width: 1200px;">
<li id="cell_25" class="cell">
<img src="data:image/png;base64,"
style="width: 240px; height: auto;"></img>
</li>
<li id="cell_22" class="cell">
<img src="data:image/png;base64,i"
style="width: 240px; height: auto;"></img>
</li>
. . .

Browser
support

Finally, a <div> tag must be erected. ChunkIt


will use it as the mother tag for the
generated structure:

ChunkIt uses HTML5


<div id="gridHouse"></div>
Canvas internally, and thus
may not work on older versions
ChunkIt should not be combined
of browsers. Compatible
with very large images: sizes that
browsers include Chrome, IE9,
are any larger than about 1600 x
Firefox 12 and more. Read
1200 leads to long processing times.
more at mzl.
This is especially harmful on singlela/1W8UMkX.
threaded browser such as Firefox: the entire
browser window shuts down when the tesselation
process is running.

The chunkIt() method takes a JSON


object which configures the actual
behaviour of the tiling engine
110 HTML5 & CSS3 Genius Guide

Face Detection expects to find its source picture in a


<img> tag. We have used an image provided by the
developer here feel free to swap out its URL to
point to a photograph of choice:

<img id="picture" src="picture.jpg">


Now lets invoke the actual processing function. As
with most other jQuery plugins, Face Detection takes
an array of elements which permit you to customise
plugin behaviour. Complete gets invoked once faces
have been detected.
The method is provided with an array of face
objects, each of which exposes a group of properties
containing further information about the detected
face. Our code example restricts itself to outputting
some data to the debuggers console:

$('#picture').faceDetection({
complete: function (faces) {
for(i=0;i<faces.length;i++)
{
console.log(faces[i].x + " " + faces[i].
width + " " + faces[i].y + " " +
faces[i].height);
}
}
});

HTML5 & CSS3

Genius Guide

Responsive charts
Plugin: chartist-js
bit.ly/1GhA775
Category: Data visualisation
Libraries that make diagrams come a dime a
dozen: ultrasimple Canvas-based ones stand
next to behemoths such as the fearfully
complex D3.js. Chartist difers from its
competitors in that it aims to combine the
no-frills approach of Canvas-based renderers
with the print-ready quality provided by SVG.

Even though Chartist can in theory also be used


without jQuery, most developers will settle with an
include structure similar to the following. At the time of
writing, the recommended CDN contained broken code
our example contains a copy of the code which works
on Firefox:

At the time of writing, the recommended


CDN contained broken code
]
}, {
fullwidth:true

following version draws a significantly larger circle on top


of each data point of our line chart:

function makeFancyChart()
{
});
var chartRef=new Chartist.Line('.ct-chart',
}
{
. . .
chartRef.on('draw', function (data)
Chartists diagram methods tend to take a pair of
{if(data.type==="point"){
parameters: the first variable contains the data to be
data.group.append(new Chartist.
displayed, while the second variable can provide
Svg('circle', {
you with a variety of display settings. Going
cx: data.x,
SMIL
on to change the display to create a pie
cy: data.y,
support
chart doesnt require much extra efort
Chartist.js supports all kinds of
r: 20
animations: charts can be enriched
}, 'ct-slice-pie'));
function makePieChart()
with marching ants and similar
}});
{
niceities. Sadly, this requires support
}
var data = {
for SMIL a feature sorely
series: [20, 30, 55]
Draw gets emitted every time a new
missing in all versions of
};
element is created: its type subattribute
Internet Explorer.
var sum = function(a, b) {
provides information about the type of
return a + b };
element at hand.
new Chartist.Pie('.ct-chart', data, {
Some features axis labels are a common example
labelInterpolationFnc: function(value) {
might be required in some jurisdictions like Austria, but
return Math.round(value / data.series.
are not considered important enough by the developers
reduce(sum) * 100) + '%';
who pride themselves on the tiny 10KB total file size of
}
their product.

at all:

www.fullengineeringbook.net
<head>
<link rel="stylesheet" href="chartist.min.
css"/>
<script src="chartist.js"></script>
<script src="jquery-2.1.4.js"></script>
</head>
<body>
<div class="ct-chart"></div>
</body>

Our example contains a group of buttons which populate


the <div> tag with various diagrams. First up is a humble
line chart generated by makeLineChart:

function makeLineChart()
{
new Chartist.Line('.ct-chart', {
labels:[1,2,3,4,5],
series: [
[12, 9, 7, 8, 5],
[2, 1, 3.5, 7, 3]

});
}

OTHER AUTHOR PLUGINS:


Gion Kunz

This example extends the diagram with custom labels


created by an interpolation function. It uses data.series.
reduce to obtain the sum of the entire dataset, which is
then applied to a simple percentage calculation.
Developers can use the events exposed by Chartist
to modify the look of the resulting diagram. The

github.com/gionkunz
Plugin 1: Accessibility for Chartist
bit.ly/1GhD6MG
Plugin 2: Point Labels for Chartist
bit.ly/1NfSeKe

To follow

To follow

To follow

John Resig

JQuery Foundation

JQuery Plugins

@jeresig
Two words: jQuery.daddy==John.
Follow him to enrich your Twitter
timeline with content more or less
related to the big jQ!

@jquery
The jQuery Foundation is the body
which governs the jQuery product
family. Follow the account for all the
latest, oficial announcements.

@jqueryplugins_
This Twitter account provides a
never-ending stream of interesting,
weird and/or useful jQuery plugins for
your perusal.

HTML5 & CSS3 Genius Guide 111

Developer

Tile interface
Simply changing
the background
colour is but part
of the solution;
adding pictures
makes your tiles
look more natural.

By default, jsTiles
renders its tiles
right next to one
another. Creating
spacing is best
accomplished via
CSS attributes.

The black borders


have the same
width across all
centre boxes: the
width diferences
in the middle are
an optical illusion.

JsTiles is based on
Bootstrap: the
scaling behaviour
of the boxes is
determined by
attributes taken
from Bootstrap.

www.fullengineeringbook.net
User avatar selection

Progress dots

bit.ly/1VWCIKO

bit.ly/1jGTzzS

Displaying faces next to comments adds to the perception of an active site or


application. Tapatar simplifies the avatar procurement process: it provides a small
widget where customers can select their avatar of choice by uploading a file from
their desktop, logging in on Facebook or using the Gravatar database.

Waiting sucks. If the duration of a process is not known in advance, displaying a


Windows Phone-inspired line of marching ants is but a small acknowledgment of the
users patience. ProgressDots lets you deploy a dotted line with but five lines of code:

112 HTML5 & CSS3 Genius Guide

$( '#progressBox' ).dottify({
dotSize: '28px', //set size of dot
randomColors: true, //use random colors
numDots: 7, //number of dots
radius: '20%' //set dot corner radius
});

HTML5 & CSS3

Genius Guide

Plugin: jsTiles
bit.ly/1GhDhro
Category: Tile manager
Microsofts Windows Phone 7 introduced the
world to the concept of the tile: ever since, the
design paradigm got more and more attention.
Implementing tiles looks simple at first glance,
but tends to become tedious once attention is
paid to details.

Getting started with jsTiles requires the presence of three


support libraries: jQuery, jQuery Easing and Bootstrap. As
you can see in the full code on FileSilo, Style.css and
jstiles.js come from the jstiles distribution, while the
remaining references come from support libraries. The
following container is to be created:

<div id="tiles-container">
<div class="tl-page" data-tltemplate="myTemplate">
<div style="background-color: #f00;
border-style: solid; border-width:
5px;">Content</div>

</div>
</div>
A superficial inspection of the code on FileSilo reveals
that the tile management framework limits itself to the
arranging of the individual elements; their design, layout
and content lie in the responsibility of the developer. With
that out of the way, the template must be configured:

var myTemplateObject = {
myTemplate: {
tilesNum: 6,
rows: {
0: {
rowClass: 'tl-row col-xs-12',
start: '3',
end: '5'
}
},
tiles: {
0: 'col-xs-6 col-md-3',
1: 'col-xs-6 col-md-3',
2: 'col-xs-6 col-md-3',
3: 'col-xs-6 col-md-3',

4: 'col-xs-6 col-md-3',
5: 'col-xs-6 col-md-3'
}
}
}
The most important part of the options array is the
tilesNum property: it must match the number of the
<div> tags in the container. Rows sets up the size of the
individual rows, while tiles configure the individual tile
widths. Js-tiles will need to work with Bootstrap: the class
names used are taken from the template framework.
Next up well apply the generated configuration. In our
example, the following bit of code shall sufice:

var opt = {
templateObj: myTemplateObject,
}
$('#tiles-container').jstiles(opt);
});
With that, our example is done. Js-tiles provides a variety
of additional features for animation and card
management: further information on these topics can be
found in the documentation.

www.fullengineeringbook.net
Keep headers on top
Plugin: Headtacular
bit.ly/1Lon5ld
Category: GUI stack
Keeping a header on top of scrolling content
can turn out to be a daunting task. This plugin is
a representative of the BYOS genre: the
acronym stands for Bring Your Own Style,
which means that it limits itself to the provision
of display logic.

As always, our code example starts out by including both


jQuery and the headtacular file. In the next step, shown
below, you can now see that a little stylesheet has been
generated for us:

<!DocType html>
<html>
<head>
<script src="jquery-2.1.4.js"></script>
<script src="jquery.headtacular.js"></
script>
<style>
.header {
transition: all 300ms;
background-color: #f00;
position: relative;

z-index: 9999;
}
.header.is-stuck {
position: fixed;
top: 0;
width: 100%;
background-color: #f0f;
}
</style>
</head>
Headtacular permits you to use two styles: header is
used when the user has not touched the scroll point,
while header.is-stucks turn comes once scrolling has
begun. In the next step, a small header a b tag along
with some text shall sufice is created:

<body>
<div id="myHead" class="header"><b> My
Header</b> and some text</div>
<div id="myFill"></div>
</body>

</html>
Finally, the headtacular method must be invoked after
the DOM tree has been initialised. In the case of our
snippet, we pass in an object showing one of the
supported options as the plugin contains sensible
defaults for all options, you can also call the method with
an empty JSON object:

<script type="text/javascript">
$(document).ready(function() {
var innerHtml="Lorem Ipsum sic . . .<br>";
for(i=0;i<12;i++){innerHtml+=innerHtml;}
$( "#myFill" ).html(innerHtml);
$('#myHead').headtacular({ scrollPoint: 1
});
});
</script>
The lorem ipsum code unfortunately bloats the page: an
empty website does not flow over the screen and thus
does not require scrolling.

The acronym BYOS stands for Bring Your


Own Style, which means that it limits itself to
the provision of display logic

HTML5 & CSS3 Genius Guide 113

Developer
Timeline display

{'time': 1398706771300, 'category': 'pings',


'line': "fred", 'label': "two"},
];
var options = {'categories': categories};
</script>

bit.ly/1NLSX96

Log file viewers benefit from a timeline view. This


timeline plugin takes a dataset, which is displayed in a
zoomable, double-clickable widget. The dots in the
timeline are presented horizontally and they
Each event is made up of three tuples: a
can help users to visualise any graph
Timeline lines
Unix timestamp, a category (like colour
patterns, as part of their log analysis. Its
Its important to specify your
for example) and a line identifier
data structure looks like this:
lines because if you dont,
var categories = {
which describes the timeline
'alarms': {'color':
Timeline will automatically identify
housing it.
"rgba(255, 0, 0, 0.7)"},
your lines and plot them in the
The Timeline plot uses the
};
order in which the plugin finds
options object that is passed in for
var events = [
them (likely to be from
configuration. The options object
{'time': 1398706972000,
bottom to top).
currently supports attributes such as
'category': 'alarms', 'line':
categories, lines, lineLabels and
12345, 'label': "one"},
sortLines.

This timeline plugin takes a data set,


which is displayed in a zoomable, doubleclickable widget

Colour picker
bit.ly/1ReHcpt

Integrating the colour picker is as easy as adding an


input element to the site. A call to the jPipette() method
then makes sure that everything is set up correctly:

Footer
Testing a footer management plugin requires the
presence of a footer start out by creating the
following example page, which self-populates with a
bit of lorem ipsum and also contains a footer with
some buttons:

<html>
<body>
<script src="jquery-2.1.4.js"></script>
<script src="jquery.downboy.js"></script>
<script>
$( document ).ready(function() {
var innerHtml="Lorem Ipsum sic . .
.<br>";
for(i=0;i<7;i++){innerHtml+=innerHtml;}
$( "#myFill" ).html(innerHtml);
});
</script>
<div id="myFill"></div>
<div id="myFooter" style="backgroundcolor: yellow;"><h1>This is a footer</
h1></div>
</body></html>

www.fullengineeringbook.net

The creation of colour pickers have always turned out to


be a nuisance, but you can easily rectify this problem in
our example by making an open source colour picker for
Windows Mobile. JPipette is a similar extension which lets
users pick colours from an image on non-IE browsers.

<input type="text" name="myInput">


$(document).ready(function(){
$('input').jPipette();
)}

DownBoy is ofered in two versions. If your footer goes


by the name #footer, simply embed downboy.auto.*.js
in order to put the element in its place. Developers
working with a custom footer must instead deploy
downboy.*.js, which requires the following bit of extra
code to be used:

<script src="jquery.downboy.min.js"></
script>
<script>
$(function() {
downBoy('#myFooter'); // Run on load
window.onresize = function() { // On
Resize
downBoy('#myFooter'); // Run Again
};
});
</script>
Keep in mind that DownBoy can handle scrolling only
if the DocType is set like this::

<!DocType html>

Plugin: jQuery.downBoy
bit.ly/1PlZesf
Category: Footer management

Tooltip windows
sweefty.com/tinytip
Forcing users to consult a manual is a sure-fire way to
drive them straight to the arms of your biggest
competitors. This plugin strives to increase discoverability
by displaying tooltip windows with further information at
strategic locations.

114 HTML5 & CSS3 Genius Guide

TinyTip difers from other products due to its flexibility.


Tooltips can be styled via CSS; their appearance can
furthermore be triggered by mouse-over, click and even
certain custom gestures. One classic example involves
complex tooltip windows which get spruced up visually
via CSS-generated arrow shapes and/or custom
background colours.

A footer can makes web apps look much


more professional. Sadly, keeping content at
the bottom of a page can be a bit of a
daunting task for people who are not 100 per
cent confident at working with CSS. This
plugin wants to help you out here.

HTML5 & CSS3

Genius Guide

www.fullengineeringbook.net

Rain effect
bit.ly/1NLRfVa

Scrolling indicator
bit.ly/1MHijDH

This plugin uses wave theory to render a line,


This plugin treats your users to a progress
Substitute
which is then animated to simulate
indicator informing them about how far
raindrop impact seen from the side.
they have already scrolled down the
with icons
For the scrolling indicator, its
Daniela Harel and Gred McAuslands
page coders working with Sublime
possible that you may
plugin is dificult to describe take a
Text will find the feature familiar right
encounter roadblocks with the
look at the examples by going to the
away. The viewport difers from
overview image. Should this
URL above.
classic IDEs in that you need to
ever become a problem, feel
provide the overview image.
Virtual terminal
free to substitute the
bit.ly/1GK5Qso
image with icons.
This plugin simulates a Ubuntu-styled
Circle calculations
terminal window by displaying a set of span
bit.ly/1MtzZye
Waiting for Godot is normal nowadays: why not ease the
elements according to a timing schedule. It is best suited
to providing a visual guide for unsophisticated users
wait by presenting your users with a snazzy little circular
progress bar? This plugin saves you from having to deal
working on a command-line system be aware that the
plugin cannot handle user interaction.
with the sine, cosine and tangent as found in circles.

Superfast parallax
bit.ly/1MtzLXU
Research conducted by the Purdue University (docs.
lib.purdue.edu/cgttheses/27/) has produced results
that show that the presence parallax scrolling
significantly increases user satisfaction. Bring a few
svelte panoramic shots and this little plugin by
Kaspars Jaudzems of Latvia can add the impressive
scrolling efect to your web projects with minimal
efort.

Creating and/or updating the widget is as easy as


calling the circularloader function like this:

$("#divProgress").circularloader({
progressPercent: 35
})

HTML5 & CSS3 Genius Guide 115

Developer

Produce a picture
gallery with jQuery
Use jQuery for managing user interactions with CSS to
support visual presentation

www.fullengineeringbook.net

116 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

A JavaScript library that you can almost


guarantee to be known by any web developer
is jQuery. This is a favourite of many web
developers for the simple reason that it helps to make
writing code faster and easier especially when first
learning to write code in JavaScript.
Much has changed in web development since jQuerys
first introduction particularly in webpage animation,
which was controlled almost entirely through JavaScript
at the time of jQuerys introduction. In the era of CSS3
with hardware-supported capabilities, it is easy to misuse
jQuery with outdated techniques for visual presentation;
certainly when it comes to working with designers,
keeping your presentation inside CSS avoids scenarios
where designers become restricted to when adapting
your website design. This tutorial looks at how jQuery can
be used to manage user interactions and eficient loading
of image resources while keeping the presentation
functionality within the control of CSS. This approach to
using jQuery means that designers who dont have
JavaScript skills can still contribute to adapting the design
of your website creations. Additionally, keeping your
functionality separate from your design styling and
content formatting reduces the risk of introducing faults
that break your website when you are making updates.

1. Initiate HTML page

and JavaScript code. This allows these resources to be


reused by other pages if required. See FileSilo for more
information on where the jQuery library will be placed.

3. Gallery container
Use the <body> section to place the gallery content. The
gallery template will consist of an article element used as
a container for the diferent parts of the gallery the
navigation, details and picture display. These elements
will be modified later by the jQuery JavaScript code.

"description":"A peacock standing outside.",


"url":"img/image4.jpg"
},
{
"title":"The Guy",
"description":"The guy.",
"url":"img/image5.jpg"
}
];

5. Wait until loaded


4. JQuery: data
The first step in using the jQuery component is to create
the file that the jQuery JavaScript code will be placed in
create this as controls.js. In this file, you should place
the following data structure that describes where each
gallery image can be found, as well as the title and
description to display:

var pictures = [
{
"title":"A Cottage",
"description":"A little cottage.",
"url":"img/image1.jpg"
},
{
"title":"A Horse",
"description":"A horse eating hay.",
"url":"img/image2.jpg"
},
{
"title":"Lake",
"description":"Water flowing down lake.",
"url":"img/image3.jpg"
},
{
"title":"Peacock",

Its important to tell jQuery to wait until the page has


loaded before we go on to trying to run any of the
instructions otherwise it will return errors to say it cant
find page elements. We do this by attaching a .ready
listener to the page document which will hold a
function that contains our code.

$(document).ready(function(){
//.. place code from next step here
});

6. Read picture data


The first thing we want to do inside the function created
in the previous step is to initiate the reading of the
pictures data. We do this by selecting the pictures array
with the jQuery $ selector and using jQuerys .each
functionality to loop through each of the data items.

www.fullengineeringbook.net

As with any webpage, there is a requirement to define the


pages HTML, head and body structure. Use the head
section to contain any meta data such as the page title
for SEO and accessibility that you may need.

2. Load resources
The <head> section of your HTML should contain the
links to any resources you are using for the page; in our
example, well be using this to load the CSS stylesheet

Easy to misuse
Although jQuery exists to make programming
easier, its easy to misuse it by not using it to its
full potential especially when the library costs
over 200k to download.

Left

Images referenced in the JavaScript data is loaded with


jQuery and placed in the <figure> container it looks
messy without styling
Top left

Images are copied to the <nav> container to be used as


thumbnails without needing to reload the images this
allows for fast loading pages
Top right

Initial placement of HTML elements dont appear by


default, but are ready interactions from jQuery and styling
from CSS

HTML5 & CSS3 Genius Guide 117

Developer
var count = 0;
$(pictures).each(function(){
//.. place code for next step in here
});

7. Page container
Use the <body> section to contain the visible content. We
start this by placing the <main> page container inside the
body; this will be used to allow the controlled layout of
the content. Your page title, description and index count
will go inside this.

var img = $(document.createElement("img"));


$(img).attr({
"src":this.url,
"data-index":count,
"title":this.title,
"alt":this.description
});
//.. code from next step goes here

$(img).appendTo("figure");
//.. code from next step goes here

9. Create thumbnails
A thumbnail is required to show a selectable preview for
navigating the gallery images. There is no need to reload
images jQuery can make a clone of each image and
then append to the inside of the <nav> container.

var thumb = $(img).clone().appendTo("nav");


//.. code from next step goes here

10. Thumbnail click reactions


The thumbnail images weve cloned and appended to
the <nav> container need to react to any clicks received.
We do this by attaching a bind event listener for click
which activates a function we declare as a reaction.

$(thumb).bind("click",function(){
//.. code from next step here
});
count++;

8. Image to container
After each image has been created as an element on the
webpage, it will then need to be placed inside the
location where we will store every single image. Our
example will use the pages first <figure> element. The
figure part of this code is a CSS rule that defines how to
find the location.

created in Step 7, jQuery can be used to find the image


with the same index number as the thumbnail being
clicked on and this is because it has the same details by
being a clone. Perform removeClass to take out hidden.

$('figure img[data-index="'+this.
getAttribute("data-index")+'"]').
removeClass("hidden");
//.. code from next step goes here

13. Size up the height


The thumbnail will also have copies of the title and alt
attributes from the image it has been cloned from. This
lets us easily place the image details inside the <h3> and
<figcaption> elements. We set the content HTML by
using jQuerys $() with its .html() functionality, which will
place text or HTML inside the selected element.

$('h3').html(this.getAttribute("title"));
$('figcaption').html(this.
getAttribute("alt"));

14. Initialise CSS


11. Hide images
The first reaction we perform when a thumbnail click has
been detected is to hide the images inside the <figure>
element being used as the gallery image container. We
use the jQuery $ element finder with the CSS rule to find
these figure img. We loop through each element found
and apply a function that will add a class called hidden.

At this point, the jQuery functionality is now complete,


but will not function because it lacks the CSS styling.
Create a CSS file called styles.css and place the following
initiation styling for the <html> and <body> elements.

html,body{
background: #000;
padding: 0;
margin: 0;
font-family: monospace;
height: 100%;
}

www.fullengineeringbook.net
Fast and easy
JQuery helps to make writing code faster and
easier by providing shorthand for common tasks
in JavaScript such as referencing webpage
elements and iterating through information like
with webpage elements that have been found.

Top left

Styling the page and container now shows the loaded


images in some order within the gallery component
Top right

Current picture information container now shows at the


top of the gallery. The lack of the hidden class still means
hidden pictures are visible
Right

Pictures now have the hidden class defined via CSS,


which shows the selected image

118 HTML5 & CSS3 Genius Guide

$("figure img").each(function(){
$(this).addClass("hidden");
});
//.. code from next step goes here

12. Show selected image

15. Gallery container

All images are set to hidden, so next we show the


selected image. By using the data-index attribute we

The HTML weve created uses an <article> tag to contain


the gallery content. We must use this to define the width,

HTML5 & CSS3

Genius Guide

What is jQuery?
JQuery is a general
purpose code library
created to help make
programming in
JavaScript faster and
easier. It is used by
advanced JavaScript
programmers as well as
web designers who know
the basics for tweaking
jQuery code as jQuery is
often easier to understand
than raw JavaScript. In
addition to making JS
faster to code, there are
many website components
that have been created
with jQuery for purposes
ranging from user
interface animation
through to searchable
data tables and games
creation, which often can
be customised without
advanced programming.
JQuery is possibly the
worlds most commonly
used general purpose JS
library, with it often being
listed as a requirement for
web development jobs.

www.fullengineeringbook.net

positioning, background colour and padding. Positioning


is centred with auto for left and right margins.

article{
display: block;
width: 75%;
margin: 10% auto 0 auto;
background: silver;
padding: 1em;
}

16. Information container


The gallery uses a <div> element to contain the elements
used to display information of the current picture. We will
style this to show a dark transparent background with
white text to ensure that the content stands out from the
gallery picture being shown.

article div{
display: table-caption;
position: absolute;
top: 0;
right: 0;
z-index: 2;
width: 75%;
text-align: right;
margin-left: 27%;
background: rgba(0, 0, 0, 0.75);
color: #fff;
}

child images can be placed precisely in relation to it. We


also want to set a width that the child images can be set
in relation to hence we can change the container size
and have its images automatically change accordingly

figure{
display: table-cell;
position: relative;
width: 75%;
margin-left: 25%;
z-index: 1;
overflow: auto;
}

18. Image positioning


The images inside the <figure> container are to be set to
be displayed from the same position we can set them
from the top left of the <figure> container because of the
relative positioning set in the previous step. A transition
efect is also added for changing between pictures.

figure img{
position: absolute;
top: 0;
left: 0;
transition: opacity 1s;
width: 100%;
z-index: 1;
}

19. Hidden image property


17. Image container
The gallery image container will be placed at the side of
the thumbnails and will use relative positioning so that

The jQuery code is set to add a hidden class to images


that are to be hidden from view, hence there needs to be
a presentation rule set for this. By setting the opacity to 0

with the previous steps transition rule, we will make


images fade out when their status changes.

figure img.hidden{
opacity: 0;
}

20. Thumbnail container


The thumbnail container is to be positioned at the side of
the main image spanning the full height of the gallery.
We will also want to make sure that the thumbnail panel
will enable scrolling to show any images that dont fit
onto the page.

nav{
display: inline-block;
width: 100%;
height: 100%;
overflow: auto;
background: #777;
padding: 0;
}

21. Thumbnail sizing


Thumbnail images are to be stacked above each other
with their height not being a problem due to the <nav>
container having overflow: auto to allow for scrolling if
required. These images were originally full-sized copies of
the originals, but can be resized to be the same width as
the container.

nav img{
display: inline-block;
width: 100%;
}

HTML5 & CSS3 Genius Guide 119

Developer

Code validation into


forms with
ngMessages
Learn how to create a form with reactive user feedback using
Angular and the ngMessages directive

www.fullengineeringbook.net

Forms are the gateway between your website


and the users life. Often forms capture
sensitive data like your address, telephone
number, card details and so on.
Filling in forms is annoying, so as web developers
we want to try and make this process as pain-free as
possible. One way we can do this is to show helpful,
timely messages to the user to let them know if theyve
made a mistake. These are essential to reducing

120 HTML5 & CSS3 Genius Guide

friction in forms and aiding understanding. We also


want to try and make them as accessible as possible so
we will include ngAria, too.
Angulars ngMessages module provides developers
with an easy way to present messages to a user. Its
described by Angular as being designed to handle the
complexity, inheritance and priority sequencing based
on the order of how the messages are defined in the
template. You could use ngIf to toggle the visibility of

messages but this can be complicated when there are


many conditions. NgMessages was introduced in
Angular 1.3 so it doesnt work with Internet Explorer 8
or below.
In this tutorial youll learn how to create a form and
use Angular to validate it. Our example will be a
registration form for the fictitious Lace & Order shop.
Itll feature custom validation directives, default
messages and utilise ngModel to its full ability.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

1. Install Angular and modules


First of were going to add ngMessages to our project
and our preferred method of adding this in is to use
Bower (go ahead and visit bower.io/#install-bower if you
havent got it installed already). As well as the Messages
module were also going to make use of the Animate and
ARIA modules.

$ bower install angular-animate angular-aria


angular-messages

2. Include script files


Create a file called index.html and then write the markup
required for a skeleton HTML page (with the <head>,
<body> and so on). Next well import the JavaScript files
that Bower had fetched for us just before the closing
body tag. Even though were using the minified versions
here, the browser will map to the full source files.

<script src="bower_components/angular/
angular.min.js"></script>
<script src="bower_components/angularanimate/angular-animate.min.js"></script>
<script src="bower_components/angular-aria/
angular-aria.min.js"></script>

dependencies specific to the registration form.

Directive names

angular.module('formApp', ['register.
module', 'ngAria', 'ngMessages',
'ngAnimate']);

In real-world applications you should always


prefix your directive names with a couple of
letters. This diferentiates them from standard
HTML elements.

4. The register module


When we write custom directives youll also have to add
them as a dependency to this module. Its easy to forget
to do this and find yourself spending minutes figuring
out why your directive isnt working!

angular.module('register.module',
[register.controller']);

5. Register controller
The controller for our registration form is very bare
bones. So what well do is well add some specific uses to
it later (namely to add dynamic text). Behind the scenes it
will do the internal wiring to ensure our form works as we
expect it to.

(function() {
'use strict';
angular.module('register.controller', [])
.controller('registerController', ['$scope',
function ($scope) {}]);
})();

6. Create the form tag

form tag. Ng-attr-novalidate is an Angular directive which


will only apply the novalidate attribute if the expression
evaluates to true. We want to disable the native HTML5
validation if the Angular app has successfully loaded.

<form data-ng-attr-novalidate={{true}}"
data-ng-cloak>
</form>

8. First name input


The first piece of data that well capture from the user is
their first name. NgModel is used to bind data to the
input field. This means that when the data changes, the
model is immediately updated. The rest of the markup is
your regular HTML5.

<div class="row">
<label for="firstName">First name:</label>
<input id="firstName" name="firstName"
data-ng-model=fields.firstName required
/>

www.fullengineeringbook.net
<script src="bower_components/angularmessages/angular-messages.min.js"></script>
<script src="scripts/app/app.js"></script>
<script src="scripts/app/modules/
registerModule.js"></script>
<script src="scripts/app/controllers/
registerController.js"></script>

3. The formApp module


The module that will contain all the application-wide
dependencies is called formApp. As well as the Angular
modules that we included in the previous step
register.module is also included. This will include the

The form tag is going to do a lot of work for us. Its going
to be the root of our application and also the controller.
NgSubmit is evaluated each time the form is submitted
(either by the user clicking the submit button or by
pressing the Enter key).

<form name="register"
data-ng-app="formApp"
data-ng-controller="registerController"
data-ng-submit="submitForm(register)">
<h1>Register</h1>
</form>

7. The ng-attr directive


A couple of other attributes need to be added to the

</div>

9. ngMessages first name


Heres our first example of ngMessages in action.
Ng-messages takes an Angular expression which
evaluates to a key/value object. This behaviour is just like
a switch statement. In the example that we have here,
the object evaluated is the $error property from
ngModel in the firstName field.

<div class="errors" data-ngmessages="register.firstName.$error">


<!-- next step -->
</div>

Left

This is the page that will contain our form, theres not
much to it yet but the Angulars ready to go
Top left

The initial bit of information well want is their name so we


can address future communication
Top right

With just a bit of markup and Angulars inner wirings


weve got a dynamic message box reacting to the input

HTML5 & CSS3 Genius Guide 121

Developer
10. ngMessages directive
NgMessages does a great job of toggling specific
messages but we also need to determine when to show
them. Otherwise theyll appear before the user has
touched the form! The messages should only appear if
the field is dirty (if it has been filled in) or the user
submits the form.

<div class="errors" data-ngmessages="register.firstName.$error"


data-ng-if="register.firstName.$dirty ||
register.$submitted>
<!-- next step -->
</div>

11. The required property


Within the ngMessages directive, we can now go ahead
and list specific error conditions to show. This example
here has a simple paragraph tag, but you can use any
element as well as place any markup that you want
inside of it. Ng-message=required looks for the
required property on the object that we passed above. If
true, then itll show:

<p class="error" data-ngmessage="required">Please enter your first


name.</p>

.error
{
color: #a94442;
padding: 0.875em;
background-color: #f2dede;
width: 16em;
border: 0.125em solid #ebccd1;
transition: 0.5s linear opacity;
opacity: 0;
margin: 0;
}

13. Submit the form


To allow the user to submit the form were going to need
a submit button! This calls the submit handler that was
hooked up at the top of the form. However the user
submits the form be it by click, programmatically or
pressing Enter it calls the same function.

<div class="row">
<input type="submit" value="Register" />
</div>

14. Telephone input


Lets take the concepts weve looked at and apply them
to a new field, a contact number. This time ngPattern
allows us to match what the user types to a regular
expression. This regular expression checks that only
numbers are typed.

You can chain properties together on the same error


message to prevent repeating yourself.

<div class="errors" data-ngmessages="register.tel.$error" data-ngif="register.tel.$dirty ||


register.$submitted" role="alert">
<p class="error" data-ngmessage="required">Please enter your
telephone number.
</p>
<p class="error" data-ng-message="tel,
pattern">Please enter a valid telephone
number.
</p>
</div>

16. Postcode input markup


You wouldnt think it but postcodes are actually quite
hard to get right because there are so many variations.
Nonetheless, were going to create a custom directive to
try and validate one.

<div class="row">
<label for="postcode">Postcode:</label>
<input id="postcode" name="postcode"
data-ng-model="fields.postcode" postcode
required />
</div>

www.fullengineeringbook.net

12. Style error messages

Our error messages deserve a bit of love so lets apply


some CSS to them. The most important parts to note are
the opacity and transition properties. NgAnimate will use
them in conjunction with other classes to ease them in
rather than abruptly appearing.

Debugging $errors
A useful way to get a quick understanding of an
object in real-time is to output it onto the page:
<pre>{{form.postcode.$error | json}}</pre>. This
will show the object and format it as JSON.

Top left

The telephone error message is shown when the input


doesnt match a REG_EXP pattern using ngPattern
Top right

The postcode validation error message appears when we


input an incorrect postcode meaning our custom directive
is working
Right

The default messages are now included in the template


unless theyre overridden by one further up in the markup

122 HTML5 & CSS3 Genius Guide

<div class="row">

17. Postcode directive

<label for="tel">Contact number:</label>


<input id="tel" name="tel" data-ngmodel="fields.tel" type="tel" data-ngpattern="/^[0-9]+$/" required />
<!-- next step -->
</div>

15. Telephone error messages


This time were going to use the same technique as
before to show a message. As well as required there will
also be a pattern property as ngPattern has been used.

Create a new file under directives called postcode.js. By


requiring ngModel its passed as the fourth argument to
the link function so that we can extend it. Remember to
add it as a dependency of the registration module.

angular.module('postcode.directive', [])
.directive('postcode', function() {
return {
require: 'ngModel',
scope: {
postcode: '='
},

HTML5 & CSS3

Genius Guide

Utilise ngMessage
expressions
NgMessages also supports dynamic
messages, that is, if you dont know the
name of the message that might be fired
you can check it with a message
expression. In this example weve got an
array in the controller called
errorMessages which contains a list of
objects. These objects represent diferent
error states and their corresponding text.
<div data-ng-messages=register.
test.$error role=alert>
<div data-ng-repeat=errorMessage
in errorMessages>
<div data-ng-messageexp=errorMessage.type>
<p
The ngMessages documentation has
pages on each directive:
docs.angularjs.org/api/ngMessages.

link: function (scope, elm, attrs, ctrl) {}


};
}
);

return REG_EXP.test(value);
}
};

19. Include message template


18. Regular expression test

The custom validator is then added as another property


to the $error object if it returns false. This means that it
can be used within ng-message. Were also going to use
a template to fill in common error messages. This is
included with ng-messages-include.

</div>

20. Custom message template


Ng-messages-include looks for an elements ID on the
page. Angular recommends including templates as a
script tag with a custom type so that it doesnt end up
being parsed by the browser. The downside of this
approach is the generic wording although this could be
paired with dynamic text.

www.fullengineeringbook.net

Within the link function well write the postcode validator.


logic, which validates most UK postcodes. To register a
new validator, add to $validators. Now close spaces and
see if the string passes REG_EXP.

var REG_EXP = new RegExp(/^([g][i][r][0][a]


[a])$|^((([a-pr-uwyz]{1}
([0]|[1-9]\d?))|([a-pr-uwyz]{1}[a-hk-y]{1}
([0]|[1-9]\d?))|([a-pr-uwyz]{1}[1-9]
[a-hjkps-uw]{1})|([a-pr-uwyz]{1}[a-hk-y]{1}
[1-9][a-z]{1}))(\d[abd-hjlnp-uw-z]
{2})?)$/i);
ctrl.$validators.postcode = function (value)
{
if (typeof value === 'string') {
value = value.replace(' ', '');

Whats new in Angular 1.4?


Angular 1.3 introduced ngMessages as an
experimental module. This meant that
developers were free to use it but breaking
changes could be made to the API. The
main change in 1.4 is that
ngMessagesInclude was removed as an
attribute on ngMessages. Instead its used
on a ngMessage directive, like weve used
in this tutorial. Angular 1.4 also introduced
ng-message-exp and when-exp to evaluate
expressions dynamically. Upgrading from 1.3
to 1.4 should be straightforward for most
projects and you can find detailed
migration information at docs.angularjs.

<div class="errors" data-ngmessages="register.postcode.$error"


data-ng-if="register.postcode.$dirty ||
register.$submitted" role="alert">
<p class="error" data-ngmessage="postcode">Please enter a valid
postcode.
</p>
<div data-ng-messages-include="defaulterror-messages">
</div>

<script type="text/ng-template" id="defaulterror-messages">


<p class="error" data-ngmessage="required">This field is required.
</p>
<p class="error" data-ngmessage="minlength">This field is too short.
</p>
<p class="error" data-ngmessage="maxlength">This field is too long.
</p>
</script>

Breathe life into ngMessages


You can add a sense of momentum to your messages with
ngAnimate. Weve already installed and included this
module. When ng-messages is shown, a class of ng-enter
and ng-active is added the former when its being inserted
and the latter when its active. Our message boxes all have
a class of error so well target this and change the opacity.
The CSS transition property will then smoothly animate the
box in and then out when its removed. You can use any
sort of animation to be more creative here.
.error {
transition:
0.25s linear;
opacity: 0;
}
.ng-enter .error,
.ng-active .error {
opacity: 1;
}

org/guide/migration.

HTML5 & CSS3 Genius Guide 123

Developer

Make drums with the


Web Audio API
Use Web Audio sound buffers to create a drum kit that responds
quickly and triggers sound in high-performance web apps

www.fullengineeringbook.net

Quite some time ago now, us web developers


got our eager mitts on the <audio> tag. For the
first time since the webs inception, we could
insert rich multimedia content into our webpages
without using any third-party plugins (no need for
Flash anymore). And all was good with the web
development world. For its typical use <audio> is
absolutely fantastic; with built-in GUI and JavaScript
events we can do almost anything with the content
were playing. Thing is, <audio> was never designed to
be fast or to play lots of really brief content, which is
not a massive issue unless you want to create sounds
in games or in a data visualisation. Thats where the

124 HTML5 & CSS3 Genius Guide

Web Audio API comes in. The Web Audio API is a


low-level API (which basically means its super fast
because a lot of the stuf is being done by the browser
rather than by our own JavaScript) that allows us to
control and manipulate sounds at the millisecond level.
With it, we can load sounds, create sounds and warp
sounds to make alien-like noises with absolute ease,
but its not as simple as including an <audio> tag in our
HTML weve got to deal with things such as Audio
bufers and nodes (not Node.js) if we want to get the
best out of it. Thats what were going to make in this
tutorial, a Web Audio drum kit. Drums are great,
because we need to be able to play sounds quickly. but

everything we learn here can be taken and applied to


any other kind of app that needs responsive audio
manipulation and playback.

1. Grab the resources


Before we dive into all of our Web Audio goodness,
there are some things that were going to need. Grab
the project resources from FileSilo and move them into
your project folder. In the sounds folder are the MP3
files that well be using to make sounds for our drums,
in the scripts/libraries folder is bl.js (a script written by
Boris Smus) which well use to load sound files and in
the assets/images folder is the image of our drums.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

2. Markup for our drums


In our public folder is a bare-bones HTML file. Were
going to create some divs to bind some event listeners to
so that when we hit them, sounds play. Open it in your
favourite editor and add the following between the

<body></body> tags:
<div id="drumHolder">
<div class="drum" data-sound="china"></div>
<div class="drum" data-sound="crash"></div>
<div class="drum" data-sound="floor tom"></
div>
<div class="drum" data-sound="super kick"></
div>
<div class="drum" data-sound="super
snare"></div>
</div>
<script src="scripts/libraries/bl.js"></
script>
<script src="scripts/core.js"></script>

3. Style the <div>


Run the Node app included in the project resources. If
you head to http://localhost:8118/ youll see our HTML
page. Its nothing special at the moment, just a
background image of our drums and a bunch of invisible
<div> tags. We want to position those divs over each of
our drums so that when we hit each drum, they each
make a diferent sound.

position: fixed;
left: 50%;
top: 50%;
margin-left: -350px;
margin-top: -145px;
background-color: rgba(255,0,0,.2);
}

5. Position each drum element


Now that we have our #drumHolder in the right place,
we can now do the custom styling for each individual
drum. Staying in styles.css now as well, add the following
rules to your file:

#drumHolder .drum{ background-color:


rgba(0,0,0,.5); position: absolute; }
#drumHolder .drum:nth-child(1){ top: 14px;
left: 235px; width: 87px; height: 69px; }
#drumHolder .drum:nth-child(2){ left: 350px;
top: 7px; width: 108px; height: 86px; }
#drumHolder .drum:nth-child(3){ left: 274px;
top: 145px; width: 158px; height: 114px; }
#drumHolder .drum:nth-child(4){ right: 62px;
bottom: 84px; width: 144px; height: 104px;
}
#drumHolder .drum:nth-child(5){ top: 103px;
left: 74px; width: 144px; height: 104px; }

console.log("Initialised");
}
return {
init : init
};
})();
(function(){
__web_audio_drums.init();
})();

7. The Web Audio context


Before we start doing anything with Web Audio, we need
a context we can interact with. Think of it as an audio
analogue to a <canvas> context, its simply an interface
with which we deal in order to make our code do
interesting things. Just after use strict; add:

// Web Audio Polyfill


window.audioContext = (window.AudioContext
|| window.webkitAudioContext || window.
mozAudioContext || window.oAudioContext);
and inside our init function add:

context = new window.audioContext();


Now we will also have an audio context that will work
across all browsers.

8. Set our samples

www.fullengineeringbook.net

4. Move the parent element

We have a div #drumHolder. Were going to position this


over the middle of our page to position all of the divs
inside it relative to their parent (#drumHolder). This
makes our life a little easier when it comes to doing
things responsively. Just open up styles.css now and add
the following:

#drumHolder{
width: 700px;
height: 290px;

6. Core.js

Now that we have our elements in the right place, we


can start writing some code to control them. When we
added in our <div> we also added two <script> elements,
one for our code, the other being our BuferLoader
method. Create a file called core.js in our scripts folder
and add the following to it:

In the /sounds folder of our project, there are a bunch of


MP3 files. Were going to add them to our code so we
can load them in just a little bit. Add the following just
after our Web Audio polyfill.

var samples = [{

Buttons needed

var __web_audio_drums = (function(){


'use strict';
var context = undefined,
bufferLoader = undefined;
function init(){

Before anything will work through Web Audio, a


sound has to be triggered inside of an event
handler triggered by a user, meaning you
absolutely have to make a button.

Left

Our parent element has a red background to make the


placing of our .drum elements within it much easier as
we can position them relative to the holder
Top left

The black elements on our red background are our .drum


divs. These are the elements to which well bind event
listeners to trigger audio when we hit them
Top right

By moving a parent element to overlay with the whole of


our drum kit, it will be easier to relocate our child elements
that make the drum sounds if our drum graphic changes

HTML5 & CSS3 Genius Guide 125

Developer
name :
path :
},
{
name :
path :
},
{
name :
path :
},
{
name :
path :
},
{
name :
path :
},
],
sounds

"china",
"/sounds/China.mp3"

"crash",
"/sounds/Crash.mp3"

"floor tom",
"/sounds/Floor_Tom.mp3"

10. The BufferLoader


In order to load our samples into our project and make
them useful, we need to create audio bufers to store the
sound data from our MP3 files. Think of an audio bufer
as a bucket that you can put something into, but once
you take it out again, you cant get it back in. Normally,
we would have to create all of the XHR and audio bufer
code ourselves, but the BuferLoader method takes care
of that for us.

11. Load our samples


In loadSamples, add the following:

"super kick",
"/sounds/Super_Kick.mp3"

"super snare",
"/sounds/Super_Snare.mp3"

= [];

samples contain references that well use to load our


files and assign them to the right elements, sounds will
contain the audio bufers that will actually have the
sound data in them, but well get to that later.

9. Load our drum samples

bufferLoader = new BufferLoader(context, s,


function(list){
sounds = list;
console.log(sounds);
});
bufferLoader.load();
... and add the following to init();
loadSamples(samples);
BuferLoader takes an audio context, an array of paths to
audio files and a callback as arguments. When we call
buferLoader.load(); our BuferLoader instance will work
through the array we passed to it and load all of the
sound files it can find. When all of the audio data has
been loaded, the audio bufers that have been created
are passed into the callback that we passed. Here we set
the array of audio bufers as a global object, so we can
access them elsewhere in the project.

sounds = list;
var theDrums = document.
getElementsByClassName('drum');
for(var y = 0; y < theDrums.length; y += 1)
{
theDrums[y].addEventListener(touchOrClickEve
nt(), function(){
for(var a = 0; a < samples.length; a += 1){
if(samples[a].name === this.
getAttribute('data-sound')){
playSound(a);
}
}
}, false);
}
console.log(sounds);
...

13. Detect events


On a lot of mobile devices (like iOS for example) click
events have a 300ms delay before they are dispatched
to our event listeners. For sounds and media this is a
disaster timing is key! Fortunately, touch events dont
have the same delay, so well write a function that
decides whether or not our device should use touch or
click events;

www.fullengineeringbook.net

Now that we know where we can find our drum samples


its time to load them. Create a new function called
loadSamples() and add the following code to it:

function loadSamples(passedSamples){
var s = [];
for(var x = 0; x < passedSamples.length; x
+= 1){
s.push(passedSamples[x].path);
}
}
This will simply create an array of file paths that we can
work through to load our samples into our project

Top left

By preventing events, we can make sure that nothing


untoward occurs during that crucial, epic drum solo
Top right

The properties of the returned AudioBuffer of our media


files arent all that interesting, its the nifty methods that
come with it thats really interesting
Right

Theres no visual feedback in our little app. But, if you


wanted to make it so our app responded visually to a tap
as well as audibly, you can always use border-radius

126 HTML5 & CSS3 Genius Guide

12. Event listeners


Now that we have a bunch of audio bufers that contain
our sound data, were going to need a way to trigger
them. Inside of our buferLoader callback, were going to
create a for loop that gets all of the drum elements on
our page, takes the data-sound attribute and looks for a
sound with the same name. When our div is clicked or
tapped, it will play that sound!

...

function touchOrClickEvent(){
if('ontouchend' in document){
return "touchend";
} else {
return "click";
}
}

14. Play our sounds


Now that weve got the appropriate listeners, we need a
way to play our sound. Web Audio is not like <audio>, we
cant just call .play() on an audioBufer to make it do its
thing, we need to connect our audio bufer to our audio

HTML5 & CSS3

Genius Guide

<audio> vs. audio

context in order to play it out through our speakers.


Think of it as a digital version of plugging your
headphones into a computer, we need to connect to
hear. Create a playSound() function and you then add
the following

function playSound(idx){
var src = context.createBufferSource(),
newBuffer = cloneAudioBuffer(sounds[idx]);
src.buffer = newBuffer;
var gainNode = context.createGain();
gainNode.gain.value = 1;
src.connect(gainNode);
gainNode.connect(context.destination);
src.start(0);
}

15. Clone our buffers


Earlier, we noted that audio bufers can only be played
once, which is kind of useless unless we want to be able
to only hit each drum once. In order to play our drum
sounds multiple times, were going to create copies of
our audio bufers that we play and then forget about. So
lets create a new function with cloneAudioBufer();.

function cloneAudioBuffer(audioBuffer){
var channels = [],
numChannels = audioBuffer.numberOfChannels;
for (var i = 0; i < numChannels; i++){
channels[i] = new Float32Array(audioBuffer.
getChannelData(i));
}
var newBuffer = context.createBuffer(
audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
for (var i = 0; i < numChannels; i++){
newBuffer.getChannelData(i).
set(channels[i]);
}
return newBuffer;
}

So why do we need Web Audio if <audio> exists? Well,


<audio> is great at playing sound in a limited context,
its not designed for audio manipulation not in a
low-level kind of way. The Web Audio API gives us direct
access to the data of the audio content, and with this we
can run a ton of complex operations to evaluate and
manipulate that data in next to no time at all. Compared
to a fast fourier transform, or applying a band filter,
playing audio content through Web Audio is a
comparative doddle thats why it can respond on a
microsecond time scale whereas <audio> can take
seconds to begin playback, depending on the availability
of the content. Deciding when it is appropriate to use
either interface is completely down to you!

audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
Finally, we have a brand-new bufer, but our bufer is
empty so we fix that by working through our newly
created bufers channels and setting them with the
channels we created just a moment ago. Then we return
our cloned audio bufer:

for (var i = 0; i < numChannels; i++){


newBuffer.getChannelData(i).
set(channels[i]);
}
return newBuffer;

output will go through our gain node, to our context


destination. If we can tell our bufer source at what point
we want to play from, then cant we just reset it to 0 and
play again rather than all of this cloning business? Well,
nope. An audio bufer becomes mostly useless after its
been played, and besides even if we could do that, the
efect would be undesirable by resetting the sound
mid-play, wed get a horribly jarring stutter efect. Its
much better to let the sound continue on its own and
create a new instance of it.

20. Use on iOS

www.fullengineeringbook.net

16. Clone walkthrough


Every sound file has a number of channels: if the sound
is mono then there is one channel, and if the sound is
stereo then there are two and so on. We want to clone all
of the audio data from our samples, so we need to create
a bufer for each channel and clone that data.

var channels = [],


numChannels = audioBuffer.numberOfChannels;
for (var i = 0; i < numChannels; i++){
channels[i] = new Float32Array(audioBuffer.
getChannelData(i));
}
Now that we have arrays with our data in it (a
Float32Array is not like arrays as we usually know them,
its more like a space in the computers memory) we can
create a brand-new bufer with all of the properties we
need to describe our sounds, which we do with:

var newBuffer = context.createBuffer(

17. Play the sound

Now that weve got our brand-new cloned audio context,


its time to put it to work! In playSound, just before we
cloned our audio bufer we created a bufer source in our
context with context.createBuferSource(); This is our
entry point to playing sounds through our speakers. To
use our cloned audio bufer we set it as the source for
our bufer source.

If you want to use you iPad or iPhone to play sounds,


you can, but if you get a little carried away and flick the
screen instead of tapping it, it might start scrolling and
refuse to do anything until it stops. In your init() function
add the following code to stop this:

// Stop iOS bouncing scroll


window.addEventListener('touchstart',
function(e){
e.preventDefault();
}, true);

src.buffer = newBuffer;

18. Web Audio nodes


In Web Audio, nodes are like modules that you can use
to change how a sound is played back. You can adjust
the pitch, filter frequencies and much more. Were going
to use one of the simplest nodes to give our sound
volume, a gain node. We create a gain node like so:

var gainNode = context.createGain();


gainNode.gain.value = 1;
src.connect(gainNode);
Then we connect our src (our bufer source) to that gain
node. Now, any data that is in our bufer source will be
passed through and these will be afected by our gain
node. If we wanted to double the volume of our sample,
we could set gainNode.gain.value to 2, if we wanted to
half it we could set the value to 0.5.

19. Test the sound


To play our sound, all thats left to do is connect our gain
node to our contexts destination (which could feasibly
be anything, but in this case its our speakers) and call
src.start(0). This will start our playback at 0 and the

Garbage collection
In web development, weve got a fairly consistent
expectation of what our content will do when its
loaded by somebody. While we dont have a great deal
of assets in this project, we have created many copies
of them quickly. So do you take on the big or the little?
Well, we dont have to worry about that hypothetical,
because we have garbage collection. Garbage
collection is the process in which an application (our
browser in this case) realises an object or entity is
never going to be used again by the program and so
its dereferenced and the memory it occupied is freed
for use by other objects. Think of it like a bucket that
scoops up all of those big items when they turn their
backs and deals with the problem of size for you.

HTML5 & CSS3 Genius Guide 127

Developer

Get free web hosting


with GitHub Pages
GitHub is commonly used to host portfolios of code. Showing the code in action
increases its effect ten-fold

www.fullengineeringbook.net

128 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Traditionally, developers solved the problem of


hosting by adding a link to content hosted at an
external website. Few coders know that each
and every GitHub repository comes with a dedicated
area for files which are served via a normal web server.
In fact, GitHub supports three diferent repository
types. A Project site acts as a deployment vector for the
above-mentioned cide examples. User and/or
organisation sites difer from project sites in that they are
instead intended to represent a firm or an individuals
web presence.
From a technical point of view, taking GitHubs ofering
is interesting as long as websites remain static. GitHub
does not provide databases or other active content if
you plan to host a forum or a WordPress-managed blog,
this is not the host of choice.
Please be aware that GitHub Pages is not a
replacement for a classic web host. It is a hosting option
for placing GitHub-related content, which enables its
users to test code.

git add --all


git commit -m "Initial commit"
git push -u origin master

6. Check if working
3. Initialise the local copy
The following steps are based on an Ubuntu workstation.
Open a Terminal window, and create a new and empty
folder. In the next step, enter the following commands to
connect the folder to the GitHub server. During the
process, a group of metadata files are spawned.

echo "# TAMHAN.github.io" >> README.md


git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/
TAMHAN/TAMHAN.github.io.git
git push -u origin master

1. Sign up!

4. Position your web content

Using GitHub Pages requires a GitHub account. If you


have not signed up yet, hit GitHub.com and click the big
green Sign Up button at the top right. For GitHub Pages,
purchasing a premium account is not necessary as there
are no privacy options provided either way (see steps 20
and 21 for more information).

Your Terminal windows working directory now contains


an empty file called README.md. Put a second file called
index.html in the same folder: the location of README.
md shall be the root of the web host, while subfolders
below readme.md will go to a subfolder of the newly
created website.

After this upload, our website is ready for testing. Open


the URL <username>.github.io in a browser of your
choice. Be aware that all GitHub user names are lower
case by force: even if you log in as TAMHAN, the correct
URL will still be tamhan.github.io.

7. Create a 404 message


All GitHub repositories can be equipped with a default
404 page which is displayed to users who attempt to
access invalid or non-existing parts of the GitHub
repository. In the case of our example, the file 404.html
contains a friendly error message.

<html>
<body>
<h1>An error has occurred</h1>
</body>
</html>

8. Deploy, the second


As GitHub Pages are hosted in a Git repository,
committing changes should be accompanied with a
descriptive message such as the one shown in the code

www.fullengineeringbook.net

2. Create a page repository

5. Upload the data

Personal pages must be created in a repository where


the name must match your username in a 1:1 fashion
along the rest of the string shown in the window. If you
have not created a repository before, then set one up
according to the parameters in the image that follows.

From the point of view of the git client, a GitHub


Pages-hosted website is little more than an exposed Git
repository. Due to that, the newly created page and any
contained images must be pushed to the server before
they can become visible to the World Wide Web.

Attention: Unix!
GitHub Pages is hosted on a Unix operating
system. This means that paths and file names are
case sensitive a nasty trap for people switching
from Windows Server.

Left

Using GitHub Pages requires you to sign up at GitHubs site


an act which may not appeal to the taste of more
libertarian individuals
Top left

GitHub Pages requires a specific repository name based


on the scheme <NAME>.github.io picking any other name
leads to issues
Top right

Our GitHub Pages-hosted website is being served as a


normal HTTP page when its access URL is entered into a
browser of choice

HTML5 & CSS3 Genius Guide 129

Developer
featured in this step. Do not wonder if the client will ask
for username and password from time to time as a
security precaution.

git add --all


git commit -m "Add 404 page"
git push -u origin master

9. Its really just GIT


As we have stated earlier on, a GitHub Page is really little
more than a publicly exposed Git repository. In the case
of our website, you can just open up github.com/
TAMHAN/TAMHAN.github.io in order to see the
commit history along with a stub file left over from an
editor crash.

10. Lets start a project


While personal pages on GitHub might be nice, the real
value lies in the creation of websites for projects. Let us
set out by creating a new project containing a bit of C
code simply upload it in order to make GitHub show
the project contents view when the repository is opened
in the WebView.

11. Automagic generation


In the next step, click the wrench icon on the right-hand
side of the screen. Next, move down towards the
Automatic page generator segment and click the

Launch automatic page generator button in order to


start the modification process.

switch between the two groups with the arrow symbols


pointing to the left and right.

12. Do the Markdown!

15. Go live

In the next step, GitHub will open an editor where the


contents of the projects homepage can be edited. The
product uses a Markdown-like syntax which is
well-known from a variety of CMSs and a few Mac
OS-based editors.

Finally, click the Publish button in order to go live with the


changes. GitHub will confirm the successful generation
via a small banner at the top of the screen. You can go
ahead and open tamhan.github.io/
ImagineProjPageTest in order to take a look at the
results of our labour.

13. Add Google Analytics


Tracking the successes of a GitHub repository is a
process that is best accomplished via the use of
Google Analytics. In the first step, you should work on
following the comprehensive instructions that have been
outlined on the Analytics documentation at support.
google.com/analytics/answer/1032385?hl=en in order
to obtain the Google ID. Then, once you have the Google
ID to hand, you can now enter it into the box at the
bottom of the Markdown editor.

14. Choose your layout


Presenting a bland website is no fun. Thus, click Continue
to Layouts in order to open a preview alongside with a
ribbon permitting you to select the style. GitHub
provides a total of twelve diferent themes; you can

16. Do the branching


The files intended for the GitHub page of a project are
not stored in the main branch. Instead, GitHubs
generator automatically generates a branch called
gh-pages which acts as the host containing the files
intended for the projects homepage.

www.fullengineeringbook.net

Analytics caveat
Deploying Google Analytics is complex from a
legal point of view: in many countries, users need
to be notified that their data is collected and/or
forwarded to Googles servers.

Top left

Even though the Editor embedded into GitHub Pages


looks a whole lot like WordPress, it works with a
completely diferent markup language
Top right

GitHubs automatic page generator is well-hidden: find it in


the settings dialog of a project
Right

Forgetting to remove temporary files before starting the


commit process leads to weird and sometimes
embarrassing results

130 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

Do the domain!
One way to make GitHub
Pages a little more
professional is through the
use of subdomains. You
can add a CNAME record
at your web or domain
provider in order to
redirect trafic to GitHub
Pages as the system is
based on DNS names, your
site will continue to
benefit from GitHubs
optimisation and CDN
service. For example,
orgname.github.io/
projectname could be
redirected to project.
tamoggemon.com.
If your domain provider
does not ofer the CNAME
option, you can
alternatively use an apex
domain which forwards to
the IP adress of GitHub.
GitHub oficially advises
against the use of apex
domains as they do not
permit the use of a CDN
further information on the
topic can be found at
bit.ly/1NpCaZX.

www.fullengineeringbook.net

17. Delete a personal page

19. Troubleshooting

20. The NSAs best friend

Getting rid of a personal page is not dificult. Open the


repository containing its files, and switch into the Settings
pane. Then, move into the Danger Zone tab and click the
Delete this repository button.

The automatic page generator can be a bit troublesome


at times. Fortunately, the GitHub team provides a
selection of frequent issues which can be accessed by
opening the URL help.github.com/categories/
github-pages-troubleshooting/.

While GitHub repositories can be declared private, this


flag does not apply to any Pages content found within.
Be aware that any content uploaded to the Pages system
is made publicly available if someone finds it, consider
yourself oficially out of luck.

21. HTTPs: missing in action


Another significant limitation of GitHub Pages involves
the fact that HTTPs is not supported. Even though
secure HTTP might be easy to crack for dedicated
attackers, it nevertheless provides an urgently-needed
extra layer of security that is absent here.

18. Delete a project page


Should you ever decide to eliminate your project page,
simply remove the gh-pages branch. This can be
accomplished by opening the branches tab of the
repository in the web interface. Next, click the little
garbage can next to the gh-pages branch in order to
banish it forever.

HTML5 & CSS3 Genius Guide 131

Developer

Manage JS with
asynchronous tasks
Promise objects aim to remove redundant and/or excessive
callback functions from background tasks

www.fullengineeringbook.net

Using callback functions is a sure-fire way to


induce JavaScript bloat: we know of some
code examples where the accomplishment of
a single task requires the presence of a dozen
callbacks. Furthermore, callbacks are not a catch-all
solution for event handling. As the use of exceptions
spreads over to JavaScript, keeping an eye on the
various error sources becomes tedious pretty quickly.
Even though Promises have not been fully
formalised at the time of writing, they nevertheless
provide a fascinating alternative to callbacks. In
principle, a Promise is but a state machine object
whose state reflects the situation of the task at hand.

132 HTML5 & CSS3 Genius Guide

Deploying Promises significantly reduces the eforts


involved in callback and event handling. When done
right, core functions can be observed at a glance.
Furthermore, time becomes insignificant: if a Promise
is invoked after the event it is intended to analyse has
taken place, it will automatically transition through the
necessary states.
As with all concurrent code, care must be taken to
avoid race conditions and similar problems. So, let us
be your guide and come along for a fascinating ride!

1. Set the stage


As Promises are not fully standardised at the time of

writing, care must be taken to ensure a consistent


working environment. The examples presented in this
tutorial worked well on a Firefox 42.0 hosted on a
64-bit Ubuntu workstation.

2. Create a model
A Promise class is a wrapper around an asynchronous
payload. To keep things simple, we will start out by
creating a simple model of a good friend of ours. Matz
will greet us with a friendly Oi message once a day
sadly, the time when the actual Oi takes place is not
predictable so it could occur at any time.

<html>

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

<body>
<script>
function Matz()
{
setTimeout(function(){ alert("Oi!"); },
(Math.random()*10000));
}
Matz();
</script>
</body>
</html>

3. Adapt to Promise
Adapting our Matz payload to a Promise involves the
creation of a method with two parameters. Both reject
and resolve can be invoked as normal members, along
with a value containing further information about the
state of the event at hand.

<body>
<script>
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){ resolve("Oi!"); },
(Math.random()*10000));
});
</script>
</body>

(Math.random()*10000));
});
aMatz.then(function(){alert("Matz is
here!")});
</script>
</body>

5. Transcendental Oi!
Classic event handlers sufer from a chicken/egg
problem: if the interesting event occurs before the
registration of the handler, information will be lost. As
Promises act as state machines, this problem can not
occur. Once Matz is done, its done forever, which means
that the late alert will always pops up.

6. Truly asynchronous
Then does not interrupt program execution. Instead, the
method stores the payload in an execution queue and
returns afterwards. Running the example accompanying
Step 6 a few times will lead to diferent alert dialog
sequences depending on the speed of your system and
the random timeout value.

<body>
<script>
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){ resolve("Oi!"); },
(Math.random()*10000));
});
aMatz.then(function(){alert("Matz is
here!")});
alert("We're done here");
</script>
</body>

reject method, which gets invoked instead of resolve:

<script>
window.doritIsHere=true;
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){
if(window.doritIsHere==false)
{resolve("Oi!");}
else
{reject ("Eeek!")}
}, (Math.random()*10000));
});
aMatz.then(function(){alert("Matz is
here!")});
alert("We're done here");
</script>

8. Chain it up
Step 6 established that then() does not wait for the
completion of the Promise. Thus, its returned context can
be used to chain things up. In our example, the payload
passed to catch() is executed only if Dorits presence
causes Matz to bolt.

<html>
<body>
<script>
window.doritIsHere=true;
var aMatz=new Promise(
. . .
aMatz.then(function(){alert("Matz is
here!")}).catch(function(){alert("No, it's a
Dorit!")});

www.fullengineeringbook.net

4. Announce events

Our Promise only actually becomes useful once we can


ensure that our code reacts on its completion. The
snippet accompanying this tutorial step announces the
Greeting event by displaying a message box once the Oi
has been emitted.

<body>
<script>
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){ resolve("Oi!"); },

Dont block

7. Dorit objects

Promises are not a way to perform


multithreading. If your Promise contains blocking
code, the JavaScript runtime will stall just as if it
were found in a normal function or member.

Real-world processes have the nasty habit of failing from


time to time. We will model this via the presence of a
Dorit object: if she is around, Matz gets intimidated and
no longer greets passers-by. This is modelled via the

Left

When push comes to shove, knowing the exact version of


the browser where a program is being run tends to be
really helpful
Top left

The timing of the two alerts depends on the mood of the


random number generator
Top right

Setting doritIsHere to true makes Matz think twice about


greeting passers-by a situation modelled with reject()

HTML5 & CSS3 Genius Guide 133

Developer
alert("We're done here");
</script>
</body>
</html>

9. Clean me up
Developers who are familiar with object-oriented
programming languages know the concept of a finaliser:
it is a method that gets called on both success and
failure of the underlying operation. Its position in
program execution is shown in the flowchart
accompanying this step.

10. Implement the finaliser


With that, its time to get coding. Adding a finaliser is as
easy as invoking the final method at the end of the call
queue: the execution engine will ensure that its payload
gets invoked once the then or the catch payloads were
given an opportunity to run. Unfortunately, this feature
isnt supported on Firefox, and requires the use of
external libraries.

<script>
window.doritIsHere=true;
var aMatz=new Promise(
. . .
aMatz.then(function(){alert("Matz is
here!")}).catch(function(){alert("No, it's a
Dorit!")}).finally(function(){alert("It's
done!")});
alert("We're done here");

JavaScript, as the number of callbacks raises with a


growth rate of O(n)=2*n. Fortunately, a Promise can be
made to return another one:

{
setTimeout(function(){
if(window.doritIsHere==false)
{resolve("Oi!");}
else
{reject ("Eeek!")}
}, (Math.random()*10000));
}
var matzBuilder=new Promise(function
MatzBuilder(resolve, reject)
{
setTimeout(function(){
alert("Spawning new Matz!");
resolve(new Promise(Matz));
},1500);
});

12. Gang them up, part one


With that, its time to show our MatzRaiser in action. The
following test fixture demonstrates how multiple then
commands are chained. By the way: the linear
indentation of the individual methods is recommended
in the standard.

instantiation of the mage.

<script>
window.doritIsHere=true;
matzBuilder.then(undefined,function(){
alert("Unhandled Inner Error")
}).then(function(val){
alert("Queueing completed! " + val);
});
</script>

14. Promise arrays


Pictures must be downloaded in bulk. We will simulate
this problem via a Promise which eventually changes
the colour of a table cell assigned to it:

<body>
<script src="jquery-2.1.4.js">
</script>
<script>
function DeltaColor(resolve, reject)
{
setTimeout(function(){
this.myElem.css( "color", "green" );
}, (Math.random()*10000));
}
</script>
</body>

www.fullengineeringbook.net

11. Cascade the processes


In many cases, one asynchronous process kicks of
another one. This is one of the main issues in classic

Advanced
functionality
Check out the Promise RSVP library ofered at
github.com/tildeio/rsvp.js

Top left

The colours of the XXX-laden cells are changed as the


individual Promises fire of their payloads
Top right

Failed invocations of the then() payload are indicated by


the passing of undefined for val
Right

A finaliser is run regardless of the success of the


monitored operation

134 HTML5 & CSS3 Genius Guide

var matzBuilder=new Promise(function


MatzBuilder(resolve, reject)
{
setTimeout(function(){
alert("Spawning new Matz!");
resolve(new Promise(Matz));
},1500);
});
matzBuilder.then().then(function(val)
{alert("Queueing completed! " + val);})

13. Gang them up, part two


If an error occurs in the inner part of the Promise and is
not handled in the first part of the then() chain, the
second part handles it automatically. The little snippet
shown here handles the fearsome Matz error in the

15. Set it up!

Demonstrating our code in action requires the presence


of a table containing a batch of red cells. Furthermore,
one master cell is created. Finally, each cell is assigned
with one instance of the Promise generated in Step 14.

function AddClosure(what)
{
return function (resolve, reject)
{
setTimeout(function(){
what.css( "color", "green" );
resolve();
}, (Math.random()*10000));
};
}
$( window ).load(function() {
var e1=new Promise(AddClosure($("#k1")));
e1.then();
var e2=new Promise(AddClosure($("#k2")));
e2.then();
var e3=new Promise(AddClosure($("#k3")));
e3.then();
var e4=new Promise(AddClosure($("#k4")));
e4.then();
var e5=new Promise(AddClosure($("#k5")));
e5.then();
window.myArray=[e1,e2,e3,e4,e5];
});
</script>
<table>
<tr><th>Mater</th><td
id="master">xxxxxxxxxxxxx</td></tr>
<tr><th>Kid</th><td id="k1">xxxxxxxxxxxxx</

HTML5 & CSS3

Genius Guide

Do the closure
Setting parameters on the Promise object
returned by the constructor is not a valid
way to pass them into the function
responsible for the actual handling of the
payload. Instead, parameters must be
passed using a closure which returns the
function body. In the case of the code
shown in Step 15, the element at hand is
stored as a parameter passed to
AddClosure. The inner function can
access it as if it were a global variable, as
a closure is erected around it during the
returning of the function body. It will
remain valid for the entire life cycle of
that reference: as long as someone can
invoke the function, its closure remains
alive. JavaScript newbies should be aware
of this behaviour, as it is the prime source
of excessive memory consumption.

td></tr>
<tr><th>Kid</th><td
td></tr>
<tr><th>Kid</th><td
td></tr>
<tr><th>Kid</th><td
td></tr>
<tr><th>Kid</th><td
td></tr>
</table>

id="k2">xxxxxxxxxxxxx</
id="k3">xxxxxxxxxxxxx</
id="k4">xxxxxxxxxxxxx</
id="k5">xxxxxxxxxxxxx</

17. Wait for one

19. Antipattern: recurring events

If work should proceed after one of the Promise objects


contained in the array is completed, the test harnish
must be modified along the lines shown in the code
accompanying this step.

Promises change their state but once: in the example


below, our Matz could say Oi once. Trying to shoe-horn
Promises into the role of a classic event bus as the one
shown in the image is not recommended other tools
like Radio.js provide a faster, slimmer and more
efective solution.

window.myArray=[e1,e2,e3,e4,e5];
Promise.race(window.myArray).then(function()
{
$("#master").css( "color", "blue" );
});
});

20. Cancel and Query

www.fullengineeringbook.net

16. Wait for all

One especially interesting convenience function found in


the standard involves awaiting the completion of an
entire array of Promises. In our example, the master cell
gets coloured only after all the children have achieved
readiness by changing their colours.

. . .
window.myArray=[e1,e2,e3,e4,e5];
Promise.all(window.myArray).then(function(){
$("#master").css( "color", "blue" );
});
});

18. Abbreviated then


Most then() invocations contain a success and a failure
clause. The Promises standard contains a special method
taking two parameters it prevents you from having to
invoke the failure method separately.

p.then(onFulfilled, onRejected);
p.then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});

The basics of UI design dictate that users should be


provided with progress information to shorten the wait.
Sadly, this feature is not implemented in the A+ standard.
Instead, developers are recommended to use the Q
library which, incidentally, also supports the termination
of Promise payloads.

21. Promises for IE


Analysing the compatibility of Promises on CanIUse
demonstrates that all versions of Internet Explorer dont
support it. Fortunately, a large variety of alternative
libraries are available. ES6-Promise has become a bit of a
quasi-standard due to its small size more information
awaits you at github.com/jakearchibald/es6-Promise.

Top left

If race() is used, one colour change is enough to trigger


the modification of the mater element
Top right

Radio, available from radio.uxder.com, allows you to


create event chain systems efficiently
Right

Promises are not and probably will not be supported in


Internet Explorer (Credit: caniuse.com)

HTML5 & CSS3 Genius Guide 135

Special effects

www.fullengineeringbook.net

136 HTML5 & CSS3 Genius Guide

138 HTML & CSS animation


Get pro tips for building dynamic designs

146 Create split-screen sliding


panel effects
Combine minimalism and usability on your site

148 Animate an SVG with HTML and


CSS
Create an animated GIF using SVG, HTML & CSS

150 Code animated sliding panels


on scroll
Make the most of your screen space with panels

152 Make a resizable sliding panel


for your content
Use draggable columns to present information

154 Sync animations to audio and


video with Popcorn.js

www.fullengineeringbook.net
Sync up animations and audio

158 Make a draggable fading effect


Create an interactive fading effect feature

160 Code on-scroll image animations


with CSS
Add a scroll-on effect to page features

162 Add slide-up titles on page load


using CSS
Design an alternative menu style for your site

164 Animate typography and text


effects
Add animated effects to light up your headings

168 Create a 3D navigation menu


with HTML
Have your content revealed on hover

172

Make a screen shrink on scroll


Use shrink effects as users navigate the page

174

Create scrolling text with colour


change
Keep users engaged with text colour changes

HTML5 & CSS3 Genius Guide 137

Special effects

Presenting

www.fullengineeringbook.net
THE PATH TO BUIL
L
A
E
V
E
R
S
T
EXPER UTIFUL DYNAMIC DESIGN DING
S
BEA

138 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Whats up with
web animation?
Ask any two designers what
they think of animation, and
youll get six opinions. The web
still hasnt quite recovered from the Flash
years, when loading and splash pages
stressed prebroadband modems and
made users wait for extravagant doodles.
For designers, Flash was a brilliant way
to rack up the billable hours. It wasnt so
popular with visitors, who either learned
to click on the Skip animation button as
soon as it appeared, or were left
wondering why theyd just spent two
minutes watching a cartoon rocket land
in a giant vector graphic cheesecake.
Of course Flash is still around, but it
doesnt seem to be winning new fans.
Today, most clients and creative directors
are going to look strangely at anyone
who suggests a splash screen, whether it
uses Flash or a more recent technology.
That could be because modern
animation has calmed down and tried to
make itself more of a team player. Instead
of being all about the technology or the
designer, animations have become more
about the design.
So what is animation for? Its easy to
make a site where everything moves all
the time, but visitors will hate it. Its more
useful to think of animation as a power
tool you can use to enhance your sites
production values, help users find their
way to the content theyre looking for, and

emphasise the stories you want the site


to tell.
If the animation isnt helping out, dont
use it. You can make exceptions for
showcase and demo sites where youre
exploring a new technology. But for
general public access, animation should
always be able to justify its existence.
As the technology has improved, the
limiting factor for motion design isnt the
technology. You can use animation
frameworks and plain CSS3 to do almost
anything you want in 2D. 3D isnt quite as
developed, but it doesnt have as many
clear use cases, and most sites work fine
with 2D animation, perhaps with a few
understated 3D accents.
The challenges have more to do with
clever design, creativity and most of all
efective communication. Animation isnt
so much about moving divs as about
moving visitors. If it isnt doing that, you
may need to rethink it.
To make life easy, well pull out some of
the recent UI and UX design trends so
you can look at them in more detail.
Theres no need to start with a blank
editor and an equally blank expression.
Modern animation design doesnt mean
starting from scratch on every project. A
few hints and suggestions go a long way,
as does some knowledge of what the rest
of the industry is doing. If youre ready to
be moved, read on

Shane Mielke
Creative director at shanemielke.com

www.fullengineeringbook.net

The SmartWater site (drinksmartwater.com)


has some charming animated interactive
clouds that reinforce the brands message

CSS and GreenSock animations are


amazing ways to spice up your front-end
builds. Pixi.js and three.js give us 2D and 3D
WebGL/Canvas animation playgrounds. In
the right hands all of these tools can work
magic. Were just missing a standardised
timeline animation IDE like we had in Flash
that will output clean, lightweight code

The state of browser support


CSS3 keyframes

10

16

15

7.1

4.1

CSS3 animation

10

16

15

7.1

4.1

jQuery 1.X animation

Current

Current

5.1

12.1

6.1

jQuery 2.X animation

Current

Current

5.1

12.1

6.1

Other JavaScript
frameworks

Current

Current

5.1

12.1

6.1

WebGL [1]

11

31

31[2]

29[2]

8.3

40[2]

[1] Requires compatible graphics hardware [2] Partial

HTML5 & CSS3 Genius Guide 139

Special effects
Animation in Action
Dreamteam
dreamteam.pl
The use of web animation needs to considered and have value. Alternatively, it
can be something to adore and be admired. DreamTeam by Polish creatives
BrightMedia sits very much in adore and admire. The homepage animation reveals
itself with a simple straight line before blossoming into a fully fledged animation.
The fun doesnt stop at the homescreen, scroll down and watch more smart design
unveil itself.
All for show
The opening animation has no real purpose other
Keeping up
than to engage and excite the user. The
The creatives behind
moment the animation starts, the user is
hooked. An attention-grabbing design is
DreamTeam are Polish agency
guaranteed to give the creators attention
BrightMedia. Keep up with their
right across the web design community.

latest work via brightmedia.pl.


Alternatively, check their Twitter
@brightmediapl for latest
updates.

UI animation
Simple navigation animation is used to enhance the
overall site. To reinforce the common purpose of the site
each menu item has a rollover efect. A solid white
background eases in with a subtle animation and
immediately draws the users attention.

www.fullengineeringbook.net
The technologies & tools
Keep it simple with CSS3
Knowing how to work with CSS3 animations is a core skill
now. CSS3 animations are split into two related tag
groups. The transform tags move things around the
screen, with simple support for 3D. The animation and
keyframe tags control the movement.
But there are downsides, and these will include some
of the usual CSS gotchas. Its easy to make animations
that almost work but its possible that they may just start
or stop in the wrong place, or dont quite loop as you
want them to. And CSS3 simply isnt very smart. You can
link animations to events in a basic way, and you can
chain and link animations to create complex efects as
well. But its dificult to make animations respond to
surrounding content.

JS & jQuery: the missing link


JavaScript and jQuery can fill in the features that are
missing from CSS3. Do you need to make sure an
element wont fall of the bottom of the screen, or cover
something important when the user reveals it?
JavaScript is the solution.

140 HTML5 & CSS3 Genius Guide

Theres one catch. CSS3 runs eficiently inside the


browser with superfast precompiled code. JavaScript
animation is compiled on the fly, and its not nearly as
eficient. So if you do anything complicated youll kill the
battery life on mobile, and heat up the processor on
desktops and laptops until the fans kick in.
Raw JS is a powerful option with a lot of creative
potential. But you will need to handle it with a lot of care.

Working with frameworks


JavaScript wouldnt be JavaScript without more libraries
than a human brain can remember. Luckily only a
handful are popular at a time. A few years ago MooTools
FX Morph, Transition and Tween classes were widely
used. (See mootools.net for details.) Yahoos YUI library
(yuilibrary.com) also found favour, inside and outside

Yahoo especially in the form of AlloyUI (alloyui.com)


which merged it into Bootstrap.
Now jQuery has taken over most of the load, with its
.animate function, which includes easings, durations, and
the ability to animate any numerical CSS property.
But thats not enough for some projects. For more
control, you can work with more advanced frameworks
such as paper.js (paperjs.org), Raphael.js (raphaeljs.com)
and Processing (there are two web versions
processingjs.org and p5js.org). For those who want a
Flash-like interface, theres also the paid-for GreenSock
framework (greensock.com).
The big advantage over basic CSS3/HTML is support
for vector graphics and simplified animation loop that
saves you from dealing directly with timers.
Which should you choose? Processing is the most
sophisticated, and supports pixel-level manipulations
although theyre buggy in processing.js videos,
webcams and sound. It works with HTML5 Canvas tags,

Raw JS is a powerful option with a lot of


creative potential. But you will need to handle
it with a lot of care

HTML5 & CSS3

Genius Guide

Web animation
API: a new
solution?
HTML5 technology
Taking a peek at the source
code reveals a surprisingly slim
page. It is the HTML5 Canvas
element where all the hard
work is done. The animation
sits quietly in the background
claiming all the glory while the
standard HTML creates the
crucial elements needed to
navigate and guide users
around the site.

And theres more


The homescreen is
undoubtedly the centrepiece
of the DreamTeam site, but
complimentary and more
constructive animation is
incorporated into the site.
Simply scroll down the page to
see how subtle user interface
animations are introduced into
the site design.

If youve looked at native apps, youll know the


web doesnt have anything quite like the slick
and streamline native animation frameworks
built into iOS and Android. The W3Cs web
animation API is an attempt to fix this. Its not a
drop-in replacement for mobile animation, so
dont expect to make elements glide or fade more
easily than in the past. For better or worse, the
W3C committee have gone in a diferent direction.
The current proposal bundles the existing CSS3
animation features, extends them to allow simpler
DOM element animation and adds some welcome
extras, including support for a timeline and for
play state management. Keyframes also get an
upgrade, so you can do more with them. Its also
going to be possible to start, stop, restart, and
pause animations using JavaScript code, which
will fix some of the limitations of CSS3 animation.
If youre thinking this sounds a little like Flash
it does. Or at least, the timeline and keyframe
features do. When web animation becomes widely
supported its going to become easier to chain
animations, to create animated efects by
flip-booking SVG files, and to make animations
respond to external events.
So its better to think of it as an animation
management system, and not so much as a new
set of canned efects you can drop into your pages
with almost no code.
The current API proposal has issues. One big
problem is lack of synchronisation. You can make
events play together on the same timeline, but its
hard to guarantee that animations on separate
timelines will remain synchronised across a page.
Another problem is complexity. The API
proposal tries to do so much its not a model of
elegance and clarity. Its possible to create
complex animations with it, but its not going to
win awards for being easy to use. This is good
news for designers with good code skills, who will
continue to be in demand. But perhaps its not so
good for the state of web animation in general
although its likely that as soon as the spec is
finalised, its going to be wrapped into a friendlier
and simpler framework so more people can use it
without reaching for the paracetamol.
Whatever the limitations, the API is the most
exciting thing to happen to animation since CSS3.
It should be ready for commercial use within a
year or two. Currently its being considered by
Microsoft. Chromes developer builds include it,
and Firefox has a not-quite-there implementation.
Older and more obscure browsers will play
catch-up, as usual. If you want to know more,
check out w3c.github.io/web-animations.

www.fullengineeringbook.net
Motion
so its good for big animated
emotion
with it it will definitely take your data
Dont forget that many CSS tags
backgrounds and digital art.
vis skills up a couple of levels.
including older pre-CSS3 tags
However its not so ideal for making
WebGL and 3D
UI elements and moving them
can be animated. So animation can
animation
mean creating opacity fades,
around. Raphael and paper are
Waiting in the wings is 3D animation
simpler, and concentrate more on
animated borders and text
and rendering. This has a lot of
decoration.
vector graphic design with a hint of
potential, but its not quite there yet. The
animation. GreenSock is much used by
WebGL standard is a simplified version of the
corporates and adds useful functions that
OpenGL 3D graphics programming API used in
simplify CSS animation. Theyre all worth looking at,
high-poly commercial games.
because knowing whats out there can spark new ideas
This sounds like a good thing. But not all platforms
for existing designs.
support all features, and some older hardware barely
Visualising data
supports WebGL at all. So you cant rely on it. And its
If youre working with data visualisation, the go-to
hard to make it look awesome. Gamers are used to
framework is d3.js. (d3js.org.) d3 is a monster that chews
high-poly rendering with advanced lighting efects, and
on data and spits it out in almost any shapes you can
WebGL cant match that.
imagine and a few you probably cant. Its immensely
Finally, its hard to use. The three.js framework (threejs.
powerful, but also has a steep learning curve. If you can
org) makes it more accessible, and there are plenty of
hack it though, its ideal for making and animating UI
demos to learn from (look out for the work of mrdoob
elements, especially if youre using them to display
you can follow him on Twitter @mrdoob). But its still a
quantitative data.
couple of levels up from plain CSS.
To help you get started, the d3 site has a huge
Is it worth it? For plain vanilla UI design, no. For more
selection of demos and examples. Dont expect instant
experimental projects, its certainly worth exploring to
results, but if you can spare a week or two to get familiar
see whats possible.

HTML5 & CSS3 Genius Guide 141

Special effects

Make animation work for the user


In a world after Flash, the point of animation is to
enhance the user experience without distracting or
annoying your users. Its not quite true that animation
should be unnoticeable sometimes you want
something that stands out. But it should never clash with
the rest of the site design, it should never draw attention
to itself without a good reason, and it should always
provide a clear user benefit.
Modern motion design has split into three main areas.
UI sweeteners add a hint of eye candy to plain vanilla UI
elements to raise production values without beating
visitors over the eyeballs with designer awesome.

Staying focused

equivalent of the animated GIFs that haunt the ancient


underworld of amateur web design.
The next UX group are the attention-getters. When
you want a user to focus on one point in the web sales
pitch, add some content-related animation to make that
element stand out. These elements are the descendants
of the old splash pages, but theyve been toned down for
modern sites so they dont overwhelm visitors. Theyre
very popular on Bootstrap sites, where one item out of
two or three has added movement and maybe tells a
short story. Typically theyre spread over a third or a
quarter of the page, and theyre more cute than
cinematic. The animation works a bit like a tiny video that
dramatises the point of the element it decorates, like the

visual equivalent of an <important> tag. It highlights


something you want visitors to remember.
At the top of the animation tree are full-blown
infographics. The genius of motion design means you
can make infographics interactive. This often works
better than leaving users passively looking at the screen
as an animation plays through. Its a huge win for all
kinds of education and training sites, where you can
build a simulation and help users learn about a topic by
interacting with it.
But animation isnt an obligatory part. Adding a simple
splash or bounce tells the user theyre in a new part of
the site, and youre telling them a new chapter in your
sites story. With careful tuning you can make the motion

The aim is to make your site look slicker, smoother and


glossier, and generally more sophisticated and
authoritative. A little CSS3 or JavaScript can do a
lot of good, but if the user is more likely to
Speed up
remember the motion than the content
jQuery
you may want to rethink your design
JQuery isnt fast, and .animate
strategy especially if you start
is even slower. To make your
veering towards the sketchy end of
animations faster and more
town with insane animateeficient, try Velocity.js (julian.
everything excess, and overly
com/research/velocity) for a
bouncy, distracting image carousels
drop-in .animate
and sliders. These are the modern
replacement.

www.fullengineeringbook.net

Edwin
Europe
edwin-europe.
com
Check the Denim fit guide
to see the 360-degree
view: animation with
the wow factor.

Vimeo
Cameo
vimeo.com/
cameo
Subtle, simple and
efective animations that
work on diferent levels
on diferent
devices.

142 HTML5 & CSS3 Genius Guide

HTML5 & CSS3

Genius Guide

a thing of beauty that stands on its own. Make sure that


you keep it short though

Make UI engaging
Why spice up a UI with animation? Too much twitching
and blinking can give users a migraine. But just the right
amount of animation can make the diference between a
boring site and one that users will keep coming back to.
In outline, there are three kinds of UI animations.
Highlighters decorate existing content to suggest an
afordance. The most obvious examples are link

decorations and pop-ups. Getting links right is always a


challenge. A subtle mouseover underline animation can
help draw attention to a link without making the rest of
the page look busy and link-heavy. Another example are
form error notifications. Have you ever pressed Submit
on a site and then wondered why nothing happened?
Site designers realised it was helpful to highlight mistakes
in red, so users can see problems immediately.
But sometimes this is too subtle. You can use
animation to draw attention to problems by making
incorrect elements move a little, as well as changing

The right amount of animation can make


the difference between a boring site and one
that users will keep coming back to

colour. Apples You got that wrong, so this text box looks
like its shaking its head is the classic example here.
Skeuomorphisms help make the site feel more
physical. The aim here is to use visual metaphors to
suggest physical objects. Often, just a hint of physicality
is enough for more weight and presence.
Attention seekers are the final UI group. They provide
important stand-out features that cant be ignored, so
theyre hard to get right. Examples include FILL IN OUR
FEEDBACK FORM pop-ups, but you can also find them
scrolling up from the bottom of the page on news sites
to ofer breaking news.
Attention seekers tend to annoy users, so consider
using animation to make them less distracting. Make
pop-ups appear at the side instead of the middle of the
viewport, and put breaking news in a window. The
animation should always help the user, not distract them.

Catch
the dragon
catchthe
dragon.nl

www.fullengineeringbook.net

Car manufacturer Peugeot


combine video, VR and
animation to create a
breath-taking
experience.

HTML5 & CSS3 Genius Guide 143

Special effects

www.fullengineeringbook.net

Create a
pulsating circle

HELLO MONDAY TECHNICAL LEAD


TORBEN DALGAARD JENSEN
REVEALS HOW THEY CREATED THE
EFFECTS ON REVELATOR.COM
The Revelator website is built on the idea that you only
need to use one platform if you want to run a music
business. We wanted to showcase this idea by leading the
user through an animated story that breaks the features
into simple steps. Below well explain how you can create
the type of animation we used for the Promote feature.
Well use trigonometry to create the pulsating efect
and write it entirely in JavaScript. GreenSock TweenMax is
used for the tweening, and we will be writing a JavaScript
object instance for the circle so that we can preserve
modularity and readability.

1. Initial setup
First what we will do is create a container and an array to
hold the circles. Then we are centring the container
within the window. Also we are writing some stub code
that we will revisit later.

2. Create DotCircle.js
We will go through the methods for the stub code for the
DotCircle in the next steps. We calculate the distance in
degrees between each dot and create a radius object

144 HTML5 & CSS3 Genius Guide

that we will use to tween the position of each individual


dot. We are using 7px as the value for distance you can
play around with this value to create a circle with less or
more dots in it.

3. The init method


Here we are creating each individual dot. We need to
convert the degrees to radians and then calculate the
initial position using trigonometry. We find it easier to
work with degrees than radians, but this step can be
skipped and do all calculations with radians.

4. Implode and pulse


These methods tween the radius value and update the
position of the dots (see next step). In this example they
will keep running each other when the tween completes
to create the pulsating efect.

5. Update
Now what well do is we will update the position of the
dots based on the new radius value we are tweening.
Then we will be delaying them incrementally to create
the staggered efect.

6. Ready to rock!
Going back to the main script we will now create three
instances of the DotCircle with incrementing radius. Then
we will start the animation, again using delay to stagger
them. For the full code in this tutorial, make sure that you
check out FileSilo (filesilo.co.uk/bks-887).

Torben Dalgaard Jensen


Technical lead
at hellomonday.com

We wanted to create a visual


representation and give a sense
of the excitement and relief
musicians feel when they
release their music and see the
mood of their fans rise

HTML5 & CSS3

Genius Guide

Animations: keep it simple Resources


everything needs to animate. Animations have varying
levels of expressiveness and personality. The most
colourful kind like 3D flips, bounces or elastic
easing can be a great way to make an interface more
fun but since theyre so distinct its easy for them to be
visually fatiguing. Its generally better to stick with simpler
animations for things that people interact with frequently
and save the more playful ones for areas that are used
more seldomly. Another rule of thumb I use is to show
slow and hide fast. For example, I might run a halfsecond intro animation for a modal dialog but hide it
without any animation at all. The rationale here is that
youre more willing to watch something you requested
animate in than you are waiting for something you
dismissed to animate out.

Hakim el Hattab

Which web animation technologies currently excite


you and why?
CSS transitions and animations are the technologies that
I care most about. Combined they are flexible enough to
achieve the efects I want and its been great seeing
them gain broad support so quickly.

Interviewing Julian Shapiro


bit.ly/1Jzl5tX
Find out what velocity.js author Julian Shapiro thinks
is going to happen next on the animated web. Read
his comments about the diference between good
and bad animation design, learn about the imminent
speed and eficiency bump, discover how too much
creativity can be a bad thing, and why education
matters more than ever in motion design.

Rachel Nabors UX Guide


bit.ly/1R6UdWj
This excellent slide deck introduces the latest trends
in animated UX design from the perspective of a
trainer and designer. You may not necessarily agree
with all the points especially the one about the
return of splashy flash screens. But the rest is
definitely well worth reading for a creative and
inspiring overview.

Val Heads Videos


vimeo.com/valhead/videos

www.fullengineeringbook.net
Designer and developer
hakim.se

Q. The use of web animation in any project needs to be


carefully considered. What advice would you give to
designers and developers?
When working on a web app keep in mind that excessive
and lengthy interface animations can reflect negatively
on the app as a whole. If animations are too slow the app
itself is perceived as sluggish. If there are too many
things animating too frequently it wont feel reliable and
robust. Keep animations brief and remember that not

Web animation has vast potential. How do you see it


evolving over the next couple of years?
I expect tooling to get a lot better and I know that
browser vendors are making good progress towards this.
Working with animation is a visual process often
requiring many iterations of number tweaking and
previewing. If friction can be removed in that workflow
well see higher quality animations.
The Web Animations API is looking promising too.
Theres certainly a need for animations that can be
controlled more explicitly via a script than whats
currently possible with CSS transitions and animations.

What next for animation?


In the past, web design was split into epic splash
animations and relatively small and trivial UI tweaks, with
a few sliders in the middle. What happens when the web
animation API becomes more widely used and designers
can work with more complex animations?
Some designers will stampede back towards epic
splash pages. Even though loading times and browser
speeds make splash pages more feasible than they were
in their heyday, its likely theyll remain a sideline.
The trends in current design are clear: theyre all about
integrating animation with content or rather, about
enhancing content with tasteful and relevant animation.
Parallax scrollers, minivideos, and animated icons do this
already, with varying degrees of success.
For examples of possible future trends, run a search
for the animation tag on Dribble. Most examples use the

same contemporary flat, minimal, cartoon-style design


language common on the web, but add an animated
twist to highlight a feature or make it more memorable.
Eventually some icons will be animated as a matter of
course. Balance is key. Too much movement is confusing
for users. Animated GIFs were the bane of the early web,
and animated icons could easily become the modern
equivalent. But they probably wont, because designers
are more experienced now, and theres more of a trend
towards minimal design, where designers keep removing
elements until theyre left with the bare essentials.
If those essentials happen to include some movement
that can justify its existence by telling a story about some
content or highlighting the afordances of an icon or
other UI element, that could potentially make the web
much more creative for everyone.

Not so much of the future, but you may as well get a


good guide to the state of the art in the present
before you go ahead and any higher this collection
of tutorial videos covers all the CSS3 animation bases,
and includes an impressive collection of design
examples. Theres only about half an hour here in total
though, but its certainly time well spent, especially if
youre just starting out.

Narayan Prustys Web


Animation Tutorial
qnimate.com/web-animationapi-tutorial
If API specs make you dizzy you can find some simple
code examples of the Web Animation API here.
Theres a handy comparison with traditional CSS3
animation, so that you can see how to move from the
old API to the new one. Its not going to win any
design awards, but its a good place to start if youre
feeling lost and confused about where animation will
go in the future.

The trends in
current design are
clear: integrating
animation with
content

HTML5 & CSS3 Genius Guide 145

Special effects

Create split-screen sliding


panel effects
As seen on byassociationonly.com

Menu trigger
The burger menu features
a nice transition as it
animates into an X to
remove the menu from
the screen.

The menu
Once the burger has been
pressed, the left side of
the menu slides down and
the right-hand side slides
up from the bottom.

www.fullengineeringbook.net

Split screen
The page features a
split-screen styling,
divided into two halves,
vertically and used
throughout the site.

146 HTML5 & CSS3 Genius Guide

Slideshow

The main image

The images that appear


on the homepage are a
giant slideshow that
slides upwards into view
on the screen.

The homescreen has a full


browser image. When the
mouse moves, the image
reacts and moves in a
parallax-esque style.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

The creators of the new By Association Only


website state that the hardest website to
build is your own site. This is a statement that
would certainly ring true with many web designers.
Client work always takes priority so it can be dificult
finding the time to create your own website, but at the
same time you are always going to be judged by your
own site, so its importance is crucial when looking at
self-promotion. By Association Only were keen to create
something innovative and diferent, but keeping a
minimalist approach that emphasises usability, and so
the process for creating their site had begun. They were

actually close to finishing a site, but because it had been


so long in the pipeline, they decided it would be better
to start afresh and reimagine their brand.
Realising that their own name was a bit of a
mouthful, they rebranded their logo to an easier BAO
letterform. The finished site features a consistent
two-panel approach that splits the screen in half
vertically but this isnt just for aesthetics though, as this
style is also used as part of the menu design. This
brings the form and functionality together into a
coherent whole that makes sense for the user rather
than simply satisfying a design aesthetic.

Finding visual inspiration


<comment>
What our
experts think
of the site

As designers we find inspiration in every visual medium: movies, TV,


magazines and posters. We knew we wanted to mix things up with our new
website and it turned out that one old Seventies movie poster just happened to
be that spark that informed the 50/50 design route.
Joe Trippett cofounder/creative at By Association Only

Technique
1. Create the sliding panels
In your HTML page add the tags that are shown here.
There are two panels for the left and right side of the
screen and these will be hidden to start with, then
animated when the burger menu icon is pressed in the
third div. Another div is included just to show where the
page content would go.

position: absolute;
top: 0; left: 40%;
font-size: 3em;
z-index: 250;
}
a {
text-decoration: none;
color: #fff;
}
#content{ padding: 30px; }
.hidden{ display: none; }
</style>

www.fullengineeringbook.net
<div id = "left" class="hidden animated"> </
div>
<div id = "right" class="hidden animated"></
div>
<div id = "icon"><a href="#"
onclick="menu();">&#9776;</a></div>
<div id = "content">Regular page here</div>

2. Style the content


Move to the head section of the site and link to the
animate.css file from daneden.github.io/animate.css as
they will be used to trigger the movement. Then some of
our own CSS is added in so that we can style up the
background of the page.

3. Look left and right

EXPERT INSIGHT
The rise of the preloader
Many websites now feature
preloaders, all this does is present a
holding screen until all the content is
loaded. When using large images, it
is essential to wait until they have
loaded before presenting them to
the user, otherwise they would think
that the site isnt working properly
with content missing.

Lets now add the style for the left and right panels, these
are positioned on the page appropriately to the left and
right side of the screen. They are also positioned
absolutely so that they can appear above other content
on the screen with a higher z-index. The sizing is then
handled by percentage to fit the diferent screens.

5. Set the styles


When the user clicks the burger icon the menu function
is called. This code swaps out the hidden property of the
panels so that they become visible. The CSS styles that
are applied come from the animate.css file that was
linked up in Step 2.

<script>
var over = false;
var left = document.getElementById( 'left'
);
var right = document.getElementById( 'right'
);
function menu(){
if (over==false){
left.classList.remove('hidden');
left.classList.remove('fadeOutDownBig');
left.classList.add('fadeInDownBig');
right.classList.remove('hidden');

4. Finish the styling

6. Switch out

Now lets add in the remaining CSS, which will style the
burger icon, link and the content that would appear on
the page. The final CSS style will hide any content that
shouldnt be seen until it is animated.

The rest of the class swapping code is added. Notice that


a variable is also used to hold for whether the menu is
over or not. This is then used to apply the correct classes
to the code. This is all done without the need for jQuery,
through vanilla JavaScript.

#icon{

HTML5 & CSS3 Genius Guide 147

Special effects

Animate an SVG with


HTML and CSS
As seen on cameronsworld.net

Slow scrolling
When you first get to the
site you may find yourself
a little overwhelmed. We
suggest taking it one
animated item at a time.

Multiple themes
Although it may at first
seem like a tribute site to
sci-fi, scrolling down
reveals that it is actually a
tribute to everything.

www.fullengineeringbook.net

Retro stylings
Camerons World is
basically a love letter to
the internets infancy,
piled to the brim with
animated GIFs.

148 HTML5 & CSS3 Genius Guide

GIF collection

GeoCities nostalgia

Scattered throughout
Camerons World is
probably the largest
collection of animated
GIFs in the universe.

It was one of the first


places for building
homepages, thats why so
many GeoCities assets
have been collected here.

HTML5 & CSS3

Genius Guide

Everybody loves a bit of retro, right? Nostalgia


is as inherent to the human race as innovation
and now, some 25 years after the invention of
the World Wide Web, the internet is old enough to be
able to look back fondly on its own infancy.
One such website throwing its eyes back with
unabashed fondness is Camerons World. Anyone
familiar with Nineties web browsing will recognise the
bright lights, garish colours, autoplay music and
practically no design ethic, all of which made us gasp
with awe only 20 years ago. Some will see this site and
smile fondly, yearning for simpler days. Others, of course,

will recoil in horror and wonder what the hell we were


thinking with these designs.
So how about taking one of those quaint, charming
animated GIFs and giving it the modern treatment? Lets
bridge the gap between old and new by re-creating an
animated GIF using SVG, HTML and CSS. Bearing in mind
that this is a quick exercise and we dont have a
wireframe 3D model of the USS Enterprise to hand, were
going to be picking one of the simpler GIFs to re-create.
See the alien, bottom left of the screen on initial page
load, just above the ironic coloured message? Thats our
guy. Make sure you get the full tutorial code on FileSilo.

Animated changes
<comment>
What our
experts think
of the site

Despite Camerons obvious nostalgia for the animated GIF, advances in CSS
animation, and SVG imagery coupled with JavaScript, have seen the GIF slowly
go the way of Flash animation. These days youre more likely to see animated
GIFs relegated to loading icons and little else.
Richard Lamb, freelance web designer at Inspired Lamb Design

Technique
1. Create your alien
First we to make our alien in either Photoshop or
Illustrator. Build him with two layers by making the head
shape, the mouth and nose. The eyes will be created later
on. Once you have this done, save your layers.

-5.677811,-66.79329 5.526856,-101 6.578432,20.08329 22.191729,-47.71784 38.032189,67.3146 30.93205,-38.267061 81.23502,71.07202 131.41932,-85.704791


27.5954,-8.046286 48.45573,-10.899652
79.39131,-10.85949 28.27843,0.03671
41.98283,1.701767 68,8.261848
93.39828,23.549846 167.53312,94.419523
185.44818,177.280353 9.2316,42.6981
3.71539,85.70185 -17.16761,133.83668
-22.51033,51.88577 -69.35284,114.74745
-129.44543,173.7131 -54.55723,53.5341
-86.61074,70.62438 -119.33514,63.62707 z"
id="alienHead" stroke="#1f1f1f" strokewidth="4" />
</path>
</svg>

EXPERT ADVICE
As you can see, there is a plethora of animated GIFs in
Camerons World. For the purposes of this tutorial, we
picked the relatively simple alien GIF, but we still took a
while deciding and then still had to figure out how to
translate a series of animated image layers into a
working, code-based animation. Maybe you can go one
better. Why not choose one of the more complex GIFs
and see if you can re-create it using only HTML and
CSS? Obviously, there will always be some that cant be
mimicked to perfection in pure code, at least not yet,
but sometimes great leaps in coding development
come from having to work with existing tools, but
within very narrow confines.
Besides, even if youre not about to usher in the next
big web development, solving a seemingly pointless
HTML puzzle like this can be an extremely useful
method for keeping your brain agile and ensuring
those coding skills stay honed. Remaining within your
comfort zone, churning out the same template-based
sites time and time again, is an easy trap to fall into.
Sometimes it pays to challenge yourself and try your
hand at what you think is beyond your skills. Maybe
youll surprise yourself with what you can achieve.

left: 140px;
float:left;
}

7. Position the eyes

www.fullengineeringbook.net

2. Create the SVG


There are numerous ways to do this step. You can create
SVGs from your layers with the latest versions of
Photoshop or if you are using Illustrator you can export
your layers as SVGs directly. If you have neither of these
you can use Inkscape, an open source software available
for free. You should end up with an SVG for the head and
one for the mouth and nose shapes.

3. Base HTML
Now were going to begin putting together our index.
html, placing a number of feature-named divs within a
main container div. The two eye divs will have content
created entirely in CSS.

4. Place your SVGs


Place the SVG code for the head shape inside the head
div. You should have a grey shape but you can add a
black stroke value to it for an outline. Then place the
mouth and nose shape into the face div.

<div id="head">
<svg version="1.1" xmlns="http://www.w3.
org/2000/svg" xmlns:xlink="http://www.w3.
org/1999/xlink" width="682" height="643"
viewBox="0 0 682 643">
<path style="fill:#707070" d="M
329.29383,595.34017 C 303.59048,589.84415
278.06846,571.34223 230.24763,523.53768
147.90032,441.21841 101.01898,368.99175
87.424155,303.5 c -7.385818,-35.58047

5. Start adding CSS


The base CSS for the facial features is very simple. Float
the head div left and then add the eyes and face divs
with absolute positioning, plus a zero value top
declaration. You will see your head and facial features
shapes fit together, sort of. Now we need eyes.

6. Build the eyes


Both eyes are built purely in CSS and, apart from one
diference, share the same basic values. With relative
positioning and left float we can then slot them one next
to the other.

.eye-left, .eye-right {
width: 200px;
height: 100px;
background: #1f1f1f;
border: 2px solid #1f1f1f;
border-radius: 100px / 50px;
position: relative;
top: 175px;

We need to shape the eyes for a true alien efect, theyre


too human at present. Use the transform declaration to
rotate them at opposite angles to each other. Dont forget
to add vendor prefixes for browser compatibility.

8. Animate the eyes


In order to create the blinking efect, we are going to use
the box-shadow value to fill each eye with a darker grey
colour and back again over three seconds. The
keyframes are set at irregular intervals to create a slower
end to the blink.

.eye-left, .eye-right {
animation: eye 3s ease-in-out infinite;
}
@keyframes eye {
0%
{box-shadow: 0px 0px 0px 0px #585757
inset;}
2.38% {box-shadow: 0px 140px 0px 0px #585757
inset;}
34.13% {box-shadow: 0px 0px 0px 0px #585757
inset;}
36.51% {box-shadow: 0px 0px 0px 0px #585757
inset;}
100% {box-shadow: 0px 0px 0px 0px #585757
inset;}
}

9. Animate the head


Now weve re-created the original GIF, were going to
surpass it a little by adding an extra animation using the
rotate value to tip the head slightly from side to side. This
is optional, so you can even try putting in some values of
your own devising!

HTML5 & CSS3 Genius Guide 149

Special effects

Code animated sliding


panels on scroll
As seen on isl.co

Main menu
The menu has a simple
but effective animated
rollovers, with an
expanding line appearing
below the link.

Panel content
As the user scrolls down
the page, the content
within the sections slide
into place for maximum
impact with the user.

www.fullengineeringbook.net

Scroll arrow
When the site first loads,
the image of the down
arrow slides onto the
screen showing that there
is more content below.

150 HTML5 & CSS3 Genius Guide

Motion backdrop

Rollover arrow

The background to the


top of the page is a movie
file showing ISLs projects,
with some impressive
camera moves.

The arrow indicating


more content has a
rollover effect that dips
the arrow down with a
colour transition.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

ISL is part of a new breed of digital agency


there is a growing trend that doesnt see them
exclusively tied to the desktop screen. Sure,
there are a lot of agencies that make content responsive
to diferent devices, and some of those even make apps
as well.
ISL goes beyond those conventions and also creates
hardware installations for clients and as digital devices
become ever more present in our lives, brands demand
that something completely new is created to engage
them with their audience. Theyve created a physical
mentions box for Facebook, a launch campaign for NBC

Universals Mr. Robot and an internet-controlled arcade


crane for Nickelodeons SpongeBob SquarePants.
When it comes to their own website, it becomes a
place where they can show of their skills and talents for
their varied work and approach to solving problems.
Rather than just state what theyve done for their clients,
they take a case study approach that defines the
problem, the solution that they have taken and the most
important part of all, the results that this has given their
clients. Its no use to make awesome use of technology
unless it actually works in what its trying to achieve. You
can get the full code for this tutorial on FileSilo.

A lesson in over-caffeinated, youthful exuberance


<comment>
What our
experts think
of the site

ISL.co, like the agency itself, is a balance between designerly minimalism and
over-caffeinated, youthful exuberance. In practice, this meant a combination of
vast white space and simple, clear typography, paired with tons of movement
from background videos to fluid, bouncy UI animations.
Zach Goodwin, creative director

Technique
1. Scroll-triggered animation
To trigger animation by code, the Waypoints.js
(imakewebthings.com/waypoints) library and the
Animate.css (daneden.github.io/animate.css) library will
be used. Download and add them to your document.
Then add the first CSS rule to position the top element.

top with an animated down arrow scrolling down, which


triggers the animated elements onto the page.

<div id="top">
<div class="os-animation btm" data-osanimation="fadeInLeft" data-os-animationdelay="0s">
<img src="img/arrow.png">
</div>
</div> ...

www.fullengineeringbook.net
2. Style up the page
Continue adding CSS as this will provide some classes for
us that position elements at the bottom of a div and float
elements left and right on the page. The final style here
creates a section that has a yellow background so it can
be seen on the page.

3. Final CSS
As in the previous step the CSS here creates blue and
black sections on the page so that they can easily be
seen to demonstrate what is happening. The final two
rules turn animated elements on and of by giving them
opacity values.

EXPERT ADVICE
Animation trickery
The main point of animating content
is to draw attention to it. As content
doesnt appear in its entirety in the
users viewport, it is important to
capture when it actually is present
and make it animate at that point to
give maximum impact to the user.

.blue{
background-color: #00baff;
height: 200px;
}
.black{
background-color: #282f31;
height: 200px;
}
.os-animation{ opacity: 0; }
.os-animation.animated{ opacity: 1; }
</style>

4. HTML content
Move to the HTML section of the page as this is where
the content will be added. This is all styled up via the CSS
that has been added. A full-screen section will be at the

5. Add JavaScript
Now the JavaScript is added and placed in a jQuery
document ready function to allow all elements to load.
Then the function that will be called when the user scrolls
is added. This checks elements on the screen for certain
data attributes and applies CSS accordingly.

<script type="text/javascript">
$(function(){
function onScrollInit( items, trigger ) {
items.each( function()
{
var osElement = $(this),
osAnimationClass = osElement.attr('data-osanimation'),
osAnimationDelay = osElement.attr('data-osanimation-delay');
osElement.css({
'-webkit-animation-delay': osAnimationDelay,
'-moz-animation-delay': osAnimationDelay,
'animation-delay': osAnimationDelay
});

6. Listen to the scroll


When an element is triggered, the appropriate CSS is
added from the Animate.css library. Here the listeners are
created that tie the onScrollInit function to the scrolling
action by the user. Save this and test in the browser to
see the animation triggered on the users scroll.

HTML5 & CSS3 Genius Guide 151

Special effects

Make a resizable sliding


panel for your content
As seen on sparetime.arkivert.no/en

jQuery UI-powered
Our drag and drop engine
comes from the jQuery UI
framework its well
known for its almostuniversal compatibility.

Minimal width
Our example does not
enforce a minimum width
for convenience. But
adding this feature does
not require much code.

www.fullengineeringbook.net

Touch suggestion
Tilting the movement
gems to the side provides
the users with a visual cue
to motivate them to move
the widgets around.

152 HTML5 & CSS3 Genius Guide

Static backgrounds

Another drawer

Arkivert uses cute


illustrations but you can
replace the backgrounds
with any content you
consider to be interesting.

Adding another drawer is


not particularily
complicated: simply
duplicate the <div>s and
add a bit of resizing logic.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Research has repeatedly proven that humans


often have their fair share of problems when
attempting to interpret numbers. However, if
data is spruced up visually, keeping tabs on information is
much easier.
This instalment of our never-ending series on web
techniques was inspired by one particular website
(sparetime.arkivert.no/en), which makes use of
draggable columns to represent an amount of
information visually.
Users arranged the width of multiple columns on the
screen in order to map their behavioural patterns to the

data model of the application. This, however, is but one


application for movable columns. As websites strive to
replace classic desktop applications, multicolumn views
gain importance: for example, an email client could
display three panes containing the folders content, an
emails content and a folder structure next to one
another. Providing draggable windows is a sure-fire way
to endear such an application to its users: as of this
writing, most web-based programs lack capabilities for
the flexible positioning of their contents.
Fortunately, getting started is really easy and you can
find all the code for this Web Workshop on FileSilo.

Putting a value on time


<comment>
What our
experts think
of the site

Figuring out how much one hour of your work day is worth is relatively easy.
Performing a similar computation for spare time tends to be more involved.
Arkiverts Sparetime calculator attempts to value your free time by asking a
group of questions, which are then algorithmically parsed into a surprisingly
accurate estimate. Tam Hanna

Technique
1. Div tags
Lets get started by erecting the scafolding of our
website. It consists of three <div> tags, which are
arranged next to one another via the width and
padding-left properties. Describing the spaces with
relative values ensures that the page remains fullscreen
even if the user changes his window size.

}
function handleDragStart2( event, ui ) {
console.log( "Drag starts!" + event);
}
function handleDrag2( event, ui ) {
console.log( "Drag !" + event);
}
</script>

www.fullengineeringbook.net
4. Do some maths
2. Add a draggable handle
Ofering resizable panels is fun only if the user can
actually change their size. This is best accomplished via
two handles displayed in the middle of the borders. For
now, adding simple boxes via a <span> tag and some
CSS magic shall sufice.

The next step involves the dynamic recalculation of the


column widths as the position of the element is modified.
This is relatively easy: the elements initial location is
stored as onDragStart fires. After that, the CSS properties
are recalculated dynamically.

5. Provide a helper object


3. Add draggability
JQuery UI contains a robust drag-and-drop capability
which works better than the one found in HTML5. Our
example loads jQuery UI from the oficial CDN, and it
adds event handlers which dumps the supplied
information into the browsers debugger console.

EXPERT INSIGHT
Not for mobile
Even though our slider looks
awesome on a desktop, be aware
that it is not particularily well suited
to the needs of mobile phone users.
Most smartphones are used in
portrait mode, where horizontal
space is at a premium. Drag and
drop also requires a level of accuracy
dificult to achieve on touchscreens.

<script type="text/javascript">
$( init );
function init() {
$('#box1').draggable({
start:handleDragStart,
drag:handleDrag});
$('#box2').draggable({
start:handleDragStart2,
drag:handleDrag2});
}
function handleDragStart( event, ui ) {
console.log( "Drag starts!" + event);
}
function handleDrag( event, ui ) {
console.log( "Drag !" + event);

As of this writing, the user can move the handles up and


down. This is unsatisfactory, but can be solved by
providing a helper object, which gets dragged across the
screen in place of the original object.

6. Tilt the handles


Now transform the handles to an oblong shape in order
to give our users a visual cue that they can use them to
drag around. This is easily accomplished via a transform
order, which gets added to the stylesheet of the boxes.

<style type="text/css">
div span.myBox{
position: absolute;
top: 50%;
right:-25px;
width: 50px;
height: 50px;
background-color: lavender;
border: solid 1px silver;
transform: rotate(45deg);
}

HTML5 & CSS3 Genius Guide 153

Special effects

Sync animations to
audio and video
with Popcorn.js
Trigger events easily at any timeframe and play back music or
video by using Mozillas Popcorn.js

www.fullengineeringbook.net

154 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Once upon a time syncing up music or video


with animations, overlays or other content
could be done quite easily with Flash, but since
the demise of that plugin its become harder to achieve
this kind of efect. HTML5 has given us a great way to
natively play audio or video in the browser but its still a
hassle to try and get something to happen at a key point
in your media. Fear not though because Mozilla has
come to the rescue with their media library Popcorn.js.
This has a very simple premise to enable the developer to
code content that can be triggered at various times
during the playback of their media. If youve ever seen
interactive music videos by Arcade Fire and Rome for
example, then this is the sort of library that enables the
triggering of new scenes or animations at key points in
their music videos.
In the tutorial we are going to have a 3D scene in the
background of the page, created in WebGL with three.js.
Over the top of that will be some regular DOM content,
which will be hidden. Popcorn will be used to load audio,
play it and then trigger camera moves in the 3D content,
while also fading in with CSS transitions, with the regular
div-based content over the top.

</div>
</div>

2. Link to popcorn

5. CSS animation

Change the text inside the <h1> tag for each of those
copied sections and you can refer to the text in the
finished file or add your own. A little further down the
body section you will see a bunch of script tags for the
3D animation, add this at the bottom to link to the
Popcorn library.

Now the code adds some very simple CSS3 animation.


The hide class has been applied to all the content in the
body section of the page. A transition for the opacity is
applied, which sets the length to half a second. When
content needs to fade in, the show class can be applied
to the div and it will fade in, taking half a second to do so.

3. Add the music file


Scroll back up the page to just under the div tags from
Step 1 and add this HTML5 audio tag to link to the MP3
audio. Later on, this audio tag will be hidden on the
screen using CSS and the Popcorn.js library will link to
this so that animation can be triggered based on the
current time of the song playing.

<audio id="myAudio">
<source src="autumn-leaf.mp3" type="audio/
mpeg">
</audio>

4. Start styling
1. Up and running
Open the start project folder in Brackets or a similar code
editor and open index.html. Scroll down to the body tag
and add the following div tags for our on-screen
messages that will be shown at key points with the
music. Copy and paste this code three more times and
change the id to two, three and four.

}
audio { display:none; }

In the head tag on the page, add an opening and closing


style tag, then add the following CSS into that. Here the
body tag gets the padding and margin removed and the
right typeface is set for all content. Any content that
overflows the page will be set to hidden, as is the audio
from the previous step.

.hide {
opacity: 0;
transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-webkit-transition: opacity .5s ease-in-out;
}
.show {
opacity: 1;
}

6. Position the messages


As there will be animated 3D content using WebGL in the
background, any new content to be displayed needs to
be shown over the top of this. As such the z-index, which
is like the height, is set to be higher than the rest of the
page. This section is set to fill the browser width and
height, positioned absolutely in the top left.

www.fullengineeringbook.net
<div id="one" class="outer hide">
<div class="middle">
<h1>&ldquo;Globally, loss-related floods
have more than tripled since 1980&rdquo;</
br><small>Munich Re Insurance</small></h1>

.outer {

Familiar terminology

body {
padding:0;
margin:0;
overflow:hidden;
font-family: 'Oswald', sans-serif;
color:#ffba00;

If youve ever worked with audio or video the


term cue means to start a piece of media and
hence the code to start something happening is
also cue in Popcorn.

Left

The camera is called to start animating immediately as


the song starts playing, and you will see the 3D scene
zoom closer so that the houses are the focus of attention
Top left

The Popcorn.js library can be downloaded from Popcorn.


js.org. There are also some examples so that you can
understand how to sync events with the audio
Top right

Once the content is all added to the page, the 3D scene is


called to display after the music has finished loading

HTML5 & CSS3 Genius Guide 155

Special effects
z-index: 10;
width: 100%;
height: 100%;
position: absolute;
top: 0; left: 0;
}

7. Vertical alignment
Inside the fullscreen div of the outer created in the
previous step is another div. The text inside here should
appear in the centre of the screen horizontally and
vertically. The middle class here will ensure that happens
by aligning it on the vertical axis with the page centre.

.middle{
min-height: 100%;
min-height: 100vh;
width: 100%;
display: -webkit-flex;
display: flex;
align-items: center;
-webkit-align-items: center;
}

8. Set the headings


All of the text on the page is set with headings so here,
the CSS for that is set. Because the background has a
number of colours, there is a text shadow on the text to

help it stand out against the background. The size of the


text is also increased and centred horizontally.

h1{
font-size: 3.8em;
display: inline-block;
width: 40%;
margin: 0 auto;
text-align: center;
text-shadow: 3px 3px #000;
}

9. Wait for the audio


Before the audio is set to play, it is important to ensure
that it has fully loaded and can be played. Add the code
here to just under the existing script tags on the page.
This will load all of the scripts and content in the body
tags before calling the init function. The init function will
show the 3D background, so test that in the browser.

<script>
document.addEventListener("DOMContentLoad
ed", function () {
init();
}, false);
</script>

10. Calling the music

which was added way back in Step 3. Once the link is


established, the audio is set to play. Save the document
and try this in the web browser, the music will start to
play and the 3D scene is visible in the background.

function initMusic(){
popcorn = Popcorn( "#myAudio" );
popcorn.play();
}

12. Call the first animation


The scene needs a little movement so that the first
message can be displayed. Add the line below inside
initMusic. This is calling a function on line 111 of the scene.
js file if you want to look at it. Save this and refresh your
browser and the camera will move forward in the scene.

camMove1();

13. Cache the divs


To speed up DOM manipulation of adding and removing
classes, variables are created to hold the four div tags
that contain text. The show class will be added and
removed and this will make the appropriate message
fade in or fade out at the appropriate time. Add this code
inside the initMusic function.

var
var
var
var

one = document.getElementById( 'one'


two = document.getElementById( 'two'
three = document.getElementById( 'three'
four = document.getElementById( 'four'

);
);
);
);

www.fullengineeringbook.net

Additional plugins
There are additional plugins for Popcorn that
allow you to run video from hosted sources such
as Vimeo, YouTube and SoundCloud. Its even
possible to open Google Maps.

Top left

As the bass starts in the music, lights in the scene are


turned on and of to look like lightning flashing. Popcorn
makes it easy to sync the timing of this to the music
Top right

The camera moves forward again and the third message is


displayed to show the relevance of the background. This
move is timed to coincide with the car driving past
Right

The camera moves forward to focus on the city with the


rain animating. As it does this, the second text content is
displayed on the screen

156 HTML5 & CSS3 Genius Guide

If youve loaded the content from a local server or


webhost, the 3D scene will show, but no music is playing
just yet. Just under the init(); line in the previous step add
the next line, which will call a function to play the music.
This hasnt been created yet so dont run it in a browser.

initMusic();

11. Link and play


Before the closing script tag in Step 9, add the following
function. This links to the audio with the id of myAudio,

14. Sync to music

All of the remaining code in this tutorial is added before


the closing bracket of the initMusic function at each
subsequent step. To make something happen in time to
music, the following code is used. This calls its own
function after one second of the music playing. Test in
the browser to see the message show after one second.

HTML5 & CSS3

Genius Guide

Popcorn maker
While Popcorn is easy
enough to cue content,
with its straightforward
JavaScript API, designers
might prefer not to get
into the code and instead
create content for Popcorn
with a graphical user
interface. Mozilla has
made this possible with
Popcorn Maker (popcorn.
webmaker.org). By
loading this page in your
browser it is possible to
sync up existing content
found on YouTube,
SoundCloud and Vimeo, to
make events happen at
diferent points during the
playback of that content.
Popcorn Maker comes
with a simple timeline so
you can scrub through the
content to the section
when you want something
to happen. Adding events
lets pop-ups or other
content appear. The only
problem is that Popcorn
Maker is hosted externally
to your site.

www.fullengineeringbook.net
popcorn.cue( 1, function() {
one.classList.add('show');
});

15. Move forward


Adding the next code causes the camera to start to
move forward to the next section in the 3D scene by
calling camMove2 inside the scene.js file. The text on the
screen is made to fade out by removing the show CSS
class, and so the opacity is removed to 0 again.

popcorn.cue( 13.3, function() {


camMove2();
one.classList.remove('show');
});

16. Add the message


If you looked at the last move in the browser you will
have seen the camera move forward towards the
buildings and the rain. Now the next code will show the
text in the div with the id of two. This takes place after
almost 16 seconds. Save and test to see the efect.

popcorn.cue( 15.8, function() {


two.classList.add('show');
});

17. Lightning flashes


Just after the last message displays on the screen you
will hear two bass stabs as part of the music. Its possible
to use this with a lightning efect in the 3D scene to make
it more dramatic. Here we turn a flash of light on for just
less than half a second in time with the first bass stab.

popcorn.cue( 17.2, function() {

lightOn();
});
popcorn.cue( 17.6, function() {
lightOff();
});

18. Slight change to the colour


Lets do the same again on the second bass stab. The
code here gets the timing just right for that. There are
more bass stabs a little later and you can add more by
listening to the audio and noting the times yourself.

popcorn.cue( 18, function() {


lightOn();
});
popcorn.cue( 18.4, function() {
lightOff();
});

19. Continuing the journey


Now we wait for the song to be almost 28 seconds in to
call the camera to move again with camMove3. The
second message is faded out on the screen as the
camera moves forward. Save and refresh now.

popcorn.cue( 27.7, function() {


camMove3();
two.classList.remove('show');
});

20. The next message


Just after the camera arrives at the bridge, the next
message needs to display on the screen, so in this code
the function is called at just after 30 seconds so that the

message displays. Youll notice in the browser window


that an animation of a car drives past at this particular
point and this is no coincidence as the message is
relevant to that.

popcorn.cue( 30.2, function() {


three.classList.add('show');
});

21. Final camera movement


Once the car has driven past the screen its time to move
the camera forward again to the final destination. At just
after 40 seconds the final camera move is called, and the
third message fades out on the screen by removing the
show CSS class. The camera swings up to the mountain
for the final text to display.

popcorn.cue( 40.5, function() {


camMove4();
three.classList.remove('show');
});

22. Finish off


As the camera eases into the final position in the
background, the final text is displayed on the screen. At
43 seconds the fourth text block gets the CSS class of
show added so that it fades in, and shortly after this the
music finishes playing. Now just save and test the
document in your browser to see the full animation and
music sync up together.

popcorn.cue( 43, function() {


four.classList.add('show');
});

HTML5 & CSS3 Genius Guide 157

Special effects

Make a draggable
fading effect
As seen on tuckeffect.com/

Enticing object
As the page loads the site
is hidden away behind an
illustration. A button
beckons the user to drag
down to reveal more info.

Background
The background image is
an HTML5 Canvas Tag
that contains the
illustration, this way it can
easily be changed.

www.fullengineeringbook.net

Drag downwards
As the user drags down
the shirt starts to ride up
the torso, showing that
the shirt is actually being
lifted up.

158 HTML5 & CSS3 Genius Guide

Belting up

Finish the drag

As the shirt lifts, the belt is


revealed with a variation
of the site title. Notice
how it stands out against
the illustration.

As the drag reaches the


bottom, the shirt moves
back and tucks into the
jeans. It then fades out to
reveal the real site behind.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Fruit of the Loom have recently conducted a


survey about the way men dress and found
some fascinating results. It seems that men
who tuck their shirts in are happier, wealthier and
generally more successful all-round.
This study was done to promote the brands new
undershirt. Coincidentally this new Fruit of the Loom
undershirt is specially made so that it stays in place
tucked into clothes. Researchers and scientists have no
real idea why this is found to be true but it does provide
a great way to market a new shirt that adheres to these
new findings.

The website features an animated film to report these


findings that was created by the agency Porter &
Bogusky while the microsite that holds this was created
by Legwork Studio.
The site itself features some lovely interaction around
tucking in a shirt in order to get into the site, which has
both great illustration and animation that highlights Friut
of the Looms findings in a neat way. Once the shirt is
tucked safely away behind the belt and trousers the user
is let into the real site as the illustration fades away. An
ingenious way to tie in illustration, interaction and a
brand strategy in one easy activity!

Slide to unlock
<comment>
What our
experts think
of the site

These days almost everyone has to slide-to-unlock their phone. We thought a


take on that interaction in the playful illustration style of the campaigns
animated spots was a great opportunity to establish the tone of the site while
simultaneously reinforcing the goal: encourage tucking.
Dave Soderberg, creative director, Legwork Studio

Technique
1. Create the pull-down transition
In your HTML page add the tags as shown here. The
main part is that the container will cover the screen until
the drag element is dragged downwards, then the div
below will be revealed. This is actually just held
underneath the other content.

var end = start + 300;


window.onload = addListeners;
function addListeners(){
div.addEventListener('mousedown', mouseDown,
false);
window.addEventListener('mouseup', mouseUp,
false);
}

www.fullengineeringbook.net
<div id = "container">
<div id = "drag"></div>
</div>
<div>Your real site goes here</div>

2. Style the container


Move to the head section of the site and add some style
tags then the container CSS can be added to those. This
positions the container above the page content and
positions it absolutely to fill the screen so that the site
cannot be seen below it.

3. Such a drag
The drag element is made into a circle by adding a
border radius to it and by changing the width and height
to 150px. This is centred horizontally on the page ready
to be dragged downwards and given a light grey
background so that it can be seen.

4. Add the behaviour


EXPERT ADVICE
Clean outlines
The canvas element is able to draw
very clean lines, which looks good
but can be a little dificult to make
look unique. The Tuck Efect site
gives the lines a hand-drawn look to
avoid this and uses texture to add a
little shading to the arms and torso.

Just before the closing body tag in your document, add


script tags and then add in the JavaScript code shown
here. A reference to the elements are stored for use in
the code, then the starting and ending position are
recorded. Event listeners are added for the mouse down
and mouse up events.

var div = document.getElementById("drag");


var outer = document.
getElementById("container");
var start = div.style.top;

5. On and off
When the mouse is pressed down a mouse move
listener is registered then when it is released this listener
is removed. The idea behind this is that it keeps the
movement purely restricted to when it moves and stops
it being dragged and sticking to the mouse even when
let go, which can happen!

function mouseUp(){
window.removeEventListener('mousemove',
divMove, true);
}
function mouseDown(e){
window.addEventListener('mousemove',
divMove, true);
}

6. Tidy it up
Now the function of when the mouse moves is ran and
this really does all the work. It constrains the object to be
dragged on the y axis only and for 300 pixels. When it
reaches 300 pixels the container div is faded out using
CSS transitions.

function divMove(e){
if (e.clientY < end && e.clientY >= start){
div.style.top = e.clientY + 'px';
}
if (e.clientY >= end){
outer.classList.add("fadeOut");
} }

HTML5 & CSS3 Genius Guide 159

Special effects

Code on-scroll image


animations with CSS
As seen on bloomberg.com/graphics/2015-sepp-blatter-fifa
Content overlay

Changes on scroll

Content can be placed in


the content element in
the header. This will be
placed above the
background image.

The main content is


placed under the header
image and will become
visible as the user scrolls
down the page.

Zooming image
The main photo is placed
on the bottom layer and is
resized based on the
scroll position to give the
illusion of zooming in.

www.fullengineeringbook.net

Transparency
The overlay is a
semitransparent PNG
with the middle fully
transparent to provide
focus as it resizes.

Styled text
The main body of the
page is set to have its own
colour and styling. The
header is set to the full
body width.

160 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Whether its used just for fun or to emphasise


something serious, this sinister on-scroll efect
can be exploited in web design in order to
capture the attention of your viewers and to set the
tone for the rest of their experience. With this in mind,
there can be justified use of this efect for user
experience design as well as using it from a graphic
design perspective.
This animation efect makes use of HTML, CSS and
JavaScript. This is important because CSS alone cant be
used to detect page-scrolling events, hence these

interactions are managed with JavaScript while the


default styling settings are defined in regular CSS. Note
that for this Web Workshop we have placed both CSS
and JavaScript in separate files so that the efect can be
reused across multiple pages without any code
duplication taking place.
The CSS filter property is fairly versatile and allows for
many other options, in addition to or instead of, the
greyscale property that has been incorporated into this
particular tutorial. So heres your starting point for playing
around with the efect.

Making something look serious


<comment>
What our
experts think
of the site

The sinister effect can be used to emphasise something serious and is ideal for
use on webpages promoting a serious topic. In the case of the Bloomberg
Business website, it is used to set the tone of a Fifties gangster movie, which
have been the stage for of many stories about corruption.
Leon Brown, freelance web developer

Technique
1. Main page setup
The main page requires the standard HTML, head and
body containers to be defined. This also enables us to
insert the page components in the following steps in a
way that keeps the JavaScript and CSS separate from the
page body content.

$(window).on('scroll', header{
display: block;
position: relative;
height: 100%;
text-align: center;
overflow: hidden;
margin-top: 25%;
}
header h1{
font-size: 6em;
color: #c00;
text-shadow: 2px 2px #000
}
header img,
header .content{
position: absolute;
top: 0;
left: 0;
margin: 0 auto 0 auto;
width: 100%;}

EXPERT ADVICE
Adapting the sinister effect
Sinister features
Additional features can be added to the efect by
adding new JavaScript code within the scroll listener.
This tutorial uses the greyscale filter property as an
example of changing the image colour, but other
options are also available for experimenting.

Calculations
The calculations for the transition are made using
percentages so that it works the same in diferent
resolutions. This is important to ensure that the efect
doesnt break with high-res screens. You can test this
using the zoom-out features of your web browser to
simulate a higher resolution.

Limitations
Step 8 shows a condition that stops the overlay resizing
once its horizontal position exceeds -10 pixels. This
prevents the illusion from being broken by larger
resolutions that stops the overlay covering full width,
keeping the webpage adaptable and future-proof.

</script>

7. Initiate listening code


With the styling now complete, we are ready to add the
code to trigger changes as the page scrolls. This is
achieved by adding JavaScript code that waits for a
page-scroll event. We put this inside another listener for
the completion of the page loading to avoid an error.

www.fullengineeringbook.net

2. CSS file linking


This HTML markup will link the files that the CSS and
JavaScript code are contained in to the page so that the
styling and functionality can be shared across multiple
pages. It also enables us to keep the code clean by
separating content, styling and functionality.

3. Content containers
Insert the sinister header and the main page content
inside the page <body> tag. The sinister <header>
contains the background photo image, an overlay image
used for the zoom and a content container for the
additional text content in this case its a title.

4. Initiate page styling


Now that the HTML elements are in place, we can move
to the styles.css file to start styling the page. We start this
file with the default styling of the main page mainly the
page background and the <main> content container,
which we want to use to ensure that the content is
centred and has readable text.

5. Sinister styling
The headers styling needs to stretch across the page
and have a visible height. It will also need to hide any
overflow from the zooming images we are using. Images
and the content container will be posited at the top left of
the <head>, which is made possible with the header using
relative positioning.

6. Style individual images


Two images are used in our layout: the main photo
image and the sinister zoom overlay. Weve avoided
over-complicating the HTML with class name and are
using their position in the <header> container to define
positioning styles.

$( "#header" ).click(function() {
if (menuOn == false){
$('#menu').animate({"bottom": -100}, 500 );
menuOn = true;
} else {
$('#menu').animate({"bottom": "-100%"}, 500
);
menuOn = false;
}
});
});

8. Activate image zooming


The sinister efect is primarily made from two animations
the main picture made bigger and the overlay made
smaller to focus its inverted transparent circle around the
image. We use a query selector to target the images to
apply sizing and positioning calculations based on the
scroll position.

//-- PUT THIS INSIDE THE SCROLL LISTENER


document.querySelector("header img").style.
width = (100+(window.scrollY/20))+"%";
document.querySelector("header img").style.
left = (0-(window.scrollY/50))+"%";
if(-200+(window.scrollY/3) < -10){
document.querySelector("header img:nthchild(2)").style.width = (500-(window.
scrollY/1.5))+"%";
document.querySelector("header img:nthchild(2)").style.left = (-200+(window.
scrollY/3))+"%";
}
if(-180+(window.scrollY/3.5) < -20)document.
querySelector("header img:nth-child(2)").
style.top = (-180+(window.scrollY/3.5))+"%";

9. More sinister colouring


The main photo can change from full colour to black and
white as the efect takes place by using the scroll position
to afect the greyscale property. For the full code on this
tutorial, make sure that you check our FileSilo site.

HTML5 & CSS3 Genius Guide 161

Special effects

Add slide-up titles on


page load using CSS
As seen on onedollarlesson.com

Sobering statistics
The animations deliver
some frightening stats
about the levels of
cybercrime targeting
users bank details.

www.fullengineeringbook.net

Well-laid out menu

The menu is neatly tucked


away to the left. As the
user scrolls the menu
stretches to indicate
position on page.

Claim your prize


Complete all three of the
lessons to access a free
three-month Kaspersky
security trial. A very
useful prize.

162 HTML5 & CSS3 Genius Guide

Hidden animations

On page load

Scrolling past the first


screen will reveal some
beautifully crafted
animations. These unfold
as the users scrolls down.

Once the initial load


animation (featuring a
dollar) is done, the title
elements begin their
step-by-step animation.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

So youre looking for a good way to engage


your website users from the moment the
homepage loads. Grabbing the diminishing
attention spans of web users is an on-going battle for
developers. There are all sorts of options, from autoplay
videos to pop-ups which demand user interaction.
Sometimes, though, you can keep the users attention for
those first few vital seconds with a simple animation.
Nothing too over the top, just a little something that
keeps them watching.
How about an animation that delivers the site title in
steps, over a short period of time?

Internet security company Kaspersky have put


together this wonderful-looking microsite, designed to
educate users on the dangers of online payments and
the many related cyber attacks that users can fall prey to.
Featuring some great scroll-activated animations and
fullscreen videos (worth checking out for the transportbased demonstrations of Trojans and the like), One Dollar
Lesson opens with a perfect example of the efect we
are going to re-create in this workshop. Once the
homepage background has loaded, the site title and the
Kaspersky logo ease into view, one at a time. Simple
efect, but one that keeps you watching.

Make the wait interesting


<comment>
What our
experts think
of the site

These days its a brave website that asks the user to sit through a contentloading percentage bar, however short the wait. The desire for instant content
is relentless. If this is unavoidable you better make sure your loading icons are
interesting and different enough to hold users fast.
Richard Lamb, owner and web designer at Inspired Lamb Design

Technique
1. Background image

Num Num!. Place one apiece into the four yums. Then
give each of div an individual class name, corresponding
to the image names.

The first step for our food-related example is to put in


place the fullscreen background image. Weve selected
an image which places content focus on the left, so that
we can place our animated content on the right. Ensure
that you include your vendor prefixes.

Well concentrate on writing the keyframes which will


animate our title. First, set animation durations specific to
each of our individual divs.

5. Individual animation times

www.fullengineeringbook.net
2. The base HTML
Create an intro div that will sit on the left side of the
canvas (using Bootstrap CSS makes it simpler). Within this
we need four title divs, each containing a div class were
calling yum. The yum classes will contain the animations.

<div class="intro col-md-3 col-md-push-8">


<div class="title">
<div class="yum"></div>
</div>
<div class="title">
<div class="yum"></div>
</div>
<div class="title">
<div class="yum"></div>
</div>
<div class="title">
<div class="yum"></div>
</div>
</div>

EXPERT ADVICE
Content delivery
Packaging important information
into an entertaining, easily
consumable format has become one
of the primary challenges for
websites, especially when delivering
information that has not necessarily
been sought out. One Dollar Lesson
employs just the right mix of
interaction and spectacle.

3. The initial CSS


The intro div should be given some slight padding at the
top. The title div needs to assign an overflow:hidden
property. We need the child elements invisible until they
reach the confines of their parent. Well call this rise.

4. Insert the title images


Create four PNG images for the three words and an
underline, of equal width, which make up our title, Um

.um {
animation-duration:
}
.num-one {
animation-duration:
}
.num-two {
animation-duration:
}
.underline {
animation-duration:
}

2s;

4s;

6s;

7s;

6. Write the keyframes


The keyframes re-creates the efect from our inspiration
site causing the four title elements to slide up from the
bottom, with a slight bounce on arrival.

@keyframes rise {
0%, 60%, 75%, 90%, 100% {
transition-timing-function: cubicbezier(0.215, 0.610, 0.355, 1.000);
}
0% {opacity: 0; transform: translate3d(0,
3000px, 0);}
60% {opacity: 1; transform: translate3d(0,
-20px, 0);}
75% {transform: translate3d(0, 10px, 0);}
90% {transform: translate3d(0, -5px, 0);}
100% {transform: translate3d(0, 0, 0);}
}

HTML5 & CSS3 Genius Guide 163

Special effects

Animate typography
and text effects
Give your typography the attention it deserves with these
must-see animated effects with CSS3

www.fullengineeringbook.net

164 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

One of the biggest evolutions with CSS3 has


been the ability to write behaviours for
transitions and animations. These animated
efects are a must-know for any designer or front-end
developer as they unlock all kinds of interactive
possibilities and visual feedback options.
In this tutorial the focus is on text with three diferent
efects that ofer some great possibilities. The first actually
will not use standard text on the page, but will instead
create the text inside an SVG element. The reason for this
is that SVG enables strokes on text which is not possible
to do with regular HTML text, and sometimes you may
just need strokes with text. Using the SVG right in your
HTML will keep your text accessible and will stop you
having to rely on GIFs. Once the stroke is in place, it will be
given five diferent colours and set to march around the
text with animation. The next text efect shows how to
make a text rotator so that diferent words can be cycled
through on the screen. The final efect will use text clip to
clip the image to the text so that the image only shows
inside the text. This will be turned into a call-to-action
button with a sliding image efect.

1. Set up the document


Open the project folder in Brackets or a similar code
editor and then open start.html. Create style tags in the
head section and add the CSS shown. This will import the
right typeface that will be used from Google and sets up
the basic HTML settings for the pages.

background: #35483e;
background-image: url(img/bg.jpg);
background-size: cover;
font-family: Arial;
}

4. Add the CSS for the SVG


Move back to the CSS section of the page and add the
rule for the SVG. This will display the object as a block
element so that it can be centred on the page with the
margin set to auto. The font for this element is set to
Oswald and a large text size.

2. Write an SVG graphic


As SVG graphics are written with tags they can be easily
authored without any graphics application. Move to the
body tag and add the start of this SVG graphic, which
creates text to display in the browser. Later this will get
styling from the CSS that will animate this.

<svg viewBox="0 0 960 300">


<symbol id="s-text">
<text text-anchor="middle" x="50%"
y="80%">Kinetic Design</text>
</symbol>

3. Create graphic lines


The next code that is added finishes of the SVG, more
importantly though it creates five graphics nodes that
will be styled using CSS to create five diferent coloured
strokes. These target the text that was created in Step 2.

<g class="g-ants">
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
</g>
</svg>

class="text-

5. Style specific text


Now the CSS is targeting the specifics of the text and the
fill is turned of while a white stroke is added to the text.
The stroke isnt applied all the way around the text by
using the dash array. The stroke is widened and told to
take five seconds to apply the animation.

6. Start the animation


By adding keyframes the stroke will immediately start
animating around the edge of the text. Now each
graphic element is given colour and a slight delay in its
movement to create the basis for the rotating stroke
around the outside. At present there are orange and dark
red strokes.

@keyframes stroke-offset {
100% { stroke-dashoffset: -35%;}
}
.text-copy:nth-child(1) {
stroke: #5c0404;
animation-delay: -1s;

www.fullengineeringbook.net
@import url(http://fonts.googleapis.com/
css?family=Oswald:400,700);
html, body {
height: 100%;
font-weight: 800;
}
body {

class="textclass="text-

CSS keyframes

class="text-

The CSS keyframes rule enables the designer to


specify either from or to values, or alternatively
it enables them to use a percentage that states
what should happen.

class="text-

Left

The next text elements are added to the HTML and given
some basic styling for us to place the text under the
animated heading
Top left

The SVG element is added to the page, and basic CSS


styling places this in the correct position on the page
Top right

The fill colour is removed and a stroke is added that is not


shown all around the edge of the text elements, which is
still an interesting look

HTML5 & CSS3 Genius Guide 165

Special effects
}
.text-copy:nth-child(2) {
stroke: #d6801c;
animation-delay: -2s;
}

7. Finish the stroke


As in the previous step, the CSS here is targeting the
diferent children of the graphics object and they are
given diferent colours and ofset in their own animation.
This now gives the efect of five diferent colours
marching around the edge of the text.

.text-copy:nth-child(4) {
stroke: #ffff9e;
animation-delay: -4s;
}
.text-copy:nth-child(5) {
stroke: #55981b;
animation-delay: -5s;
}
@keyframes stroke-offset {
100% { stroke-dashoffset: -35%;}
}

8. Second effect
That completes the first efect that is being added to text,
so now move down to the body tag and add our code
from FileSilo to the SVG added earlier. This readies the

setup of a text rotator that will move through the


diferent list elements with animation, great for showing
of a range of skills.

9. Style up the text


With the next content in place, move back to the CSS
style tags and our code on FileSilo places the text in the
centre of the page under the animated heading created
earlier. At the moment this still looks like a list, but that will
all change as more CSS is added to complete the efect.

10. Static section


The text is made to float left, where one half of the text is
static, ie not moving, hence the name of the class that is
controlling it here. Once floated to the left, the overflow is
hidden. The height is set up so that only one line of the
moving section can be seen.

.static {
float: left;
overflow: hidden;
height: 40px;
}

12. Set the unordered list


Now with this rule targeting the unordered list, you will
notice that the text for the first element is sitting
alongside the static text. The other list elements are
below this but because the overflow is cut, it isnt being
displayed until the animation is added.

ul {
margin-top: 0;
padding-left: 130px;
text-align: left;
list-style: none;
animation: 6s linear 0s normal none infinite
change;
}

13. Size up the height


Styling up the list elements applies the right colour for
these elements and more importantly sets the line
height so that the text moves to the right section and
can only see that section at any one given time. If the
line height was smaller it might be possible to see parts
of the other text on the screen.

11. Paragraph style

14. Make it move

The paragraph tag is targeted and given a light yellow


colour that has also been used in one of the strokes
around the edge of the previous text, just to keep
consistency with the colours. Again this text is floated to
the left so that the list can sit alongside it.

The final setup for the CSS part is to make it move by


defining the keyframes called change. Step 12 calls for
these keyframes and adding these will immediately start
the text rotator sliding up and down to show the text.
Because the animation was set to infinite, this will just
keep looping.

www.fullengineeringbook.net

Naming keyframes
Notice that the keyframes in Steps 14 and 6 have
been given a unique name so that they can be
called by the right piece of animation.

Top left

Keyframes are added to the animation and each list


element is cycled through by sliding down to the next
and back up again. The text is now about to slide up
Top right

A more button is being styled up and the background


image is only visible through the text. The image will
animate when the user rolls over
Right

At this stage this image rollover is working. The colour is


different from the previous step, but it needs to stand out
and look more like a call-to-action button

166 HTML5 & CSS3 Genius Guide

p {
display: inline;
float: left;
margin: 0;
color:
#ffff9e;
}

@keyframes change {
0% { margin-top: 0; }
15% { margin-top: 0; }
25% { margin-top: -40px; }
40% { margin-top: -40px; }
50% { margin-top: -80px; }

HTML5 & CSS3

Genius Guide

CSS animation
To take advantage of the
CSS animation, instead of
relying on JavaScript, it is
important to understand
exactly what is going on.
Transitions provide a
change from one state to
another, while animations
can set multiple keyframes
of transition.
Transitions must have a
change in state, and you
can do this with :hover,
:focus, :active and :target
pseudo-classes. The most
popular is hover as this
provides rollover changes.
There are four transition
related uses, transitionproperty, transitionduration, transition-timingfunction and
transition-delay.
Animations set multiple
keyframes that tell an
element what change they
should undergo with @
keyframes and called by
the animation using it.
Only individual properties
may be animated.

www.fullengineeringbook.net
65% { margin-top: -80px; }
75% { margin-top: -40px; }
85% { margin-top: -40px; }
100% { margin-top: 0; } }

font-size: 3em;
font-family: 'Oswald';
text-align: center;
position: relative;
display: block;

15. Call to action


That completes the second animation that we are
exploring. Now its time to add the final animation, which
will be for an animated rollover button, using a newer
CSS command: clip text. In the body add the HTML from
FileSilo below the other content that is on the page.

16. Centre the box


The first part of this is simply to centre the box and for us
to clear the floated elements in the content above. This
box is going to be quite small on the screen so it is being
made to be 400 pixels wide. The auto margin centres
the div box on the screen.

.wrapper{
clear:both;
width: 400px;
margin: 0.5em auto;}

17. Start the clipping


The next rule will set up the clipping of the text. Firstly
the right typeface is applied to this and the type is given
quite a prominent size of 3ems. The text is centred with
the block and some margin and padding sets this up
nicely on the screen.

.clip-text{
margin-top: 4em;
padding: 0.3em;

18. Apply the image


Now for the real nuts and bolts of the process. Here the
clip-text rule is continued and the background image is
set to display, however instead of it being in the
background like normal, the text is set to clip it. This
means that the background only appears inside the text.

background-image: url(img/text-bg.jpg);
background-position: bottom;
background-size: cover;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition: 2s ease all;
}

19. Rollover effect


Adding the code here will set the rollover for the text and
the background image. The image will be set to be
positioned at the top in the background. Previously it was
set to the bottom so the text will have the image slide
through the text as the user rolls over it with the mouse.

.clip-text:hover, .clip-text:hover::before {
background-position:top;
} .clip-text:before, .clip-text:after {
position: absolute;
content: '';
}

20. Create a border

This code is the first step in creating a border around the


text. This is achieved by placing the image behind the
text. The downside at this point is that the text is invisible
as the image is there. The final step will correct this.

.clip-text:before {
z-index: -2;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: inherit;
background-position: bottom;
background-size: cover;
transition: 2s ease all;
}

21. Clip the image


The final part is to place a semitransparent background
colour behind the text and to give this a slightly smaller
size than the box. The result is that the text and border
now both clip the image so that it is only visible where
they are. Save this now and test it in the browser.

.clip-text:after {
position: absolute;
z-index: -1;
top: .125em;
right: .125em;
bottom: .125em;
left: .125em;
background-color: rgba(214, 128, 28, 0.9);
}

HTML5 & CSS3 Genius Guide 167

Special effects

Create a 3D navigation
menu with HTML
Learn how to use 3D page elements to reveal content on hover

www.fullengineeringbook.net

168 HTML5 & CSS3 Genius Guide

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

The amount of space available for websites to


make use of can often be pretty limited,
especially when the website is being viewed on
a small screen. With the diferent information
components in your design competing for screen space,
it is important to make sure that you give each element
the most appropriate placement in the design of the
page or the screen.
A more recent addition to the CSS specification is the
use of 3D elements. We are all familiar with the default 2D
presentation of webpage elements, in which we can
position them on the page by using their horizontal and
vertical coordinates; the 3D presentation features takes
this one step further by allowing elements to be
presented with depth perspective, which can then be
used for rotation and making the elements appear
further into the distance.
This tutorial will look at how the use of 3D presentation
can be used to the advantage of user experience design
of websites and web apps by allowing additional
information to be expanded from the same space
without the need to scroll or load a new page. Our
example uses 3D page elements that will allow users to
hover or tap to access additional information and
navigation links similar to how game cards are
presented. To keep this tutorial uncluttered, we will avoid
using browser vendor tags such as -webkit. If you require
compatibility with older versions of Safari and Firefox,
simply add these for CSS commands such as transform,
perspective and backface-visibility.

<html>
<head>
<title>3D Card Navigation</title>
** Step 2 goes here
</head>
<body>
** Step 3 goes here
</body>
</html>

2. Load resources
The <head> section of your HTML is used to contain links
to resources you are using. Our example will contain a
CSS file for styling and a JavaScript file for detecting
when the user taps on the navigation cards.

<link rel="stylesheet" type="text/css"


href="styles.css" />
<script src="code.js"></script>

3. Card container
The easiest way to ensure consistency and simplicity to
control all elements of the 3D navigation card is to place
them inside a container. Two types of container are used
the main container will control the origin for 3D rotation
while the card container will contain the content
elements that will display relative to the card.

container having their content placed within them. The


front card will have a style added to the main element
that sets the background image to use.

<div class="front" style="backgroundimage:url(img/burger.jpg)">


<h3>Burger</h3>
</div>

5. Back content
This element will appear when the card is flipped. Like
the front element, it is a container for any content that is
to appear at the back. Using a container like this allows
CSS to rotate everything from the same place.

<div class="back">
*** Step 6 here
</div>

6. Content inside
The content to be placed inside the front and back is just
regular HTML. We will add some text descriptions and
navigation links to the back content container inside the
card. Upon completion of this step, you can now repeat
Steps 3 to 6 to add new navigation cards.

<h3>A Tasty Burger</h3>


<p>This is a tasty burger served with
cheese, tomato and lettuce.</p>
<nav>

www.fullengineeringbook.net

1. Initiate HTML page


As with any webpage, there is a requirement to define the
pages HTML, head and body structure. Use the head
section to contain any meta data such as the page title
for SEO and accessibility that you may need.

<div class="container">
<div class="card">
** Step 4 goes here
** Step 5 goes here
</div>
</div>

Better use of space


Using 3D elements for user experience design
can allow you to include more information in
limited space without disorienting the user by
taking them to a diferent part of the page.

4. Front content
The card will have two sides we place a container for
each of these inside the card container, with each

Left

The full HTML content is now ready for styling with CSS
and interaction listeners via JavaScript to be applied
Top left

Here, the basic page and element styling in place, with


front of card elements showing by default
Top right

Presentation of how one of the cards look when it has


been flipped to reveal the reverse side content

HTML5 & CSS3 Genius Guide 169

Special effects
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
</nav>

display: inline-block;
transform: rotateY(0deg);
perspective: 500px;
margin: 2em;
}

position: relative;
display: block;
transition: 1s;
transform-style: preserve-3d;
}

7. CSS initiation
With all of your HTML set up, the next step is to initiate
the CSS. The page is already expecting to load a file
called styles.css, so create this file and add the following
initial CSS for the standard page styling:

var img = $(document.createElement("img"));


$(img).attr({
"src":this.url,
"data-index":count,
"title":this.title,
"alt":this.description
});
//.. code from next step goes here

8. Container definition
The first of the containers is used to set the foundations
from which any 3D calculations are performed from. This
includes setting the position, display mode, initial rotation,
margin and also view perspective ie distance from the
viewer. We use a display of inline-block to allow multiple
cards to be placed next to each other.

9. Container interactions

12. Front and back containers

Interactions will be triggered whether either a :hover is


detected on the main container or a hover class has
been applied to the container. The reaction to these will
be a transformation that rotates the inner contents by
180 degrees around the y axis.

The front and back containers will be used to contain


content that are to be shown specifically when the front
or backside of the card is visible. We need to make sure
that the backside of these elements are not visible when
they are in reverse. We also need to position them at the
top left of the card.

.container:hover .card,
.container.hover .card{
transform: rotateY(180deg);
}

10. Set card size


We can set the size of the navigation card by setting the
size of the foundation container and the inner content
containers. We used pixel-based measurements but you
can experiment with percentages.

.container,
.front,
.back{
width: 300px;
height: 500px;
}

.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}

13. Content box sizing


In addition to the previous content container settings, we
also want to ensure that any future padding or border
additions dont make their sizing out of sync with what
weve already set up. We can achieve this by telling them
to include padding and border size as part of their width
and height settings.

www.fullengineeringbook.net

.container {

11. Card container

Different effects
Other efects can be achieved with 3D rotation by
changing settings such as the transform-origin
and perspective. Add and change these values to
see what efects you can produce.

The next container to define rules for is the card


container, which is used to activate 3D transformation
rules, animation transition time and also to set
positioning to relative so that any absolute positioning is
relative to the card and not the main screen.

.card{

Top left

Navigation elements change colour when the mouse


pointer is placed over them a way to indicate that they
can be clicked on
Top right

Elements appearing with 3D rotation applied to them. No


fancy calculation code just CSS formatting
Right

Card elements rotated with selected card showing full


reverse with navigation and content

170 HTML5 & CSS3 Genius Guide

.front, .back {
box-sizing: border-box;
}

14. Front image settings


The front of the card will have its background image set
to cover the full size of the element. It will also need to
guarantee its placement on top of the back element,
hence why a z-index is set to 2. An initial rotation of 0

HTML5 & CSS3

Genius Guide

Use of space
Our example shows how
3D cards can be used to
present basic text content
and navigation links, but
the concept could be used
for more than just these
types of content. Other
content that cards can be
used to reveal include
video, charts, and
interactive applications.
Links can also be used to
activate the presentation
of a light box, allowing you
to make your website
more convenient for any
features where users will
not want to leave your
webpage when accessing
information from links,
preventing any early exits.
BBC News is an example
of a news website that
contains a lot of
information, making it
dificult for users to
identify whether they want
to read further without
loading a new page not
good for users on mobile
data plans.

www.fullengineeringbook.net

degrees is also set for displaying content right at


the front.

.front {
z-index: 2;
transform: rotateY(0deg);
background-size: cover;
}

15. Front title


The front of the card makes use of a <h3> title tag to
present the introduction title of the card. The title will
have a semitransparent black background with white
text. We want to make sure that the styling for this is
specific to <h3> tags inside of the front class.

.front h3{
background: rgba(0,0,0,0.5);
color: #fff;
text-align: center;
padding: .5em;
}

16. Back card


The presentation of the back of the card will have a plain
grey colour background and will require some padding
to ensure that there is some spacing between text and
the edges of the card. The element will need to be
initially rotated by 180 degrees.

.back {
padding: 1em;
transform: rotateY(180deg);
background: #eee;
}

17. Navigation container

The navigation links of each card are placed inside a


<nav> container. This means we can apply styling to their
container in this case to set the font size, padding and
the display mode to ensure that links appear separate to
the main content.

nav{
display: block;
padding: 2em;
margin: 0;
}

18. Navigation links


Navigation links will appear in darker grey boxes with
white text. Each element will use padding to make the
boxes appear more prominent and margin to make
them appear separate to each other.

nav a{
display: block;
list-style: none;
background: #aaa;
color: #fff;
font-size: 1.5em;
margin-top: .5em;
padding: .5em;
text-align: center;
}

19. Navigation hover


Changing the colour of navigation options that are being
hovered over is a really good way to indicate to the user
that the item is an option that is available to be selected.

Clicking on this item will cause the user to navigate away


to a new page. This efect is achieved by using the :hover
property on the navigation item.

nav a:hover{
background: #333;
}

20. JavaScript get cards


We now need to add some JavaScript to activate
detection of taps on the cards when used on mobile
devices. Create a file called code.js and add the following
code to fetch all elements with a class name of container
when the page loads:

window.addEventListener("load", function(){
var containers = document.
querySelectorAll(".container");
** Step 21 code here
});

21. Touch start listener


With JavaScript now having all of the container elements,
it can now loop through each of the elements and apply
a listener for each time one of these elements are
touched. Our code will toggle the addition or removal of
a hover class of which the presentation rules were
defined in Step 9.

for(var i=0; i<containers.length; i++){


containers[i].addEventListener("touchstart",
function(){
this.classList.toggle('hover');
})
}

HTML5 & CSS3 Genius Guide 171

Special effects

Make a screen
shrink on scroll
As seen on devstars.com

Hidden menu
The regular menu is
hidden behind the burger
menu and sits over the
entire page on the screen
when activated.

Resizing sections
Clicking the dots (right)
automatically scrolls the
page down to the next
section, this fits the
browser window exactly.

www.fullengineeringbook.net

Shrinking images
The graphical content on
the screen animates
down in size, giving a
pleasing shrink effect as
the page scrolls upwards.

172 HTML5 & CSS3 Genius Guide

Reverse in size

Varied navigation

Returning back through


the navigation dots
causes the page to slide
back up and the graphic
content to expand in size.

The homepage combines


a one-page style site and
a slide show. The scrollbar
is hidden but navigation
dots are still visible.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

As a web design and development agency its


very important that you can show of what
your skills are; if you can combine samples of
your work into an innovative presentation on your site
then thats even better. Thats exactly what Devstars
have done on their site. Devstars.com is a full multipage
site but use the one-page style website idea for the
homepage to show of exactly what they do. The sites
homepage has a number of navigation dots that you
immediately associate with a slideshow and these
contain the latest work oferings, while giving an
overview of the company. The little animation touches as

the user slides down are the neat show-of points in this
site. Each browser-sized screen on the homepage is like a
diferent slide in a slide show, but you click the navigation
dots on the right-hand side to move down rather than
right to left. The scrollbar is hidden away so this nifty
navigation is a great way to explore the screens that
follow. As you slide down to the next section, the graphic
content on the screen animates, shrinking down in size
and moving of the top of the page. The real menu is
hidden behind the burger icon so what this presents is
an unusual slideshow of important content that Devstars
wants users to see.

Making your work the star


<comment>
What our
experts think
of the site

Bright bold colours make this site stand out with just enough negative space to
make the logo and site content stand out. The homepages featured content
has an animated effect that draws attention to the care the team put into the
small details of their site.
Mark Shufflebottom, professor of Interaction Design, Sheridan College

Technique
1. Create the shrinking logo effect
When making this efect work, the logo needs to be
placed within a page. As there is no page content here,
some div tags are being added, which will have 600
pixels of height added to them. When the image reaches
the top of the page, it will be shrunk down.

3. Finish the style


The image with the ID of shrink will be scaled down
when it hits the top of the page this shrink will then be
detected through jQuery code later. The image is
displayed as a block element to enable the centring of
the image horizontally.

www.fullengineeringbook.net
<div
<img
png"
<div
<div

class="space"></div>
id="shrink" src="img/Wikimedia-logo.
/>
class="space"></div>
class="space"></div>

#shrink{
display: block;
margin: 0 auto;
}
</style>

4. Detect the position


Just before the closing body tag, the script tag is added
along with any of the code that follows. This script tag will
check how far down the page the document has actually
scrolled. From there the topDistance variable grabs the
position of the image in relation to the top.

<script >
$(function () {
$(window).on('scroll', function() {
var scrollTop = $(this).scrollTop();
var topDistance = $('#shrink').offset().top;

5. Start the shrink


2. Add the library

EXPERT ADVICE
Reinforcing the brand
A logo can say a lot about any
company and Devstars logo features
a series of stars laid out horizontally.
For their showcase content, Devstars
uses the shape of the logo as a mask
for images of work that theyve
produced. This not only looks good
but also reinforces the brand in the
homepage design.

In the head section of the page, the script tag calls the
jQuery library so that we can detect the position of the
page and make DOM changes based on that. The CSS
styling gives the space class a height of 600 pixels, as
the comment states this is purely for demonstration only.

<script type="text/javascript" src="js/


jquery.js"></script>
<style>
.space{
height:600px;
/*Purely Demonstration Purposes*/
}

When the image is within the space of the top of the


page, the shrink image is animated down to 0 on the
width and height over half a second. Now go ahead and
save the page, then you can test the efect in the browser
to see the efect in action as you scroll the image to the
top of the page.

if ( topDistance < scrollTop ) {


$('#shrink').animate({"width": 0, "height":
0}, 500 );
}
});
});
</script>

HTML5 & CSS3 Genius Guide 173

Special effects

Create scrolling text


with colour change
As seen on deuxhuithuit.com/en/

Intro
The site opens with a
striking piece of animated
text, set against an
eye-catching colourchanging background.

Beyond home
Try the Projects page out
to see some clever
scrolling techniques, with
slower scrolling in the
centre column.

www.fullengineeringbook.net

Portfolio section
A little further down you
will find, in bold black and
white, a Current Projects
section with nice hover
effects and links.

174 HTML5 & CSS3 Genius Guide

The scrolling text

Site Overview

Scroll down to find


another (and simpler)
version of the scrolling
text animation, we are
emulating in this tutorial.

The Deux Huit Huit site


combines carefullythought-out parallax
effects, CSS animations
and subtle hover effects.

DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887

HTML5 & CSS3

Genius Guide

Web design agencies building their own


showcase websites must always manage the
balance between building a website which will
impress and engage potential clients, while also
building a website that will impress other web
designers. French Canadian digital agency Deux Huit
Huit have put together a website that is simple and
unfussy, but designed to have enough fireworks to
dazzle browsing clientele without leaving them
completely intimidated. Among the bells and whistles on
ofer are some neat parallax efects, particularly on the
Projects page, and a few sections that burst into life with

colour-changing backgrounds. Probably the most


impressive efect that Deux Huit Huit utilise is found
directly after the intro message on the homepage. Set
over a monotone image of Chteau Frontenac (or a
model of it, anyway) are the scrolling words Featured
Project, continuously moving across the screen in
ticker-tape style.
What is most striking is how the words appear to
change from dark grey to white as they hit the boundary
of the image and then back again as they leave it. So,
how is this efect achieved? As ever, we learn by doing.
Lets re-create the scrolling text with colour change.

Stop trying to impress your peers


<comment>
What our
experts think
of the site

As mentioned in the intro, web designers can make the mistake of building
their websites with too much of an eye on impressing other web designers,
rather than luring in potential clients. Its an easy trap to fall into, leaving you
with a website that is inscrutable to the layman and useless as a marketing tool.
Richard Lamb, freelance web designer at Inspired Lamb Design

Technique
1. First layer
The efect is achieved with a series of layers arranged
over each other. We build our layers from back to front,
beginning the first set of text. To ensure that the text
flows on one line, spaces should be coded using &nbsp
and two sets of text per layer should be used.

bsp;Our&nbsp;Words</span>&nbsp;
<span class="scrText light">These&nbsp;Are&n
bsp;Our&nbsp;Words</span>&nbsp;
</span>

EXPERT ADVICE
Sleight of hand
This particular Web Workshop is a great example of
using CSS trickery to create the impression of
something happening which actually isnt. While it may
appear that a single line of scrolling text is changing
colour, in fact there are two lines of scrolling text, one
on top of the other, strategically set to appear and
disappear at concurrent points. It is actually a very
clever piece of trickery when you think it through and
understand the method. And it raises an interesting
point about how we should approach CSS animations
and efects.
Sometimes you dont have to figure out how to
make a particular HTML efect or animation work.
Sometimes you are better of figuring out how to
simply make it look like its working. Sure, an element
scrolling into frame on page-load is actually scrolling
into frame. Thats a simple efect to achieve. But if you
are striving to create an efect that is more complex,
dont rule out the possibility of trying diferent
techniques that create the illusion of the efect, rather
than the efect itself. Its not cheating to use a little
trickery, the efect is just as good and it may just make
your work a little simpler.

box-sizing:border-box;
}
.scroll-image {
position: relative;
z-index: 10;
}

www.fullengineeringbook.net
<div id="wrapper">
<span class="scroller">
<span class="scrText dark">These&nbsp;Are&nb
sp;Our&nbsp;Words</span>&nbsp;
<span class="scrText dark">These&nbsp;Are&nb
sp;Our&nbsp;Words</span>&nbsp;
</span>
</div>

2. Second layer
Below the above code, but within the wrapper, add the
following divs and the image which will interact with the
text. While it may seem like we are using a few
superfluous divs, the CSS applied to each, with z-indexes
and positioning, will hold the entire construct together.

<div class="scroll-container">
<div class="scroll-image">
<div class="overflow-hidden relative">
<img src="img/bg.jpg"/>
</div><!--overflow-hidden-->
</div><!--scroll-image-->
</div><!--scroll-container-->

3. Third layer
The third layer represents the second set of text, which
will scroll above the image. This should be placed below
the image, within the three divs applied in the previous
step. This should have a unique identifier, front.

<span class="scroller front">


<span class="scrText light">These&nbsp;Are&n

4. First layer CSS

The initial CSS here sets the vital hidden overflow for the
wrapper, so the text does not break the boundaries of
the screen space. Absolute positioning for the scroller
builds the base for our construct. The animation
keyframes will follow.

5. Animation keyframes
Set your animation keyframes for a smooth transition
across the screen, creating an endless loop for the
scrolling text. Remember to include all vendor prefixes
for browser variations, including on the animation
declaration in the scroller div.

@keyframes scroll-left {
0% {
transform: translate(0, -50%)
}
100% {
transform: translate(-50%, -50%)
}
}

6. Second layer CSS


Use padding to set the boundaries of the container
which will hold both the image and the front text. Using
the relative rem measurements will allow us to easily
match subsequent values on the front scroller later on.
The scroll-image div is given a z-index value to keep it
behind the front text.

.scroll-container {
padding-left:8rem;
padding-right:8rem;
width:100%;

7. Second layer CSS (cont)

The image itself should be given a 100% width value to


keep it from breaking its boundary. The overflow-hidden
relative div, with its self-explanatory values, can easily be
combined into one class, if need be. The hidden overflow
keeps the white text within the confines of the image.

.scroll-image img {
width:100%;
height:auto;
}
.overflow-hidden {
overflow:hidden;
}
.relative
{
position:relative;
}

8. Third layer CSS


The final layer, containing the front set of scrolling text, is
assigned the following values, not applied to the initial
text layer. A z-index to keep it at the front and a left value
that mirrors the padding of the image container, bring
the text in line with that in the first layer.

9. Text colours
Finally we have come to the last step. Assign colours to
the dark and light classes, so that each layer of text has
the colour diferences which create the illusion of a single
layer changing colour. A little piece of HTML sleight of
hand has been pulled of.

HTML5 & CSS3 Genius Guide 175

tr Spe
ia c
l o ia
ffe l
r

Enjoyed
this book?

Exclusive offer for new


www.fullengineeringbook.net

Try
3 issues
for just

* This offer entitles new UK Direct Debit subscribers to receive their first 3 issues for 5. After these issues, subscribers will then pay
25.15 every 6 issues. Subscribers can cancel this subscription at any time. New subscriptions will start from the next available issue.
Offer code ZGGZINE must be quoted to receive this special subscription price. Direct Debit Guarantee available on request.
This offer will expire on 28 February 2017.
** 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. This offer expires on 28 February 2017

Uncover the
secrets of
web design

Practical projects

About
the
mag

Every issue is packed with step-by-step tutorials


for Flash, Dreamweaver, 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
www.fullengineeringbook.net
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 ZGGZINE+

Or telephone: UK 0844 848 8413 Overseas +44 (0) 1795 592 878
* Calls will cost 7p per minute plus your telephone companys access charge

HOW TO USE
LOG IN TO FILESILO.CO.UK/BKS-887 AND
DOWNLOAD YOUR GREAT RESOURCES NOW!

To access FileSilo, please visit filesilo.co.uk/bks-887

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.

www.fullengineeringbook.net

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

www.fullengineeringbook.net

A comprehensive masterclass
in becoming an instant expert

The professional guide


to programming for web
design and development

Tools & Techniques


www.fullengineeringbook.net
Everything from the best HTML
tools to responsive images

Front-end
Master your content, embellish
basic elements and more

Developer
Host your site free with GitHub
and master plugins

Special Effects
Learn to animate, add fun effects
and transform type

Free download
All the essential assets
to help you master
HTML & CSS

You might also like