Você está na página 1de 180

NEW FREE RESOURCES

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 isn’t 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

www.fullengineeringbook.net
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
HTML5 Imagine Publishing Ltd
CSS3
Richmond House
33 Richmond Hill
Bournemouth
Dorset BH2 6EZ
 +44 (0) 1202 586200
Website: www.imagine-publishing.co.uk

www.fullengineeringbook.net
Twitter: @Books_Imagine
Facebook: www.facebook.com/ImagineBookazines

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
Get to grips with how VR technology is revolutionising
the way we think about the future of the internet
92

Tips & Techniques Front-end


10 20 HTML5 tools you need now 52 Responsive design decoded
18 VR & the web 60 Is your content king?

www.fullengineeringbook.net
26 Integrate payments with the
Stripe API
30 Master responsive image
techniques
66 Design aspect ratio-based layouts
with HTML and CSS
70 Make dynamic graphics with the
p5.js library
88 Create an interactive mobile 3D
interface
92 Assemble full-screen navigation
34 Create animated infographics with 74 Code 3D zoom effects with CSS
Snap.svg
76 Form pop-up modal boxes with
Developer
38 Build with AngularJS pure CSS 98 Be a jQuery code master
42 Develop apps with Facebook’s 80 Build offline web apps with 106 25 pro plugins
React Native framework Service Workers
84 Model a unique mobile 3D 116 Produce a picture gallery with
46 What’s new with Modernizr? jQuery
interface

26 70

34

6 HTML5
Mac OS&XCSS3
Genius
Genius
GuideGuide
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
effects
148 Animate an SVG with HTML and
CSS
with CSS
162 Add slide-up titles on page load
using CSS
128 Get free web hosting with GitHub 150 Code animated sliding panels on 164 Animate typography and text
Pages scroll effects
132 Manage JS with asynchronous 152 Make a resizable sliding panel for 168 Create a 3D navigation menu with
tasks your content HTML
154 Sync animations to audio and
Special effects video with Popcorn.js
172 Make a screen shrink on scroll
138 HTML & CSS animation 174 Create scrolling text with colour
158 Make a draggable fading effect change

98 164

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 Facebook’s
React Native framework
Build an image catalogue app with
Facebook React

46 What’s 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

1 Web Speech API


A TECHNOLOGY IN ITS INFANCY, BUT WITH THE POTENTIAL TO INTRODUCE
2 Text to
speech API
WEB SPEECH API’S OTHER HALF
ENTIRELY NEW MODES OF EXPERIENCE TO THE WEB

The Web Speech API is an experimental onresult, onerror, and onend. Rather than try to explain The flip side of speech-to-text is text-to-speech. It
technology due to its ever-changing the event-oriented nature of the API, here is a basic really is just like the ‘say’ command on any Mac OS
specification, which brings voice dictation example of it in action. X machine. Of course because this API is a web
software to the web. The underlying premise of the API <textarea id="dict"></textarea> technology, it can and should be put to better use.
is to provide capacity for both brief input (think var recog = new window. Most of the legwork is done by Web Speech API’s
commands) as well as continuous input (think classic SpeechRecognition(); SpeechSynthesis interface, which works in a similar
dictation, allowing for pauses). var dict = document. manner to SpeechRecognition, where evented
With a bit of imagination, this feature could begin querySelector('#dict'); functions are exposed along with the speech
quite a change in the way that user interfaces are recog.continuous = true; function aptly named ‘speak’. Check out a
designed on the web. Google and Apple have already recog.onresult = function(e) { stripped-down example of what it can look like in
been exploring speech to enhance particular aspects of e.results.forEach(function(r) { action below:
the user experience in their products with ‘Okay dict.textContent += r[0].transcript; var s = new SpeechSynthesisUtterance();
Google’ and ‘Hey Siri’. Such facilities on the web will }); s.text = 'I like cat food';
surely bring new and exciting opportunities. } s.lang = 'en-US';
The specification suggests more than a few recog.start(); window.speechSynthesis.speak(s);
useful functions such as voice web search, This code creates a new instance of A new instance of the SpeechSynthesisUtterance
continuous recognition of open dialog, the SpeechRecognition interface. It interface is instantiated. The instance then has the
speech UI present when no visible UI Target then configures the instance to text defined – the string the computer is going to
needs to be present and voice Audience recognise continuous input, which speak, along with a language. The final line passes

www.fullengineeringbook.net
activity detection (dvcs.w3.org/hg/ This technology will be particularly enables the speaker to pause. The the configured instance to the speak function and
speech-api/raw-file/tip/ useful for people with disabilities instance is then started. When the the computer begins to talk.
webspeechapi.html#use_cases). such as visual impairment, and results are determined as the Unlike the SpeechRecognition API,
Of course there will be some generally make the web an speaker talks, the textarea is SpeechSynthesis is more widely supported, which
privacy concerns with any API that even more accessible appended to with the most likely makes it a real option provided that the target
potentially enables a device to capture place. correct result. market is on iOS’s Safari. This is quite handy for any
and store local ambience for later. The URL: bit.ly/1WsQh1u hands-free mobile applications, such as turn-by-turn
specification sets out two mandatory conditions directions, or maybe even a step-by-step recipe app.
for vendors to follow, which paraphrased are: “User URL: bit.ly/1L5Hbpj
agents can only start recording speech with explicit and Scenarios
informed consent… User agents must provide obvious VOICE WEB SEARCH Scenarios
indications when speech is being recorded. This No doubt when this API becomes
interface element must also allow users to cancel the commonplace there will be clients requesting LISTENABLE BLOG POSTS
current speech session.” their own version of ‘Okay Google’. A great feature for the visually impaired, blog
In terms of implementation, like most APIs of this CONTINUOUS RECOGNITION OF posts that people can listen to would make
type, the interface is event-driven. SpeechRecognition OPEN DIALOG for a really compelling experience.
exposes four evented functions, which are: onstart, This one really depends on who is using it.
Hook it up to an email client and send ten times TURN-BY-TURN DIRECTIONS
more email! Put your phone in your pocket and you can
Browser Support SPEECH UI PRESENT WHEN NO then be audibly guided to your destination by
the browser’s voice.
VISIBLE UI NEEDS TO BE PRESENT
CHROME 25+ This technology could unlock an entirely new
STEP-BY-STEP RECIPES
CHROME FOR ANDROID 44+ market of even more minimal writing.
Sticky marks on touchscreens while weighing
FIREFOX N/A VOICE ACTIVITY DETECTION
out ingredients could be a thing of the past.
SAFARI N/A There have got to be some interesting
EDGE/IE N/A
IOS N/A
opportunities when general voice activity
levels are paired with HTML5 Canvas.
Browser Support
CHROME 43+
CHROME FOR ANDROID 44+


FIREFOX N/A
Google and Apple have already been SAFARI 8+
exploring speech to enhance particular EDGE/IE
IOS
N/A
7.1+
aspects of the user experience
” HTML5 & CSS3 Genius Guide 11
Tips & Techniques

6
3 WebSockets API
GetUserMedia API
CAPTURE VIDEO/AUDIO FROM DEVICES
HTML5’s getUserMedia API allows developers to
capture media streams from the device – video, audio,
FIRST THERE WAS HTTP, THEN ALONG CAME AJAX.
NOW, THERE IS WEBSOCKETS and both at the same time. This capability isn’t that
exciting on its own, but it gets interesting when paired
WebSockets is a fundamentally diferent concept to
HTTP and AJAX. Instead of the client requesting
Scenarios with other HTML5 technologies. For example, the
video stream returned by getUserMedia can be
resources and the server responding with them, the REAL-TIME PROPERTY UPDATES applied locally to a video element. That video element
server and client agree to maintain a connection, called a A forward-thinking estate agent implements can be drawn to HTML5 Canvas, which in turn can be
socket. At any time, the server and client can start real-time property updates, providing an turned into a dataURL and then into a blob, ready to be
sending each other data across this socket, inherently ever-changing map of property to let. sent across a WebSocket to all other connected clients.
avoiding the overhead that comes with HTTP. The lean The nice thing about being able to bring the video
MULTIPLAYER GAMING AND
nature of this protocol lends itself to latency-critical COLLECTIVE EXPERIENCES stream into HTML5 Canvas is it allows for manipulation
applications and real-time experiences. of the image before it gets sent to the server. It would
Any multiplayer game will require low-latency
WebSocket-driven applications often require large be very easy to scale the frames down, run filters over
communication between clients and the server.
numbers of persistent connections, something that them or even apply advanced efects such as blurring
This could apply to other group experiences as
traditional server-side technologies tend to be bad at and distortion.
well.
facilitating. Server-side architectures that allow for high GetUserMedia returns a stream of data that can be
concurrency on a budget are often favoured – like those REAL-TIME CHAT used locally by HTML5’s video element, like so:
that are touted as ‘non-blocking IO’. WebSockets could make a reasonable <video autoplay></video>
URL: mzl.la/1j9X55Q replacement for the aging IRC, enabling richer var video = document.
media to be used in discussion. querySelector('video');
Tools navigator.getUserMedia({
SOCKET.IO
SOCKET.IO
Browser Support video: true,

www.fullengineeringbook.net
audio: true
Real-time Node.js WebSocket architecture. CHROME 31+ }, function(s) {
TORNADO ANDROID 4.4 + video.src = window.URL.createObjectURL(s);
GITHUB.COM/TORNADOWEB/TORNADO FIREFOX 38+ video.play();
Python networking library and framework. SAFARI 8+ });
PLINK EDGE/IE 10+
DINAHMOELABS.COM/PLINK IOS 7.1+ The DOM is queried for the video element. The script
Real-time collaborative music-making experience. 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.
4 History API 5 Link Prefetch API URL: mzl.la/1iLRLWp

SAVE STATES IN A SINGLE-PAGE WEB APP PREFETCH NEXT STEPS IN KEY JOURNEYS
This API provides means to manipulate browser history The HTML5 Prefetch API is a browser mechanism that Parameters
with JavaScript. This isn’t limited to just forward, prefetches documents before a user manually requests CONSTRAINTS
backward and specific points, it also lets developers the ones that they are likely to visit in the near future. Takes an object describing the stream constraints,
add their history events with pushState. Prefetching resources like this stop users having to waste such as width, height, frame rate and more.
History.pushState takes three values: an object time waiting for server response – the largest delay when SUCCESSCALLBACK
associated with the state, a title and then a page URL fetching new pages and assets. If the request for a user’s media was successful, this
which will be displayed in the browser’s address bar. Implementing prefetch cunningly can have a vast function is invoked and the stream is passed.
The history API is very useful for single-page efect on perceived performance, especially when users ERRORCALLBACK
applications that have diferent states or views that a are doing repetitive tasks. If the request for media fails due to permissions, or
user may want to navigate between, but it still retains Prefetching tags appear in the <head> of the page, lack of sources, this function is invoked.
the benefit of XHRs. along with the other metadata relating to the site.
URL: mzl.la/1KzFuKx URL: mzl.la/1VafzyW
Browser Support
CHROME 31+
Browser Support Browser Support CHROME FOR ANDROID 44+
FIREFOX 38+
CHROME 31+ CHROME 31+ SAFARI N/A
FIREFOX 38+ FIREFOX 38+ EDGE/IE 12+
SAFARI 8+ SAFARI N/A IOS N/A

12 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

The API that is The API provides


associated with media access to a property
elements allows for called currentTime.
separate media This property controls
controls in the DOM. the playback of the
Although basic in this media but it will also
example, the feature return the media’s
does enable some current position.
interesting aesthetics.

The API also enables The MediaElement


basic properties of the interface allows the
media to be controlled, developer to control
including playback the playback of media.
speed. Here the Here the developer has
developer has combined a play/pause
implemented a as one button rather
bespoke volume than having two
control interface. separate ones.

7 HTML Media API


www.fullengineeringbook.net
HTML5 VIDEO AND AUDIO HAVE PHASED OUT FLASH. IT’S TIME
TO THINK ABOUT USING EMBEDDED MEDIA MORE CREATIVELY

The HTML5 Media API provides a standard JavaScript


API for interacting with the HTMLMediaElement
<button>Play</button>
var video = document.querySelector('video');
Scenarios
interface. HTMLVideoElement and HTMLAudioElement var button = document. STANDARD VIDEO EMBED
are both children of the HTMLMediaElement and inherit querySelector('button'); Browser support for HTML5 media is so good
its properties. button.addEventListener('click', play, there really is no excuse for not using it as
Media Elements have properties for manipulating the false); standard for media embedding.
playback of media, including load, play and so on. function play() { STANDARD AUDIO EMBED
The scenarios for using this capability at first may if(video.paused) { Standard audio embedding is also preferred
seem obvious. Any media that Flash would have been video.play(); over plugin-powered solutions, such as Flash or
used for before can now be done without browser } else { Silverlight.
plugins – but there are other benefits. video.pause(); SILENT VIDEO
It’s now easy to combine video and audio with other } Use silent video instead of images to capture
HTML5 technologies such as Canvas for the production } human emotion and make emotional
of more engaging and grander interactive experiences. First, DOM references are made to the video and button
connections with users.
Canvas lets developers manipulate video pixels and elements. Then, a click handler called ‘Play’ is then bound
apply bespoke efects. to the button. The play function provides playing and HYPERREALITY
Video that’s more integrated with the surrounding pausing functionality to the video by making use of the Shoot a video that contains very little
webpage is also now possible. The JavaScript interface HTMLMediaElement API interface. movement, but more than a photograph.
allows for play buttons to be separate from the traditional Going on to build more advanced controls that Hyperreal scenes can bring a page to life.
video user interface, opening up brand new possibilities
for user experience designers to make use of.
incorporate volume, seeking, playback speed and
tracking functions are all possible through the API. What
Browser Support
Incorporating supporting animation to control this means is that it’s much easier to bring a visual style CHROME 31+
elements, such as expanding/revealing a video on a or brand to embedded media on the web than it ever ANDROID 4.1+
button click, is now not only possible but also easy. has been before. FIREFOX 38+
<video> Finally, the media element interface lets developers SAFARI 8+
<source src="example.mp4" type="video/mp4" create autoplaying media, giving rise to silent video as a EDGE/IE 9+
/> design element in a webpage – or transparent media. IOS 7.1+
</video> URL: mzl.la/1NM0jYk

HTML5 & CSS3 Genius Guide 13


Tips & Techniques

8 Navigation 9 Network
Information API
Timing API SMART DECISIONS AND CONNECTIONS
Long have developers wanted a definitive way to
determine what type of connection a user is on so
PERFORM ANALYSIS ON LOAD TIMES OF WEB PAGES WITH THIS API they’re better able to tailor experiences. The
Network Information API promises exactly this kind
Ensuring pages are quick to load is crucial. The interactive, DOM content was loaded and the page had
of function capability.
Navigation Timing API can gather statistics on page-load finished loading. URL: mzl.la/1eUB4oS
This API will allow developers to make subtle but
performance for developers to analyse. The statistics
important tweaks to experience, such as loading
allow for useful metrics such as the critical render path
standard-definition video when a user is on a mobile
and identification of slow images. Scenarios data connection, as opposed to high definition when
Use snippets in Chrome Developer Tools to store
ANALYSIS OF ANY GIVEN PAGE they’re on Wi-Fi and are therefore able to load
useful functions for pulling metrics out of any page:
The navigation timing API should be used as a high-quality content better.
quick reference to determine the critical render This distinction can also be efectively used in
function criticalRenderPath() {
path of any webpage. broader strokes, for example the user may want to
var t = window.performance.timing;
send less data to the client for standard XHRs and
// Converting to seconds
COMPARATIVE ANALYSIS this is especially useful if they are connected via a
return {
Store the performance timing results when mobile data connection.
interactiveAt: (t.domInteractive t.
conducting a series of improvements as a URL: mzl.la/1KAJcV4
domLoading) / 1000,
benchmark for subsequent tests.
domContentLoaded:
(t.domContentLoadedEventStart t.
Browser Support Browser Support
domLoading) / 1000,
complete: (t.domComplete t.domLoading) / CHROME 31+ CHROME N/A
ANDROID 4.1+ CHROME FOR ANDROID 44+

www.fullengineeringbook.net
1000
} FIREFOX 38+ FIREFOX N/A
} SAFARI 8+ SAFARI N/A
This references the performance.timing metrics, then EDGE/IE 9+ EDGE/IE N/A
determines the metrics for each stage in the critical IOS 9+ IOS N/A
render path to provide stats on when the page was

10 User Timing 11 Page Visibility 12 Battery 13 IndexedDB


API API Status API
STORE DATA IN THE BROWSER
BESPOKE CODE BENCHMARKS FOR LOST FOCUS IN WEBPAGES TAILOR FOR BATTERY
IndexedDB provides developers a
The User Timing API is an extension Users often have a bunch of webpages This API exposes useful battery low-level API to persistently store data
window.performance, enabling open at once, with only one in focus. information. This includes charging, a to a browser. Developers can store data
developers to mark points in their code The Page Visibility API fires events Boolean indicating whether the device locally first and sync with the remote
and make measurements. User Timing when a webpage loses focus or returns is currently charging; chargingTime, server when a data connection is
can be used to identify areas of code into focus again, allowing developers to which tells you how long until the available. This can be especially useful
that are slower than desired. get smart about the experiences on the battery will be fully charged; when working with large datasets,
Window.performance.mark lets page that loses focus. This includes dischargingTime, which tells you how which should only be transferred over a
developers store a high resolution. pausing streaming media, as well as long until the battery is depleted and Wi-Fi connection. Like localStorage,
Window.performance.measure lets avoiding unnecessary processing when the device puts itself to sleep; and level, IndexedDB is subject to storage limits
developers calculate the elapsed time it comes to continuous animations and which is the current battery level on a and eviction criteria. The mechanisms
between recorded marks. even live media. scale between 0 and 1.0. behind it are complex and vary with the
URL: bit.ly/1MIIXwN URL: mzl.la/1Fu21wh URL: mzl.la/UlVKw7 browser too. URL: mzl.la/1y2iyCj

Browser Support Browser Support Browser Support Browser Support


CHROME 31+ CHROME 31+ CHROME 43+ CHROME 31+
FIREFOX 38+ FIREFOX 38+ FIREFOX 38+ FIREFOX 38+
SAFARI N/A SAFARI 8+ SAFARI N/A SAFARI 8+

14 HTML5 & CSS3 Genius Guide


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 } }


JavaScript UI frameworks like jQuery to enable the function dragOver(e) { var i = document.querySelectorAll('.
implementation of drag and drop. The HTML5 if (e.preventDefault) { item');
drag-and-drop API provides evented functions and e.preventDefault(); i.addEventListener('dragstart',
HTML attributes, enabling most elements on any given } dragStart, false);
page to be made natively draggable. This means e.dataTransfer.dropEffect = 'move'; i.addEventListener('dragenter',
developers can add cheap drag-and-drop functionality to return false; dragEnter, false);
everyday tasks and applications; previously the } i.addEventListener('dragover', dragOver,
overhead of libraries ensured it wasn’t an function dragEnter(e) { false);
option. With a good implementation of this.classList.add('dragging'); i.addEventListener('dragleave',
drag and drop, it should be harder Colliding } dragLeave, false);
than ever to distinguish web views elements function dragLeave(e) { i.addEventListener('drop', drop, false);
from native apps. There are seven It’s important for users to get this.classList. i.addEventListener('dragend', dragEnd,
events that cover the entire drag high-quality visual feedback from remove('dragging'); false);
lifecycle. Just like mouse events, drag-and-drop mechanisms. They }
these can be bound to elements should be confident of where function drop(e) { First the various functions are set up to handle events.
using addEventListener. A basic the item being dropped will if (e.stopPropagation) { DragStart() reduces the opacity of the dragged
implementation of the drag life cycle be placed. e.stopPropagation(); element. DragEnter() and dragLeave() manage
would look something like this: } classes used to style the item when it’s colliding with
<div class="item" return false; another item. Drop() stops all of the current event

www.fullengineeringbook.net
draggable=”true”></div> } propagation. DragEnd() ensures the class used to
function dragStart(e) { function dragEnd(e) { style ‘collisions’ is removed.
this.style.opacity = '0.6'; item.classList.remove('dragging'); URL: mzl.la/1ENGVEq

Scenarios
MANAGING CALENDAR ENTRIES
Rather than editing specific times and dates
when managing a calendar, it’s 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 31+
ANDROID N/A
FIREFOX 38+
SAFARI 8+
EDGE/IE 8+
IOS 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 The basic premise is to connect devices with each
other using a common platform where it’s easy to
Low concurrency CPU-intensive processing is something processing that would happen in the worker would be craft rich experiences that leverage technologies
that JavaScript in the browser has never been good at kicked of in this function, but for now the example just – hence RTC (Real-Time Communications). The
due to its single-threaded nature. Operations that take a sends a message back to the main thread containing three APIs that WebRTC implements are:
long time block the thread and stop other things from identical data. MediaStream (known as getUserMedia),
happening on the page. URL: mzl.la/1KAJDyK RTCPeerConnection and RTCDataChannel.
The Web Workers API can enable background threads MediaStream provides access to streaming media
to be spawned on the fly that can handle from a user’s device, like a camera and
computationally expensive tasks without there being any Scenarios microphone. RTCPeerConnection enables audio
detrimental efects to the main application thread. Web and video calling as well as providing encryption
Workers communicate with the main JavaScript thread SPREADSHEET APPLICATION and bandwidth management capabilities.
through an exposed function called postMessage. Here’s Spreadsheets can require an immense amount of RTCDataChannel is for peer-to-peer
a basic example: calculation if they’re large enough. Hand that communication of generic data.
var worker = new Worker('worker.js'); computation to another thread. The MediaStream aspects of WebRTC are
worker.addEventListener('message', covered by the getUserMedia API section of this
function(e) { VIDEO ENCODING feature. RTCPeerConnection’s job is to facilitate
console.log(e.data); Video encoding is an intensive computational streaming data between peers, but it doesn’t
}, false); task and is not something that should be done in define any protocols to do so. Instead, developers
worker.postMessage('I like cat food'); the main thread. can choose any messaging protocol they desire,
// worker.js such as XMPP, to handle the signaling required.
self.addEventListener('message',function(e){ Browser Support The signaling channel is used to exchange three

www.fullengineeringbook.net
self.postMessage(e.data); types of information between peers: media
}, false); CHROME 31+ abilities, the resolution and codecs supported by a
There are two files here: the first is the main thread which ANDROID 4.4+ peer’s web browser; network information, a peer’s
instantiates a worker from the other file, worker.js. The FIREFOX 38+ external IP address and port; and Session control
main thread starts listening for data sent by the worker. SAFARI 8+ for starting and closing communications as well as
Then it sends data to the worker using postMessage, in EDGE/IE 10+ error reporting.
this case a simple string. Worker.js contains a function IOS 7.1+ WebRTC has a third API called RTCDataChannel,
that listens for data sent by the main thread. The which lets peers exchange miscellaneous data
with low latency. This makes WebRTC a contender
for low latency peer-to-peer applications or a
16 Pointer Lock API 17 Vibration API decentralised version of Web Sockets.
URL: webrtc.org
ENHANCE IMMERSIVE 3D EXPERIENCES PROVIDE PHYSICAL FEEDBACK
Scenarios
The premise of the Pointer Lock API is to provide access As smart devices become more common for interacting
to raw mouse movement occurring beyond the with the web it makes sense to start taking advantage of DEVICE-AGNOSTIC VIDEO CHAT
constraints of the browser window as well as hiding the their unique abilities – such as tactile feedback like that of WebRTC can bring video chat to almost any device
cursor. The API lends itself to first-person controls in vibration. Most modern mobile devices have vibration with a browser, camera and microphone.
games, as well as other interactive first-person hardware. The vibration API ofers applications the ability PEER-TO-PEER GAMING
experiences and experiences that require lots of mouse to access this hardware if it exists. The API is very Games designed without a centralised server can
movement such as 3D editing tools. straightforward, as follows: use WebRTC to connect peers with low latency.
Before the Pointer Lock API, full-screen experiences window.navigator.vibrate(250);
PEER-TO-PEER FILE TRANSFER
WebRTC makes it possible to send large amounts
would run up against the edge of the browser window, This line of code will cause the device to vibrate for 250
of data between peers.
or worse go beyond it – making it easy for users to be milliseconds. If an array is passed to vibrate, it will vibrate
taken out of the experience. and then pause for every other argument.
URL: mzl.la/1j9YZDr URL: mzl.la/1MIJ77B Browser Support
CHROME 31+
Browser Support Browser Support CHROME FOR ANDROID 44+
FIREFOX 38+
CHROME 31+ CHROME 31+ SAFARI N/A
FIREFOX 38+ FIREFOX 38+ EDGE/IE N/A
SAFARI 8+ SAFARI N/A IOS N/A

16 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

19 Web Components Scenarios


MULTISITE EVENTS WIDGET
USE WEB COMPONENTS TO PACKAGE HTML, CSS AND JAVASCRIPT Develop an events widget that lists events from
WIDGETS INTO REUSABLE, ISOLATED PACKAGES an API dropped onto any site with one Import
statement and a Custom Element.
Like WebRTC, the Web Components specification is a Templates are similar to templates in other
collection of several separate technologies. Web third-party technologies like AngularJS. They enable SEARCH WITH AUTOCOMPLETE
Take a search with autocomplete, such as
Components are self-contained, reusable user interface markup to be defined, ready to be made use of later.
Google’s Places, and then turn it into a reusable
widgets that leverage other open web technologies. Shadow DOM is the specific technology that solves component.
Using already public Web Components is the DOM sandboxing issue, whereas
something that’s as easy as writing an Custom Elements enable IMAGE CAROUSEL
import statement in an HTML page. developers to create fully featured Implement a carousel in a Web Component
Web Components provide a way Remember it is DOM elements. HTML Imports are and never write another carousel. Import the
to package widgets built with HTML, not Polymer similar to imports in other old one that uses Custom Elements.
CSS and JavaScript into reusable Iolymer is a Google framework languages, enabling the import of
components – they’re just as based on Web Components entire Web Components, including ACCORDION COMPONENT
capable as anything else that’s technologies and is not required their CSS and JavaScript. You can turn any piece of markup into an
available out there. to make effective use of Web While the four technologies in accordion by importing an accordion Web
For years, developers have worked Components. Web Components are supposed to Component and surrounding the item in a
with widgets that aren’t sandboxed be used in conjunction with one Custom Element.
from the rest of the DOM. The widget’s
styling sat with the rest of the CSS, the JavaScript
another, developers can select which
parts of Web Components they need to use.
Browser Support
with the rest of the JavaScript. This lack of sandboxing The amount of things that can be achieved is broad. CHROME 41+
made it hard to extend existing widgets without When thinking about Web Components retrospectively CHROME FOR ANDROID 44+
FIREFOX N/A

www.fullengineeringbook.net
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 SAFARI N/A
this problem are as follows: Templates, Shadow DOM, component to be imported anywhere in the project. EDGE/IE N/A
Custom Elements and HTML imports. URL: webcomponents.org IOS N/A

20 Shadow DOM Parameters


ELEMENT.SHADOWROOT
ISOLATE PRESENTATION FROM CONTENT FOR MORE FLEXIBLE AND This is a read-only property that represents the
ROBUST FRONT-END ARCHITECTURES youngest shadow root that is hosted on the
element.
The Shadow DOM enables developers to encapsulate <article class="directions-widget">
DOM elements from the rest of the page. In conjunction <header> <CONTENT SELECT=””>
with templates, this enables the separation of concerns <h2>Directions to my house</h2> The content element used inside of the
with content and presentation. Before, a developer may </header> Shadow DOM is an insertion point, only to be
have written something like this when wanting to share <p class="directions">Turn left</p> used in Web Components
directions to their house: </article>
<style> </template> <SHADOW>
.directions-widget { ... } <script> Much like the <content>, the <shadow>
</style> var s = document. parameter is also an insertion point but it can
<article class="directions-widget"> querySelector('#directions'). also be used for older shadow roots on the
<header> createShadowRoot(), same shadow host.
<h2>Directions to my house</h2> t = document.querySelector('#directionsTempl
</header> ate'), Browser Support
<p>Turn left</p> c = document.importNode(t.content, true);
</article> s.appendChild(c); CHROME 31+
But with Shadow DOM, they can write this: </script> ANDROID 4.4+
<p id="directions">Turn left</p> The presentation code here is now inside a template, so FIREFOX N/A
<template id="directionsTemplate> it won’t be rendered by the browser. The script at the SAFARI N/A
<style> bottom clones the template to the Shadow DOM, with EDGE/IE N/A
... the presentation initially intended. IOS N/A
</style> 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
THERE’S A LOT TO CONTEMPLATE WHEN DESIGNING FOR THE WEB. IT’S NOT EASY, AND IF YOU’RE READING THIS
YOU PROBABLY HAVE A GOOD IDEA OF WHAT WE’RE 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 How VR and 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. web can work
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 together
minds. You want to give them an which we are already familiar and stay the
experience that is both memorable WEB same. The basic way the human eye Education
and meaningful, within the confines REALITY works stays the same. Principles such The proliferation of online courses is just getting
of two dimensions. The prospect of designing for a as contrast, colour, and pattern started. Once you can immerse yourself into an online
Now consider how you would new dimension is a very exciting recognition are still valid tools. These classroom, the possibilities could be endless. Check
accomplish the same goal in a one. Check out the Catch the concepts can still be useful as the out Unimersiv.com for a glimpse into some of what’s
three-dimensional medium. There Dragon site www. building blocks in our new virtual already available.
are new factors to consider such as catchthedragon.nl. This medium. We may even be able to
the user’s head angle and their combines and 360-degree explore them further.
viewing radius. How do you make video and VR. “But VR is just for videogamers, right?”
elements touchable in a manner that is you may think. Virtual reality has the

www.fullengineeringbook.net
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 user’s form a new way of life, change it forever, and make it so
attention so that they turn their head? We’re no longer much better. Socialising
designing in a flat medium, but within all the space As web designers and developers, we can be at the We’re already connected with each other through
around a person. It may seem like there are fewer forefront of this new digital medium. We already are at Twitter, Google+, Facebook, and other social networks.
constraints and that can be freeing, but also scary. We the forefront of the current prolific digital medium; the Imagine logging in and walking around in these sites
know that with some form of constraints, or rules, that it web. The bleeding edge is sharp, but we roll with it in with their own architecture and content with your
can be easier to work within those confines. It may seem stride and push the boundaries of what is possible. This friends. Check out Beloola.com to get an insight into
like the sky’s the limit when designing for a three- is just another step into the unknown. We should do so one company’s vision.
dimensional medium. But we’re finding that there are with confidence and enthusiasm.
Relaxation

“ Your goal is to make those two


dimensions convey meaning and order in a
way that touches their hearts and minds
Wouldn’t 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
Jerad Bitner Technical project manager
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
and VR enthusiast (vimeo.com/138790270), and check out this
augmented reality colouring book for children
“VR is the next medium for the web (youtube.com/watch?v=SWzurBQ81CM).
and should become a natural
transition for web developers and Exploration
designers. My recommendation is to So many countries, so little time. With 360° videos
start studying architectural design being taken worldwide of some of the most beautiful
now so this can be applied to your and remote places, you can now fully immerse
virtual worlds.” 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 Facebook’s purchase of
Palmer Luckey’s device means it will reach every corner Oculus Rift Samsung Gear VR
of the market. As with any new tech, the pleasure of oculus.com/en-us/rift/ oculus.com/en-us/gear-vr/
owning such a device will cost you dearly. But, the Facebook bought Oculus for $2 billion (£1.3 billion) to A product of Samsung and Oculus, the Gear VR is a
budget option (less than £5) is already out there in the get their hands on this one. The consumer version is wireless headset used with a Samsung phone. The
shape of Google Cardboard. So go get your hands on set to be available in July 2016 and is the default for headset can be found for $99 (£65), but the Samsung
one now! almost all VR software. It’s to ship with hand controls. phones are typically around $700 (£464).

What are spatial memories?


Have you ever watched or read Dream Catcher? Well, This technique isn’t quite as science fiction-esque. how to get home, and which plants are edible or

www.fullengineeringbook.net
within the story, one of the main characters has what The memory warehouse or memory palace is a system poisonous. This is most likely why we are so good at
he calls a ‘memory warehouse’. He can recall any given of storing information in your brain by creating an remembering things visually and spatially.
memory, dragging it up from a virtual warehouse he imaginary building and filling it with imagery of what By creating virtual worlds in which we can see and
has built in his mind. He can walk around the building needs to be recalled. Learn how to build your own at hear, we are better able to create and recall memories
and find any memory due to its relative position to wikihow.com/Build-a-Memory-Palace. in the human brain, so it’s important that the
other memories. As such, he follows a ‘path’ to locate a Our brains were always meant to store information to experience be a positive and even desirable one for
particular memory. stay alive, like where you can find food and resources, our users.

“ 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 Placing typical UI elements in such an environment The second factor is the distance to which a user can
two-dimensional screens sitting on a desk. The screen can be tricky. It can be hard to work out what is optimal comfortably see. This distance is around 0.5 to 1 meter
appears to disappear with a screen mounted to your when the sky’s the limit. In order to get an idea of some from the user as a result of how the eyes attempt to
head. As you move your head there is new canvas of the factors involved in finding the level, take a look at focus more and the strain caused after this distance.
space available all around. The head-mounted display some research conducted by Mike Alger, which is in Oculus recently recommended a distance of 0.75
gives a sense of depth and scale, and we can have turn based on useful observations provided by Alex meters to developers. The third factor is the head
browsers and apps all around us. Chu of Samsung. Alger’s research concludes that a rotation of a user.
Additionally we should consider how to organise measurable area looking as follows is what is optimal Horizontally the comfort zone is about 30° from the
these apps in the space around us. Spatial organisation for user interface elements. centre with a maximum distance of 55° to the side.
of our UI components can help a user remember This conclusion is based on several factors, as The fourth is head pitch, or the distance up and down
where they can find things. Or it could degrade into the explained by Mike Alger in his paper. The first is the field that is comfortable for a user to position their head.
nightmare desktop we’ve all seen with a massive clutter of view when a user is looking straight forward. This Upwards this is comfortable up to 20° with a
of icons. But even then, our brains are capable of distance is variable from device to device, but to give maximum of 60°. Downwards this is comfortably 12°
making sense of that chaos. you a good idea, the Oculus Rift’s field of view is 94.2°. with a maximum of 40°.

20 HTML5 & CSS3 Genius Guide


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 HTC and Valve have partnered on this headset which This is a little diferent in that it is the first open source
head-mounted display, the Cardboard is actual comes with hand controllers and multiple light sensors virtual reality headset. The goals of the project are to
cardboard and works with many phones. The for ‘room-scale’ VR applications. It is due to be make the parts available for you to build and upgrade
Cardboard app is available on Android and iOS. available in April 2016. over time.

Creating memorable Scale can be a powerful tool


experiences Another useful tool to consider is how scale can afect A new shopping
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 experience
memory due to the feeling of being inside a new robot were a cute toy. But scale the robot up to three or

www.fullengineeringbook.net
environment rather than watching it on a screen. four times the original size and it’s now far more Advertising in VR is a whole new field, and
Feeling as though you’re a part of it all creates menacing. Depending on the memory you’re trying to companies are just starting to wrap their minds
memories of the experience, not just retention of create, scale can be useful in shaping the experience around the possibilities of connecting with their
what we learned through reading. Engaging of the user. intended audiences in a whole new way.
a user and creating memories on a level Advertisers and marketers have been trying
where they can almost forget that Steady Create beautiful new ways of selling products for ages. One of the
what they are experiencing is virtual Horizons scenes basic principles of selling or marketing is making
is what we refer to as immersion. When you are creating Visually stunning scenery can afect the consumer identify on a personal level with a
Immersion is at the heart of VR immersive environments, the immersion experience as well. product in order for them to want to buy it. Many
make sure you keep your
applications. It being a core goal of horizon nice and steady for your A beautiful sunset, or a star-filled tactics are engineered and employed to get
the VR experience, we should try users in order to avoid inducing night sky can give the user an people to buy things, but almost all of them come
to understand the factors involved the all-too-often experienced environment to which they can down to this one over-arching goal of having a
and the techniques that are “VR sickness”. relate. Relating to known places and person identify with the product.
becoming best practices in the scenes is an efective means of VR could be a huge catalyst for achieving this
creation of an immersive experience. creating memorable experiences. It’s a goal. Visiting a shop in virtual reality where you
means of triggering other similar memories can walk around the wares, see their size and
Use sound to draw attention and feelings and then building on those with the shape, hold them up with your virtual hands to
Positional audio is a way of seeing with your ears. direction you are trying to take the user. An immersed really identify the product’s dimensions, and even
Ingrained in us from early evolution, our brains have user may have been there before, but now there is a obtain additional information through a display of
attuned themselves to figuring out exactly where a new experience to remember. information attached to the product – all of these
sound comes from in relation to ourselves. A are possible. Or perhaps you’re taken to a whole
recognisable sound that is behind you and to your left Make learning memorable new place when you pick up the object to
can quickly trigger not only an image of what made the Teaching someone a new and wonderful thing can also experience the use and operation of the product.
sound, but we can approximate where that sound came be a useful memory trigger. Do you remember where All of these are additional ways that a person can
from. It also triggers feelings within us. We might feel a you were when you first learned of HTML, or identify with a product on a deeper level than a
measure of fear or soothing depending on what our Photoshop? The knowledge that tends to stick out the two-dimensional representation allows.
brain relates this sound to and how close it is to us. As most to us can trigger pretty powerful images and the There are some great examples of how VR is
in real life, so it is in VR. We can use positional audio as feelings that we memorised in those movements. being used in the commercial space. Trillenium
cues to gain a user’s attention, or to give them Heralded by some to be an important catalyst in (trillenium.com) is just one of the many. They are
information that is not presented visually. Remembering changing how we learn, VR has the potential to looking to bring the retail experience to shoppers
a time when you were in VR and a sudden loud sound revolutionise education. Indeed we are better able to by creating virtual stores that allows users to
scared the pants of of you can immediately recall a create memories through the use of VR, and what browse through shops as in real life.
memory of everything else you were experiencing at better memories than those of learning new and
the time. interesting things?

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

www.fullengineeringbook.net
Unity is one of the most ubiquitous of tools used today These are Autodesk products for modelling, animation, the software, but also giving introductory lessons to
for in the development of VR technology. At its heart it’s lighting and VFX. They don’t have VR support by default basic 3D modelling concepts. You can quickly learn the
a game engine. It has a direct VR mode to preview your but through pricey plugins instead. AutoCAD and 3ds basics of modelling with SketchUp and then move onto
work in an HMD, which can really boost productivity by Max are long-time standards in the architectural design more advanced tools like Blender if you desire. It’s really
designing for VR almost within a virtual environment. industry and have some of the most precise tools in their great for modelling, quickly learning the lingo, and then
Unity is quickly becoming the default tool for VR UI. Like almost all GUI’s for building 3D environments and moving onto bigger and better things. You can grab a
development due to its ease of use and the ability it drawings, these tend to be quite massive UI’s with a lot of free trial version of the software at sketchup.com.
afords for quickly making prototype VR applications tools hidden behind menus, submenus, and toolbars.
with it. There’s a huge community around this Learn more about 3ds Max, Maya and other GearVRf
tool and so there are a plethora of Autodesk products at autodesk.com/ The GearVR framework (GearVRf) is an open source VR
resources and documentation to learn WebVR products/maya/overview. rendering library for application development on
from. What’s more, a market of 3D Standards VR-supported Android devices. While many of the other
assets can get you up and running When you are looking to Blender tools can export Android or iOS applications to use with
in just a short amount of time. If develop for the web and VR, take Blender is quickly becoming a your phone, this is an Android native framework for
you’re familiar with C++ or a look at the WebVR standard favourite modeller for VR developing VR applications. You can dig into this one
JavaScript, you can get into the drafted by Mozilla and Google: developers. It’s free and open more at gearvrf.org.
scripting pretty easily as well. All mozvr.github.io/webvr-spec/ source software written in Python.
major HMDs are supported and it’s webvr.html There’s a huge community of people Three.js
cross platform. You can even export to devoted to this software and its use. This is a JavaScript library which works as a layer on top
WebGL. Unity can be found by visiting Many websites provide tutorial videos, of WebGL. It has many helpers and abstractions that
unity3d.com. forums, and documentation. The software’s oficial make working with WebGL much easier than the WebGL
documentation is also quite impressive. Mainly for API alone. WebGL is an OpenGL implementation within
Unreal Engine (UE4) modelling, UV mapping, lighting, rigging, and animation, modern browsers such as Chrome, Firefox, and Safari.
One of the main competitors of Unity 3D, Unreal Engine you can export your models to a multitude of formats There are some excellent applications being developed
is another gaming engine with VR integrations, an asset that can then be used with many other tools. There’s with Three.js which utilise 3D design to create anything
store, and it also has great documentation. The graphics even a great plugin for exporting your creations into from fun demos, to multiplayer worlds and games.
are more advanced and realistic by default, and the JanusVR with a free open source plugin at github.com/ Most WebVR implementations are built using Three.js
learning curve is not dissimilar to Unity. Many of the VR void4/FireVR. You can download Blender and use it for due to its ease of use and in part due to how popular
demos built with UE4 are much more life-like and free at blender.org. JavaScript has become. Doing 3D graphics in the
smoother to navigation within. It provides great browser is hardly done without Three.js. Check out
performance with the conveniences of a modern editing SketchUp github.com/borismus/webvr-boilerplate to get started.
environment. UE4 itself is also cross platform, but it Google’s SketchUp is a basic modelling application with a Most browsers are still struggling with headset device
exports to slightly fewer platforms than Unity does. Find very low learning curve that can get anyone up and support, but they’re getting much closer to being
out more about UE4 by visiting unrealengine.com. running in a short amount of time. The tutorials on the included in the main builds of modern browsers like

22 HTML5 & CSS3 Genius Guide


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

www.fullengineeringbook.net
applications are already extremely compelling.
INSPIRIT Quake 3 A great place to start is the Oculus Share site,
mozvr.com/projects/inspirit media.tojicode.com/q3bsp with hundreds of games and demos for VR already
Based on Three.js, built in Blender, and utilising the Web This is a working version and level rendered of the game in the making, and that’s just for the Oculus Rift.
Audio API, this example of virtual reality will knock your Quake 3 in WebVR. You can check out its source here: There are many more being created for your
socks of. github.com/toji/webgl-quake3. browser in WebVR, and for Android and iOS
devices in their respective app stores.
You can also check out some exploration into
Chrome and Firefox. However, most phones can be JavaScript, and a subset CSS. This approach makes it journalism with VR. There’s a great piece created
detected with github.com/borismus/webvr-polyfill and quicker for the web development community to get for LA Times on graphics.latimes.com/mars-
if turned sideways, they can be switched to a dual display involved and familiar with designing for VR. You can gale-crater-how-we-did-it/ which was created in
mode that you can use with Google Cardboard, create games like Puck-man (scenevr.com/ws/puckman. WebGL for WebVR. You can experience this in VR
Samsung VR, or other headsets that are built to be used scenevr.hosting/game.xml), or just import a model and using your phone and Google Cardboard, or
in conjunction with a smartphone. show it of to your friends. simply go to the website graphics.latimes.com/
Virtual environments built using SceneVR are even mars-gale-crater-vr.
Vizor.io somewhat compatible with our next tool, JanusVR. Try it
Vizor is an interesting take on a WebVR editor in your out at scenevr.com or, to read more, head over to docs.
browser built with NodeJS and Three.js. It’s a visual scenevr.com. Within Janus you can hit ‘tab’ to create a portal to a
programming environment for WebGL, WebVR and new website, in much the same way you enter an
other HTML5 APIs. It features live preview, data flow JanusVR address into your usual web browser. Click the portal and
visualisation, network communication, publishing, Janus is more like an actual web browser for VR than a walk through to a new website, or “room”. You can even
unlimited undo, and presets that can be used as modular development tool. It’s a platform in the way that SceneVR place the Janus markup inside a traditional website
building blocks. Complex logic can be nested in is a platform, and while the client is closed source and within comment tags so that when you view the site with
subgraphs and they can be rendered directly to a built in QT5, the server-side component is open source a typical browser, you see your regular website with
specific render target, or simply used as a texture. Loops and written in NodeJS. Janus has full Oculus Rift support parsed HTML, and Janus sees the 3D version. Janus lets
are modelled as nested graphs that are evaluated once with avatars and some hand control via the leapmotion. you edit the code of the room from directly within Janus,
per loop iteration. All within your browser. To give it a try, com Leap Motion controller. Virtual environments are and save.
head to vizor.io. written in much the same way as a more traditional This is one feature making Janus a popular option for
website is created. An HTML-like syntax is used to set up web developers to start the transition to building VR. It
SceneVR “rooms” with basic JavaScript support. As virtual even has built-in multi-user support so you can walk
Scene is an open source platform built using WebGL and environments are just websites in Janus, you can serve around the internet with your friends, and talk to them
Three.js for the client and NodeJS for the server side and them up like a traditional site, using whatever server you via the built-in voice chat support. It’s a lot of fun and has
multiplayer component. With Scene you can create like, hosting it anywhere. It’s distributed just like the web a very low learning curve, especially if you’re already
virtual reality scenes using a simple HTML-like markup, of today. 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 – it’s 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 countdown
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
to WebVR
make it more useful or provide new experiences while JOSH CARPENTER (PRODUCT DESIGN LEAD ON THE MOZVR TEAM)
you interact with it. You can walk around with AR devices REVEALS HOW MOZILLA ARE BUILDING THE NEXT-GEN OPEN WEB
untethered by cables. There’s typically a camera which
you may see through, or perhaps light is projected Q . What is the MozVR mission? much more accessible for developers, thanks to new
directly onto the retina to create pixels that appear to To help build the next great generation of the open web developer tools like A-Frame and Vizor.

www.fullengineeringbook.net
the user to be in the real world. This is the by upgrading it for high-performance virtual
area that products like MagicLeap reality and all forms of immersive Firefox Nightly currently ofers support for Android.
(magicleap.com) are turning their Liv computing beyond. We believe it is the Are there any plans to add iOS to the list?
focus on. Erickson @ imperative of those of us who love the Firefox for iOS is very new so it’s too soon to say how it
They’re fairly independent misslivirose open web to be proactive about will evolve, but our team would love to see WebVR
concepts but already we’re This is the account for a VR & AR extending it early into promising running inside it eventually, as is the case with Firefox for
looking for ways to make them developer at Microsoft who often frontiers like VR, so that it is present Android. In the meantime, the great thing about WebVR
converge. Imagine a device that writes a lot about teaching VR & for developers and users from day is that it runs wherever WebGL is available. With WebGL
could let you see and interact AR as well as sharing her one, and awesome.
with the real world until you want experiences as she learns
to watch a movie with your friends more herself. Who works on the MozVR team, how
in VR. At that point it would simply take did it come together and how is it being The easy way to
up your entire field of view and provide a funded?
more virtual experience rather than augmented. We’re a group of designers, engineers, and researchers create for VR
The web is a concept that works with both, either by working from the ofice of the CTO, an organisation
re-imaging webpages as virtual places you can interact within Mozilla that works to invent the next generation of WEBGL IS HARD. A-FRAME IS
with, or by overlaying information from the web onto the web platform. Our team includes both full-time GOING TO CHANGE THAT
existing real world objects. The point is that the members such as myself and Vlad Vukicevic (co-creator
underlying network of the internet itself can be applied of WebGL), and passionate volunteers who just want to WebGL is the backbone of today’s WebVR. It has
to and can support both mediums in very useful ways. work on something they believe in deeply. It was two of amazing 3D performance and broad adoption. And
us to start with, and we’ve been expanding the team in it’s 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. It’s 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, we’ve 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. We’re 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

24 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

“ Virtual reality consists of creating new


worlds in which to immerse yourself and
others within
Essential VR


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.
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?
Resources
A COLLECTION THAT WILL
MAKE YOUR VR BETTER

You’ll put on your headset, and surf the web. Gliding from
Which VR hardware is getting you excited? link to link, into experiences that are “worlds”, not “sites”.
All of it! There’s so much to choose from. Multiple These experiences will satisfy new jobs to be done,
companies approaching the market from very diferent emphasising what is uniquely awesome about VR: awe,
angles means we have an amazing array of hardware immediacy, empathy, and so on. You’ll still use your
coming, from low-cost mobile solutions to high-end phone and your laptop to book a flight. But you’ll preview
room-scale rigs. I personally have a soft spot for the the destination in VR. Meanwhile, native VR will be
Vive’s full-positional tracking and motion control. Mice amazing, but WebVR will add an essential Cardboard Design Lab
and keyboards are wonderfully eficient input devices, complementary parallel. Lower friction, more content, bit.ly/1X2cpU7
but they’re kinesthetically constrained. I want to design and truly connected with the rest of the digital world, not A set of intrinsic rules that you need to know
like how Jiro makes sushi, with fluid motion and freedom just the other handful of people who own the same to be able to respect physiologically and
of movement. The hardware for that is going be a reality headset as you. We’re extremely excited about the next treat your users carefully. Google has
soon, and I cannot wait. 12 months. It’s going to get very, very interesting. regrouped some of these principles in an
app so you can learn through this great
immersive experience.

WebVR Information
webvr.info

www.fullengineeringbook.net 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. It’s a great quick
stop for getting into the nitty gritty of the
idea behind WebVR and why.

James individual, connecting to an ecosystem of devices, cloud


platforms and intelligent spaces. 3D User Interfaces: Theory
and Practice
Deeley “This ‘mixed reality’ will blend virtual reality with
augmented reality, ambient and in-store technology and
wearable devices.
bit.ly/1T3aBV7
This book addresses the critical area of 3D
Creative strategy director at Amaze “We know that the next wave will move VR on from user interface design – a field that seeks to
being just a ‘headset experience’ and extend it into the answer detailed questions that make the
Virtual Reality has attracted a lot of excitement and wider environment. This might be via the use of gloves, difference between a 3D system that is
buzz recently. Yet, for it to be around for the long sensors and connected devices, afecting the way we usable and efficient and conversely, one that
term, brands are going to have to start getting interact and control our involvement, and that causes user frustration, errors, and even
smarter in how they use it, particularly if it is to avoid development has a real purpose beyond just the ‘wow’ physical discomfort.
being another ‘gimmick’. We all expect VR to have a factor.
big future in gaming, and in immersive brand and “The next leap forward will be to make the VR Oculus Developer Center
retail experiences, but to reach the everyday it will world live – using it to experience live events, to control developer.oculus.com
also need to ofer something for the home and perspectives and go deep inside stories and experiences. Signing up for an account here can give you
contribute to the way in which we live our lives today, Then finally, VR will make it into the home. Like all truly access to the developer forums which
and also tomorrow. vital technology, for VR to grow and become part of our contain tons of nuggets of information and
“The smart approach is to see VR as a part of a everyday it needs to start to disappear, to be so simple to discussion about VR, best practices, and
wider technology evolution, all built around the use and so beneficial that we don’t think twice about it. 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 the project resources. Enter code/start and then
retailer from before the time of the web hasn’t run npm install to begin installing the Stripe
either felt its impact or been gobbled up by Node.js library
web-born goliaths that have adopted their business
models for the internet era. E-commerce is also hard, 4. Get the Stripe JS library
sure, you pay for things online all of the time, but the Using Stripe has been made even simpler by the
credit card details aren’t going straight from us to the lovely developers over at Stripe who have put
service you’re paying, often a payment gateway service is together a ton of neat libraries for us to use. You’re

www.fullengineeringbook.net
used somewhere along the line to process your credit going to grab the Stripe.js library that will let us
card and pass along the information to the retailer that build what’s known as a custom forms which is a
you just made a purchase from. form like any other, but with Stripe integrated into it.
If you’re the owner of a small web store, or just want to Open ‘index.html’ and just after where you import jQuery 7. Find the publishable Stripe key
take payments for some reason or another on your own at the bottom of the HTML document add: In order to interact with the Stripe API, you need to get
website, integrating with one of these payment gateways <script src="https://code.jquery.com/ what’s called the “publishable key”. By including this key
can be tough and complicated. jquery-1.11.3.min.js"></script> with each request you make to Stripe, the API can
Fortunately for us, there’s Stripe, a simple but powerful <!-- Add this --> identify us and handle payments appropriately. You can
API that allows us to process and receive monies from <script type="text/javascript" src="https:// find your publishable keys at dashboard.stripe.com/
card payments without too much hassle. In this tutorial, js.stripe.com/v2/"></script> account/apikeys. Use the TEST key for this tutorial and
you’re going to take a demo web-store and implement <!-- --> never share your secret keys with anyone.
Stripe.js and the Stripe API into it. <script src="scripts/storeUI.js"></script>
8. Back to core.js
1. Get a Stripe account 5. A home for the JavaScript Once you’ve got your TEST publishable Stripe key, head
Before you kick this project of, you’re going to need to All of the code that the store uses to keep a track of an back to core.js and just after where you initialised the
get ourselves a Stripe account. Head on over to order is in the storeUI.js file in the scripts folder. You don’t store events, add Stripe.setPublishableKey();
dashboard.stripe.com/register and follow the on-screen need to do anything with this, it’s a helper library for the function init(){
instructions in order to get a Stripe account set up. Once store, but you do need to initialise it, and you need a store = new store_events;
you’ve received a confirmation email from Stripe come place to do that from. Add the following just after where Stripe.setPublishableKey('YOUR_TEST_
back here. you import the storeUI.js file into ‘index.html’ and then PUBLISHABLE_STRIPE_KEY');
open core.js for editing. }
2. Grab the project resources <script src="scripts/core.js"></script
We’re not going to build a web store from scratch 9. Create a card payment form
because that’s not what this tutorial is about. In the 6. Initialise the store You may have noticed that although you have some
FileSilo resources for this project, there is a prebuilt web Our demo store is made up of a couple of forms and code to make a shopping cart, you don’t have any
store with all of the things you need to handle a basic inventory items. You don’t want to concern ourselves markup to take the users card details when they try to
ordering process. Download the demo files and move with binding events and handling callbacks in core.js, so checkout. Let’s do that now. In index.html, just after the
them into a folder of your choosing, keeping the all of the logic is in storeUI.js - but it hasn’t been initialised <button> element with the id of “false_purchase” add the
directory structure intact. yet. In the init() function of your core.js file add the following markup to your code:
following code: <div id="card_creds" data-display="false">
3. Install Node.js dependancies function init(){
Now go ahead and open up terminal (or command store = new store_events; <div class="container">
prompt if you’re on Windows) and you will need to }
change directory to the location where you just stored all This will create all of the event listeners you’ll need. <h3>Please enter your card details</h3>

26 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

<label> </label> processed. Once those details have been validated a


<span>Card Number</span> <label> one-time-use token will be returned to us. To test the
<input type="text" size="20" /> <span>CVC</span> code out, you can use any of the card details from stripe.
</label> <input type="text" size="4" data- com/docs/testing, so long as you’re using the TEST
<label> stripe="cvc"/> publishable API key.
<span>CVC</span> </label> order_form.addEventListener('submit',
<input type="text" size="4" /> <label> function(){
</label> <span>Expiration (MM/YYYY)</span> Stripe.card.createToken(order_form,
<label> function(status, res){
<span>Expiration (MM/YYYY)</span> <input type="text" size="2" data- if(status !== 200){
<input type="text" size="2" /> stripe="exp-month"/> alert("Something went wrong. Sorry");
<span> / </span> <span> / </span> order_form.reset();
<input type="text" size="4" /> <input type="text" size="4" data- }
</label> stripe="exp-year"/> else
</label> {
<input type="submit" value="Pay" /> submitOrder(res.id, function(response){
</div> <input type="submit" value="Pay" /> store.closeForm();
</div> </div> store.showReceipt
</div> (response.thingsBought);
10. Work with data-stripe });
Right now, the #card_creds form doesn’t do anything 11. Set user’s security and liability }
special with Stripe. In order to make Stripe recognise the Using the data-stripe attributes allows Stripe to strip out });
form, you need to add data-stripe attributes to the all sensitive data about the user before it ever hits the });
elements that contain specific parts of the cards details server. Cyber-crime is on the rise and you can’t all aford
so that they can be passed on to Stripe. to have a security team working to ensure that all of the 13. The order token
For the credit card number you add data- servers are impenetrable. By allowing Stripe to take We don’t want the users card details to go anywhere

www.fullengineeringbook.net
stripe=”number” to the input where you expect the user sensitive payment data of of our hands before it ever near the server because that opens up to a world of
to add the card number, for the CVC (3 numbers on the hits the server, you never have to worry about the potential trouble (see the ‘Why tokens?’ boxout), but how
back of the card) you add data-stripe=”cvc” and so on security of the users or the liability if ever you were to is a payment processed? Simple, you can use the token
and so forth. have a data breach. you just received in the response from the Stripe API.
<div id="card_creds" data-display="false"> Along with the customers order, you send the order
12. Test the cart
<div class="container"> Right now, if you add some items to the cart and enter
your card details into the form, the page will reload. you
<h3>Please enter your card details</h3> need to prevent the submit event and work some AJAX Store keys
Instead of switching keys every time you want to
<label> magic with Stripe to get the card details of in a usable
deploy to your production environment, save
<span>Card Number</span> way. Add the following code to the addEvents function
them as environment variables. One for your
<input type="text" size="20" data- of core.js. Using the Stripe.js library, send of the card development and one for your live platforms.
stripe="number"/> details the user has entered to the Stripe API to be

Left
Once our order has completed and our payment
accepted, our store will generate an itemised receipt for
our customer

Top left
We don’t want to build a whole store, we wouldn’t 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
doesn’t 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 product-id'), item purchased by the customer and returns an
deduct a credit from the users balance. Before you do price : thisItem.getAttribute('data-price') organised list.
that, you need to sort out the customers order. });
17. Parse the request
14. Tally up the order payload.total += parseInt(thisItem. On lines 71 and 72 of stripeServer.js,, parse the body of
Before you send to the order to the server, you need to getAttribute('data-price')); the AJAX request sent to the server to retrieve the order
create a payload describing what they actually ordered }} payload and Stripe token for the customer. Now that you
that you can process server-side. In the empty have a Stripe token, you can charge the customers card
submitOrder function of core.js add the following. First, it 15. Send the order to the server (stored on the Stripe servers) using this token. you do
takes all of the items out of the cart and puts them into Now that you have the payload containing the total price this with stripe.charges.create(); This function takes two
an array, then it gets the price of those items and creates and the items in the cart, as well as the stripe token we’ve arguments. An option argument, which needs to contain
a total in pence (assuming you’re using GBP) which you acquired, it’s time to send it to the server. you can do this the amount of monies being charged (in pennies, a
will ultimately charge to the user. This isn’t the most using a good ol’ fashioned jQuery AJAX request. Add the currency and a payment source (our card token). The
tamper-proof way of calculating price, but it’s good for following code just after the last bit of code you added to second argument is a callback to handle the response
demoing the power of Stripe. submitOrder(); from the Stripe API.
function submitOrder(){ jQuery.ajax({ stripe.charges.create
if(token === undefined){ throw "No Stripe type : "POST", ({
card token has been passed"; } url : window.location.origin + "/order", amount: price,
data : { currency: "gbp",
var items = document. order : payload, source: card_token,
getElementById('purchase_list'). stripe_token : token description: "Customer cheese order"
getElementsByTagName('li'); }, }, ...
payload = { items : [], total : 0 }; success : callback,
for(var g = 0; g < items.length; g += 1){ error : function(err){ 18. Handle the Stripe response
var thisItem = items[g]; console.log(err); If something goes wrong, Stripe will pass an error back to
}, the server, but if there is no error, everything has gone

www.fullengineeringbook.net
payload.items.push({ dataType : "json" great, you’ve been paid! (although it may take up to 7
productID : thisItem.getAttribute('data- } days for you to receive the money); Now you need to
) inform the user, which you do here with res.json. It’s at
; this point that you would write logic to set up a delivery
or store the order in a database somewhere or maybe
All in the platform 16. Receive the order
In the root of your project folder, open stripeServer.js. On
send a confirmation email, but that implementation is up
to you and your (or your customers) needs.
If you want put your store in an app, you don’t
have to change much. Stripe has libraries for iOS lines 69-100 define a single endpoint, /order. This is ... function(err, charge)
and Android. If you’re running a Cordova app, where you will handle the data that has been sent from {
use the same process, but whitelist stripe.com.
the demo store. On lines 37-67 you will have the if (err && err.type === 'StripeCardError')
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 let’s you know for certain the exact quantity
of produce purchased by the server
Right
When you’re testing the code out, you don’t 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


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, it’s
unlike you’ll ever be able to
match the strength of security
ofered by an enterprise-level
payments platform. Stripe’s 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, it’s
what they’re really good at. On a
side note, say you do store card
details on your service and you
get hacked, you’re liable for that
data’s 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); confirmed by Stripe the Node server sends a JSON-


res.json({ encoded itemised list in its response. the helper library Detecting fraud
Stripe uses machine learning algorithms to
status : "ERR", that’s been handling all of the store logic kicks in here
detect potential fraudulent purchases. If you

www.fullengineeringbook.net
message : "Something has gone horribly again. Once that the confirmation has finally been
know a payment was genuine you can tell Stripe
wrong" received, it will reset and close the card details overlay and they’ll process the payment.
}); and if you pass the itemised list that the server sends
} back, then it will generate a receipt to show the customer
else what they have ordered. This will happen in the callback reset everything when they close the receipt dialog, but
{ you passed as part of the submitOrder function call, as on a real store, we would let them browse around the
res.json({ we have shown below: website or you can even view all of their orders in a
status : "OK", submitOrder(res.id, function(response) dashboard somewhere if that’s what you want.
thingsBought : itemisedItems {
}); store.closeForm(); 21. Prime time
} store.showReceipt(response.thingsBought); When you’re ready to take your new web store live, don’t
}); forget to change the TEST publishable API key to the
20. Square one LIVE one. Otherwise, all of the orders that you end up
19. Generate a receipt So that’s the order process complete. Now you can show taking won’t actually charge the people for any of the
On the client-side, the form will still be waiting for a the customer what they’ve ordered and then you can let purchases that they make, regardless of the validity of
response from the server. Once payment has been them continue on their way. In this case, you can now 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 we’d 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 2. Basic responsive images <img src="small.jpg"
thing designers and developers have been Responsive images will need to shrink with their alt="text for screen readers"
looking for better tools to manage imagery containers. The code that we’re using below is a bit srcset="medium.jpg 500w,
across many diferent clients and viewports. With the counter-intuitive because it suggests that it just limits the large.jpg 800w"
advent of the srcset attribute and picture elements, this is width of the image, but in efect it implies the image sizes="66vw" />
now achievable in modern browsers and responsive should be flexible in its width. These images are really
images are even starting to become possible on mobile flexible rather than responsive. 6. Responsive srcset behavior
devices, with Android 4.4.4 ofering good native support. img The sizes attribute also takes media queries, which allows
For aging browsers, Scott Jehl’s picturefill JavaScript { developers to change the behaviour of images
polyfill can be used to plaster over the cracks – although max-width: 100%; depending on the viewport. Here, 66vw is used
network performance will still be an issue. } whenever the viewport is wider than 499px, otherwise
The pinnacle of this new feature set from HTML5 is the the image will display with 100vw.
picture element, enabling creative teams finite control of 3. Change resolutions with srcset <img src="small.jpg"
how images are presented to their web browser – Modern browsers can make use of the srcset attribute alt="text for screen readers"
creative teams are finally able to give art direction on a that enables the browser to make a decision with regards srcset="medium.jpg 600w,
per-client basis. This can be something that works as to what image to actually display. The width specified large.jpg 1200w"
simple as serving diferent aspect ratios to mobile after each additional image path corresponds to the sizes="(min-width: 500px) 66vw,
devices, to serving entirely diferent image compositions width of the image. 100vw"
for diferent viewports. <img src="small.jpg" />
This tutorial will walk you through the process of alt="text for screen readers"
crafting flexible images the old way, image swapping srcset="medium.jpg 600w, 7. Retina support with srcset
using srcset for diferent viewports and display large.jpg 1200w" /> Srcset enables developers to specify the use of hi-DPI
capabilities, fully responsive images using picture, using imagery via the x descriptor. Unfortunately though,
picturefill the right way, and finally bringing all of these 4. See srcset in action images with the x descriptor are fixed-width only (not
components together to produce an interactive demo Here’s a basic implementation of srcset on jsfiddle as a flexible), which limits their usefulness. This is something
that exploits the best that a picture has to ofer. Maximise live demo (jsfiddle.net/aqx9aoat). The browser has that prove to be handy for making hi-res cropped

www.fullengineeringbook.net
your online real estate now. chosen to display the 500px width image rather than the background efects, however.
initial 1000px one. The browser is choosing which image
1. Basic image markup to pick by itself here.
Marking up a standard image hasn’t changed for a long
time. The src attribute specifies the location of the image. 5. Control srcset behaviour Use calc in sizes
The alt attribute is for supporting text that should be The sizes attribute can enable developers to control the
The sizes attribute allows for using calc() just like
useful if the image can’t be found, or for the visually amount of screen real estate the image will take up. The CSS. This enables us to have finite control that
impaired who use screen readers. example code shown specifies that the image will take wouldn’t be possible otherwise, like calc(100vw
<img src="image.jpg" up 66 per cent of the viewport width as opposed to the – 40px). It’s handy for keeping gutters on images.
alt="text for screen readers" /> preset value of 100vw.

Top left
When the user increases the width of their viewport, the
browser loads the 800px version as it’ll 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 it’s smaller in
dimensions and file size

HTML5 & CSS3 Genius Guide 31


Tips & Techniques

<img src="image.jpg" as an image. The picture simply wraps an image, passing wide800-2x.jpg 2x" />
alt="alt text" the right image path for any given media to the image
srcset="imageRetina.jpg 2x, element. Flexible images are also possible within picture 12. Markup for responsive
hiDPI.jpg 3x" elements, but they will first need to be marked up like the This final source caters for the smallest viewports and
/> code as shown below: implements the same technique as the one in Step 11.
picture img The downside to using this approach is that a lot of
8. Responsive art direction { markup is needed for one responsive image – each
The picture element enables developers to specify max-width: 100%; version will require its own source tag as well as a set of
multiple source elements and a fallback img, enabling } media queries.
media queries to be applied to each. The code shown <source
below swaps out widescreen images for square ones – 10. Starting markup media="(max-width: 500px)"
as this will be a better aspect ratio for mobile – at a Earlier on, this tutorial briefly covered Retina image srcset="square500.png 500w,
499px wide viewport. support using srcset and explained that Retina support square500-2x.jpg 2x" />
<picture> only worked for fixed-width images. Picture can provide
<source us with a way around that problem by making use of the 13. Style picture elements
media="(min-width: 500px)" media attribute. As you can see in the code below: Picture elements are essentially glorified spans – a
srcset="wideLarge.jpg 800w, catering for wide devices first, the fallback.jpg file will now display:block later and you’re able to add whatever styles
wideMedium.jpg 500w" /> be replaced with wide1200.png. that you want. The code shown below uses calc and
<source <picture class="album"> margin to add gutters to the picture, as well as show a
srcset="squareLarge.jpg 800w, <source nice box shadow.
squareMedium.jpg 500w" /> media="(min-width: 801px)" .album {
<img src="fallback.jpg" alt="" /> srcset="wide1200.png 1200w" /> display: block;
</picture> <!-- ... --> width: calc(100% 40px);
<img src="fallback.jpg" alt="" /> margin: 0 auto;
9. Style picture elements </picture> box-shadow: #A39A9A 0 0 30px;
This may also appear to be counter-intuitive, but the position: relative;
11. Responsive Retina images
www.fullengineeringbook.net
picture element can’t exactly be styled in the same way }
In this additional source the media attribute specifies that
these images are only to apply to viewports between 14. Extended picture styling
501px and 800px. Srcset will then load the image that is Because the picture element behaves like a regular span,

Comment sources found to be the most suitable to the client with either the
1x or 2x versions of wide800.
the element can be extended with :before and :after in
CSS to apply efects over the top of images. Below this, a
With so many diferent sources required for each
responsive image being implemented, it pays <source gradient is overlaid the image. View the full source of this
dividends to write HTML comments to help keep media="(max-width: 800px) and (min- demo on FileSilo.
track of the images being sourced. width:501px)" .album:before
srcset="wide800.png 800w, {

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 Apple’s
iPad, when they eventually support it

32 HTML5 & CSS3 Genius Guide


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. It’s
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).

www.fullengineeringbook.net
“possible image for a given environment
The ultimate goal is [...] to deliver the best
content: '';
position: absolute;
width: 100%;
height: 100%;
background:linear-gradient(...);
}
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.
{
display: flex;
align-items: center;

15. Image styling picture img { justify-content: center;
Picture essentially progressively enhances img elements. -webkit-filter: contrast(1.25); }
CSS can still target the image, just as if it’s inside a regular }
container. Images inside picture elements are available 20. Picture polyfill
for styling just like any other image. 18. Centre everything Scott Jehl has led the development of a polyfill for the
picture img { The first part of centring the image is to have the Picture element called picturefill. Why not head over to
border-radius: 3px; container (in this case, the page body) fill the entire GitHub (github.com/scottjehl/picturefill/releases) right
} viewport. This is easily achieved using absolute now, in order to download the latest release and try it out
picture { positioning and resetting any margins/padding to 0. for yourself.
border-radius: 3px; body
} { 21. Use picturefill
margin: 0; Like most polyfills, using picturefill is very straightforward.
16. Add interactions padding:0; First, make sure that you reference the script in the head
The process of adding interactions to picture elements is position: absolute; of the page – the async attribute is optional but it’s
slightly diferent. Binding hover to the picture element height: 100%; beneficial for performance. Also you should create the
ensures the hover will work as intended. However, the width: 100%; element for any browsers that don’t support HTML5
visual feedback still needs to happen on the image, so background-color: #E1E4E2; – but bare in mind that this isn’t a required step if HTML5
that’s where styles should be applied. } shiv is already present.
picture:hover img { <head>
opacity: 0.5; 19. Vertical centre <script>
cursor: pointer; Flexbox can easily be used to vertically centre content of // Picture element HTML5 shiv
} variable height. Align-items will vertically centre child document.createElement( "picture" );
elements, and justify-content horizontally will centre </script>
17. Add filters them. Try playing around with these in dev tools to see <script src="picturefill.js" async>
With filters coming to CSS, developers are able to apply how they behave. </script>
filter efects to DOM elements – this includes picture body </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 centred on the page and a background image is placed 5. Reference individual graphics
designers have to inhabit, sizing graphics is of in there so that all the vector lines and shapes have a Once the scene has finished loading up, we will need to
the utmost importance to us as web designers. background to stand out against. do an important part of the tutorial – we need to
Getting crisp graphics on both a phone and on a huge <style> reference individual graphic elements so that they can
cinema display monitor is not just desirable, but essential. svg{ be animated or interacted with on the page. Here the
To that end most of us have switched to using SVG display: block; variables will reference unique IDs and these IDs are the
images for our icons and line art drawings, which are margin: 0 auto; ones that you’d find on any regular HTML tag. They will
always crisp on every display. Not only that but the file background-image: url(bg.jpg); be stored in a variable to be used later on.
size is often much smaller than a PNG image. When it } var menu = f.select("#menu"),
comes to creating animated images or interaction with </style>
graphically rich content we will need a solution that can pin = f.select("#pin"),
help us do this too. Thankfully Snap.svg comes to the 3. Start up Snap.svg chatPin = f.select("#chatPin"),
rescue because it lets us use crisp SVG graphics but also After the CSS styling in the head section, script tags are thumb = f.select("#thumb"),
adds the polish that clients have come to love for their added with an onload function that detects if the page disc = f.select("#disc"),
shiny web apps. has finished loading. Once the page has been loaded up,
In this tutorial we are going to use Snap.svg to create two variables will be declared. One of these variables will 6. More references
one of those exploded-view images that you would find hold a timer that waits a fraction of a second before Notice that each line of the code shown below has the
in Haynes’ car manuals but we’re going to dissect a starting the animation and another variable holds the variable that is then followed by the letter f. If you take a
mobile app. We’ll take a regular SVG created in Illustrator Snap SVG file. look at Step 4’s code, you will notice that the f included
and add animations to this, then make some of the <script> there appears inside the brackets of the function, and all
buttons on the interface work. These will drop pins onto a window.onload = function () { of this code is in that function. The letter f simply stands
map and slide an of-canvas menu onto the screen. This var timer; for file and it is a reference to the SVG file that we had set
provides a great introduction into how you can make var s = Snap(1280, 800); to load from before.
your own graphically rich applications using Snap.svg. }; header = f.select("#header"),
</script> icons = f.select("#icons"),
1. Start the project base = f.select("#base"),
4. Load an SVG file
www.fullengineeringbook.net
To start of the project, take the tutorial files from FileSilo baseText = f.select("#baseText"),
and open the Start folder in a code editor such as Before the closing bracket of the onload function in the
Brackets. In the head section of the index.html page add previous step, add the code shown here. This tells snap
a link as shown to the Snap.svg library. You can also to load the scene.svg file. Notice the comment that states
download the library from snapsvg.io for reference.
<script src="js/snap.svg-min.js"></script>
the ‘tutorial code goes here’ – this is where the rest of the
tutorial code will go. Because once the SVG is loaded, the
Coding Snap.svg
Snap.svg uses JavaScript to manipulate the still
code between the curly brackets is called. SVG images that you import into it. The code
2. Style the SVG element Snap.load("scene.svg", function(f) { adds animation and interactivity to the graphics
Just after the Snap code library has been imported, the //TUTORIAL CODE GOES HERE for a rich user experience.
CSS styling for the SVG element is set. This is displayed, });

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 we added in Step 8 as this efect should be applied thumb.animate( {transform: "t0,-160"},1500,
Here the last references are stored in variables and you before the image is displayed. mina.backout );
may be wondering where exactly these names came menu.attr({ opacity:0 }); disc.animate({transform: "t0,-150"},1100,
from or how they got in the SVG file. When graphics are pin.attr({ opacity:0 }); mina.backout);
grouped together in Illustrator, they can be named in the chatPin.attr({ opacity:0 }); header.animate({transform: "t0,-130"},850,
layer panel, these names are applied as IDs when mina.backout);
exported into SVG. 10. Hide ‘hit areas’ of buttons icons.animate({transform: "t0,-100"},550,
map = f.select("#map"), You can refresh the browser now and see the updates to mina.backout);
people = f.select("#peopleBtn"), the graphic from the previous step. There are some hit }
chat = f.select("#chatBtn"), areas for buttons to hide the button icons, so those will
burger = f.select("#burgerBtn"); need to be made invisible as well. Add this code that 13. More animation
we’ve provided below immediately after the code from The graphics that are at the bottom of the app will also
8. Display the SVG on the page the last step. need to be animated, and so does the map in the
The next line of code is quite an important line because people.attr({ opacity:0 }); background. Add the following lines of code before the
this line displays the graphic on the screen. If you chat.attr({ opacity:0 }); closing bracket that we showed you in the previous step.
remember that s is the Snap reference, then append burger.attr({ opacity:0 }); Now just save the file and view it in your browser to see
means to add to that, so we use the reference of f which all the elements animate into position on the screen.
is the SVG file. Save the page now and hit the ‘live 11. Leave a pause baseText.animate({transform: "t0,-130"},850,
preview’ in Brackets or view the page from a server to Once the graphic is on the screen, the animation is ready mina.backout);
see the graphic. to be applied but it should wait a little before starting – base.animate({transform: "t0,-100"},550,
s.append(f); this is so that the user can see the graphic, then see it as mina.backout);
it moves into position. Add the code here after the s. map.animate({transform: "t0,-70"},450, mina.
9. Clean up the graphic append(f); from Step 8. This code will set a timer to wait backout);
At present there are some pins floating in space and a for 300 milliseconds.
menu that is obstructing the way of the main graphic. timer = setTimeout(designIn, 300); 14. Move the thumb icon
These will be important to us later but for now let’s make function designIn() { As it stands, the animation stops moving but it would be

www.fullengineeringbook.net
them invisible. Place the code here, just before the line clearTimeout(timer); good if we could make the thumb continuously bob
about in the graphic. Go back to the code added in Step
12. Animate the graphics 12 and amend the ‘thumb’ code as shown. This will call
Add the code to finish the function from the previous another function thumbUp when it has finished.

Animating scale
If you want to animate the scale of an image,
step. These graphics are animated with a slight bounce
to get them into the position we want. The t inside the
thumb.animate( {transform: "t0,-160"},1600,
mina.backout, function(){thumbUp()} );
then SVG is the perfect graphic to scale as it is a transform means that they are transformed relatively
vector and it can be blown up in size without any from their current position. The timing of each is placed 15. Move the thumb up
loss of quality. after this. Then just hit Save and view it in the browser to The thumbUp function is added here and it needs to go
see the animation. just below the closing bracket of the designIn function.

Top left
A little tidy up is required as some graphics aren’t 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


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
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.
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
subsequently slows down again. popcorn.cue( 17.2, people.click(function () will display at a time.
function thumbUp() { pin.animate({opacity:0, transform:
{ pin.animate({opacity:1, transform: "t0,0"},900, mina.backin);
"t0,280"},900, mina.backout);
thumb.animate( {transform: "t0,-210"},800, });
mina.easeinout, function() {thumbDown()} ); 21. Bring in the menu
18. Click the chat icon Right back at the start there was a menu that was made
} Similar to the previous step, if the user clicks on the chat invisible. Now let’s make the burger icon a button that
icon, the chat pin should drop onto the map and show can be clicked and this will bring the of-canvas menu
16. Move back again the location of the chat. The code adds this on-click into the app. Add this code below, which will animate this
Once the thumb has moved up, it calls the function animation, and once this is done you can save the page onto the screen. Then save this and try clicking the icon
thumbDown so now we will add that function below. and view it in a browser to test that the click is working. in the browser.
Again this moves the thumb down and calls the chat.click(function () { burger.click(function () {
thumbUp function that keeps the thumb bobbing up chatPin.animate({opacity:1, transform: menu.animate({opacity:1, transform:
and down in a loop. Now just save this and view it in the "t0,280"},900, mina.backout); "t150,-70"},900, mina.backout);
browser, as we have done previously, to see the }); });
animation in action.
function thumbDown() 19. Reset the pins
{ When the user clicks either of the icons and the pins 22. Remove the menu
drop into position, they will stay there. It’s possible to only To get rid of the menu, it is as easy as letting the user
thumb.animate( {transform: "t0,-160"},800, show one at a time by making the first pin animate back click on the actual menu itself. Adding the following code
mina.easeinout, function(){thumbUp()} ); of when the other icon is pressed. Just add this line of will animate it back to the original position, while also
code to the click function of Step 17 to do exactly that. taking the opacity down and making the menu invisible.
} chatPin.animate({opacity:0, transform: Save this and view again in the browser to see and test
"t0,0"},900, mina.backin); all the functionality.
17. Add interactivity menu.click(function () {
It’s time to make the graphic interactive now. Adding the 20. Adjust the second pin menu.animate({opacity:0, transform:
next set of code will make the icon of the person a As in the previous step, the code here needs adding to "t0,0"},900, mina.backin);
button. Clicking on this button will make the pin animate the click function in Step 19. This will make the first pin });

HTML5 & CSS3 Genius Guide 37


Tips & Techniques

Build with 5 best


libraries
and tools
AngularJS
Learn everything you need to know to start building
web apps with the framework
Lodash
lodash.com

Start building 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
START WITH THE DATA, FIND APIS, READ THE DATA THAT THEY PROVIDE so it’s a good idea to use it instead of some slower
AND THAT’LL GIVE YOU IDEAS AngularJS methods.

Package managers can simplify the finding, Structuring your app Angular UI
downloading and updating process of app Organising an app is tricky in the beginning. AngularJS angular-ui.github.io
dependencies, and there’s no good reason not allows for complete flexibility which also means that you AngularUI is an amazing set of tools, frameworks
to use them. You can install AngularJS with NPM, the have to figure out the best way. Think about it as and even directives to help you build your Angular

www.fullengineeringbook.net
Node package manager, or with the help of Bower. something organic that can be modified down the line apps faster.
You might find that some packages that you want are and grow and change with your app.
not on NPM however it is the most reliable manager for Start of by putting all your files in the main directory
you to use. Bower can be slightly less reliable but it does and create a new subdirectory to group files together as
benefit from there being more front-end packages you progress.
available, as well as its use of a flat dependency tree, so It’s better to structure your app in folders by feature
you are probably better of with using it as a manager rather than by type (for example as services, controllers,
over NPM. templates and so on). That way it’s easier to locate your
Remember to save all your dependencies in code quickly, keep a flat structure, and stay DRY
your package file regardless of the package (don’t repeat yourself). It might feel UI Router
manager that you use, so your app is To Follow counterintuitive initially, but as github.com/angular-ui/ui-router
easy to share or reinstall. Adventures In Angular applications grow over a certain size, UI Router is part of Angular UI and has become
@angularpodcast it’s quite dificult to find things if files the de facto routing framework that everyone
Build Adventures in Angular is a weekly are organised by type. It’s very likely uses. It’s much more powerful than ngRoute – the
In AngularJS, modularity is a key podcast dedicated to all matters that code is going to be repeated so one provided by Angular. It allows you to manage
principle and you’ll soon find out that of the framework. Guests from try to avoid that as much as you can. your application’s interface by states bound to
there are many small files that you Ionic and GSAP have both Choose a naming convention and named, nested and parallel views, providing a lot
want to load. It’s not a good idea to appeared on the podcast make sure that you stick to using it. of flexibility.
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 UI Bootstrap
could come up if your app ends up in production ensure that you organise your app in folders by angular-ui.github.io/bootstrap/
looking like that. For these reasons it’s better to use a feature, it will help you a lot if you add a type sufix to the Another component of Angular UI is UI Bootstrap,
task runner or tool, like Grunt or Gulp, to help you run names such as example.controller.js. a very useful set of AngularJS directives that
some tasks and optimise your workflow. Modularity is also quite important, although it’s not a mimics Bootstrap components. If you use
requirement. You could potentially have everything Foundation there’s an unoficial port of UI
The key tasks that you are going to want in your build under the main app module and it would work okay. But Bootstrap called Angular Foundation.
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 John Papa’s Angular Styleguide
and production then other modules to be shared across the app and github.com/johnpapa/angular-styleguide/
– Watch files for change modules by feature. blob/master/README.md
– Concatenate, mangle and minify The main benefit of this type of structure shines John Papa wrote an amazingly thorough and very
– Create source maps for easier debugging through on big apps; also it’s good to note that by having opinionated style guide that has been improved
– Linting (especially for teams) this level of modularity, it’s very easy to reuse modules upon by a good number of contributions. This is
– Run tests on diferent apps. highly recommended reading.

38 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Bootstrapping
ANGULARJS IS NOT BASED ON CONVENTIONS LIKE OTHER FRAMEWORKS

It’s 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 it’s better to stick to a series of module by omitting the second argument
conventions. In AngularJS the best way of To Follow angular.module(‘exampleApp’);.
working is by creating single Joe Eames
responsibility modules that will work @josepheames Configuration
together with other modules to Joe is a panelist in the JS Jabber In a configuration block you set
create an app, which is in itself a and Adventures in AngularJS elements like routes, exception
module. Then you just inject the podcasts and a great developer handlers, providers and constants
services that the diferent modules to follow. He is the organiser of which need to be there before the
Rafa Garcia-Lepper provide, keeping your code tidy. ngConf, and active in app starts.
Lead front-end engineer To bootstrap an app, all you need to sharing tips and advice.
do is to declare a module, give it a name Run block
“AngularJS is an amazing and then declare all the other modules on In a run block, you trigger logic that needs to
framework for creating which it depends. Then in the HTML you can load the happen when the app is starting. Things like
data-driven SPAs. Working app in any element you want; AngularJS will replace authentication, translation or analytics, for example, will
with it is a lot of fun and I love anything inside it with the views of your app. belong in here. It’s better to not write the logic code
that it encourages me to A module is a collection of configuration and run inside the run block for testing. Rather, create factory
write better code.”

www.fullengineeringbook.net
blocks although you don’t actually need either. It sounds services with the logic, inject them in the run block and
confusing but to create a module all you need to do is to then invoke the required methods from it.

“ To bootstrap an app… declare a module, give it a name and then


declare all the other modules on which it depends

Performance Security
IT CAN BE EASY TO MESS UP THE DIGEST CYCLE
ANGULARJS INTRODUCES SOME
Every model in AngularJS is represented as a $scope It’s important for you to be aware of this issue and so,
RISKS WORTH NOTING
object and these will make use of an array called you should make sure that you avoid any of the
$$watchers, which can then be utilised to store unnecessary cycles by minimising the number of
Avoid mixing server and the
functions. Every single time that $watch is called or a watched values. Filters can be a performance problem
client templates
value is bound from the DOM (using ng-repeat, ng-class, too because they are run twice with every digest cycle
In AngularJS, templates are just HTML files, but you can
ng-show and so on) a and because they only
call a server-side file which will be processed and sent as
new function will be hide the filtered items
HTML. The risk is clear as you are exposing some code
stored in $$watchers. using CSS, which means
that will be executed on the server, potentially
Every single time that that the collection will
introducing some unintended XSS vectors.
one of these values in the stay in memory. Try not
$scope object is modified, to use filters unless you
CSRF
the digest cycle will go really have to.
If there’s a cookie called XSRF-TOKEN, AngularJS will
through the $$watchers Also, you’ll find that it’s
recognise it and automatically convert it into a request
array and it will then run faster to work with simple
header X-XSRF-TOKEN. This will be sent on every request
all of the functions in it. objects, especially with
sent by $http for the server to validate the token.
If any of the functions the data that comes from
in the array changes any the backend. Try to make
The ngSanitize module
watched value in the sure that the object has
This module changes how AngularJS encodes the
scope, then the cycle will only the keys that are
output and creates a list of allowable HTML elements,
run again. really necessary.
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


To communicate with
the controller, then
the backend, use a
in the activation
factory, inject $http
function call the
and return an object
getExample function
exposing all the
for the example
public methods.
data and wait for
the promise.

Use $http to make a Create a function


request to the API getExample to call
and use then and the service for the
catch. Try to avoid data and wait for the
anonymous promise; next, set
functions to improve the data and resolve
code readability. the promise.

www.fullengineeringbook.net
Communicating with the backend data from and its interface. If you require some data in a it blindly. Make sure you learn about scopes in AngularJS
When making requests to the backend, it’s tempting to controller for a view to work, load it in the resolve first. If you need to manipulate the DOM at all, you need
do it from the controller, but it’s better not to do it and member of the state, and then inject it into the controller. to do it from a directive inside the linking function.
keep a separation of concerns. Otherwise your controller Again if you have a factory you can inject it in the resolve Angular also works nicely with jQuery. It comes with
will become bloated very quickly and it will be dificult to and use all the exposed methods. jqLite, so out of the box you’ll have a subset of the most
test and maintain. common jQuery functionality available, but if you load
You want to create a service that can be reused from Work with directives jQuery it will overwrite and become available instead.
other parts of the app. This is the best way to work with Directives are reusable self-contained components Avoid invoking directives as classes or comments. Use
AngularJS in general, but it’s particularly useful when created to add bits of enhanced HTML functionality that element directives when they are a component, when
interacting with the backend so data can be cached and are used from the views. They can have a controller and you are actually creating a new HTML tag. Use attribute
reused – this will make your app feel faster. a template and can be invoked from the HTML in four directives when they modify or add some behaviour to
Use a factory where you inject $http and create an diferent ways: by custom element, attribute, class or by an existing element.
object literal where you expose pointers to private comment. Create one directive per file, and name the file The name of a directive should be in CamelCase
functions and properties, similar to the revealing module after the directive; if it has a template file, put them exampleDIrective in JavaScript when you declare it, and
pattern. Then use $http in the private functions for the together in a folder of the same name so it’s easy to find it needs to be dash separated when invoked in the HTML
CRUD operations and return it. This way the controllers and maintain. <example-directive></example-directive>.
remain oblivious to the logic. A controller – or any other Directives inherit their parent scope by default, so it’s To get values into the directive isolated $scope, you
consumer – will only need to know what service to get probably a good idea to isolate the scope – but don’t do can use custom HTML attributes and bind them to the
scope object in the directive definition object. The keys

“ Use element directives when they are a of the scope object will be the HTML custom attributes
– using the same CamelCase to dash rule. You can bind
component, when you are actually creating them as strings by making use of @, or to an expression
using &. You can also use = to create a two-way data
a new HTML tag
40 HTML5 & CSS3 Genius Guide
” bound object.
HTML5 & CSS3
Genius Guide

Models, controllers Services


LEARNING TO USE SERVICES IS

and views KEY TO MASTERING ANGULAR


In AngularJS there are services, providers,
factories and constants that create a lot of
IF YOU ARE NOT FAMILIAR WITH THE MVC PATTERN THIS MIGHT BE confusion as they are all diferent types of
CONFUSING AT FIRST, BUT IT’S A LOT EASIER THAN IT LOOKS services. They are all singletons, so just use
factories, forget about the rest. One exception is in
AngularJS is structured around data which should bloating the controller by using $scope methods the config block, where only providers are
come from services and you want to display that would be better of in a factory. allowed. Other than that, stick to factories.
your data in the views, so what you do is If you do this, don’t forget to capture Put in services any logic that could be shared
Avoid
use a controller. A controller is bound ng-controller ‘this’ into a variable like vm, which across the app. Then all you need to do when you
to a view and the data model is Ng-controller doesn’t stands for View Model, so it doesn’t need some functionality is to inject it.
represented as the $scope object. enforce one-to-one coupling, change by context. Dependency injection is a key feature of
The $scope object is accessible from it’s not reusable and it’s not In the HTML you can display the AngularJS and it’s really nice to work with.
the view so you can have any data flexible. Attach a controller elements in the model ($scope or Make multiple small factories with one
by adding it to $scope. to a template using a route vm), all by using double curly braces responsibility each. Services can be injected into
It’s a good idea to avoid the $scope definition or a directive. like this {{vm.example}}. If you decide other services so any functionality can be reused.
object though and to use controllerAs you don’t want to bother with the This is a really nice way of working; it will keep
syntax instead. ControllerAs binds ‘this’ to controllerAs syntax, $scope is implicit so that your code clean and clearly defines the diferent
the $scope object which will help you to avoid you can just use {{example}}. parts of your app.

Register functions
www.fullengineeringbook.net
with Grunt and Gulp, so it’s easy to run tests as part of
your build process.
If you want to learn more about testing in Angular,
EXECUTE ASYNCHRONOUS OPERATIONS WITH PROMISES, CHOOSE THE then we’d recommend you to read the book AngularJS
MOST APPROPRIATE TEST TOOL AND FIND OUT HOW TO ROUTE Testing Cookbook by Simon Bailey, which gives you
easy-to-follow recipes for testing out the diferent parts of
Promises Unit tests your application.
AngularJS has a promise implementation by default Jasmine is the most common testing framework for
exposed as the $q service, it’s also implicit as part of running unit tests in AngularJS. It’s the one used by the Routing
the $http service. It might be confusing at first. The AngularJS core team, although you can use Mocha if you Ideally your app should be organised by feature
basic way you use it is by creating a deferred object prefer it. modules, and every single module that needs a route will
using $q.defer();, which you then use inside an To run tests with AngularJS you will need angular- also have its own module. When you are working with a
asynchronous operation to resolve or reject the mocks.js, which is a tool provided by the AngularJS that is UI router, you will need to declare states instead of routes
deferred object. Then you can return deferred as a designed to create replicas of the objects called mocks. – a state may or may not have a route and you can also
promise. There are very few times when you are going This makes it easier for you to decouple components nest states.
to need to use $q.defer(). Mainly it will be when you and inject and mock AngularJS services in your tests by Declare the routes in the config block of each of your
need to wrap a jQuery plugin to work in Angular and making use of ngMock. modules and then inject $stateProvider and
you need to start a promise to replace the callbacks. $urlRouterProvider.
Promises in $http are a bit diferent, but you’ll be safe End to end Use $stateProvider to declare the diferent states, and
just using then() and by remembering to always catch() Unit tests alone aren’t enough. If you really want to $urlRouterProvider to declare the route alternatives. Give
rejected promises. minimise risks you will need to run end-to-end tests in a name to the state and pass an object with the diferent
actual browsers. The AngularJS team provides a useful parameters for it.
Tests & tools NodeJS program called Protractor to run end-to-end If you find that you need to do things in-between the
Keep ESLint running in your code editor and keep a lint tests. It uses WebDriver for controlling web browsers and routes, then you can make use of the run block. You can
config file in the repository too, so that everyone in simulating user interactions. also create links to states in your HTML by first utilising
your team writes code in the same style. It’s also a ui-sref as an attribute.
good idea to lint your code as a build task, and even Running tests Use $stateParams if you need to access the
better to do it as a pre-commit Git hook to ensure a Karma is framework agnostic and very configurable tool parameters of the routes, but keep in mind they are not
baseline of code sanity before running tests. provided by the AngularJS team to run tests. It works well inherited by nested routes.

“ It’s 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


Facebook’s 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, you’ve been writing JavaScript for a little Hit play and the app should run. The iOS simulator might var styles = StyleSheet.create({
while now, you’d say you’ve become quite throw an error so select ‘iOS simulator’ in the menubar container: {
good at it, you’ve made websites, a couple of and click ‘reset content and settings’ and hit play again. flex: 1,
small libraries and even a few web apps. The thing is, no flexDirection: 'row',
matter how awesome the web is (and it is fully awesome) 6. Our bare-bones app justifyContent: 'center',
the call of the native platform still beckons. You decide to In our iOS simulator, our app will now be open. Go back // alignItems: 'center',
give it a crack, but you’ve never written anything with to the catalogue folder we created and open index.ios.js backgroundColor: 'white',
Objective-C before – sure, there’s this new Swift thing that in your favourite IDE. This is the main entry point for },
looks familiar, but the process of building an app is still React Native to run our app from. We’re using the virtual });
foreign to you. We could try some transpilers, that is, write DOM to create elements, but instead of DOM elements, AppRegistry.registerComponent('catalogue',
some apps in JavaScript and then have something like we’re using equivalent iOS elements. () => catalogue);
Titanium figure out what your code is trying to do, but
that’s a painful process to get right. We could try out 7. Clear the house 10. Create list.js
PhoneGap – that’s nice and familiar and you can get great This React Native project has one view, but we need two In index.ios.js we defined the List component as our first
results after some tweaking, but JavaScript optimisation is views for this tutorial: one for listing our categories, and view. Create the file ‘list.js’ in our project folder and a file
hard – especially when it’s inside a native wrapper. What another for viewing the photos in that category. Delete called ‘catViewing.js’. Import the following modules:
are we to do? Wouldn’t it be great if we could write apps everything in index.ios.js and insert the following in its 'use strict';
in JavaScript with our favourite IDE but have everything place to import the required modules for our project. var React = require('react-native');
in our views be native – wouldn’t that be ideal? Well, that’s 'use strict'; var {
React Native – a supercool framework from Facebook var React = require('react-native'); AppRegistry,
that lets you write your app logic in familiar React.js var { StyleSheet,
syntax and then renders all of the view using native iOS/ AppRegistry, Text,
Android elements. It’s not transpiling or reinterpreting StyleSheet, Image,
your JavaScript code, it’s running it separately in the Text, ListView,
background. In this tutorial, we’re going to be making a Image, TouchableHighlight,
catalogue app, that is, an app that shows us cats (see ListView, View,

www.fullengineeringbook.net
what we did there?), so let’s get to it! TouchableHighlight, } = React;
NavigatorIOS, var cats = require("./cats"),
View, thumbCats = [];
1. Get React installed } = React; var CatViewing = require('./catViewing');
React Native is a complicated piece of kit, so there are var CatViewing = require('./catViewing'); just after that, we’re going to create the List class and all
quite a few dependancies but thanks to homebrew, NPM var List = require("./list") of the functions that it will use to build our view:
and Node.js setting up React Native is simple. To install var list = React.createClass({
just run these commands in a terminal window: 8. Create a starting point getInitialState : function(){
brew install watchman We now have everything we need except for a view. Add },
npm install -g react-native-cli the following code to index.ios.js, it uses the NavigatorIOS renderCatThumb : function(cat){
module to let us create views, this means we get a lot of },
2. Create a new project things like back buttons and animations between views loadCat_egory : function(category){
Now we have the React Native CLI tools installed, CD to a for free. The initialRoute property determines where our },
directory that you want to create your React Native app should find the code for our first view. render: function() {
project in and run ‘react-native init catalogue’. This will var catalogue = React.createClass({ },
create a bare-bones project with everything we need. render: function() { });
return (
3. Fix Xcode project/iOS simulator <NavigatorIOS 11. Find the cats module
For some, the Xcode project might not work out of the style={styles.container} If we run our code, we get an error, this is because it can’t
box, Xcode can fix that for us. Open the Cat-alogue. initialRoute={{ find the cats module we defined earlier. You can grab
xcodeproj file inside the folder you just created. Xcode title: 'Cat-Alogue', cats.js from FileSilo and add it to our project folder, it’s a
will open. Click on the project tab on the left and select component: List,
8.0 from the Deployment Target drop-down menu. }}
/>
4. Select device ); Learn once,
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 }); write everywhere
or something similar, click it and select iPhone 5s or We’ve all heard of ‘write once, deploy
everywhere’ but there’s rarely an instance where
iPhone 6 (depending on your version of Xcode) from the 9. Stylings that actually works out. Facebook’s suggested
dropdown that appears and hit play. Let’s create a simple stylesheet. React doesn’t use CSS, it
philosophy is “learn once, write everywhere”.
uses a JavaScript polyfill to emulate a limited subset CSS Once you’ve learned React, you can write it for
5. Fix errors with native components, and as such we define styles any platform, rather than maintaining one
If you get errors, the fix is simple. Click on the tabs like so. AppRegistery exposes our React class to our codebase that has to accommodate everything.
showing the error and select the first fix that’s suggested. native code, it’s our true entry point to the application.

HTML5 & CSS3 Genius Guide 43


Tips & Techniques

really simple JavaScript module that contains URLs for render items, we’re going to need a function to define <ListView dataSource={this.state.dataSource}
the cat images we’ll be using. what each list item should look and how it works. We can renderRow={this.renderCatThumb}
do this in the renderThumbCat function. Here, we’re style={styles.listView} />
12. Set our initial state using React Native’s iOS analogous virtual DOM to </View>
We need to help React make sense of our data for iOS so express how the list elements should be laid out. );
we use a ListView to list categories and a ListView will renderCatThumb : function(cat){ },
only accept a DataSource object as an argument. Inside return (
of getInitialState, add the following code to create an <TouchableHighlight onPress={() => {this. 15. JsCSS stylings
object for each of our categories for making a tab: loadCat_egory(cat.title)}} underlayColor="rg Add some stylings or everything will be clumped
... ba(0,0,0,0.1)"> together. We can do this with Stylesheet.create(). This is
for(var key in cats){ not CSS, but what Facebook calls JsCSS, a subset of CSS
thumbCats.push({ <View style={styles.cell} > expressed as objects. Each object in styles can be
image : cats[key][0], <Image source={{uri : cat.image}} thought of as a class name and each property is a
title : key style={styles.thumbnail} /> 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. <Text style={styles.title}>{cat.title} Head over to the iOS simulator and hit Cmd/Ctr+R on
DataSource({rowHasChanged: (r1, r2) => r1 Cats</Text> your keyboard to render. We don’t need to recompile the
!== r2}); app, because we’re using JavaScript to determine our
return { dataSource: ds. </View> views, we can rerender on-the-fly. If your keyboard did
cloneWithRows(thumbCats), </View> nothing you need to go to Hardware>Keyboard>Connect
}; </TouchableHighlight> Hardware Keyboard in your iOS Simulator Menu bar.
... );
}, 17. Push a view to the stack
13. Render the thumb cats Now we have a scrollable list of categories, but when we
14. The first render
www.fullengineeringbook.net
Now that we have a data source our ListView can use to tap them, they highlight, but nothing happens. If we want
We’ve not had much to look at so far, but that’s about to to see the images in the category, we need to push a
change. We now have almost enough code to render new view to our stack and pass the relevant images to it
our first view. Once every React Module has been for loading. Add the following code to loadCat_egory()

Is it honestly native?
Yes! Facebook have yanked out the JavaScript
loaded, the render function is the last function called and
it will render the view. Now change your render function
and then create the file catViewing.js in our project folder:
...
engine from the WebViews and run it in a separate to the following: var catsToView = cats[category];
thread. Your app logic runs in JS but everything render: function() { this.props.navigator.push({
you see on the screen is completely native. return ( title: category + " Cats",
<View style={styles.container}> component: CatViewing,

Top left
Historically, error messages have been obfuscated noise
that are rarely any help. Fortunately, that’s not so much
the case these days. The fix Xcode prescribes is spot on
in this case

Top right
Facebook doesn’t want your code to fail silently. It wants
to get up in your face so you write better code, so here is
what they’ve 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


HTML5 & CSS3
Genius Guide

JsCSS – WAT?
Aligning objects on a
screen is a tough business,
just ask any iOS developer
who’s 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},
});
...
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 don’t need many functions
render: function() {
return (
<View style={styles.centering}>
here for our CatViewing class, in fact we only really need <Image style={styles.imageHolder}
18. catViewing.js one and that is a render(). So ammend render() to look source={{uri:this.props.uri}} />
With loadCategory() we’ve passed everything we need like the following: </View>
to render our images, but where did we pass it to? What render: function() { );
about the CatViewing class we’re about to create in var catsToShow = this.props.catsToView; }
catViewing.js? CatViewing works just the same as our list return ( });
class worked, except instead of being a ListView, we’re <ScrollView contentContainerStyle={styles.
using a ScrollView which gives us a little more flexibility contentContainer}> 21. Finish up
when it comes to how we lay content out. Add the {catsToShow.map(createThumbRow)} We’re almost ready to view all of our cats. If you refresh
following code to catViewing.js to get started: </ScrollView> the iOS simulator, we get a nice big error (we might even
'use strict'; crash Xcode!) because we haven’t added styles for the
var React = require('react-native'); ); Picture or CatViewing classes. But, that’s simple, if we just
var }, add the following after our Picture class closes, we’re all
{ done. Now we can take our Cat-alogue, and put it
Image, 20. Map our cats wherever we want it to be.
PixelRatio, In our scrollView, we have mapped catsToShow to var styles = StyleSheet.create({
ScrollView, createThumbRow, but we haven’t written that yet! So the contentContainer: {
StyleSheet, actual making of the createThumbRow is a very simple padding: 10,
Text, process – for each image we pass to it, it will create an },
View, instance of the Picture class we’re about to create. Picture centering : {
} = React; is a very simple class, so it’s very similar to CatViewing in alignItems : "center"
var CatViewing = React.createClass({ that sense, it only has a render function and all it does is },
render: function() { take a wrap for an image in a view and then it will grab imageHolder : {
}, that image’s source. Just think of it as if you are wrapping width : 280,
}); an <img> in a <div> and then setting the src attribute height : 280,
module.exports = CatViewing; over in HTML. marginBottom : 5
var createThumbRow = (uri, i) => <Picture
19. Get our list of cats key={i} uri={uri} />; }
The first thing we want to do is get a reference for our list var Picture = React.createClass({ });

HTML5 & CSS3 Genius Guide 45


Tips & Techniques

What’s 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 every browser to make sure it hasn’t added or actually applies it, or that Chrome throws an exception
five years, you have undoubtedly run into removed something you inferred was there just for WebSQL only inside of Incognito Mode. You just
Modernizr. Browsers add new features to the because of its name, company, or version. Yuck. A get to write a simple if/else, and focus on the code you
web all the time, but unless you are just making demos much simpler method is to use Modernizr. It checks actually want to be writing. On top of that, Modernizr is
you probably aren’t that comfortable using them for for the actual HTML, CSS, or JavaScript feature you 100 per cent open source. You can view the code for
quite a while. It can feel dificult to know when – if ever care about, and gives you a simple true or false result. every feature detection on GitHub, complete with
– you are actually able to deploy them into production The code you wrote to use the new and shiny will start comments and explanation for why each part was
and count on them to work. Modernizr takes the stress working as soon as the feature is added to your user’s added. Modernizr 3 builds on top of all of this, with
out of that decision by giving you an incredibly simple browsers, with no changes needed on your part. dozens of new feature detections, reduced file size,
API to hundreds of diferent battle-tested feature So feature detections are the way to go, but why custom builds, and much, much more.
detects. Can’t you just send a diferent site to basic should you use Modernizr instead of just rolling your As well as the large selection of new features in
browsers? In a few cases that makes perfect sense, but own? Quite a few of the things Modernizr checks for Modernizr 3, the website has been given a revamp.
it adds a ton of work and headaches. If you assume seems very simple to test for yourself, but due to the This makes it easier to find the detects users need to
that the client isn’t capable enough to render your fact that humans create our web browsers, there is an add to their builds.
latest and greatest simply because it happened to be endless amount of quirks and oddities between them. The new site also allows for real-time search for
made by Microsoft or Mozilla, prepare for a world of Modernizr acts to clear house of these idiosyncrasies, detects on the download page and each detect now
hurt. Those assumptions will inevitably come back to collecting and sharing the issues so that you get tons has a special comment with useful information
bite you once the browser has been updated. You of bug fixes for free! You don’t have to find out that including polyfills and links. Total browser support just
need to actively check each and every new version of Internet Explorer 11 parses preserve-3d but never got a whole lot easier.

46 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

What’s new?
THE LATEST VERSION IS BIGGER AND BETTER. HERE’S WHY

Lean and mean feature detection machine


From its inception Modernizr has had a core monolithic detect, allowing for 100 per cent custom builds tailored
suite of feature detects. It turns out this is a terrible idea! to your specific website. That means an even smaller file
Most websites never use a majority of the detects that to include and faster loading site for all of your users. The
were included. Even though it is a relatively small file, all downside of this is that there is no longer that single Patrick Kettner
those extra bytes add up, slowing down the load time for monolithic file to use when you are building your site, but Lead Modernizr developer
your site and making for some sad users. Modernizr 3 keep reading to see how the Modernizr team has made
has done away with this by modularising every single it making your own custom build of version 3 a doddle. “Modernizr 3 takes away of the
guesswork of browser support, and
lets me concentrate on writing
Hundreds of new detects code for the problems I actually
want to be solving.”
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,
documentation and polyfill information! Changes to make your touch interactions work Choosing the right
While a full list is available at modernizr. detects properly across all browsers by
com/download, some of the A few detects have been checking Touch and Pointer Events, or build for your site
www.fullengineeringbook.net
highlights include the industry’s most renamed since version 2. Make maybe reduce your @font-face
robust Flash (and Flash blocking) sure to read the changelog on download size by checking out CUSTOM BUILDS SPEED THINGS
detect, functional tests for video and modernizr.com to see if your unicode-range. There are many more UP AND MAKE USERS HAPPIER
audio autoplay (that means proper code will actually require great features that have been added, so
results – even on mobile!) and nearly a any updates. make sure to checkout the Modernizr It is super simple to create a custom build of
dozen detects for new image, audio, and download page to read the documentation Modernizr. Once you have a feature to detect (and
video formats and codecs. on all of them. not before – adding dependencies to your site
before they’re 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

A perfect fit for the 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

modern build toolchain documentation, caniuse, and many other sources


in order to make it simple to find everything.
Tapping on the detect will pop up its
MODERNIZR 3 INTRODUCES A NUMBER OF NEW WAYS TO INTEGRATE documentation, including a short description of
QUICKLY AND EASILY INTO YOUR EXISTING TOOLCHAIN the feature, any polyfills that are available, as well
as links to in-depth resources like dedicated blog
Visiting the oficial website has always been the default up the more you use it, and keeps it working even if you posts and specifications. Once you have selected
way to get your copy of Modernizr, and with version 3.0 are ofline! The constant build also gives you the ability to everything you want, tap on the BUILD button to
it is stronger and better looking than ever. check on just how much bloat (or lack thereof) your build get a list of various ways to get the code. As we
The new site includes a number of improvements to has, with the compressed and uncompressed file size will explain later on, Modernizr 3 fits well into your
make generating your custom Modernizr faster and listed on the left-hand side of the page at all times. modern build toolchain, so there are a number of
easier. Powering the Download page, a new Universal Remember that every byte you add, every single one of options available. The Build option gives you the
Builder creates the exact same code as any of the other your users has to download. Be kind to your network and raw Modernizr file. Command Line Config will
tools you can use to create your Modernizr. That means theirs – keep it as small as possible. The site even has a produce a JSON file thats used to power the
better consistency and fewer chances for bugs to creep fully responsive design, allowing you to generate your Modernizr CLI tool. A Grunt Config can be
in. The new site automatically creates a build for you build or check the documentation on your mobile. downloaded as well to automate your Grunt-
every single time you change an option. That means that But having to go to the site to recreate the build every modernizr setup. Finally, if you want to test
by the time you are ready to build, it has already been single time you want to make a small change can quickly Modernizr results in the various browsers you
built for you. This process is kept snappy by using a become tedious and boring. Its 2015 – robots should be support, try it out on CodePen. You may not even
Service Worker to cache all of the modules as you select doing boring junk like this. That is why version 3 has need to test for that feature any more!
them. That means that your build time actually speeds added new ways to integrate Modernizr into your build.

HTML5 & CSS3 Genius Guide 47


Tips & Techniques

Whether you Grunt your site or Jam with the console cowboys in npm install https://modernizr.com/
Gulp it, Modernizr can help cyberspace download?promises-unicoderange --save
Once upon a time, when dinosaurs roamed the earth, Almost all of the tools that Modernizr 3 introduces are bower install https://modernizr.com/
websites were written in notepad, uploaded to your FTP built upon the its npm package. It even powers the download?promises-unicoderange --save
server and you were done. But the web has grown up Modernizr website! The straightforward command line
quite a bit since the Jurassic period, and with it so has interface can take a JSON configuration file as input, and Thats it! Every time you run Bower or npm update, it will
the way that sites are built. uses it to create your custom build. check to ensure you have the latest and greatest version
Ben Alman’s GruntJS was the first really popular modernizr --config config.json --dest of Modernizr, complete with all bug fixes and
JavaScript build system, and Eric “Contra” Schofstall’s custom_modernizr.min.js performance improvements. The only caveat to using
Gulp quickly became extremely popular as well. There the download service is that if you ever want to add or
are a number of ideological diferences between the two, You don’t have to generate the configuration by hand remove detects from your build, you will need to either
but the Modernizr team thinks both are great and has – grabbing the build URL that is included by default update or remove the existing entry in your package/
created tools to easily integrate it into either of them. in the header of all builds of Modernizr (like bower.json. Since the new dependencies
Created by Modernizr team member Richard Herrera, modernizr.com/download?emoji) will would mean you are using a diferent
both Grunt-modernizr and gulp-modernizr will search take you to a version with all of your Keep an eye URL, you would end up with duplicate
your code base for references to Modernizr’s feature detects, already checked. From there on file size versions of Modernizr in your project.
detects and automatically generate a customised build you can tap on the BUILD button It’s all too easy to bloat your
with only the features you actually use. Rather than and grab the generated Command build by adding too many new Code it forward
manually creating a new build every time you want to Line Config. Using the above URL, features – always remember to So you have created your build of
add something new, you just have to write your code as you get the following JSON file: keep an eye on the overall file Modernizr, but now you have
though it was there already and your build system will { size to make sure your discovered that, horror of horrors, it
take care of the rest! You get all of the great benefits of "minify": true, website stays fast. doesn’t detect something you need!
developing with the gigantic full version of Modernizr "feature-detects": [ How can you remedy that situation? The
with none of the performance concerns. "test/emoji" Modernizr team has thought of this too, and
Full documentation is available on npm and GitHub ] created generator-modernizr-detect. Yet another
for both modules, but they are both very simple to add } nodejs package, generator-modernizr-detect is a plugin

www.fullengineeringbook.net
to an existing project. Here is an example of a Grunt for the popular Yeoman tool. It will ask you a few
configuration you can add to your existing Gruntfile: 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 don’t ever change. Or maybe on GitHub to share your discoveries with the rest of the
"customTests": [], you just don’t 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. Can’t 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
thanks to the likes of Bower and npm. Version 3 is far from the end. Since its release in
Since Grunt/gulp-modernizr searches for One of the most frequent requests the Modernizr September 2015, there have already been dozens of
references to the Modernizr detects, you team has received is the ability to treat it like improvements, with many more to come. One of the
almost never need to actually include any other JavaScript dependency, and be things that is quickly becoming the most requested is
the “tests” portion. If you ever want installable via one of these package support for new module syntaxes. Between npm, ES7’s
to force the inclusion of certain Modernizr.on managers. But, due to its highly
detects, you can always add them Modernizr 3 adds the idea of modular nature, it was simply not
to that array. asynchronous feature detects. possible (let alone practical) to
If you really like the idea of the Check out the Modernizr.on API to publish every possible
Grunt and gulp versions, but use react to feature detects that take combination. It would require
one of the other build systems, some extra time. nearly a centillion individual
such as Broccoli, Brunch or Mimosa, packages! That didn’t 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 custom URL that is included by default in the header The new modernizr.com has a brand new look,
help get stuf done. of every Modernizr build. and a ton of new features

48 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

JavaScript modules, and tools like Browserify and when you can use them. But today is not that day, and
Webpack, modularity has become a huge part of the tomorrow likely won’t be either. Adding the latest version Working with CSS
JavaScript landscape. Modernizr’s internal modules will of Modernizr to your project can save hours trying to
soon be updated to be compatible with these other research and debug diferent ways to handle tiered MODERNIZR IS STILL THE SIMPLEST
syntaxes. This means that someday soon you won’t even browsing experiences. Version 3 has added a ton of new WAY TO STYLE YOUR SITE
have to build the bundled Modernizr file any longer. You ways to easily integrate an updated version to your Since the very beginning, Modernizr has been a
will be able to just import or require each individual existing toolchain. Whether you grab it from the website fantastic way to add functional if statements to your
detect as you need them, like you would any other as you always have, generate it via Grunt or Gulp, or CSS. Rather than worrying about selector hacks or
standard module. download a prebuilt version through npm or Bower via specificity bugs to make sure that browsers purvey
In a perfect world, all browsers will implement features the download service, Modernizr wants to make it as the styles you intended, Modernizr adds a class for
as they are created, and tools like Modernizr will no easy as possible to stop worrying about cross-browser every feature detect to the root element. This means
longer need to be used in order to figure out what and issues, and start making the next amazing website. that you write clear and self-documenting CSS.
.cssgradients .header {
background-image: linear-
Working with JS gradient(cornflowerblue, rebeccapurple);
}
QUICKLY QUERY THE RESULTS OF ANY FEATURE DETECTS .no-cssgradients .header {
background: url("images/glossybutton.
if (Modernizr.awesomeNewFeature) { Modernizr.atRule lets you check support for both png");
showOffAwesomeNewFeature(); prefixed and unprefixed @rules (e.g. @font-face, @ }
} else { keyframes, etc). Sometimes Modernizr can clash with CSS you have
getTheOldLameExperience(); if ( !(Modernizr.atRule(“keyframes”) ) { created, or perhaps some included in a framework
} // load JS powered animation lib being used. That is why Modernizr has the
Version 3 adds a few of new APIs that you can leverage } classPrefix option. This can can be added or
on your code. Modernizr.on was added as a way to hook Modernizr.prefixedCSS is similar to the older Modernizr. configured in any of the tools mentioned in this
into all of the new asyncronous feature detects. Since the prefixed, but will return the (possibly) prefixed version of article, like so:

www.fullengineeringbook.net
code you write may execute before the results of the a value in kebab-case rather than prefixed’s camelCase {
detect are known, you can register a callback to run once Modernizr.prefixed(“backfaceVisibility”) "classPrefix": "webdesignermag-",
Modernizr has finished. webkitBackfaceVisibility "feature-detects": ["css/gradients"]
Modernizr.on(“videoautoplay”, Modernizr.prefixedCSS(“backfaceVisibility”) }
function(supportsAutoplay) { -webkit-backface-visibility Now, rather than this
if (supportsAutoplay) { There are a few more, and some updates to older APIs as <html class=”cssgradients”>
//replace static image with video well. Check out the complete changelog on modernizr. you get this
} com to see all of the changes. <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

“ It’s also a good idea to lint your code as a


build task, and even better to do it as a
pre-commit Git hook
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.

Five tools & resources


Ryan Seddon’s guide to Building Resilient Web Modernizr GitHub customizr How to use Modernizr
Modernizr 3 Apps – NPM blog source code bit.ly/1LxUIzM Responsibly
bit.ly/1IegIzt bit.ly/1P6HFgh bit.ly/1SikoG0 You can try customising your bit.ly/1GYl7Gh
This short course in Modernizr 3 Patrick Kettner lays out the The entire library is available own Modernizr build and Discover how a responsible
willl take you through the fundamental tools for keeping here on the GitHub repository, exporting it without having to approach to Modernizr can
fundamentals in JS and CSS. Modernizr compatible. free for you to dip into. worry about optimisation. 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


THE CREW BEHIND FOUNDATION 6
CHECK SOME OF THE EXCITING NEW ADDITIONS TO FOUNDATION
TELL US HOW IT ALL GOT STARTED
Half the filesize More flexible Sass The newest version of Foundation is here and,
The total filesize of every component and In Foundation 6 customisation is what it is according to ZURB, the team behind the build
class in Foundation 6 now weighs in at all about. The Sass mixins have been itself, it’s a whole lot more than just a visual
60KB CSS and 84KB JS, with plenty Use fewer divs made stronger to allow devs to build iteration, code restructure or even a simple change in
of room to make them even smaller for the grid even more customised rows with version number. ZURB had tons of phone calls,
when selectively removing any Combine rows and columns in a any number of columns they need. conversations at meetups, and even sent staf on the
unused components. single div for a maxwidth centered So, if a designer or developer ZURB World Tour to hear how people were using the
column, by using the following wants to use a four-column grid past versions.
A11y friendly code example: inside a five-column grid inside a From New York to Hong Kong to Ontario and Sydney
All code snippets will come with <div class=”row twelve they can. This means that people spoke about their love of rapidly prototyping with
attributes and roles along with column”> </div>. almost any grid can be created. But, Foundation and their interest in how ZURB used it for
instructions on how and why these don’t get too overexcited, a grid still production sites. From these conversations the team’s
elements need to be used. This will help needs to functional. goals for the next version of Foundation would rely on
ensure that every website built on Foundation 6 will getting people producing faster prototypes, so they can
be able to be seen anywhere, on any device, Starter projects iterate quickly, and then taking those prototypes to
by anyone. Foundation 6 will be ofering not only production code that’s leaner and more maintainable.
Right to left the CSS versions and the regular Sass The biggest and most noticeable diference for
Styled for ultimate compatible versions of Foundation, but a Foundation 6 is that it’s now half the filesize of
simplicity Not everyone reads from left to souped-up stack complete with a Foundation 5. Weighing in at 60KB CSS & 84KB JS the
With the goal that the base styles right. Add the following for sites custom static site generator Foundation team has put tons of care and energy into

www.fullengineeringbook.net
are to act as a wireframe rather that need it. Add dir=”rtl” to the named Panini to help flatten files producing a framework that’s as light as possible while
than a final design, the team pulled HTML tag and $globaltext- into single HTML documents. still being a powerful foundation for any website. The
more and more styles from direction: rtl; in the settings to Panini is a Gulp-powered build ability to pare down the components to the ones you’ll
components, so users can more make your site flip for rtl system that can do a lot. It can use and a larger emphasis on more powerful Sass
easily style them to fit the brand of their languages. compile Sass to CSS, combine JS into functions will help users decrease file size even more. A
production work. one file and create production-ready code. 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

“ The biggest and most noticeable a11y-friendly framework in Foundation 5.5 and are
continuing that work by re-coding every component
difference for Foundation 6 is that it’s now with accessibility in the forefront of their minds. Every
Foundation component uses accessibility standards and
half the filesize of Foundation 5
” the team has been working with some killer a11y
advocates to make sure they’re 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

HTML5 & CSS3 Genius Guide 53


Front-end

stronger to allow devs to build custom rows with any New desktop companion app There’s a new menu system that is completely
number of columns they need. If a design needs a Spin up projects with a single mouse click customisable and modular.
four-column grid inside a five-column grid inside a Foundation for Sites 6 comes with a new companion
twelve, new mixins will make that super quick and easy. app, Yeti Launch (foundation.zurb.com/develop/ Modular JavaScript utilities
Users can still use the mixins for almost every yeti-launch.html), that makes it dead simple to spin up Create your own JS plugins
component and rename the classes to match their Sass projects, compile them and upload them to The utility libraries are publicly accessible so users can
necessary names. This means developers can convert Notable Code where you can get feedback directly on make their own amazing plugins.
presentational classes from prototypes to semantic the site.
markup and not need to import those classes into their Quick project starts
final code. This has always been a great part about Collaborate on responsive Spin up projects faster than
Foundation with Sass, but the team is taking care to design prototypes ever before
make it even more powerful. Upload your responsive design web The new command-line tool (CLI) enables users to set
Finally, Foundation 6 will be ofering not only the CSS pages to easily get contextual feedback on up blank Foundation for Sites, Apps, or Emails
versions and the regular Sass versions, but a souped-up any breakpoint projects with fewer dependencies than ever before.
stack complete with a custom static site generator Stakeholders and collaborators can annotate and Users can also choose to install through NPM, Bower,
named Panini to help flatten files into single HTML review coded webpages on any device. Take your Meteor, or Composer.
documents. Devs can spin up a browser sync server Foundation projects from prototype to production with
with tons of ways to optimise code with UNCSS and Notable (foundation.zurb.com/responsive-design- 50 building blocks and 15 new
UglifyJS. This is the same stack ZURB uses to build for code-review). templates
their client work and they are making it available for the A growing library of resources
first time to the Foundation community. Flexible navigation patterns Pop these premade components into your projects and
Customisable and modular navigation save time and resources.

Motion UI work with any JavaScript animation library.


Need more
details of an efect, from what direction an

www.fullengineeringbook.net
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
EASILY CREATE ANIMATIONS important thing is that it will make A the bottom of every includes a large number of premade
AND TRANSITIONS
prototyping easy. When moving to a component, hidden away in the CSS classes in order to help you get
This Sass library includes more than two dozen production environment, the library documentation, you can find a up and running quickly.
diferent built-in transition and animation classes for gives users total control over how selection of building blocks that It is worth noting that the library
you to make the most of. Originally part of the efects work. expand on that particular was designed specifically for use with
Foundation for Apps code, ZURB has decided to make it At the very core of the library is a component’s functionality the Foundation frameworks, but it can
its very own library. The updated version includes set of powerful transition and animation or style. also be adapted to work with any
significantly more robust transition options, an animation Sass mixins, which work to give users framework’s animation library, such as
queueing system, and flexible CSS patterns that can complete freedom and absolute control over the Angular or React.

54 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Who’s using Foundation?


THE POWER OF THE FRAMEWORKS HAS ATTRACTED SOME BIG NAMES. HERE’S 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, “I personally prefer using Foundation because of its
mobile-first responsive. I did an assessment of the not because I’m content to stick with what I know, but more robust grid system. When I design new web
front-end frameworks available at that time and because it remains the best framework of its kind by a projects, I always start by thinking about the mobile
decided to use Foundation. I particularly liked long shot. The ease of customisation and hassle-free experience before I move on to larger screen sizes,
Foundation’s grid system and general philosophy. setup it provides are unparalleled. and I personally feel like Foundation has an edge with

www.fullengineeringbook.net
The front-end was completed on schedule, The Foundation framework has not only helped me block grids and collapsible rows.”
integrated into CQ5, and released with great success. I cut down my workflow time, but more importantly it
believe that Foundation’s robustness was a big factor inspired me to grow as a web developer. I studied

The hassle-free

to the success of the project. In fact the modules built Computer Science in college, but knew hardly
for the dotcom website are being used across various anything about front-end web development prior to
other Barclays projects.
Thanks for producing this great framework, and
working in my current position. When I discovered
Foundation, it made me want to improve my workflow
setup it provides is
unparalleled
keep up the good work!”

Prototype to production
THE TENETS OF FOUNDATION 6
and get up to speed with the changing landscape.”

Yeti launch

Once a site, app or email is uploaded to Notable
Code, users can receive contextual feedback on
Foundation for Sites 6 is aimed at helping people get SPIN UP FOUNDATION PROJECTS JOEJWJEVBMFMFNFOUTBUBMMEJŇFSFOUTDSFFOTJ[FT5IJT
their projects from prototype to production. To make
WITH THE PUSH OF A BUTTON hopefully means plenty of feedback from clients and
sure every decision was working towards that goal, the Working with Sass and build systems is awesome, but stakeholders on actual elements and not just vague
Foundation team came up with specific tenets that setting up a machine to work with them can be notes about pieces of a website.
include the following: daunting. Some users really like the increased The app itself was created using Foundation for
Prototyping in Foundation 6 should... benefits a full web stack brings, but are Apps and wrapped with an Electron shell.
s Get me running with minimal dependencies, but simply not up for the challenge of This allowed the ZURB team to use web
give me tools that modern sites need. hopping into command line to set up JS knows technologies to rapidly prototype and
s Be able to rapidly produce a proof of concept in an entire build system. breakpoints then take those straight to a native
code with easily readable presentational classes. That’s why along with the launch You can easily use JS to expose app-like experience.
s)BWFBCBTFTUZMFUIBUJTBTVOPQJOJPOBUFEBTUIF of Foundation for Sites 6, ZURB has the breakpoint of the current Future versions will include the
wireframes we’re replacing them with. released a free Mac app (also device by using the Foundation ability to spin up templates and
s(JWFNFBDPNNPOSBOHFPGQMVHJOTUIBUDBOCF coming to Windows soon) to spin MediaQuery object: selectively import components, and
easily configured without writing JavaScript. up any Foundation website, email or Foundation.MediaQuery. in the very near future the
Production in Foundation 6 should... app. This installs a new instance and current. app will be expanded to Windows. Yeti
sBe able to easily streamline code by using Sass runs a build system to compile Sass, -BVODIXJMMCFQFSGFDUGPSOFXVTFSTUP
mixins to create semantic classes. Concatenate JS and even compress images. TQJOVQQSPKFDUTRVJDLMZBOEFWFOGPSNPSF
s-FUNFRVJDLMZQBSFEPXOUIFTUSFBNMJOFEŢJMFTJ[F Then it lets users take those projects and upload BEWBODFEVTFSTXIPXBOUUPRVJDLMZBOEFBTJMZ
by selectively importing the components I used. them into Notable Code, a new service to upload create a prototype and share it for instant feedback.
s#FTUZMFEUPNBUDINZDVTUPNEFTJHOTXJUIPVUUIF prototypes and get contextual feedback straight on the (SBC:FUJ-BVODIBUhttp://foundation.zurb.com/
need to override code or change tons of variables. coded pages. develop/yeti-launch.html.

HTML5 & CSS3 Genius Guide 55


Front-end

Build your own JS plugin };


Plugin.prototype._events = function(){
//add event listeners
};
DISCOVER THE TECHNIQUES NEEDED TO CODE A CUSTOM ADD-ON //add logic functions here \/...
Plugin.prototype.destroy = function(){
Anyone who has ever needed to make a custom plugin utilise this with: //remove event listeners
for a web design knows it can be a pain. Even if you $element.on('swipe swiperight swipeleft'); //remove elements from the DOM
utilise a framework, there hasn’t been a lot of built-in Foundation.util.motion.j is the file that is the JavaScript Foundation.unregisterPlugin(this);
support for layering over the top of it and creating behind the Motion-UI library. It adds custom classes to };
whatever doodads and whizbangs you might want. add transitions to elements and move them ofscreen. Foundation.plugin(Plugin);
Foundation 6 has solved this problem by ofering a We will utilise this with: These are the non-optional methods for each plugin, and
plethora of public APIs to make it faster and simpler to Foundation.Motion.animateOut($element, naming conventions should be followed (otherwise
integrate your own custom plugins. Part of the 50 per ‘animationClass’, function(){ Foundation._reflow() won’t work!). Everything else is
cent code reduction is due to separating out these //optional callback completely up to you.
common functions and these utilities. We’re going to //do stuff Now that we know how to start a plugin, we can build
show you how. }); our Tind...er, Card Swiping plugin, for succinctness and
What we’re doing: This file is dependent on another helper file: foundation. humour, we’re going to call it ‘Swipin’. We know how to
s Setting up a custom trigger for our element to fire, util.animationFrame.js, build the skeleton of a plugin already, so let’s look at the
based on the user’s input. which has one function – to utilise hardware acceleration _init function in detail.
sGrabbing the index of the current card, we’ll need to improve animation efects. This will be called with: Swipin.prototype._init = function(firstTime)
that going forward. Foundation.Move(timeOfAnimationInMS, {
sCalling on our Foundation.Motion library and $element, function(){ this.$element.addClass(this.options.
animating the card out. For this demo, we used //apply animations/transitions here. containerClass);
‘slideOut(Left/Right)’ for swipe events and }); this.$cards = this.$element.find('.' +
‘scaleOutDown’ for button clicks. Foundation.util.triggers.js is an event listener/ this.options.cardClass);

www.fullengineeringbook.net
sOnce our animation is complete, fire our custom emitter helper file. This listens for click if(this.options.hasDetail &&
trigger and remove the card from the view as we don’t events on: Custom firstTime){
need it anymore. [data- columns this._makeModals();
Finally, if we opted for modals, (we did), let’s invoke close="idOfThingToClose"], You can use the gridcolumn }
that modal’s destroy method and clean up our DOM [data- function in order to create a if(this.$element.find('.' +
structure a bit. Put it all together, and you’ve got yourself open="idOfThingToOpen"], column class with a custom size: this.options.
a custom-built plugin that works seamlessly within the [data- @include grid- btnContainerClass).length){
Foundation framework. We save you time by providing toggle="idOfThingToToggle"] column(4 of 5) makes an this.options.hasBtns = true;
utility functions. There are a quite a few we didn’t go over as well as listening for any other events 80%wide column. }
in this article, but information about how to use them can you may want to tap into. if(!Foundation.MediaQuery.
be found on our docs page. We’ve given designers a set Next up is foundation.reveal.js. We want atLeast(this.options.unstackOn)){
of power tools to build their own plugins and details for our little image-filled cards, so let’s this._stack();
functionality, and we can’t wait to see what you do with it. programmatically create some modals that will open }
The JS utilities in Foundation 6 save you time and when we click or tap on our cards. Reveal has its own this._events();
efort. Separating out the common functions into smaller dependencies as well, including foundation.util. };
utilities saves code and gives you power tools for your sizeAndCollision.js, to properly size modal frames, detect
production. Foundation not only has very useful popular collision events, and set the ofsets of the modal element. A few things that we did:
plugins for you to develop with, but also tons of tools to We’re going to create these on the fly with: sAdd the container class to the root $element for
help you build your own. new Foundation.Reveal($element); easy styling.
To view the full code for this plugin, follow this link: and add a few elements within them. sCreate a jQuery collection of our individual cards.
github.com/zurb/foundation-sites-6/blob/tutorial/ That covers the basic components we’re going to s$IFDLBCPPMFBOUPTFFJGXFOFFEUPNBLFPVS
testing/js/swipin.js. need, so let’s see how a plugin is built. The basic modals, the ‘firstTime’ argument is passed from the
structure of each and every JS-based plugin is this: constructor function’s call to _init(), we don’t want to
Build a responsive card swiper function Plugin(element, options){ make more modals when we reflow this plugin.
We’ll start with some of the utility functions and existing this.$element = element; sCheck the markup for a button container, if we
plugins we’re going to want: this.options = $.extend({}, Plugin.defaults, have buttons, then we’ll need that boolean in our event
Foundation.MediaQuery this.$element.data(), options); handler.
This utility library has a few helper functions such as this._init(); sCheck the size of the screen, if it’s below our
Foundation.MediaQuery. Foundation.registerPlugin(this); ‘unstackOn’ threshold, we’ll stack our cards and add the
atLeast('breakpointString'); } ‘swipe’ event listener.
as well as an event emitter that triggers when a Plugin.defaults = {}; So we know we can programmatically create plugins
breakpoint is hit. Plugin.prototype._init = function(){ with our JS, let’s see what that looks like.
Foundation.util.swipe.js is a file in the JS folder that //do stuff Swipin.prototype._makeModals = function(){
adds a swipe event emitter to jQuery elements. We will this._events(); var _this = this,

56 HTML5 & CSS3 Genius Guide


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 [data-
sticky-container].
<divclass="columnssmall 6right"data sticky
container>
<divclass="sticky"data sticky>
<imgsrc="assets/img/interchange/small.jpg">
</div>
modal = '<div class="reveal" data-reveal></ $modals = $modals.add(reveal.$element); // </div>
div>', //declare our reveal markup we don’t need the elements, so $modals is
closeBtn = '<button class="close-button" a temporary variable Toggler – add and remove classes
aria-label="Close alert" }); without writing JS
type="button"><span>&times;</span></ $(document.body).append($modals);// attach Quickly prototype interactions by toggling classes
button>', //utilize a Foundation helper CSS them to the DOM all at once. onto any element using simple data attributes. To
class ‘close-button’ }; setup a class toggle, start by adding the attribute

www.fullengineeringbook.net
lorem = '<p>This is just some lorem ipsum Now we have our modals, they are attached to the datatoggler to an element. The value of datatoggler is
for this tutorial</p>'; //and generate some DOM, and they have open and close triggers applied to the class you want to toggle. Also give the element a
generic text for the sake of this lesson. them, thanks to our handy triggers library. Next, check unique ID so it can be targeted. Then, add datatoggle
var $modals = $(); //create an empty jQuery out the _events function. It manages triggers from to any element, with the ID of the target as the value of
collection, we’ll need that in a minute media query changes and applies event listeners to our the attribute. Now, any time you click on this element,
this.reveals = []; //save our shiny new cards. It will need to delegate some tasks to helper the class will toggle on and of on the target.
modals to our current plugin, we need that functions, but we’ll leave those out for brevity. <ulclass="menu"id="menuBar"data toggler=".
too! Swipin.prototype._events = function(){ expanded">
this.$cards.each(function(){ //iterate var _this = this; <li><ahref="#">One</a></li>
through all our cards $(window).on('changed.zf.mediaquery', <li><ahref="#">Two</a></li>
var $card = $(this), function(){ <li><ahref="#">Three</a></li>
imgSrc = $card.find('img').attr('src'), // _this._handleMQChange(); <li><ahref="#">Four</a></li>
since each card has an image, grab the src }); </ul>
attr if(this.stacked){ <p><adata-toggle="menuBar">Expand!</a></p>
id = this.id || Foundation. this._addSwipe();
GetYoDigits(6, 'card-detail'), // } <div class="column card"> <!-- repeat as
we need an id for our triggers this.$cards.off('click.zf.swipin many of these as you like -->
utility functions, so let’s
Responsive tap.zf.swipin') <div class="thumbnail">
make one. GetYoDigits gives
typography .on('click.zf.swipin tap.zf. <img src="http://placehold.it/450x650">
Change the values in the
you a psuedo-random string. swipin', function(e){ <div class="button-group expanded">
$headersizes variable in
reveal = new Foundation. _this._handleClick(e, <a class="button tiny alert">No Thanks</a>
order to create responsive
Reveal($(modal).attr('id', $(this)); <a class="button tiny success">Yes Please</
typographic scales that change
id)),//generate our modal }); a>
to adapt themselves to a
for this card }; </div>
variety of diferent
$closeBtn = $(closeBtn). Here, we’re applying a listener to the </div>
screen sizes.
attr('data-close', id); and window, for media query events, and </div>
update our close button with the adding the click handler for our cards. Since </div>
data-close attr for our triggers utility we only add the swipe listener when the cards are The Sass:
$card.attr('data-open', id); stacked, let’s take a look at our card markup, CSS, and .swipin {
reveal.$element.append($closeBtn, '<img stacking logic. position: relative;
src="’ + imgSrc + ’"/>' + lorem);//append The markup: top: 50px;
our elements to the modal we just created <div class="row medium-up-3" data-swipin> .thumbnail .button-group {
_this.reveals.push(reveal); // and save our <!-- this data attribute is what foundation margin-bottom: 0;
new modals to their proper place looks for to initialize your plugin --> margin-top: .25em;

HTML5 & CSS3 Genius Guide 57


Front-end

.button { $(this).css('z-index', '') };


border: 1px solid #FEFEFE; .find('.' + _this.options.btnClass).show(); Because the whole card has an event listener, we
border-radius: 0px; }); need to see if one of the buttons was clicked, and if it is
} this.$element.removeClass('is-stacked') then we will stop propagation so our event doesn’t
} .trigger('unstacked.zf.swipin'); bubble to our [data-open] listener and open our modal. If
} this.stacked = false; it wasn’t a button though, let’s allow that modal to open.
.is-stacked .column { }; Our swipe listener will look like this:
position: absolute; While our cards are unstacked we get: this.$cards.off('swiperight.zf.swipin
left: 0; swipeleft.zf.swipin')
width: auto; .on('swiperight.zf.swipin', function(e){
transition: transform .5s ease; e.preventDefault();
transform: scale(0.6) translate(0px, -30%); _this._swipe($(this), 'Right');
} }).on('swipeleft.zf.swipin', function(e){
.is-stacked .column:first-child { e.preventDefault();
transform: scale(1) translate(0px, 0); _this._swipe($(this), 'Left');
} });
.is-stacked .column:nth-child(2) { Which calls this:
transform: scale(0.9) translate(0px, -10%); Swipin.prototype._swipe = function($card,
} Which, when stacked gives us: dir){
.is-stacked .column:nth-child(3) { var isYes = dir === 'Right';
transform: scale(0.8) translate(0px, -20%);; this.dismissCard($card, isYes, 'slideOut' +
} dir);
.is-stacked .column:nth-child(4) { };
transform: scale(0.7) translate(0px, -30%); And this dismisses our card with the ‘slideout’ animation
} to the left or right. This function, is the bread and butter
The stack is simple, merely adding a class to the main of this whole plugin. We wanted to make two common

www.fullengineeringbook.net
element, setting a z-index so the cards stack correctly, user interactions, click buttons and swiping right or left,
and hiding buttons as we’ll be swiping now: and combine them in a responsive way with a
Swipin.prototype._stack = function(){ Now we’re getting somewhere! Of course, though we recognisable layout.
var counter = this.$cards.length, have our cards and they stack nicely, we have to be able Swipin.prototype.dismissCard =
_this = this; to do something with them. Let’s look at our click and function($card, isYes, animOut){
this.$cards.each(function(){ swipe handlers… var trigger = (isYes ? 'yesplease' :
$(this).css('z-index', counter) Swipin.prototype._handleClick = function(e, 'nothanks') + '.zf.card',
.find('.' + _this.options.btnClass).hide(); $card){ idx = this.$cards.index($card),
counter--; var $target = $(e.target), _this = this;
}); isBtn = $target.hasClass(this.options. Foundation.Motion.animateOut($card, animOut,
this.$element.addClass('is-stacked') btnClass); function(){
.trigger('stacked.zf.swipin'); if(isBtn){ $card.trigger(trigger, [$card]).remove();
this.stacked = true; e.stopImmediatePropagation(); if(_this.options.hasDetail){
}; var isYes = $target.hasClass(this.options. _this.reveals[idx].destroy();
The _unstack function is pretty similar: yesClass); }
Swipin.prototype._unstack = function(){ this.dismissCard($card, isYes, this.options. });
var _this = this; animOut); };
this.$cards.each(function(){ }

How to build with the basic slide with a custom hinge. $duration: 0.25s,
Motion UI .hinge-in { $timing: easeInOut
@include mui-hinge( );
CHECK OUT FOUNDATION’S SASS- $from: right, }
BASED ANIMATION LIBRARY $fade: true, Lastly, in
Motion UI ships with over two dozen premade CSS $duration: 0.25s, plugin.js
transition classes, which we used in the tutorial. $timing: easeInOut , replace the references to
However, if you want to streamline your CSS output, ); slide-in and slide-out with hinge-in and
and create more fine-tuned efects, you can use } hinge-out
Motion UI’s Sass mixins. .hinge-out { When you refresh the page and use the plugin, you’ll
First, comment out @include mui-hinge( see the new efects in place. You can refer to Motion
@import motion-ui-transitions in app.scss $state: in, UI’s full documentation (at https://github.com/zurb/
to remove the pre-built classes. $from: right, motion-ui) to learn more about making use of the
Next, add this code to your Sass file. We’ll replace our $fade: true, custom efects.

58 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

A look ahead at Foundation where they’re opened. Sone of the features in 2.0 include:
s"GVMMZŢMFYJCMFHSJE— even on small screens! That

for Apps 2 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
WHAT DOES THE FUTURE HOLD FOR ZURB’S WEB APP FRAMEWORK?
variables, mixins and partials!
Last year ZURB launched Foundation for Apps, an Angular framework, so it’s specifically designed with s/FXUFNQMBUJOHMBOHVBHFn*OLZ— Say goodbye to
Angular-powered framework that was primarily single-page apps in mind. Foundation for Apps also sifting through hundreds of pesky table tags. With Inky
focused on creating fully responsive web apps. It shipped with a small plugin called Front Router, which you can write tags like “<row” and “<columns>” to spit out
includes a flexbox-powered grid built for flexible, allows for the creation of Angular routes (URLs) directly the six table tags needed to just get the skeleton of your
responsive app layouts, in addition to a series of Angular within the HTML of each page. email together.
directives for creating of-canvas panels, modals, Version 1.0 of Foundation for Apps launched in s)FMQGVM6*DPNQPOFOUT— Row, Columns, Callouts,
notifications, and more. December of 2014, and the Foundation team is already Inline Lists, Vertical Lists, Block Grid and Thumbnails.
Foundation for Apps was created as a brand new hard at work on Foundation for Apps 2, which is going to s*OMJOFBMMPGUIFTUZMFT— There’s a handy Gulp task
framework, because the team at ZURB felt like be powered by version 2.0 of the Angular framework. that inlines all your CSS from a remote stylesheet.
Foundation 5, while an amazing tool for building Foundation for Apps 2 features even more robust s)BOEMFCBSTUPLFFQZPVPOUSBDL— We’ve included
websites, was not as great when it came to building web responsive layout options, a greatly improved visual style, the support of Handlebars templates to keep you from
apps. Further, there were no existing solutions in the and more powerful Angular components. Many ideas repeating yourself! Things like the header and footer of
open source world for building fully-responsive web apps developed in Foundation for Sites 6 will also be ported to your email can stay the same, allowing you to change
designed specifically for the browser. Much like how Foundation for Apps 2, ensuring it features all the latest only the content that matters!
Foundation for Emails (previously known as Ink) is improvements. We’ve also packaged up a handful of battle-tested
designed specifically for HTML email, Foundation for Angular 2 is a drastic departure from Angular 1, so the templates to get you up and running with Foundation for
Apps is designed specifically with HTML apps in mind. JavaScript codebase will be overhauled to fit Angular 2’s Emails 2.0! We’re really excited to share the workflow
The framework borrows fairly heavily from existing new design patterns. The code will also be written in improvements with the world, and can’t wait to see what
ideas in Foundation for Sites, but it also includes many TypeScript, a new superset of JavaScript designed by you can do with it.

www.fullengineeringbook.net
unique components specifically designed for responsive Microsoft – it’s also the oficial language of Angular 2.
web apps, including a flexbox-powered app grid, Angular 2 is due to launch next year, and ZURB will be at &YBNQMFDPEF
collapsible panels, flexible menu patterns, and responsive the forefront of Angular 2 development with Foundation <row>
action sheets. The framework’s JavaScript is built on the for Apps 2. <columns large=’8’ small=’4’>
</columns>
<columns large=’4’ small=’8’>
</columns>

“ Angular 2 is due to launch next year, </row>


A better solution than this:
and ZURB will be at the forefront of <table class="row">

Angular 2 development

<tr>
<td class="wrapper">
<table class="six columns">
<tr>
Responsive emails <td class="expander">
</td>
GET ALL-SCREEN FRIENDLY </tr>
</table>
Responsive email design has been growing steadily in </td>
popularity, and it’s no surprise as to why: 47 per cent <td class="wrapper last">
of email opens are actioned on a mobile device <table class="six columns">
(litmus.com/blog/mobile-opens-hit-record-high- <tr>
of-47), and some brands see upwards of 70 per cent of <td class="expander">
their emails opened on mobile. Ensuring that emails </td>
looked good on any device was imperative, therefore </tr>
ZURB created Foundation for Emails, formerly known as </table>
Ink, for our own emails. This was then later released to </td>
Brandon Arnold the general public as open source software. </tr>
Foundation Lead, ZURB Foundation for Emails helps people build responsive </table>
”We wanted to learn how people actually used emails that look great on all major email clients, <row>
Foundation, so we travelled around the world and especially Outlook! We took on the significant workload <columns large='6' small='12'>
hopped on hundreds of calls to actually watch how the of figuring out all the diferent quirks in all the most </columns>
community used the Framework and discussed what popular email clients and devices in order to provide a <columns large='6' small='12'>
they needed from it. It was amazing!” framework for creating emails that just work, no matter </columns> </row>

HTML5 & CSS3 Genius Guide 59


Front-end

Is your
www.fullengineeringbook.net

content
king?
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! DON’T DESIGN A THING UNTIL YOUR
CONTENT STRATEGY IS SOLID

Design is content. Content is design; it’s time to get over the old
‘designers-don’t-do-words’ story. It’s time to get intimate with
content, and embrace it as the first fundamental part of any design
journey. But before we begin, let’s 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, you’ll 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, it’ll bug Natasha Spice
them so much, they’ll start spouting bad press about your brand. It really Designer at Folk
@natashalindblum
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 Starting a project off with a
their business vision and the content they need to fulfil that promise
authentically, you can start to have a conversation about the experience
content strategy means I can solve
problems for real people. Designs
www.fullengineeringbook.net
you’re creating, not simply whether the logo is in the right place or the right
size. Imagine, a client/designer relationship where you’re both focused on the
nuts and bolts of the content first, where the client doesn’t simply say they can look and feel fantastic, whilst
love it, like it, dislike it or hate it – they can articulate why it does or doesn’t fit.
It’s time for some new thinking. And if you’re someone who’s serious about
leaving the client and the end-user
feeling empowered

solving problems with your design, this is really, truly the new way to work.

Five masters of content cartography


THESE ORIENTEERS REALLY KNOW THEIR WAY AROUND THEIR BRAND VISIONS

airbnb airbnb.co.uk
Airbnb’s 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 they’re stateside though.

Hatchet + Bear hatchetandbear.co.uk


Homely, rustic, unique – Hatchet + Bear know themselves. They
understand consistency of personality, which is why they’re always
out of stock.

Go Pro gopro.com
Go Pro’s genius hinges on cleverly showcasing its users’ footage
throughout the site experience – it’s 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 Case study


ASOS
started
THE BASICS OF A KILLER CONTENT
asos.com
Most people are at least aware of ASOS in some
capacity, even if they don’t fall into their
20-something demographic. It’s an online fashion
superstore, fundamentally. But they are so incredibly
STRATEGY, IN LINE WITH YOUR good at seamlessly incorporating their content into
BRAND VISION design, product and messaging that it would be rude
So, you’re about to design a website. Hold it. First, we to leave them out of this feature. Flawless user
need to hail back to the old school and draw up a experience and targeting means that their customers
scenario to really think about the process. have literally no reason not to buy again, again and
again. Everything is spot on, and laser-focused.
Let’s say Mr and Mrs Customer saunter up to you and
say, “Hi, I’d like to buy a car.”

And you say, “Sure, what kind of car do you want?”


They’re great at weaving stories through their
products and collections, but notice that it’s never
“Any will be fine,” they reply. “Four wheels and a ever contrived; think the Festival Chic theme that
chassis.” You nod. You head over to the garage, and after takes control of their Women’s section. This is, once
again, something that their customers genuinely
a few minutes, you pull up in a shiny new hatchback.
want; it’s a style that meets their needs and ambitions
at the current time in context with what’s happening
They look plain-faced for a second. in their customer’s worlds. It’s also a theme that is
bound to be a big product seller for the company too.

www.fullengineeringbook.net
“That’s not going to work,” Mrs Customer says. “Where
will our five children sit?”

Don’t clench your fists in fury just yet. You could have
They’re exceptional at picking partnership
predicted this.
opportunities which feel ‘on-brand’ like Britain’s Next
Top Model for example, and a variety of festivals –
The user journey right now ASOS are working on connecting clientele
What does a typical user want to do? What with Glastonbury. Like their content, this is
are their goals in life, their gains and their down to good old-fashioned research. The
time, the place; the connection. These
pains? Put yourself in their shoes for a Every page is partnerships are tailored to the
second. They might want to spend a landing page consumer’s needs to a hair’s width.
more time with the kids. They might People won’t just be landing
want to succeed in their job, or on your homepage. Think about
attain the perfect work-life balance. the multitude of ways a customer
Whatever it is, you need to find this can come to the site. Each page
goal out, and articulate exactly how should be self-contained, think of. This is bigger than business. and pick them apart. You’ll usually find a hair’s width
you can help them achieve it with your self-explanatory and The answers here will be more honest, angle in the market that’s untapped by anyone. Learn it,
website. If content is king, then the unconfusing. and more valuable than a dozen surveys. own it, master it. This is yours. Write the user and
customer is the supreme overlord of the Sure – they might not be as representative as competitor analyses down. Stick them on the wall.
universe. You want them to provide the clicks. a 10,000 strong body of consumer data, but it’s They’re your bible now.
But how do you get the kind of information to make more specific. It’s real.
this specificity happen? Everyone knows how annoying it All you need is a trend of five or six, and you can start Sitemapping
can be to have some anonymous organisation cram a to get a feel for a customer type and then following on Before you start writing any content, or drawing up any
survey down their throats for the chance to win x or y. from this you can start to sense the kinds of content that designs, you’ll need a comprehensive map of the pages
The problem here lies in the approach. Hell, we’re already might help them to achieve what the clients actually you need, an idea of what they’ll contain, and how they’ll
kicking it old school, so let’s just hang around for a while; want to achieve. Another benefit that can be gained here interact with each other.
the best way to find this information is to physically talk is that you can gain useful, precise feedback on ideas A logical sitemap enables you to maximise your user
to people, face to face. Talk to your friends, neighbours, roaming uncharted territory. experience; to see the bigger picture ahead. It also
family members, clients, and anyone you happen to be It’s a good idea to evaluate any existing content once makes it infinitely easier to delegate content generation
chatting to through sheer serendipity. you’ve done this. This includes anything you or your tasks to freelancers when you’ve got every item of detail
Ask them what makes them happy, sad; ask them client may have already, but focuses more specifically on listed out. Moreover, the impact of call to actions can be
what would be their proudest moment if they had the your competitors. clearly distinguished for an excellent site journey with
opportunity. Ask them what grinds their gears, and what Get a big list – brands whose products are similar, admirable click-rates. This same concept is true when it
they’d like to have done as a kid. Everything you can whose audience is similar, whose mantras are similar – comes to actually designing each page and page

62 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Mobile and desktop are one thing, but when


you’re ASOS, you’ve got a dragon’s wealth of
content to deliver. And people want to read it.
That’s 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

www.fullengineeringbook.net customers. This makes users want to ofer


things like their phone number as they know
it’ll be used to enhance their experience.

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 content’s in place. Here’s the than using a placeholder when you have no idea what
slightly tricky part though. How can you design a website the finished product will actually look like. Plot an effective
that melds seamlessly with its content if you don’t have
the content itself, using just lorem ipsum to fill in the
Leave the writing of any of the fancy stuf to your
copywriter. This extra distance will make it easier for analysis
spaces? And how can you write excellent content when clients to see the whole picture, and get a better feel for You need a solid understanding of a number of
you’re unsure of its design context? The answer is simple: the site in the lead-up to sign-of. It makes it a hell of a lot things in your competitor analysis. This ranges
mock up the content yourself. easier for your content writer to populate too. And finally, from homepage meta descriptions and tone of
It might not seem like it’s in your remit, and as far as it makes it so much easier for you to design a site whose voice, to content themes, objectives, and how
finished products go, it’s not. But lorem ipsum is the essence is there already. efective these appear to be. When you’re
mortal enemy of a content-first approach. If it’s an events Another point is an important ‘don’t’. Don’t ever, confident in this, you can plot it and put this to use.
page you’re drawing up, throw in the date, a title and a under any circumstances allow the ‘luxuriousness’ of a You’ll need to select two scales, set against axes,
description. It doesn’t have to be good content; it doesn’t brand to influence the readability of its content. Here’s an eg in a cross-section of cosmetics brands,
even have to be grammatically correct but it’s better example. Let’s say your site’s a piece of high-shooting sustainability/technology vs. fun/professional. Put
an X for each brand studied according to how they

“ A logical sitemap enables you to fare on these scales. Once you’ve plotted eight to
12 Xs, you’ll notice a significant gap in this
maximise your user experience; to see the spectrum. That’s the flavour your content needs to
have to secure a space in the market.
bigger picture ahead
” 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
Don’t fall into the ‘content dump’ trap. If it’s an
important CTA, hero it on your homepage, even
on mobile devices

You’ll
never get it
straightaway
Learning your customer takes
time. You’ll need to use analytics to
check how they’re interacting with
contemporary art. It sells high-price-point goods to few things. Research your customer content. You need to take this With this information to hand, next
high-net-worth customers. The first temptation for many extensively. The more you know about information and constantly you’ll need a sitemap. As mentioned
is to put on airs with the content. “But if it’s a luxury the customer, the greater clarity you’ll tweak and improve. earlier, this gives you a pragmatic
product, surely it’s got to sound luxury, right?” have on the direction, themes and purpose knowledge of every pathway, every step,
Wrong. Kind of. If your product or service is what your of your content. every call to action, and every goal within your
customers are looking for, don’t put them of with Know their desires, their fears, their ambitions, their site. It naturally gives you a comprehensive list of every
verbosity. Often, you’ll lose traction in your attempts to habits, their favourite brands, and more. Research these page too, so it’ll keep you and any content delegates
be descriptive. Keep sentences simple, and try to include brands – and other competitors – extensively. This sane and ordered when it comes to designing and
just one concept in each. Use the active voice, and write includes any content you’ve done before. The more you populating the site. Remember that dropping in some
as if you were having a conversation with your customer. 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
Start as close to the end as Looking at your own past content will assist you in bubbling along nicely, don’t neglect to check your
possible, and don’t waste your identifying why things may not have worked so well readability. You can do test this out by using a number of
reader’s time previously, and might highlight ways you can specifically online sources – just look up Flesch-Kincaid, and aim for
The legendary American writer, Kurt Vonnegut, said to improve. This research stage is crucial, as it’ll define the a score of 65 in its Reading Ease results. Note that the
remember these two points. Ultimately, it boils down to a 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

“ With your themes and content/design score of about 52 whereas the BBC News website comes
up as 67.4 (bit.ly/1Hq0pmd). Remember: even the most
relationship bubbling along nicely, don’t elite, technical or hard-to-find products need to be
accessible to an online reader. Okay. Now you can move
neglect to check your readability
64 HTML5 & CSS3 Genius Guide
” past content strategy and start designing again.
HTML5 & CSS3
Genius Guide

Desktop vs mobile Nine to


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 THE ALL-IMPORTANT ACCOUNTS
content – say they’re commuting on the Tube – then it’s do with software and download speed restrictions, there
unlikely they’ll be viewing it on their PC device. Say are far fewer large graphics on a mobile site. It’s kind of
they’re conducting some in-depth research like the distinction between a corner shop and Alistapart
for a paper: they won’t be doing it on Don’t a supermarket; one’s a little more @alistapart
their smartphone. This kind of forget buttons expensive, with a smaller range of For people who make websites – some fantastic
distinction is especially true for Ban ‘Submit’ from your products available, but it’s super easy resources and authors.
features like store finders. dictionary. Use CTAs which grab and requires much less efort. For the
Chances are, people are more user attention and are relevant to other, the opposite is true. Both play Ian Lurie
likely to use a smartphone for what you want them to do. If you’re an important role in our lives @portentint
viewing content when they’re on the ofering something for free, use Ian provides great tips for optimising everything to do
go – so bringing it to the forefront for ‘get’. If you want to inspire Credibility or bust with web and design.
mobile is important. If you want to take a purchase, say People online are sceptical about
it one step further, great integration with ‘purchase’. everything, so make sure to include trust Jonathon Colman
map software means your customers will indicators in your designs. And while you don’t @jcolman
know you’ve thought have to state them in your copy, just keep your trust The content strategist at Facebook shares his
about their journey. promises at the front of your mind. Place any trust thoughts and insights about everything you do.
Next, and unsurprisingly, mobile should be as minimal indicators somewhere that follows the eye so they feel
as possible. It’s pretty obvious that when you’re designing natural and unobtrusive. Kristina Halvorson
for 320 x 480, you can’t include half the stuf you would @halvorson
Where does site traffic come from?

www.fullengineeringbook.net
for 1920 x 1080 without sacrificing a scary chunk of Author of one of the most useful books on content
usability. This is when your user journey from before strategy, Content Strategy for the Web, Christina
comes in handy. Think back to their pains and gains. knows her stuf.
What content do they want? Boil every last speck of your
site content down to the essence that drives your The Content Marketing
customer, and minimalism won’t be a problem. Institute
On a related note, there’s a lot less floating hypertext @CMIContent
content on a mobile site, but that’s not because the links 50.3% 49.7% As the name suggests, this Twitter account is more
aren’t there. You’ll typically see a greater number of focused on content marketing, but still has some
buttons and bars which serve this linking function, to Source – Shopify, August 2014 great resources and insights.

Melissa Rach
@melissarach
Content Strategy The co-author of Content Strategy for the Web,

for the Web regularly posts about the latest content case studies.
Melissa describes herself as a content nerd.
contentstrategy.com
@BrainTraffic Contents magazine
@contents
Written by Kristina Halvorson and Melissa Rach, A digital magazine dedicated to the art of content
this is one of the best books about content strategy & online publishing. It hasn’t been updated
strategy available today. It gives so much since 2013 but still divulges some must-know topics.
information and many tips to make what could be
a complicated process very simple, and it gives We Live Content
some totally solid reasons to share with clients @welivecontent
about why it’s best to get the content parts sorted This account shares timely and useful resources for
first above all else. It’s a manual that provides you content marketers and content strategy professionals.
with the knowledge to deliver meaningful and Something new appears daily.
efective content when and where it’s most
relevant to your clientele. It also helps you Karen McGrane
understand processes, teaches you to make better @karenmcgrane
decisions and plan for the long term. 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 ratio-


based 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 3. Style aspect ratios .aspect-content {


flexible and likely content managed. Boxes We’re using the ratio data attribute we created as a margin: 20px;
change in height as the page resizes because selector (supported by IE9 and up). Set the height to 0 }
they’re defined by a percentage width and their content. and control the size of the box with padding only. As
But this flexibility isn’t always an absolute requirement. we’re creating a square, the padding is equal to the width. 6. Add imagery
We can craft more interesting layouts when content is We also hide any child content if it were to overflow. Working with images in aspect ratios is tricky. We want
well defined. .aspect[data-ratio="1:1"] { the image to scale, but we don’t want to distort it. With
Aspect ratio-based layouts prioritise proportion over max-width: 100%; this in mind, we will need to write markup that enables us
content. In this sense the process is much more like height: 0; to crop it if necessary.
editorial – with all of its pros and cons. The aspect ratio padding-bottom: 100%; <div class="aspect" data-ratio="2:1">
approach gives us more design control but it’s much overflow:hidden; <img src="./img/floor-3.jpg" alt="" />
more labour intensive to produce a good experience. If background: rgb(211, 22, 22); <div class="aspect-content">
your client does not want to engage in editorial processes color: #fff; <h4 class="headline">Directions</h2>
or requires flexible systems then steer clear! } </div>
This approach is fantastic for scenarios where data is </div>
well defined or can be truncated without issue or where 4. Harder ratios
iconography is more important than text. Dashboard Using 4:3 is a little more complicated because we have to 7. Style the image
pages, widget collections and even some web do some maths to figure out this ratio. The way to Here we position the image absolutely, relative to its
applications are all digital experiences that could benefit calculate how much padding you need to give an parent container. We also tell it to fit its parent container
from this approach. element is by dividing the height by the width and with the max-width property and have it crop from the
Here we’re going to cover how to semantically build multiplying by 100. So for example we would use in this bottom right. We also want this image to sit behind
aspect ratio-based layouts, approaches for dealing with case: 3 / 4 = 0.75 * 100 = 75. everything, so give it a z-index of 0.
overflowing content, and overcoming the issues with .aspect[data-ratio="4:3"] { .aspect {
making aspect ratios work responsively. max-width: 100%; position: relative;
height: 0; }
1. Download files padding-bottom: 75%; .aspect img {

www.fullengineeringbook.net
The ZIP file provided on FileSilo for this tutorial contains background: rgb(223, 28, 66); max-width: 100%;
all the assets that we will be using along with a basic overflow: hidden;
boilerplate setup. We’re going to use an npm package color: #fff;
called http-server to serve our files. }

2. Mark up aspect ratios 5. Style aspect content Compress images


The images provided in this tutorial are
The aspect ratio boxes don’t have any semantic value in The content inside any given aspect box will look bad if it uncompressed – they weigh 4MBs each. Images
this tutorial, so we’ve used <div> tags. They could be sits flush against the edges of the box. We can get can be compressed in Photoshop with the ‘save
<section> tags if appropriate. We’re also using data around this by giving a margin to the .aspect-content div, for web’ dialog or an npm module like imagemin.
attributes to semantically describe our ‘aspect’ element. which should wrap all written content in a given box.

Left
The image we’ve put in is far too large. Let’s 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; height: 100%; opacity:.5;


right: 0; margin: 0; }
bottom: 0; position: absolute;
z-index: 0; display: flex; 13. Bring it together
} align-items: center; Now we’ve got the diferent aspect ratios and some
justify-content: center; styles together we need to pull it together. Because the
8. Content to the front } aspect boxes are fully responsive we can simply wrap
We need to bring the content to the front so we’re giving them inside a div that limits their width.
it a higher z-index than the absolutely positioned image 11. Animate hover on directions <div class="one-half">
and we give it the lowest possible z-index for this efect. We want the hover state to change the entire tile as the <a href="#directions" title="Directions to
.aspect-content { area is clicked. We’ve created a cubic-bezier transition for event" class="directions">
z-index: 1; a nicer animation and all attributes that change between <div class="aspect" data-ratio="2:1">
position: relative; normal and :hover states will animate using this. <!-- … -->
} .directions .aspect-content { </div>
color: rgb(55, 55, 55); </a>
9. Link the boxes to other pages background-color: rgba(255, 255, 255, 0.83); </div>
Here we take the 2:1 box and wrap it in an anchor transition: all .5s cubic-bezier(0, 1.14, 1,
element. In HTML5 this is valid so long as there isn’t an 1); 14. One half and one quarter
anchor within an anchor. We also give this anchor a class, } The one-half class limits the width of its child elements to
which we will use to change styles specifically to this box. .directions:hover .aspect-content { 50% and will try and float itself along side other content.
background-color: rgba(47, 47, 47, 0.8); It works for siblings like other grid systems, but you also
10. Style directions color: #fff; nest them to get quarters.
We’re overriding the normal .aspect-content styles so the } .one-half {
content area fills the box and resets margins. Flexbox width: 50%;
brings the content to a vertical and horizontal centre. 12. Animate the image hover float: left;
.directions .aspect-content { Fading the image out on hover will pull focus to the text }

www.fullengineeringbook.net
width: 100%; and therefore the action of the box. We use the same <!-- Nesting to get quarters! -->
animation and timing as the other hover efects on this <div class=”one-half”>
element. The short duration is important because we’re <div class=”one-half”>
used to state changing instantly on hover. Animations </div>

Avoid styling
Large images with CSS styles on (like opacity)
over .5s feel sluggish.
.directions img {
</div>

can take longer to render which makes transition: opacity .5s cubic-bezier(0, 15. Going responsive
animations slow. Try avoid applying styles to 1.14, 1, 1); Where we go responsive will depend entirely on the
images and instead animate simpler elements. } content you wish to place in the boxes and how you
.directions:hover img { structured the one-half markup. You will have to resize

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


HTML5 & CSS3
Genius Guide

Changing aspect
ratio sizes
Unfortunately, aspect
ratios don’t 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.
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
<div class="aspect" data-ratio="1:1">
<div class="aspect-content">
<h4 class="headline">Sponsors</h4>
@media screen and (max-width:1000px) { we’ve had to take it down to 3:2 at 850px and below and <p>View our list of sponsors</p>
.one-half {width:100%;} then bring it back to 1:1 at 600px and below. </div>
.one-half .one-half {width:50%;} @media screen and (max-width:850px) { </div>
} .aspect[data-ratio="1:1"] { /* Make 1:1 </a>
become 3:2 */ </div>
16. 420px and below padding-bottom:66.6%}
We also had to bring the nested halves back to 100% at } 21. Finishing touches – styles
420px and below so all the content remained visible. In @media screen and (max-width:600px) { Here we’re using the :after pseudo element to place an
the build example there are 1:1 boxes inside the nested .aspect[data-ratio="1:1"] { /* Make 1:1 image after our tile. Then we absolutely position it over
halves, so we’re still able to see two boxes in a portrait become 1:1 again */ the top. We need to make it clear that these tiles are
view on a mobile device. padding-bottom:100%} CTAs on a web platform where users aren’t used to
@media screen and (max-width:420px) { } seeing them in action.
.one-half .one-half {width: 100%;} .sponsors .aspect:after {
} 19. Aspect at mobile content: '';
At 420px and below, the 2:1 box (which was 4:1 at tablet) width:13px;
17. Changing aspect ratio was looking a bit thin, even though all the content fit fine height:20px;
There was also a need in the example to modify the with the ratio. After some trial and error, we found that background-image:url('./img/arrow.png');
aspect ratios as the browser got smaller. This was the 2:1 ratio worked better and it being the original ratio position:absolute;
because they became too large when the halves was an added bonus! right:20px;
stacked. It feels counterintuitive to have a ratio of 1:1 look bottom:20px;
like 2:1, but this is the best performing solution. 20. Finishing touches – markup transition: right .5s cubic-bezier(0, 1.14,
@media screen and (max-width:1000px) { Add another call-to-action tile to see how it works with 1, 1); }
/* Make 1:1 become 2:1 */ your other tiles in the layout. In the example it sits within
.aspect[data-ratio="1:1"] { a nested one-half container. This is a fairly straightforward 22. Finishing touches – animation
padding-bottom:50%;} CTA as there isn’t much content here, it should just work To make the hover state a bit more obvious we can
/* Make 2:1 become 4:1 */ with the responsive styles that have already been written. change the ‘right’ property which we set up a transition
.aspect[data-ratio="2:1"] { <div class="one-half"> for in the previous step. It’s fairly subtle but reinforces the
padding-bottom:25%; <a href="#sponsors" title="Sponsors" notion that the user is interacting with an element that
}} class="sponsors"> 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 bare-bones template ready for us to start with the coding stroke(255, 255, 255, 28);
has been used by designers and artists as a process. Open this up in your code editor and you will ellipse(0, 0, 120, 80);
creative coding environment to create see that there are two functions here. The first function, }
stunning visuals with very few lines of code. The setup, is used to set all the things at the start of the
Processing library is actually a Java library and this is project like background colour and size. The draw 5. Start the draw function
useful for creating interactive installations and prints. The function is called every frame. Now inside the draw function, add the first line in the
p5.js project is a new initiative to bring the ease of function setup() { code below, which is the same as in the setup, for
Processing to the web by enabling designers and // put setup code here making the background a black colour. The diference
developers the same easy controls to draw to the Canvas } here is that it is called every frame and therefore
element in HTML5. This means that live, interactive function draw() { removes any drawing from the previous frame so that
visuals can easily be created for just about any HTML5 // put drawing code here we end up with a new drawing every frame. The
capable browser, which is almost any browser from the } translate line moves the drawing point to the middle of
last three or four years. the browser window.
The screenshots for this project do not do it justice as 3. Edit the setup function background(0);
the project has to be interacted with in order to see it In the setup function add the code that is presented translate(windowWidth/2, windowHeight/2);
work properly. We are going to be creating an organic below. This creates a new Canvas element to draw into
shape that is drawn pretty similar to an old spirograph, and set this up to be the current width and height of the 6. Draw around a circle
but it’s going to morph, change size, shape and colour browser window. The background of the Canvas is set to A ‘for’ loop is added here to create 720 ellipses. The ‘for’
based on the user’s mouse input. As the user moves black, and the Canvas itself is set to smooth, or antialias. loop increases by 0.5 every loop so it will draw 720
their mouse, the shape ripples and changes to create a This will ensure that the lines are crisp but not jagged at instances. The push line enables the drawing to rotate
stunning interactive shape-shifting visual. With a little the edges. around the middle of the screen. The drawing position is
manipulation this could easily become a music visualiser! createCanvas(windowWidth, windowHeight); then pushed out 200 pixels on the y axis.
background(0); for (var i=0; i<360; i += 0.5) {
1. Start the project smooth(); push();
Open up your web browser, type in p5js.org, click rotate(radians(i));
Download and then choose Complete Library. Once it 4. A new function translate(0, 200);

www.fullengineeringbook.net
has finished downloading, open the folder ‘empty- In between the setup and draw function, add a new
example’ and copy the file p5.min.js into it. Open index. function as we have shown in this step. This code is
html in your code editor and change the script file to use called to draw an ellipse on the screen and we will be
the minified version.
<script language="javascript" type="text/
drawing a large number of ellipses later using this. The fill
colour is turned of and the stroke is white but with a low
Adding colour in p5.js
Colour in p5.js follows a pattern of 0-255 to give
javascript" src="p5.min.js"></script> opacity that is just over 10 per cent visible. The ellipse is
256 colours for each colour channel and this in
drawn from 0, 0 pixels to 120, and 80 pixels on the x and turn will give around 16 million diferent colours!
2. Open sketch.js y axis respectively. To get random colours, a random number in that
After installation, the app is usually extracted. The main function drawEllipse() { scale can be created.
code for our project will be found in sketch.js – this is a 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 numbers that draw the shape. Here the variables are 12. Map other values
Now as the drawing point is 200 pixels out from the added just above the setup function so that we can call Just below the code that was added in Step 10, add the
centre of the screen, p5 will draw an orbit around that them from any function that we want. The names are code that we have included below. It looks very similar to
point but first it will rotate again here. The whole drawing fairly self-explanatory, and you will also see them in our other pieces of code, but what’s diferent is that this
will be scaled but it will also be based on a sine wave action in the coming steps. time the position of the mouse on the x axis is mapped
that modulates between 1 and – 1 so that the result is a var scaleX; onto a range of numbers from just 0.1 to 0.5 and the y
very organic shape. var scaleY; mouse is mapped onto 0.8 to 1.8. These positions will
rotate(radians(i*3)); var min; provide some subtle diferences in the drawing when
scale(map(sin(radians(i*6)), 1, 1, 0.5, var max; they are applied in the next step.
1), map(sin(radians(i*3)), 1, 1, 0.5, var radius; min = map(mouseX, 0, windowWidth, 0.1,
1)); var r, g, b; 0.5);
max = map(mouseY, 0, windowHeight, 0.8,
8. Draw the ellipse 10. Scale based on position 1.8);
Now as the drawing point is at the right place, the ellipse In the draw function add the following code at the top,
is drawn and the pop command places the drawing and this code will set the values of scaleX to take the 13. Scale again
point back to the centre of the document. Save the file mouse’s x position. As it moves 0 pixels to the right-hand Just like we did in Step 12, locate the ‘scale’ line of code
and view the index.html page in the browser to see the side of the screen, those values will be mapped onto a inside the ‘for’ loop. Here the min and max variables are
drawing of the organic shape in action. Now we are range of values from 1.5 to 11.5. The same thing will then added. Save this and view it in the browser to see how it
going to change the shape interactively based on the happen with the y position of the mouse and the adjusts the drawing on the screen. Remember that these
mouse movement of the user. window height as well. numbers will be adjusted as the mouse moves around
drawEllipse(); scaleX = map(mouseX, 0, windowWidth, 1.5, on the screen.
pop(); 11.5); scale(map(sin(radians(i*scaleX)), 1, 1,
} scaleY = map(mouseY, 0, windowHeight, 1.5, min, max), map(sin(radians(i*scaleY)), 1,
11.5); 1, min, max));
9. Add some variables
In order to add interactivity to the screen, we will need 11. Amend the ‘for’ scale 14. Change colours

www.fullengineeringbook.net
some variables to dynamically control some of the Look inside the ‘for’ loop, further down in the draw In much the same way as the shape of our graphic can
function. Here you will see a line of code beginning with be altered based on where the mouse is, as we have
‘scale’. Change the numbers from 6 and 3 to scaleX and shown in the previous steps, it is also possible to
scaleY as we have shown here. This means that the code dynamically change the colour. In the setup function add

The nature of code


Because p5.js is a port of Processing, most
will now take the mouse position for how the shape will
be drawn. Save this now and try it out in your browser to
these random numbers for the red, green and blue
values. The colour values are measured from 0 (for
Processing code can quickly be adapted. Check see it in action. darkest) to 255 (the brightest).
out Dan Shifman’s eBook The Nature of Code scale(map(sin(radians(i*scaleX)), 1, 1, r = random(255);
(natureofcode.com/book) for more information. 0.5, 1), map(sin(radians(i*scaleY)), 1, 1, g = random(255);
0.5, 1)); b = random(255);

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


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
the screen. Keep in mind though that each third will
afect a diferent colour.
else if (mouseX > ((windowWidth/3)-
20. Update the radius
Now in the mouseMoved function, add the following line
just before the closing bracket of the function. The y
drawEllipse function. This means that when it draws the windowWidth)){ position of the mouse will decide how large the radius of
ellipse it will also make use of the random values. Save b = random(255); the circle will be. Note that this will never be smaller than
this now and test it in the browser to see how it works //b = map(mouseY, 0, windowHeight, 0, 255); 100 pixels and never larger than 350 pixels, but you can
and looks. Each time you refresh the page a new colour } else { change these values if you want them to be slightly
will be used. g = random(255); larger or smaller.
stroke(r, g, b, 28); //g = map(mouseY, 0, windowHeight, 0, 255); radius = map(mouseY, 0, windowHeight, 100,
} 350);
16. Colourful mouse moves }
Having to refresh the screen to change the mouse colour 21. Set the radius
is okay, but we may also want to update the colour based 18. Slight change to the colour In order for these radius values to actually be used, look
on the screen position of the mouse. This colour efect is The random colour changes have worked well so far, but inside the draw function and inside the ‘for’ loop is a
possible via an ‘if’ statement as we have shown in the now we can specify that the colour now changes translate line. Update the value of 200 to the radius
code below, which divides the screen into three specifically based on how far down the page the mouse variable. Now you can save the file and then refresh in
horizontal strips for RGB colour. In this step we have is. To do that we will need to revisit the ‘if’ statements that the browser to see this in action. There will be a lot of
started of with the first third and mapped it to the red, we have already used in Steps 16 and 17. First, comment changes now to the shape, size and colour.
giving it a random colour. out the random line and uncomment the line afterwards. translate(0, radius);
function mouseMoved() { Then, save this and test this change in the browser to see
if (mouseX < (windowWidth/3)){ it all working. 22. Fade out
r = random(255); //r = random(255); Finally it is possible to fade out the drawing from all of
//r = map(mouseY, 0, windowHeight, 0, 255); r = map(mouseY, 0, windowHeight, 0, 255); the previous frames. In the ‘draw’ function, comment out
} the background colour. So now we want to set the fill
19. Change the drawing radius colour to black with a low opacity of around 10 per cent.
17. Green and blue changes Now we go back to the shape itself, it is possible to Then, a rectangle is drawn over previous frames with the
Continuing on from what we’ve learned in the previous change how large the circle is drawn around the centre low opacity on top and this will cause the previous
step, we can use the ‘if’ statement to take the last third of point. In the setup function add the radius value as frames to fade out. Save and test this now to see the final
the screen and map that to a random blue colour. Then, shown here. This started of the project with an initial efects in all their glory.
we can also do the same for the green in the middle. value of 150 pixels as the radius from the centre of the background(0);
Save all of this now and test it in the browser to see all of screen, but this can now be updated. fill(0, 25);
the random colours as the mouse moves around, all over radius = 150; 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

www.fullengineeringbook.net
camera is moving.

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

Animated image Full homepage


The background image is The homepage itself is
made of two images and much larger than shown
move at different speeds here as it can be scrolled
towards the viewer for a down to bring more
parallax effect. content to the user.

74 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

Parallax scrolling on sites is getting to the point impression that a camera is moving closer to the EXPERT ADVICE
of being overdone; as soon as every site starts content. Not only that, but this also helps the user to
Controlling CSS keyframes
As the 3D zooming parallax efect is the focus of this
to have the same features it’s time to start focus on specific content, as the image is brought into site it can be reproduced using HTML and CSS alone
looking to add a touch more originality into the design the foreground. without any JavaScript. This is down to the use of CSS
process. The Scholz & Friends site has taken the familiar This gives a very unique look to the content and it keyframes, which enable us to specify how something
will look on frame one and in the final frame of
paradigm of the parallax efect on images, but has done provides a freshness that makes a subtle change from
animation. The duration is also controlled in ‘seconds’
this with a diferent take. the scrolling efects that other sites employ. as opposed to milliseconds in JavaScript.
Parallax is usually done with images or content When content that you design looks just diferent CSS keyframes normally loop, so in the workshop
moving at diferent speeds as the user scrolls down the enough from the competition it helps you to stand out as the animation takes place over six seconds and the
default would be for it to start again and loop through.
page, this was original and novel five years ago. Instead a designer and helps your clients stand out and every
There are some commands that enable us to control
of doing it this way, the parallax efect on Scholz & designer needs to remember that the success of their exactly what happens with the keyframes and they can
Friends is actually a zooming efect, which gives the clients is ultimately a reflection of their own success. 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
Fresh paint on a familiar style set to forward, meaning they play once and hold on the
final frame of animation. Set this to backward and they
“Producing content for the image slider in the site requires a fresh approach, will play in reverse order. Change this to both and it will
almost every site on the web has featured content displayed at the top of the double the duration, playing it forward and backwards.
site. To show off Scholz & Friends, a zooming effect was used on the images to Using the animation iteration count, the amount of
<comment>
times it loops can be controlled. This will reset on the
What our freshen up the dated parallax look.” first frame of animation so be careful of your content
experts think
of the site
Mark Shufflebottom, professor of Interaction Design jumping back to the start.

Technique image is just scaled up slightly so that it looks like the animation-name: fore;
camera is zooming in on the image. animation-duration: 6s;
1. Creating 3D zoom effects @-webkit-keyframes back { animation-fill-mode: forwards;
To create some of the 3D zoom efects found on the from {transform: scale(1);} }

www.fullengineeringbook.net
Scholz & Friends site, create a new HTML document and to {transform: scale(1.2);}
add this code to the body. This will display two images on } 8. First keyframes
the webpage. The foreground keyframes animate two diferent
<div id="wrapper"> 5. No prefix code properties at once. They increase the scale and move the
<img src="img/bg.jpg" id="bg"> Newer browsers that don’t require the vendor prefix image slightly to the left, this helps to give a 3D efect as
<img src="img/fg.png" id="fg"> should also be catered for, so here is the code for those. this zooms in more than the background to make it look
</div> It’s slightly smaller because it doesn’t have -webkit- in like it’s in front.
front. Notice the keyframes have the label ‘back’ which is @-webkit-keyframes fore {
2. Wrap them up picked up in Step 3’s code. from {
Now create style tags in the head section of the @keyframes back { transform: scale(1);
document and add the CSS rule for the wrapper. This from {transform: scale(1);} left: 100px;
holds both images and centres them on the page. As the to {transform: scale(1.2);} }
images zoom in, the overflow is set to hidden. } to {
transform: scale(1.4);
3. Position the background 6. Foreground image left: 40px;
The background image needs to be positioned The foreground image isn’t currently visible because the }
absolutely so that each image can be overlaid on top of overflow is hidden. Adding this rule for it will position the }
each other. The animation is going to be stored in foreground over the top of the background image and it
keyframes with the title ‘back’. This should hold on the aligns to the bottom of the background image, while 9. Final keyframes
last frame of animation so the ‘forward’ animation fill being 100 pixels in from the left. Add the last keyframes to the CSS and then save the
mode is used. #fg { document. Opening this in your web browser will show
#bg { position: absolute; you the efect running over six seconds and you will see
position: absolute; bottom: 0; the foreground and background moving separately to
-webkit-animation-name: back; left: 100px; complete this 3D zoom efect.
-webkit-animation-duration: 6s; @keyframes fore {
-webkit-animation-fill-mode: forwards; 7. Finishing the foreground from {
animation-name: back; As with the background image this is also being transform: scale(1);
animation-duration: 6s; animated to zoom in. The remaining code for the left: 100px;
animation-fill-mode: forwards; foreground CSS rule sets up to run on keyframes that are }
} labelled ‘fore’. It takes six seconds to run and will pause to {
on the last frame of the animation like the background. transform: scale(1.4);
4. Add keyframes -webkit-animation-name: fore; left: 40px;
Safari, Chrome and Opera use the webkit prefix on CSS -webkit-animation-duration: 6s; }
so here the keyframes are added. As you can see the -webkit-animation-fill-mode: forwards; }

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 page. This will provide information needed by the reader 5. Modal box content
information in a way that is simple to to identify whether they want to read further. Insert content into each of the <article> containers. Each
understand. And yet, sometimes the amount of modal box will need the ability to be closed, which will be
information causes a conflict with the need to present 3. Option navigation triggered by an <a> tag linking to a blank ID using just #
information in a way that is easy to comprehend and Next insert the available options that will provide the user for its href. We also want to give this closing button a
where the information is still complete. One option would with access to additional information. These options will ‘data-button=”close’ attribute so we can style it later.
be to separate content onto diferent pages, but this be regular <a> links contained inside a <nav> container. <article id="bravo" data-transition="left">
causes scope for unnecessary page loading and poor Unlike regular <a> tags that use their href to link to <a href="#" data-button="close">x</a>
usability, especially where users are accessing the external pages, these <a> links will link to ID components <img src="img/photo1.jpg" alt="Coastline" />
webpage through a slow internet connection such as via on this page using a # symbol in their href attribute <h2>Bravo</h2>
mobile data with poor reception. preceding the ID name being linked to. <p>Lorem ipsum dolor sit amet.</p>
Modal boxes ofer a perfect solution to the problem by <nav> </article>
enabling additional information to appear on the page <a href="#alpha">Alpha</a>
when they are clicked without the need to load a new <a href="#bravo">Bravo</a> 6. Initiate CSS styling
page. Furthermore, modal boxes can be closed again in <a href="#charlie">Charlie</a> The main HTML template content is now complete, but
order to return the user to the original content without <a href="#delta">Delta</a> the additional CSS stylesheet resource file is still required
the need to reload. <a href="#echo">Echo</a> to add the styling. Create a text file called ‘styles.css’,
This tutorial looks at several options for how modal </nav> making sure that your text editor does not add .txt as a
boxes can be developed with CSS to provide highly file extension. These also need attaching from the
usable designs for websites and web apps that are easy 4. Add modal boxes <head> section of HTML document.
to adapt for diferent types of content you may want to The modal boxes will all use <article> as their container
present. The functionality of these modal boxes will focus element and will have an optional attribute of data- 7. Style HTML body
on easy access in a way that enhances the user transition to specify the type of transition they will use to Don’t forget that the <html> and <body> elements on a
experience of the webpage. appear and disappear, providing a high degree of webpage are set to a height of just one line by default,
flexibility for individual sections. hence causing problems if we want to create a container
1. Get started <article id="alpha"> that has a full webpage height. Solve this by setting the

www.fullengineeringbook.net
First, declare the main HTML page structure, including </article> <html> and <body> elements to be full height in the CSS.
the head and body section within the HTML page. We <article id="bravo" data-transition="left">
will need a content container made from a div element </article>
with an ID called container to control page content flow. <article id="charlie" data-

2. Content overview
transition="right">
</article>
Multiple transitions
Use data attributes to enable multiple transitions
With the main layout elements in place, we can insert the <article id="delta" data-transition="zoom"> to be defined that can be easily added to
main content inside the container element. The page will </article> individual modal boxes without having to
have a descriptive title and introduction text to provide <article id="echo" data-transition="fade"> overcomplicate your CSS.
the main overview of the information contained on the </article>

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

html,body{ 9. Options container nav a:hover{


display: block; We want the options to stand out from any standard border-color: #333;
width: 100%; content on the page. You can do by styling the options background: #fff;
height: 100%; container that was created with the <nav> tag. This will color: #333;
margin: 0; be styled with a distinctive border and margin spacing to }
padding: 0; ensure it appears separate from surrounding content.
} nav{ 12. Define modal boxes
display: block; The modal boxes all use <article> elements as their
8. Style the container padding: 1em; containers, hence we can use CSS to define their default
The container needs to be styled in a way so that it will border: 3px solid #000; styles for width, height and positing. We want these
stand out. This can be done by changing the main page margin: 2em 0 2em 0; elements to appear at pixel-specific locations on the
background colour and positioning the container in the } screen so we use absolute positioning to allow attributes
centre of the page. To do this, we need to update the for top, left and z-index.
<head>, <body> and container sections. 10. Option styles article{
html,body{ The option navigation elements need to appear like display: block;
font-family: "Trebuchet MS", Helvetica, buttons, even though they are just <a> link tags. This can position: fixed;
sans-serif; be done through CSS by making these elements display z-index: 9999;
background: rgb(21, 34, 47); as an inline-block, which enables us to apply sizing and left: 25%;
} padding to make them appear like buttons. top: 100%;
#container{ nav a { width: 40%;
display: block; display: inline-block; height: 50%;
width: 1000px; padding: 1em; padding: 2em 5% 0 5%;
height: 100%; margin-left: 1em; border-radius: 1em;
background: #ccc; font-size: 1.5em; background: #000;
margin: 0 auto 0 auto; border: 3px solid #fff; color: #fff;
padding: 1em; background: #333; overflow: auto;

www.fullengineeringbook.net
} color: #fff; }
}

“ Make full use of 13. Set transitions


11. Option hover Modal boxes need to be able to show transition from
visual information Good usability will make it easy for users to know which one CSS property state to another for the animation to

without option they will select if they are to press on their


trackpad or mouse button. We can apply the :hover
be visible. To keep our CSS simple, set ‘all’ properties to
be eligible for transition animations. You can add other
compromising on property to the options so that they change colour when
the user’s mouse pointer is placed over them, indicating
properties later to trigger their animation sequence.
article{
presentation
” which option is about to be selected. padding-bottom: 1em;

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


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;
}
Modal box usage in UX design
15. Transition: fade Visual information often needs to take up a large amount of space in order to be fully useful. Check out Twitter, which
Now that the modal boxes have the ability to transition uses modal boxes to display basic information about a person’s profile that are triggered when you click on a Twitter
from the default <article> settings to the :target settings, handle. Using text or thumbnails to trigger the presentation of the full image or video when clicked provides a way to
we can apply rules that will overwrite the default <article> 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
settings through the data-transition attribute. Our first
be used with alerts and notices – automated appearances of information can be provided to show important
rule will let the modal box fade in and out of view. information that the user must see. Similarly, modal boxes for tips are presented as a clickable options for requesting

www.fullengineeringbook.net
[data-transition="fade"]{ additional information – useful for enabling users to access more information when they want it.
left: 25%;
top: 25%;
opacity: 0; [data-transition="zoom"]{ article [data-button="close"]:hover{
visibility: hidden; visibility: hidden; background: #fff;
} left: 50%; color: #c00;
top: 50%; border: 3px solid #c00;
16. Transition: left width: 0; }
The next transition we want to use is to let the modal box height: 0;
slide in from the left by placing the default position of the opacity: 0; 21. Image spacing
modal box as fully of the screen to the left. This means } Our modal box design makes use of an image to be
that it will move from this position to the centred position displayed at the left of the text content. This image
set in the :target when this element is selected for display. 19. Style close buttons should be the height of the modal box – we can use CSS
[data-transition="left"]{ The modal boxes have an an element with an attribute of to set the image as 100 per cent of the modal box article
left: -100%; ‘data-button=”close”’ used to close the modal box. We will img{
top: 25%; style this to appear in the top-right corner as a red circle display: block;
} – achieved by setting the border radius to be curved and float: left;
for the element to float to the right. height: 100%;
17. Transition: right article [data-button="close"]{ }
We also want a transition efect to make the modal box display: block;
slide in from the right by placing the default position of float: right; 22. Place a margin
the modal box as fully of the screen to the right – ie 100 background: #c00; Make sure that there is a margin of one text character to
per cent of the screen width from the left. color: #fff; the right of the image so the text isn’t too close to the
[data-transition="right"]{ border: 3px solid #fff; image. Place a margin to the right of the image, so that
left: 100%; border-radius: 1em; the positioning of all elements in the modal box will take
top: 25%; padding: 1em; this into account.
} text-decoration: none; article img{
} margin-right: 1em;
18. Transition: zoom }
The final transition to add is the ability for a modal box to 20. Style images article img{
zoom in and out from the screen centre. This transition Now we change the colour of the close button by display: block;
requires the default style to be of zero width and height. applying styles through the :hover selector that will float: left;
We’ll also add an opacity of zero so that the modal box trigger the change when the user hovers their mouse height: 100%;
will fade in and out of view as it sizes up or down. pointer over the close button. }

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 file at the root of the site called sw.js (eg example.com/ 5. Pick a place to save
of of Twitter for a while) you are likely to have sw.js) The location of the file is important (we will go Where the sw.js is loaded from is very important, and it
heard that the hot new thing in web over why that’s the case in Step 5). should probably be /. That is because what the SW is
development is ‘progressive web apps’. Already being navigator.serviceWorker.register('/sw.js') able to control (and therefore make work ofline) is
implemented by major websites like Flipkart, Facebook // .register() is async, and it limited to it’s scope. That means that if you register
and Google, Progressive web apps basically mean a // returns a promise example.com/js/sw.js, it will only be able to control any
collection of new APIs that have very recently been .then(registration => { URLs that begin with example.com/js.
added to some browsers that allow for authors to create // we're installed! // control everything on the domain
rich, native-like experiences. The key bit that ties }).catch(err => { navigator.serviceWorker.register('/sw.js')
together most of these new browser APIs is Service // there was some kind of error // control everything served from /js
Workers, and it will radically change the way that you go }) navigator.serviceWorker.register('/js/sw.
on to make websites in future. js')
Introduced in Chrome version 40, Service Workers 3. Use Promises
are a new type of web worker that act as a kind of proxy Service Workers are completely asyncronous, and so 6. Listen for fetch
between your website and the network. That means they use Promises everywhere. Promises are a new-ish Now we’ll add some functionality by listening for the
with a little bit of JavaScript we will be able to intercept, browser API that makes it easier to reason about async fetch event (fired for any network activity covered by
modify and even respond to requests from our site code. If you haven’t brushed up on them before now, it the SW’s scope and this will include XHR, CSS and
without ever hitting the network! By using Service would be a great time to do so – all new async APIs will more). It will respond with data stored via the new
Workers, we can make web apps work 100 per cent be based on them. Cache API if it exists. If it isn’t cached, that’s fine, we will
ofline, allow for content sites to have fun and enjoyable functionReturningAPromise() just fire of a new fetch call.
ofline fallbacks, and supercharge the responsiveness of .then((result) => { self.addEventListener('fetch', ev => {
our site for everyone else. // All Promises have a `then` method ev.respondWith(
In this tutorial we will update an HTML5 podcasting // where can do something with the caches.match(ev.request)
app by adding a Service Worker to our site, include // result of the function .then(response => {
some tips to make your own upgrades easier and }).catch((e) => { return response || fetch(ev.request)
explain the common pitfalls that you can avoid. // Always make sure to define a catch })

www.fullengineeringbook.net
// on your promise, otherwise you )};
1. Get support // won't know if there was an err
Service Workers aren’t supported everywhere yet, and })
won’t be for a while. So the first step whenever dealing
with new APIs is to do an existence check. Tools like 4. HTTPS only Let’s encrypt!
Modernizr make this easy for trickier APIs, but Service You can only register a Service Worker if the site is
LetsEncrypt.org is a safe and free new way to
Workers are quite simple to check for without it connected to HTTPS (or accessed via localhost). This is get and automatically renew SSL certificates,
going to be true for most new browser APIs, so if you which are required for new browser APIs like
2. Create a Service Worker haven’t gotten a SSL cert for your site, now is a great Service Workers.
Let’s add a Service Worker. To start, we create a blank time to do so,

Left
For security’s sake, browsers will only let you register a
Service Worker if the site is connected to over HTTPS

Top left
Chrome’s internet connection error message shows up
when the user is offline and no Service Worker has been
registered. Our users can’t do anything in this case

Top right
By using a fallback image we are able to ensure that even
when resources aren’t cached or available, our users still
get a visually pleasing experience

HTML5 & CSS3 Genius Guide 81


Front-end

7. Add responses return cache.addAll([ 11. Disable for offline functions


You may have noticed that we never actually added to '/logo.svg', Our app relies on audio files from outside sources. We
the Cache. Since Cache is not the same as the '/fallback.jpg', can’t really presync every podcast ever, so when we go
browser’s HTTP cache we have to manually add the ]) ofline we want to disable some functionality to prevent
responses as they come in. You may only want to do }); user confusion. In this case, we will hide the search
this for only certain items, though, otherwise none of ) button when we get an ofline event.
your REST calls would ever update! }) let cL = document.body.classList
… let toggle = () => {
let request = ev.request 9. Fallbacks failing // add the class “hideSearch” to the
caches.match(request) In our app, we are going to load a number of images, // body tag when nav.onLine is false
.then(response => { and on slow connections, they may take a long time to cL.toggle('hideSearch', !navigator.onLine)
return response || fetch(request) load. We can add a fallback to the fetch call that we just }
.then(response => { made, so that we can show our default image rather window.addEventListener('online', toggle);
// only add JPGs to the Cache than an empty spot. window.addEventListener('offline', toggle);
if (request.url.match('/jpg$') { return fetch(ev.request)
cache.add(request); .then(response => { 12. Alternate experiences
} cache.add(ev.request); One thing we are all trying to avoid is the dreaded user
}).catch(err => { bounce rate. If the site is ofline, it’s more or less useless
8. Prime the cache // reply with the precached image to the user. You can use Service Workers in creative ways
In addition to fetch, we can listen for the install event in return cache.match('/fallback.jpg') to serve temporary content if a user navigates to a page
order to fire some set-up code. This lets us prime the }) that is not cache. For example, The Guardian ‘s website
cache with a few entries for things we know are going displays a crossword!
to be requested, as well as any fallback content we may 10. Keep our users in the loop caches.match(request)
want to load later on. Even though we are creating a great ofline experience, .then(response => {
self.addEventListener('install', event => { there are going to be some things that won’t work. if (response) return response;
event.waitUntil( Therefore, we want to make sure our users know that if (request.url.match('/article/') &&

www.fullengineeringbook.net
caches.open('cache-v1').then(cache => { the app has gone ofline, in case they are unaware. Just !navigator.onLine) {
how you show that information is up to you, the // if the request isn't cached and we
browser provides an easy way to check. // are offline, serve this instead
let updateStatus = (event) => { cache.match('/crossword.html')

The UpUp API


Hit the ground running with UpUp (talater.com/
// inform user of offline status
}
}
)})
upup) – a great library that provides a simple API window.addEventListener('online',
for a lot of Service Workers as well as more updateStatus); 13. Communication is key
common use cases. window.addEventListener('offline', Service Workers are like other web workers in that they
updateStatus); 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 can’t 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
aren’t 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 can’t 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.
15. Update caches
Eventually our cached content will be stale. When that
happens, you will probably want to delete the old
})

17. Update the Service Worker


// sw.js caches in order to let the server give us the updates. The process for updating your Service Worker is pretty
self.onmessage = (message) => { This is usually best done in the activate event, where simple, just change the file. When your site registers the
// the string passed to the worker you can register a function just like we did before for Service Worker, the browser will always attempt to
// exists on the `data` prop the fetch or install events. download it. If it has a single byte of diference from
let msg = message.data; event.waitUntil( what it got last time, it will start using the new version
console.log('msg from the DOM ' + msg) caches.keys().then((names) => { after the page reloads – that’s unless you tell it
} return Promise.all( otherwise.
// index.js names.map((name) => { self.addEventListener('install', (ev) => {
navigator.serviceWorker caches.delete(name); // you can take control from the old
.controller.postMessage('HELLO WORLD!') }) // service worker immediately by
); // calling skipWaiting on “install”
14. Share actions }) ev.waitUntil(self.skipWaiting());
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 16. Solve multiple issues 18. Debug your Workers
consistent state across tabs, even if the user is only Let’s say we update our site’s layout and we want to Since they’re so new, the tooling around Service
interacting with a single one. delete the HTML and CSS, but we don’t want to lose Workers is not great yet. A lot of errors are often
any audio cached for playback. In this case, we should swallowed in ways that are pretty opaque. In Chrome,
let url = request.url; register multiple caches – one for the code and you have the ability to go to chrome://serviceworker-
if (url.match(\/delete\/\d+)) { another for audio. Then we can invalidate them one at internals to see more advanced options. The devtools
fetch(request).then(() => { a time. team is working hard to make this better!
self.clients.matchAll() let whitelist = ['audio-cache']
.then(all => all.map(c => { caches.keys().then((names) => { 19. Future support
c.postMessage("{delete:"+url+"}") return Promise.all( Supporting ofline is just the beginning for Service
)); cacheNames.map((name) => { Workers. Background sync, which is used to update
}) if (whitelist.indexOf(name) === -1) { your app without the user even having it open; push
}) return caches.delete(name); 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 mobile’s 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 <script src="js/CSS3DRenderer.js"></script> position: [ 0, 512, 0 ],


mobile devices has come a long way, there are <script> rotation: [ Math.PI / 2, 0, Math.PI ]
a whole raft of phone functions that designers var camera, scene, renderer; },{
can plug in to and access without the need for var circle1, circle2;
packaging up the mobile site as an app. In this tutorial 4. Add each side
what is being achieved with the native mobile web would 2. Set the scene Each side has to be added so in total there will be six
have been pretty hard to conceive as an app going back The code now adds the init function, used to initialise the sides for this. If you wanted to create your own
just a few years, but now this is running purely as a scene. A camera is created, the control system is initiated background, an image with a 90-degree field of view
mobile optimised website. to run on the device orientation controls. The scene is horizontally and vertically has to be taken that points at
The site itself will be in 3D and rendered by three.js but created now that the camera and control system can all six sides. It’s easier to create this with a 3D application
instead of this being rendered with the WebGL renderer, work with. The final code starts an array and this as the rotation and field of view can be exact.
the scene will be rendered using the CSS3 renderer, contains an object. url: 'img/scene-base.jpg',
giving us maximum compatibility with devices. Having 3D function init() { position: [ 0, -512, 0 ],
as part of the design is going to be an important part of camera = new THREE.PerspectiveCamera( 75, rotation: [ Math.PI / 2, 0, Math.PI ]
the interface. In order to browse around the interface the window.innerWidth / window.innerHeight, 1, },{
user will need to rotate their phone and the display will 1000 ); url: 'img/scene-front.jpg',
update, placing them in the centre of an augmented controls = new THREE. position: [ 0, 0, 512 ],
interface. Moving the phone around becomes like DeviceOrientationControls( camera ); rotation: [ 0, Math.PI, 0 ]
moving a camera in the interface to explore the links that scene = new THREE.Scene(); },{
are on ofer to the user. This is made possible through the var sides = [{
‘Device Orientation Controls’ that come bundled with url: 'img/scene-right.jpg', 5. Set up the cube
three.js and can turn our phone into something similar to position: [ -512, 0, 0 ], Now as all six sides have been referenced in the array, a
an Oculus Rift. rotation: [ 0, Math.PI / 2, 0 ] cube is created by making a new 3D object and this is
This is part of a two-part tutorial; creating the interface },{ added into the scene. A for loop is created to iterate
and get the device orientation working, we will focus on through each position in the array and this will be used
the interaction with the menu in the following pages. 3. Create the background to display the images in the scene as a box.

www.fullengineeringbook.net
To create the background for the 3D scene a skybox will
1. Link the libraries be created, which is a large cube placed on the outside
Open the ‘start’ folder in a code editor such as Brackets. of all other objects. The code here is holding a reference
In the body of the document, add the following code to
link up the libraries. This uses the three.js library available
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
from threejs.org. Following this is an opening script tag url: 'img/scene-left.jpg', pixels but it has been set to display at 1026 by
with some global variables that are needed in the project. position: [ 512, 0, 0 ], 1026 so that there is a slight overlap in all of the
<script src="js/three.min.js"></script> rotation: [ 0, -Math.PI / 2, 0 ] sides, as CSS 3D transformations are not as
<script src="js/DeviceOrientationControls. },{ accurate as WebGL.
js"></script> 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', array is created, but this time round there is much less 11. Add to the scene
position: [ 0, 0, -512 ], information than before and that’s because the image The final step is to tell the object to look at the vector
rotation: [ 0, 0, 0 ] needs to be stored for each of the icons that will be position setup, then the icon is added into the scene. The
}]; placed on the screen. closing bracket will now finish of the for loop. This will
var cube = new THREE.Object3D(); mean that all of the code that is inside of the for loop is
scene.add( cube ); 8. Iterate the icons applied to each image icon so that they are all positioned
for ( var i = 0; i < sides.length; i ++ ) { Again a for loop is created to iterate through the images. to orbit the camera.
A div element is created to hold each image within. The object.lookAt( vector );
6. Set each side image is added using the JavaScript innerHTML scene.add( object );
Information from each array position is stored in the command to create content inside of it. The image is }
variable side. A new image element is created and given given a unique id and the class of ‘pic’ that is used to
a specific width. A CSS3DObject is created and added. style it later in the CSS. The source image is also added 12. Interactive map
var side = sides[ i ]; for the icon. This next block of code is to add an interactive Google
var element = document.createElement( 'img' Map to the page. Visit Google Maps and find a location
); 9. Handle the interaction you’d like to show, then click the menu button and from
element.width = 1026; A click handler is added for the picture and at the the slide-out panel, click the ‘share’ button. In the popup
element.src = side.url; moment this simply returns the value of the id to the grab the embed code and paste the iframe into the third
var object = new THREE.CSS3DObject( element console log. In the second part of the tutorial, we will line of code shown here.
); learn how this calls the correct content to load for each element = document.createElement( 'div' );
object.position.fromArray( side.position ); of the icons. The image is then added to a CSS3DObject element.className = 'mapped';
object.rotation.fromArray for placing in the scene. Then the position of the icon is element.innerHTML = ‘embed code here’;
( side.rotation ); calculated around the camera. var elementWidth = 600;
cube.add( object ); } pic.addEventListener( 'click', function ( var elementHeight = 600;
event ) {
7. Icon images console.log(event.target.id); 13. Position the map
Now that the background is in place, our attention will }, false ); There is a large red square on the floor of the 3D scene,

www.fullengineeringbook.net
turn to creating icons that will sit in front of that. Another var object = new THREE.CSS3DObject( pic ); which is part of the background images added earlier on.
var phi = (Math.PI*2) / menu.length; We are positioning the map to be 600 by 600 pixels so,
phi = phi * i; in the embed code added from Google, change the
width and height to 600 for both. The map is positioned

3D CSS transforms 10. Position the icon further down away from the camera and then rotated
Using the code from the previous section each icon is toward the camera.
Anything can be displayed in the 3D scene that
can be displayed on a regular webpage, such as positioned at equal positions around the camera. The element.style.width = elementWidth + "px";
video, maps, text and images, because the scene 350 relates to the radius of the circle or how far from the element.style.height = elementHeight + "px";
is all controlled with CSS 3D transforms. camera the icons will appear. Once in position each icon var cssObject = new THREE.CSS3DObject(
is rotated to face the camera in the centre of the scene. element );

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


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 can’t
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 it’s 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
doesn’t 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


14. Add animated elements If the phone or tablet device is rotated from portrait to Open the project.css file from the css folder on FileSilo.
The next element that is being added is a transparent landscape or vice versa, the browser changes This is empty of all code, so add the code shown here for
PNG image with circular lines on it. This is added into the dimensions. In order to capture this, the onWindowResize the body tag styling. This sets the background colour to
3D scene and positioned above the camera while being function updates the aspect ratio of both the camera white and sets the margins to zero, so that the scene fills
rotated towards the camera. This will be animated to spin and the renderer so this will work on any size device with the full browser display. The overflow is hidden and the
later on to provide some animation within the scene. any size display. font set to Helvetica or Arial.
body {
15. A second circle 18. Animate the scene background-color: #ffffff;
Another circle is added and you will notice the pattern The animate function updates the screen’s display using margin: 0;
that a div element is created, inside here an image is the browser’s requestAnimationFrame command to cursor: move;
placed. The div needs to be added as a CSS3DObject, update the screen at 60 frames per second, or as fast as overflow: hidden;
this can be positioned and rotated to display correctly. the device can render it. The circles are rotated on the font-family: helvetica, arial, sans-serif;
Finally add the object to the scene to be displayed. screen, the controls update and the scene is rendered or }
updated to display the view.
16. Display the 3D scene function animate() { 21. The menu items
The way the scene is to be updated is now set. Normally requestAnimationFrame( animate ); The next CSS rule sets the image icons that are
with three.js scenes this is the WebGL renderer but in this circle1.rotation.z += 0.001; displaying as the menu. This just sets the cursor to a
tutorial the CSS3D renderer is being used, for maximum circle2.rotation.z -= 0.002; pointer if the user has a cursor on rollover. This won’t be
compatibility. An event handler is registered to call the controls.update(); necessary for the majority of browsers as mobile and
onWindowResize function if the screen changes and the renderer.render( scene, camera ); tablets don’t usually have mouse pointers!
animate function is used to update the screen. }
renderer = new THREE.CSS3DRenderer(); 22. Finish and save
renderer.setSize( window.innerWidth, window. 19. Set it all up The size of the pictures is set here using the width and
innerHeight ); As we come to the end of the JavaScript code, the init() height properties. Without this the image icons are just
document.body.appendChild( renderer. function is called which sets the scene up, placing too big on the screen, but it’s useful to have the images a
domElement ); everything in there and calling the scene to start little bigger as most mobiles and tablets have high-pixel
window.addEventListener( 'resize', rendering. After this the script tag is closed. Save this resolution screens. Save the file and place on a server
onWindowResize, false ); page now as all of theJavaScript code is added in here. 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 mobile’s 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), 2. Content panels appropriate icon the panel will slide in from the left.
a unique mobile augmented website menu was There are going to be four content panels in the project Clicking the burger icon will make it slide back to the left.
created. The site was created with the help of the – these will appear when the user clicks on one of the <div id="info3" class="panel hidden animated
three.js library and was rendered using the CSS3 renderer icons in the menu inside the 3D scene. Add the code as weather">
rather than the WebGL renderer to give maximum we’ve below to the body of the page just above the script <div class="head">
compatibility with devices. The 3D was an integrated part tags. This creates a top bar section and an area for text. <a href="#" onclick="fade3();">&#9776;</a>
of the design as the user had to rotate their phone <div id="info1" class="panel hidden <h2>Weather</h2>
around them to display the interface, augmenting the site animated"> </div>
around them. This placed the user in the centre of the <div class="head"> <p>Text here</p>
interface. The movement of the phone was created using <a href="#" onclick="fade1();">&#9776;</a> <p>Text here</p>
the ‘Device Orientation Controls’ that come bundled with <h2>Chat</h2> </div>
three.js and this sort of turned our phone into something </div>
similar to an Oculus Rift. <p>Text here </p> 5. Five into four
Now, in this final part of the tutorial, the interface will be <p>Text here </p> Each panel will be styled up to match the colour of the
given some content so that it actually becomes useful. </div> icon using CSS code – the colour will be used to reinforce
This content will be hidden from the user until they click the selection made by the user. There are five icons and
on the appropriate icon in 3D space, at which point a 2D 3. Panel details but only four panels. One icon is the logo of the website
panel will slide in over the top of the existing 3D menu You can fill the text with your own content or even so that will not link anywhere, but it will orientate the user.
system. The animation in the panels,will be powered by images. You may notice that there is a strange code in <div id="info4" class="panel hidden
the Animate.CSS library, which will slide on the new the link tag, this is actually the code to create the three animated">
content. This gives us access to a quick way to create lines of the burger icon for the menu button. This will <div class="head">
animated elements. take the users back to the 3D menu screen. <a href="#" onclick="fade4();">&#9776;</a>
Each panel will be colour-coordinated to match the <div id="info2" class="panel hidden <h2>Events</h2>
icon that has been clicked and then the panel can be animated"> </div>
removed again by clicking a burger menu icon in the top <div class="head"> <p>Text here</p>
left to take the user back to the experimental menu. <a href="#" onclick="fade2();">&#9776;</a> <p>Text here </p>

www.fullengineeringbook.net
<h2>Arriving</h2> </div>
1. Pick up from part one </div>
This tutorial picks up directly where it was left of at the <p>Text here </p>
end of part one (see page 87). First link up the animate. <p>Text here</p>
css library, available from daneden.github.io/animate.
css, which we’ve already downloaded and put in the CSS
</div>
Positioning above
The new panels added in this tutorial are
folder. This will power the sliding on of popover content 4. Panel power positioned on a z plane above the background
later on. The panels are constructed from regular HTML elements CSS panels so that they appear in front of the 3D
<link rel="stylesheet" href="css/animate.css" and will be hidden from the site using CSS. Then linking scene as 2D panels.
/> 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 hasn’t quite fully fallen into
place in the image

HTML5 & CSS3 Genius Guide 89


Front-end

6. Responsive srcset behaviour allows for the head section to have the right height for 11. Paragraph settings
Save the HTML document for now and open the ‘project. both of those elements. Below the heading there is just a couple of paragraphs,
css’ file from the CSS folder. Add on the code in the next .head{ but if this was your own design this could contain a
few steps to style the content in the panels appropriately. height: 45px; variety of content, from images, video’s or anything else
The first content merely creates the generic style for all } you wish to display on a HTML page. As there is only text
of the panels that place this above the other content on in the example there is just a 5 pixel padding for the top
the page. 9. Position the menu and bottom and 10 pixels for left and right.
The link in the head section of the panels is the burger p{
7. Hide and seek menu icon and here the code is floating that icon to the padding: 5px 10px;
When the App starts up the menu should be visible and left of the screen. It’s given a slight padding around the }
nothing else. The hidden class is used to hide all the top and left so it isn’t too close to the sides. The text
panels when the App first launches and then only as the decoration is set to none and ensures that the underline 12. Individual style
user taps the device screen should it be visible to the doesn’t appear below this. Each panel shares the same generic styling that has
user. The visible class was actually used during testing .head a { been applied in the previous six steps. Now you need to
but is not used in the final site. display: inline-block; concentrate on giving each panel a colour scheme that
.hidden{ float: left; fits with the initial icon that it represents. Here the panel
display: none; width: 10%; is given a light green background with dark green text
} padding: 10px 0 0 10px; and header.
.visible{ text-decoration: none;
display: block; } 13. Blue section
} As in the previous step, the styling is now looking at the
10. Lay out the heading individual panels. The second panel will be styled up with
8. Break down the parts Now, turn your attention to the h2 heading tag, which is a light blue background, giving a darker blue colour for
After the panel is styled up, each panel will have a head made to float to the right of the menu icon. The padding the text. The header panel of this is the reverse of that
section that has a burger menu button to take users on this reflects the slightly diferent shape of the text and styling with a dark blue background and lighter text.
back to the menu and a heading so that they know they the icon, with there being less top padding on the text.
14. Third panel
www.fullengineeringbook.net
are seeing the right content on the screen. This CSS just The text is also aligned to the right so that the menu and
heading are on opposite sides of the screen. The third panel takes on purple characteristics for the
.head h2{ colour scheme with lighter styling for the background
display: inline-block; and a darker header section on this panel. The colours

Know your code


HTML is the content of your website while CSS
width: 70%;
margin: 0;
help to reinforce to the user the icon that they’ve just
clicked on to give them a way to orientate themselves in
provides the way those elements are rendered padding: 7px 10px 0 0 ; the mobile web site.
by the browser giving a unique design. The float: right; #info3.panel{ background-color: #d1b3ce ; }
JavaScript part of the site provides functionality. text-align: right; #info3 .head{
} color: #eed8ec;

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


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, don’t
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; }
change.classList.add('bounceOutLeft');
}
content. Find styles that work together and make sense
with your functionality rather than choosing the most
attention grabbing animation that you see.
#info3 p{ color: #584356; } 17. Bounce around function fade4(){
The next code is for the second panel and these series var change = document.getElementById(
15. Final panel colours of functions take the ID of the relevant info panel then 'info4' );
The final panel that is being styled up again reflects the remove the class that has made them bounce onto the change.classList.remove('bounceInLeft');
colours of the icon used to access it from the original 3D screen from the left. Once this is removed the code to change.classList.add('bounceOutLeft');
menu created in part one of this project. This time the make them leave is added and the elements bounce }
colour scheme is given an orange theme with light tints back out to the left.
and dark shades used to create the panel. Save the CSS function fade2(){ 20. Grab the link
file and close it. var change = document.getElementById( Following this you’ll need to scroll down through the
#info4.panel{ background-color: #f5c5a7 ; } 'info2' ); code until you find the code that has the click function
#info4 .head{ change.classList.remove('bounceInLeft'); event listener on the pic variable. Inside this function, add
color: #f5c5a7; change.classList.add('bounceOutLeft'); the two lines of code in bold shown below. These lines
background: #b65212; } check that the icon that has been clicked on is not the
} first icon, and if so it stores the current icon’s ID in the
#info4 .head a{ color: #f5c5a7; } 18. Use Animate CSS change variable.
#info4 p{ color: #b65212; } The CSS styles that are being added and removed for pic.addEventListener( 'click', function (
these sections have not been created here – instead they event ) {
16. Start the JavaScript are from the Animate.CSS library that was hooked up to console.log(event.target.id);
All of the requisite elements are now in place for the our page in the first step of this tutorial. You can visit if(event.target.id != "0"){
design and content of the panels. It’s just a case of daneden.github.io/animate.css to see more styles. var change = document.getElementById(
adding the desired functionality to make these panels function fade3(){ 'info'+event.target.id );
work. In the JavaScript code locate the global variables var change = document.getElementById(
on lines 56 and 57, then add this function below it. This is 'info3' ); 21. Finish the code
called into efect when the menu burger icon is pressed change.classList.remove('bounceInLeft'); Now continue with the following code that turns of the
on the first panel. change.classList.add('bounceOutLeft');} hidden property, and if it has been clicked on previously
function fade1(){ it removes the bounce out CSS. The bounce in animation
var change = document.getElementById( 19. Customise the animation is added to bring the panel onto the screen. Save this,
'info1' ); If you visit Dan Eden’s Animate.CSS site you can try out upload it to a server and connect using your phone’s
change.classList.remove('bounceInLeft'); diferent animation styles before applying them to your browser to see it all working.

HTML5 & CSS3 Genius Guide 91


Front-end

Assemble full-
screen 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 this to load the CSS stylesheet and JS code. This lets the ability to contain these elements inside a container that
the delivery of information and content to also resources to be reused by other pages if required. has controls, such as to exit full-screen mode and/or
being capable of delivering software <link rel="stylesheet" type="text/css" switch to viewing other elements.
applications. Web-based software applications have href="styles.css" /> <div id="screen3" class="fullscreen">
often been labelled as ‘not as good’ as their native <script src="controls.js" type="text/ <span action="exit">close</span>
counterparts – an attribute that is now more of an javascript"></script> <iframe src="http://www.monkey-x.com"></
incorrect stereotype with the modern browsers now iframe>
supporting HTML5. 3. Page container </div>
A big part of the problem that web applications face in Use the <body> section to contain the visible content. We
their accusation of being a poorer equivalent of their start this by placing the <main> page container inside the 7. JavaScript selector functions
native counterparts is based on psychology – people who body; this will be used to allow the controlled layout of With all of the HTML elements on the page, the next step
make such accusations are often unaware that many the content. Your page title and introduction content will is to start building functionality with JavaScript. Create a
apps they’ve download from their app store account are go inside this. file called ‘controls.js’ and add the following functions to
merely web apps wrapped by a native web view element. allow easy selection of HTML page elements.
One of the features of HTML5 that can be used to 4. Fullscreen: controls $ = function(cssRule){
condition users to take your web app more seriously is to The controls to access the full-screen elements are return document.querySelector(cssRule);
display content in fullscreen – this is more relevant to the placed as content inside the <main> container element. }
desktop where windows can clutter the screen, but are Each of these items have a [data-screen] attribute that $$ = function(cssRule){
also relevant to mobile smartphones and tablets. stores the element ID of the item to open. return document.querySelectorAll(cssRule);
Our example will create a menu page that provides the }
user with the option to access content in full-screen 5. Fullscreen: elements
mode. A useful element for full-screen applications is the Some elements will be displayed directly in full-page 8. JS full-screen activation
use of iframes, which are a good solution for the limitation mode. These elements are to be added to the content Our example will use a single function to activate any of
of the browser exiting full-screen mode as soon as the inside the <main> container. We add a selection of the full-screen presentation of the elements passed to it.
user visits a new URL; iframe elements enable page images that will be selectable, as well as a number of This allows the control of full-screen requests to be
changing without changing the current URL. iframe pages with ‘class=”fullscreen”’ to be called on later. managed from one place, with it being easy to upgrade

www.fullengineeringbook.net
<iframe id="screen1" class="fullscreen" later if this is required.
1. Initiate HTML page src="http://www.nextpoint.co.uk"></iframe>
As with any webpage, there is a requirement to define the <iframe id="screen2" class="fullscreen"
page’s HTML, head and body structure. Use the head src="http://www.blitzbasic.com"></iframe>
section to contain any meta data such as the page title
for SEO and accessibility that you may need.
<img id="screen4" class="fullscreen"
src="img/guy.jpg" />
Use iframe apps
A problem with full-screen mode is that it closes
when the user visits a new URL – this is solved by
2. Load resources 6. Fullscreen: containers using iframes, enabling you to show diferent
The HTML <head> section should contain the links to In addition, providing the ability to make elements webpages without changing the URL.
any resources you are using for the page. We’re using directly display in full-screen mode, we also have the

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(); 12. Initialise styling
} else if(element.mozRequestFullScreen) { 10. JS action listeners Now that the JavaScript functionality is complete, the
element.mozRequestFullScreen(); Controls that are responsible for activating full-screen next stage is to start the definitions for the visual
} else if(element.webkitRequestFullscreen) { presentation of other elements require their JavaScript presentations. Create a file called ‘main.css’ and then
element.webkitRequestFullscreen(); listener to behave slightly diferently – instead of insert the following CSS formatting for the main HTML
} else if(element.msRequestFullscreen) { activating themselves, we use the [data-screen] attribute and body containers.
element.msRequestFullscreen(); to reference the ID of the element to activate the html,body{
} full-screen presentation. background: #000;
} window.addEventListener("load",function(){ padding: 0;
var screenTriggers = $$('[data-screen]'); margin: 0;
9. Controls: exit fullscreen for(var i=0; i<screenTriggers.length; i++){ font-family: monospace;
There is a need to allow the user to exit full-screen mode screenTriggers[i].addEventListener("click",f height: 100%;
from within the webpage. This is performed in a similar unction(){ }
way to opening full-screen mode, but instead referencing fullscreen( $('#'+this.getAttribute("data-
the main document’s exitFullScreen() function. screen")) ); 13. Content container
function fullscreen_exit(){ }); The content is contained inside the <main> element,
if (document.exitFullscreen) { } which positions the content in the centre of the screen.
document.exitFullscreen(); }); We achieve this positioning by setting the left and right
} else if (document.msExitFullscreen) { margins of <main> to auto, which will balance the margin
document.msExitFullscreen(); 11. Attach fullscreen_exit() spacing between both sides.
} else if (document.mozCancelFullScreen) { Looking back at Step 6, there are elements used as main{
document.mozCancelFullScreen(); containers for presentation – complete with controls. display: block;
} else if (document.webkitExitFullscreen) { Attach the previously created fullscreen_exit() function to width: 75%;
document.webkitExitFullscreen(); elements with a [data-action=”exit”] attribute when margin: 10% auto 0 auto;

www.fullengineeringbook.net
clicked, in order for the user to exit full-screen mode.. background: silver;
window.addEventListener("load",function(){ padding: 1em;
var screenTriggers = $$('[data- }

About the exit plan action="exit"]');


for(var i=0; i<screenTriggers.length; i++){ 14. Navigation styling
Browsers provide a way to exit full-screen mode,
screenTriggers[i].addEventListener("click",f The full-screen options all have the [data-screen]
but users will forget any notice they are shown.
Make sure to add an on-page exit button to make unction(){ attribute, hence why we use this in order to reference
it easy for users to exit fullscreen when they fullscreen_exit(); them; enabling us to change their element type from
want to do so. }); button if needed. Also apply colour, padding and
} transition properties.

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


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;
background: #c00;
color: #fff;
transition: background-color 1s;
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
font-size: 2em; -webkit-transition: background-color 1s; full-screen selectors.
background: #333; } .fullscreen{
color: #fff; display: none;
transition: background-color 1s; 17. Exit hover width: 100%;
-webkit-transition: background-color 1s; The exit option will also change appearance when the height: 100%;
} user hovers over it. This is achieved by using the :hover }
selector, in which we will change the background and
15. Navigation hover effect text colours. With the background-color property being 20. Full-screen visibility
In order to make sure that users can clearly identify that set as a transition in the previous step, the colour change Items that have been hidden from normal view need to
navigation elements can be interacted with, we will place will animate when the element is hovered over. become visible when the browser enters full-screen
an efect on each of the navigation items to slightly .fullscreen [data-action="exit"]:hover{ mode. This is achieved by using :fullscreen selector –
change their appearance when the mouse pointer is background-color: #fff; although take note that diferent browser vendors use
hovering over them. Changing the colour to become a color: #c00; diferent versions and spellings for this selector.
lighter shade when it is hovered over gives the } .fullscreen:-webkit-full-screen{display:
appearance of it lighting up. block;}
[data-screen]:hover{ 18. The iframe styling .fullscreen:-moz-full-screen{display:
background-color: #777; Container elements that contain an iframe element will block;}
} be displayed to show them at full size. This needs to take .fullscreen:-ms-fullscreen{display: block;}
into account the five per cent height of the exit option, .fullscreen:full-screen{display: block;}
16. Exit style hence the height of the iframe will be 95%. .fullscreen:fullscreen{display: block;}
Elements that have [data-action=”exit”] will need to have .fullscreen iframe{
this displayed as a visible control. We will make this display: block; 21. Finishing touch
appear as a full-size red bar with white text that stretches width: 100%; With everything complete, you are now free to make any
across the full width of the screen. This element will also height: 95%; additional styling required for your version of the
be 5% of the height of the full screen. } full-screen menu tool. In this example, we add an
.fullscreen [data-action="exit"]{ underline style to the h1 element used as the visible
display: block; 19. Hiding full-screen elements page title.
width: 100%; Full-screen elements use the class name ‘fullscreen’ and h1{
height: 5%; are hidden by default. Properties to ensure 100 per cent 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


IT’S 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 The library has enabled developers to work with the
years, jQuery can sometimes be described as DOM API to build a far richer web than we had ten What’s up with v3?
‘not-cool’ – especially when used in the same years ago – improving the end user’s experience, which
sentence as libraries like Angular or React. JQuery should ultimately be the most important goal of any LEARN MORE ABOUT THE FIRST
doesn’t include a templating language or follow a MV* web project. MAJOR RELEASE IN TWO YEARS
pattern, yet it’s still an incredibly useful library in the The library will be a whopping ten years old in Version 3 alpha is now out in the wild and
modern developer’s toolset. August 2016, making it the great grandfather of comes in two flavours; much like the release
JQuery’s gentle learning curve can be a great JavaScript frameworks – a proven and stable platform of version 2 it drops support for Internet
introduction to JavaScript and since conception it’s that has enhanced millions of websites. There was a Explorer below version 9. There is however a
become the go-to for a first ‘taste’ of JavaScript – a time when people believed Facebook would start losing ‘compat’ version if you want to support older
language that is leaving its browser only roots behind. users as its popularity increased – this never happened browsers and utilise new features for your
The library enables complex topics to be introduced because the platform worked whilst serving a purpose, more up-to-date users. The only caveat here
sooner and in bite-size chunks. The more experienced like jQuery. being that the compat version will be of a
developer should remind themselves of jQuery’s own Understanding, when enhancing an interface to larger file size as well as being slower in
slogan which is ‘write less, do more’. This ease of use improve the end user’s experience, is key and jQuery real-use performance.
can, in the ‘real’ world of fast-paced deadline-driven has been successfully doing this for nearly ten years. When developers release a major version of
development, be a lifesaver. How many of us can Newer libraries may introduce new features and any framework there is usually a queue of
remember how to efectively traverse the DOM in paradigms; it may not be faster than its native people complaining about breaking changes,
vanilla JavaScript? counterpart functionality, yet jQuery’s dependable core and the jQuery team has worked hard to
Simplicity shouldn’t be a negative, the library is in use and widespread knowledge base ensure that it stays ensure this isn’t the case – almost all code

www.fullengineeringbook.net
in over 65 per cent of the top one million websites production ready. should continue to work with zero changes.
(libscore.com/#jQuery) and this isn’t a coincidence. There are, however, changes that are a step
The library’s core is well-thought-out and the jQuery in the right direction. In previous releases any
team has an incredibly methodical process to jQuery methods that hide/show content (.
implementing new features – features that are hide(),.show(), .slideIn()) applied display
introduced to improve the library with each release. properties directly to the element, sometimes
Being designed from day one with extensibility in adding display:block to elements and
mind has meant that in the last ten or so years, overriding display properties that should have
thousands of plugins have been developed by a huge been display:inline – this can cause a lot of
open source-based community; there is a jQuery plugin layout issues. This is no longer the case and
for almost all use cases now. Unfortunately though, jQuery recommends to hide/show content
some of these plugins that have been created may also using CSS classes with methods such as .
generate some bad press due to the poor-performing toggleClass(). This increases performance by
and underdeveloped code involved. The saying ‘A poor ensuring the change is rendered by the CSS
workman blames his tools’ is true for all of these terribly render engine.
written plugins and the developers that decide to Performance seems to be high on the
actually use them. Knowledge within the open source agenda and whilst reworking the internals of
community allows the cream to rise to the top and the custom attribute selectors (:visible, :hidden)
jQuery community has published guidelines on they’ve noted speed increases of up to 17 times
extending the library. Daniel Jenkins faster in execution. The underlying animation
We have to thank jQuery’s popularity for kick-starting Development lead engine now utilises requestAnimationFrame
the vibrant JavaScript community we have today. There “JQuery’s easy-to-understand meaning smoother animations, less CPU time
have been of-spin projects such as ‘jQuery Mobile’, syntax allows me to introduce and reduced battery drain on mobile devices
which is an extension of the library to produce mobile experience-enhancing features on – great if you’re using jQuery in PhoneGap or a
and tablet-ready interfaces. Web developers can use an websites quickly and efficiently that Cordova application.
existing skillset to make advanced interfaces for the work across multiple web browsers Version 3.0 goes some way to
newest devices – devices that didn’t exist when it was and devices.” futureproofing the library, ensuring that it’s
initially released. keeping up with the latest standards (.
deferred() is now Promises/A+ compliant for

“ The library is well-thought-out and the example). Along with the increase in
performance, and when combined with the
jQuery team has an incredibly methodical removal of deprecated functionality, jQuery v3
is another step forwards.
process to implementing new features
” HTML5 & CSS3 Genius Guide 99
Developer

What’s in the core API?


REMEMBERING THE CORE METHODS IS A BIG UNDERTAKING, SO HERE’S A LIST OF WHAT YOU SHOULD KNOW

selectors Attributes .innerHeight() Browser


$(‘selector’) & CSS api.jquery.com/innerHeight/ Events
Gets the height of first matched
* .attr() element, This will include the .resize()
api.jquery.com/all-selector/ api.jquery.com/attr/ padding as well but does not api.jquery.com/resize/
Selects all elements. Gets the attribute for the first include the border. Binds event handler on resizing.
selected element.
.class .innerWidth() event
api.jquery.com/class-selector/ .data() api.jquery.com/innerWidth/ preventDefault()
Selects all elements with the api.jquery.com/data/ Gets the width of first matched api.jquery.com/event.
given class. Store data associated with element. This will include the preventDefault/
matched element or return the padding as well but does not If this method is called, then the
#id first matched elements. include the border. default action of the event will not
api.jquery.com/id-selector/ be triggered.
Selects a single element with the .prop() .outerHeight()
given id. api.jquery.com/prop/ api.jquery.com/outerHeight/ .scroll()
Gets the value of a property for Gets the height of first matched api.jquery.com/scroll/
selector1, selector2, the first matched element or sets a element. This will include the Binds event handler upon
selector3

www.fullengineeringbook.net
property on matched elements. padding, border and optionally element scrolling.
bit.ly/1Cs2xEX the margin.
Selects the combined results of all .val() .load()
the specified selectors. api.jquery.com/val/ .outerWidth() api.jquery.com/load/
Gets the value of the first matched api.jquery.com/outerWidth/ Binds event handler to JavaScript
element element or sets a value on the Gets the width of the first matched ‘load’ event.
bit.ly/207g9md matched elements. element. This includes padding,
Selects all elements with the given border and optionally the margin. .ready()
tag name. .addClass() api.jquery/ready/
api.jquery.com/addClass/ .width() Specify function to run when DOM
parent > child Adds specified class to the api.jquery.com/width/ load is complete
bit.ly/207gbdS matched elements. Gets the current computed width
Selects all direct ‘child’ elements (in px) of the first matched .on()
specified by ‘parent’ .css() element, or it will set the width on api.jquery.com/on/
api.jquery.com/css/ all of the matched elements. Attaches an event handler for one
ancestor descendant Adds specified style property to or more events.
bit.ly/1PPT039 the matched elements. .offsetParent()
Selects all of the elements api.jquery.com/offsetParent/ .trigger()
that are the descendants of the .hasClass() Gets the closest ancestor element api.jquery.com/trigger/
ancestor element. api.jquery.com/hasClass/ that is positioned. Executes matched events.
Determines if any matched
:first elements are assigned to a .position() .blur()
api.jquery.com/first-selector/ specific class. api.jquery.com/position/ api.jquery.com/blur/
Selects the first matched element. Gets the current coordinates of Binds to the form ‘Blur’ event.
.removeClass() the first matched element, relative
:last api.jquery.com/removeClass/ to the ofset parent. .change()
api.jquery.com/last-selector/ Removes specified class from api.jquery.com/change/
Selects the last matched element. matched elements. .scrollLeft() Binds to the ‘change’ event handler.
api.jquery.com/scrollLeft/
:first-child .toggleClass() The current horizontal position of .focus()
bit.ly/1LXfv4A api.jquery.com/toggleClass/ the scrollbar for the first matched api.jquery.com/focus/
Selects all elements that are the Adds or removes a specific class element or sets horizontal position Binds or triggers to the form
first child of their parent. from matched elements. of the scrollbar for elements. ‘Focus’ event.

100 HTML5 & CSS3 Genius Guide


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
jQuery’s 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:
//script.js
<module>
import * as $ from 'jquery';

jQuery and ES6 </module>


//jquery.js
module.exports = {

www.fullengineeringbook.net
$ : jQuery()
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 This module pattern would enable jQuery to remove
latest version of JavaScript, oficially the library works with the latest version of the method $.fn.extend() and allow plugin developers to
launched in June 2015, it’s going to Extending today’s browsers, and vice versa with still hook into the jQuery core.
take browsers a considerable jQuery code written in v2 and older ES6 controversially introduces classes, constructors
amount of time to implement all of You can make use of jQuery.fn. browsers. This is no mean feat – it’s and extend into the language – something back-end
the new features. Developers extend() ($.fn) to extend the one of the main reasons the jQuery developers will rejoice about. Regardless of opinion the
wishing to implement the code jQuery prototype and provide library still exists and has a massive new inheritance model could be put to good use with
now will need to use a compiler yourself with new methods that user base, a lot of logic happens jQuery becoming class-based, with plugins extending
from ES6 into ES5 such as babel can be chained of the jQuery() behind the scenes. As newer the base jQuery class.
(babeljs.io) to ensure backwards function. features are introduced, jQuery takes class pictureSlider extends jQuery {
compatibility. The current version of a logical approach to supporting them constructor() {
JavaScript (ES5) can turn developers with a with a good forewarning on sunsetting this.slideSpeed = 5;
back-end mindset blue in the face with its lack of older functionality. this.touchEnabled = true;
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 //plugin code
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 There isn’t currently an ES6 implementation of the
proven that JavaScript is an extensive language no browser using the $.ajax() wrapper. jQuery library, but as popularity increases the library will
longer existing in just the traditional web browser var request = $.ajax({ look to support it. A large community built on plugins
context. Smart TVs, mobile applications, websites, url: "script.php", using the current $.fn.extend() prototype makes picking
servers and many other platforms now depend on method: "POST", one of the previous two examples for extending the
JavaScript, thus updating the language needs to be }); library a logical move once browser support is ready.
controlled and ES6 goes a long way to becoming request.done(function( msg ) { ES6 introduces many native APIs that jQuery has
backwards compatible. console.log(msg); included workarounds for in previous releases such as
ES6 may not be production-ready today – unless the }); new iterators (for + of) and common data-structures
exact platform specifications are known, yet it contains request.fail(function( jqXHR, textStatus ) { (.map). You can read more at ecma-international.org/
features the modern web developer will want to be console.log(‘error’); ecma-262/6.0/) for a full list of all the new ES6 features.
aware of. Languages evolve and the technology that }); ES6 will make a lighter and faster jQuery, ensuring that
supports them does too, jQuery has a proven track developers using the library can focus on writing code
record of helping developers build interfaces for the JQuery’s recent implementation of Promises enables that is doing less behind the scenes and more for the
widest level of support available. The majority of developers to efectively ensure that the JavaScript 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 pro’s guide to the


www.fullengineeringbook.net
benefits of jQuery
JQUERY HAS THE POTENTIAL TO TURN A GOOD DEVELOPER INTO AN EXPERT – FIND OUT HOW

When looking to use web technologies for a project elements such as allowing new features to be added to
there are many factors involved in the decision-making a website within tight timescales or ensuring a student
process to consider, such as how long until the project can complete a task they set out to do. Take for
needs to be delivered. Does the project need to example the blue chip world, a world that has inherently
support the latest browsers? Or even worse support the slow IT upgrade schedules with the majority of these
oldest of browsers? Does the project have to withstand users using much older versions of Internet Explorer,
being production-ready, bug-free and dependable? picking the right library helps to ease the pain of
Multiple factors play a part, some that may not even be building features that are cross-browser compliant.
considered by the developer when embarking on a Trying to write vanilla JavaScript for even basic use
new project. cases can be painful, taking the blue chip world for
Working with HTML and CSS can, for many, be an example try adding a class in jQuery:
easy choice when it comes to building interfaces, yet $(‘#contact’).addClass(’sent’);
the sheer number of JavaScript frameworks to choose
from can be bewildering. Syntax aside, choosing the The jQuery method has enabled this functionality in
right framework takes a large amount of consideration. minimal code for working across multiple browsers.
It’s the wider thought process of the entire project and Now try writing that in native JavaScript:
the impact of decisions made early on that makes a document.getElementById(“contact”).
Matt Leach good developer, great. Knowledge like this isn’t gained classList.add("sent");
Head of development, Thinking Juice over night but practising, experimenting, making
mistakes, learning and talking to peers can reduce the Now this is nearly double the length and works in
“Using jQuery was the first time I
headaches along the way of mastering development. modern browsers, looking back to older versions of IE
saw the web as more than a flat
this would cause an error. To ensure cross-browser
interface and a place to create
experiences for users and
Progressive enhancements compliance look at this code (and its length):
JQuery was initially introduced to enhance the world of var d = document.getElementById("contact");
customers, every time I use the
web development and, like all open source eforts, to d.className = d.className + " sent";
library I learn something new.”
enhance the framework user’s experience. In the real One line of code may sufice if the project only uses
world these enhancements can be measured by trivial JavaScript for this single action – loading in a library

102 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

5 jQuery features
you need to know
METHODS THAT ARE WELL
WORTH USING

.promise() .ajaxSetup()
You can use this method to api.jquery.com/jQuery.ajaxSetup/
return a Promise object to This little-known method allows variables to be
observe when all actions of a predefined for all AJAX requests. For example
certain type that are bound to the using a defined URL route for all requests in an
collection, regardless of whether application could be set via:
it is queued or not, have $.ajaxSetup({
finished. 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.
var data = [0,1,2];
would then be overkill. JQuery gives developers a set of repeated more than once there is probably a way of var filteredData = $.grep( [ 0, 1, 2
tools that keeps all levels focused on the end goal. automating that process. ], function( n, i ) {
DRY (don’t repeat yourself) principles are abundant return n > 0;
Deadline-driven development

www.fullengineeringbook.net
when it comes to writing eficient, human-readable }, true );
Deadlines, much like taxes, are unavoidable in most code. Look at this code for changing an element’s state The variable filteredData is now an array of any
walks of life, and a day-to-day occurrence. Known for once interacted with: values greater than 0;.
causing many a grey hair, working smart can make the $(‘.btn’).addClass(‘in-use’);
approach much more bearable. It’s all too common to $(‘.btn’).attr(‘disabled’, true); .closest()
see more junior developers looking at a current project $(‘.btn’).data(‘used’, true); api.jquery.com/closest/
or application and then announce ‘Hey, we should This method traverses upwards from the
rewrite that in this cool framework’. This doesn’t mean JQuery provides a smart developer the ability to chain current DOM element to a document’s root
they are incorrect and their enthusiasm shouldn’t be these methods, using the prototype inheritance model (a element. It accepts a jQuery object as an
rewarded, but taking on board a new library has to be paradigm widely used JavaScript): argument and if included when traversing,
carefully considered. It needs to ensure a return on $(‘.btn’).addClass(‘in-use’). jQuery returns the first matching element.
investment whether that’s personal or financial. There attr(‘disabled’, true).data(‘used’,true);
will be companies pushing products live with a new .holdReady()
library, built by a freelance resource that their internal JQuery provides a multitude of helpful functions, that api.jquery.com/jQuery.holdReady/
developers can’t support. In a development team, at should have been included in JavaScript from day one. This is a relatively unknown method that holds
crunch time, everyone will be expected to help and Replicating functionality that other languages contain or releases the .ready() function. Use cases for
chances are nine out of ten developers in the team will from the outset, a lot of very similar libraries exist purely this may seem far-fetched, but there can be
be able to help iterate on any code wrote in jQuery. If to fulfil these tasks. Many JQuery utility methods are a times where the DOM is ready but other
written in the ‘cool’ framework the resource pool may secret toolset that a lot of developers don’t mention functionality should happen first.
be slightly smaller. When starting any project be aware frequently. $.holdReady( true );
that at some point in the future, other developers will The jQuery library may not be the fastest or the $.getScript( "myplugin.js", function()
have to support it. lightest but a community of thousands can continue {
producing interfaces in an ever-changing world of $.holdReady( false );
How do the pros really use it? technology. Being a good developer isn’t about being });
A skilful developer is someone that has not only an early adopter it’s about writing well-formed code that
mastered the art of writing code and logical thinking works when required, whilst knowing the tools to get $.merge()
but the understanding that if something has to be the best out of the platform. api.jquery.com/jQuery.merge
Developers used to PHP (array_merge) will
recognise this as a fast way of merging two

“ Taking on board a new library has to be arrays – this neat helper provides functionality
that native JavaScript doesn’t provide.
carefully considered. It needs to ensure a var new_array = $.merge( [ 0, 1, 2 ],
[ 2, 3, 4 ] )
return on investment
” HTML5 & CSS3 Genius Guide 103
Developer

Advanced jQuery
REGARDLESS OF EXPERIENCE, THESE ADVANCED METHODS OF ARE DEFINITELY WORTH CHECKING OUT

Filters Utilities Deferred AJAX


Object
.eq() inArray() jQuery.ajax()
api.jquery.com/eq/ bit.ly/1MgB8c6 deferred.always() api.jquery.com/jQuery.ajax/
Reduces the set of matched Searches for a specified value in api.jquery.com/deferred. Performs an asynchronous HTTP
elements to the one at the an array and returns its index. always/ (AJAX) request.
specified index. Adds handlers to be called when
jQuery.isArray() the deferred object is either jQuery.ajaxSetup()
.filter() bit.ly/1GvAzz8 resolved or rejected. api.jquery.com/jQuery.
api.jquery.com/filter/ Determines whether the argument ajaxSetup/
Reduces the set of matched is an array. deferred.done() Sets default values for any future
elements to those that have api.jquery.com/deferred. AJAX requests.
matched the selector or pass the .jQuery. done/
function’s test. isEmptyObject() Adds handlers to be called when jQuery.get()
bit.ly/1Nyv0zh the Deferred object is resolved. api.jquery.com/jQuery.get/
.first() Checks to see if an object is empty. Loads data from the server using a
api.jquery.com/first/ deferred.notify() HTTP GET request.
Reduces the set of matched jQuery.isFunction() api.jquery.com/deferred.
api.jquery.com/jQuery. notify/ jQuery.getJSON()

www.fullengineeringbook.net
elements to the first one that is in
the set. isFunction/ Calls the progressCallbacks on a api.jquery.com/jQuery.
Checks if the argument passed is a deferred object along with the getJSON/
.has() JavaScript function object. given arguments. Loads JSON data from the server
api.jquery.com/has/ with a GET HTTP request.
Reduces the set of matched jQuery.isNumeric() deferred.progress()
elements to those that have a api.jquery.com/jQuery. api.jquery.com/deferred. jQuery.getScript()
descendant that matches the isNumeric/ progress/ bit.ly/1RdOJVI
selector or DOM element. Determines whether its argument Adds the handlers that will be Specifies a function to run when
is a number. called when the deferred object DOM load is complete.
.is() goes on to generate the
api.jquery.com/is/ jQuery.makeArray() progress notifications. .on()
Checks against a selector and api.jquery.com/jQuery. api.jquery.com/on/
return true if at least one of these makeArray/ deferred.reject() Attaches an event handler for one
elements matches the selector. Converts an array-like object into bit.ly/1GIgIMT or more events.
a true JavaScript array. Rejects a deferred object and
.last() calls any failCallbacks with .trigger()
api.jquery.com/last/ jQuery.merge() specified arguments. api.jquery.com/jQuery.
Reduces the set of matched api.jquery.com/jQuery. getScript/
elements to the final one in the set. merge/ deferred.resolve() Loads a JavaScript file from the
Merges the contents of two arrays api.jquery.com/deferred. server using a GET HTTP request,
.map() together into the first array. resolve/ then executes it.
api.jquery.com/map/ Rejects a deferred object and calls
Parses each element in the current jQuery.now() any failCallbacks with the given .load()
matched set, producing a new api.jquery.com/jQuery.now/ arguments. api.jquery.com/jQuery.load/
jQuery object containing the Returns a number representing Loads data from the server and
return values. the current time. deferred. places the returned HTML into the
resolveWith() matched element.
.slice() jQuery.parseHTML() api.jquery.com/deferred.
api.jquery.com/slice/ api.jquery.com/jQuery. resolveWith/ jQuery.post()
Reduces the set of matched parseHTML/ Resolves a deferred object and api.jquery.com/jQuery.post/
elements to a subset specified by Parses a string into an array of calls any doneCallbacks with the Loads data from the server using a
a range of indices. DOM nodes. given context and args. HTTP POST request.

104 HTML5 & CSS3 Genius Guide


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 browser’s cache, which would reduce bandwidth and $('#navigation').addClass('visible');
Including JavaScript in the <head></head> tags and then page-load time. //execute other code
waiting for jQuery to run when the DOM is fully loaded $('#navigation').removeClass('visible');
can cause the end user a headache-inducing wait. 3. Faster selectors Every time jQuery wants to alter the navigations class
Executing JavaScript code when the browser has loaded With the introduction of CSS preprocessors, it’s become attributes, it has to traverse the whole DOM and find the
the complete DOM is in itself inherently dificult and a bit of an issue with overly specific CSS declarations yet element with the id #navigation, alter its class then
troublesome. Each browser tells JavaScript when the with jQuery – we find the opposite happening. Look at continue processing the next line of JavaScript. Each
DOM is ready at a diferent time and jQuery has a this navigation code: time the $(‘selector’) is used, jQuery has to look for this
helpful method – .ready() – that does a <ul id="navigation"> element in the DOM. Assign the jQuery $(‘selector’)
multitude of things in the background to The <li><a class="nav-item" object to a variable increases performance, as a
ensure the DOM is loaded before firing. $var syntax href='#home'>Home</a></li> reference to that element is now available in memory.
JavaScript is a blocking script – Use the dollar $var syntax to <li><a class="nav-item" var $navigation = $('#navigation');
meaning when the browser finds let others know it’s a jQuery href='#about'>about</a></li> $navigation.addClass('visible');
the <script> tag it won’t do anything object. If the variable is in the <li><a class="nav-item" //execute other code
else until that code has loaded in. correct scope, then jQuery will be href='#contact'>contact</a></ $navigation.removeClass(‘visible');
Any assets, photos, CSS and other able to access the element li>
JavaScript files, won’t execute until without having to search for </ul> 5. Animating with jQuery
this file is loaded. It’s considered best the DOM again. <script> When jQuery was initially released, its internal animation
practice to place all JavaScript assets in $('.nav-item').click(function(){ engine was one of the most ground-breaking features
the footer as JavaScript should enhance a //code to scroll to location – since then browsers and CSS have moved considerably

www.fullengineeringbook.net
page, not build the UI. If code is required to execute }) forward. Take this example of animating an element’s
when all assets in the webpage are ready, it would be </script> height for example:
convenient to do this: The lack of specificity here means that jQuery has to $('.changeHeight').animate({
The code doesn’t get executed until the whole DOM is traverse the whole DOM to find .nav-item – on big pages 'height' : 250
ready – large images slow down the time from page load this can reduce performance greatly. It’s like going }, 650);
to the JavaScript firing. shopping and having to look at every item in the shop to JQuery internally calculates the element’s height, then
//code// find a specific item. You can increase performance by changes the height up to 60 times a second, causing the
(function($) { increasing selector specificity: browser to redraw the DOM every single time it’s
//fire code <ul id="navigation"> changed (60fps). CSS animations in modern
})(jQuery); <li><a class="nav-item" browsers are handled using hardware
href='#home'>Home</a></li> Smooth acceleration and are processed by the
Initialising any functions this way enables the JavaScript <li><a class="nav-item" auto heights GPU ensuring a faster experience over
to execute when it’s possible. The end user will see the href='#about'>about</a></li> Adding the class .open to the CPU tasks like rerendering the DOM
page being usable sooner – perceiving a faster load time. <li><a class="nav-item" element will cause the GPU to for example.
If specific code needs to ensure a certain element is href='#contact'>contact</ redraw the elements properties <style>
completely loaded before being executed, use .load(): a></li> without having to do any of the .changeHeight{
$(img).load(function(){ </ul> complex JavaScript calculations -webkit-transition: all 0.65s
//execute code <script> that will be running. ease-in-out;
}) $('#navigation .nav-item'). -moz-transition: all 0.65s
click(function(){ ease-in-out;
2. Hosting jQuery yourself //code to scroll to location -o-transition: all 0.65s ease-in-out;
When building a website that utilises jQuery it’s all too }) transition: all 0.65s ease-in-out;
easy to download a copy of the library, place it in a local </script> overflow:hidden;
directory then load it in to the pages required. Now when traversing the DOM, jQuery looks for the height:auto;
<head> parent id (#navigation) and then looks for its child max-height:0;
<script src='/jQuery.js'></script> element with the class declared. Going back to the shop display:block;
</head> analogy, the aisle would now be known as (#id), thus }
For every new visitor to a website they have to download searching for the specific item would take much less .open{
this file from the server, which slows down the initial page time than before. max-height:250px;
load and introduces an extra drain on bandwidth. }
Reference jQuery from a CDN and the chances are that 4. Not caching DOM elements </style>
when someone visits the website, they will previously Here is a simple script for adding a class to a website’s <script>
have visited a website that hosts jQuery with that CDN navigation, then removing that class after executing $('.changeHeight').addClass('open');
(Google for example) and already have jQuery stored in other logic: </script>

HTML5 & CSS3 Genius Guide 105


Developer

www.fullengineeringbook.net

discove
m ak i r the top jquery add - ons for
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

Manage UIs

Tweak Photos 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. EasyJSTree’s
<body> tree structures start out as a group of list tags,
Plugin: Image Editor <div id="editor-window"></div> which are then spruced up by invoking the
bit.ly/1hIv6c1 <script type="text/javascript"> easytree() method on the mother element.
Category: Photo editing $("#editor-window").imageEditor({
Users love to edit uploaded pictures on the 'source': '/img/demo.jpg',
web. Image Editor provides a svelte little GUI "maxWidth": 500,
wrapper around the Camanjs filter library: it "onClose": function () {
saves you from the hassle of coding a set of }
sliders, buttons and symbols which come });
together to make up a little editor. </script>
</body>

Getting started with the Image Editor plugin OnClose is invoked if the user clicks the close button
requires the embedding of four libraries and a below the image: you can use the various methods
picture box. Our test harness starts like this: found in Canvas in order to obtain the results of the
editing operation. Image Editor’s 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 Pop-up dialogs
<script src="dependencies/jquery-ui.js"></ maximum height of the image; maxWidth, for the bit.ly/1MWNFGr
script> maximum width of the image; remoteSave, where the Palm OS graced developers with the popup: a

www.fullengineeringbook.net
<script src="dependencies/bootstrap.min. default save method is browser; remoteURL, for where complex modal dialog which could be invoked to
js"></script> you want to send the image to; blockEnable, get a result. Prompt21 obviously was inspired by
<script src="dependencies/caman. which should only be enabled if jQuery the golden oldie. Invoke the popup after calling the
full.js"></script> Required BLOCKUI is enabled; blockMessage, a var p = $(“.popup”).prompt21(); method on it, and
<script src="js/boostrap- dependencies message that will be displayed in the feast your eyes on a JSON object containing the
image-editor.min.js"></ Image Editor will need these blockUI; and saveCallBack, the values entered in the dialog’s widgets.
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 Tab bars
rel="stylesheet"> with a constantly growing provided to inform you about the bit.ly/1OHWpjG
<link href="dependencies/ number of image editing individual steps taken. Image Editor Tab bars are a classic: if there’s little screen real
css/bootstrap.css" capabilities. should not be used to process large files: estate, multiply it by introducing some tabbing.
rel="stylesheet"> most browsers pop up an alert dialog about TurboTabs expects you to feed it with a structure
<link href="css/boostrap-image-editor. unresponsive scripts if an operation takes too long. of <ul> and <div> elements alongside a
css" rel="stylesheet"> In practice, images smaller than XGA tend to work well – configuration object that can be set up via a tool
</head> keep in mind that Firefox is not multithreaded, which on the plugin’s website. Your input will then be
leads to resource competition between tabs. transformed into a svelte-looking and nicely
Keep in mind that the download is not complete and animated tab bar.
that’s because each of the libraries also expects its
resources to be in place for the GUI to work. This can be OTHER AUTHOR PLUGINS:
accomplished by extracting the individual archive’s Ritchy Chen Sticky cursors
contents into the /dependencies folder. rithychhen.com bit.ly/1RMbaSs
Image Editor does its magic in a <div> tag, which is Plugin 1: Scrollbar Indicator Making a widget stick to the cursor is helpful when
populated at runtime via the imageEditor function. Our bit.ly/1LxgHeR a drag-and-drop-like interface is to be
example loads the editing tools during page load – in Plugin 2: Birthday Picker implemented. ObeyCursor transforms this task
practical applications, starting the editor on demand bit.ly/1hIvnvy into a no-brainer: simply configure a <div> tag of
might be more eficient: choice, and configure it with a call to the
obeyCursor method:
<script type="text/javascript">

“ Image Editor does its magic in a <div> tag, $(function() {


$("#slave").obeyCursor(opts);
which is populated at runtime via the });

imageEditor function

</script>

HTML5 & CSS3 Genius Guide 107


Developer

Web Windows manager


Our web app has been Users are free to
rendered in a little change the desktop
pop-up window. You background to an
can spruce up its looks image as they see fit.
by deploying your
chosen GUI framework.

Deskible’s start menu


will remind users of A small clock located
classic versions of in the bottom-right
Windows 95 to 7. The corner of the screen
‘default’ items in our can help your users to
screenshot can be keep track of time.
removed if desired.

www.fullengineeringbook.net
id: 'docu-setup', function tmgnBtnClicked()
Plugin: Deskible label: 'Setup and Layout', {alert ("Hello World!");}
bit.ly/1PwPvyu options: { </script>
Category: Window manager tabs: false, R: <input type="text" name="r" ><br>
Ever found yourself sufering from MDI envy content: { U: <input type="text" name="u" ><br>
while working on a web app? This proof of url: 'apps/documentation/setup.html' I: <input type="text" name="i" ><br>
concept creates a relatively full-featured } } }, { <button onclick="tmgnBtnClicked()">Calcula
Window Manager based on your favourite web te</button>
technologies. It helps developers to create and Higher-level folders are created as simple array elements, </p>
manage a number of dynamic windows inside while their subelement contains the actual content.
their web applications. Looking at /apps/examples/irc.html reveals that the IRC Next, add the relevant entry to the start menu. Our
client consists of but the following line: resistance calculating widget will sit in Tamoggemon ->
OhmCalc, accomplished via the following snippet:
First download Deskible from GitHub. This must be done <iframe type="text/html" width="100%"
via the command line to satisfy the dependencies. Next, height="100%" src="https://kiwiirc.com/ startMenu: [{
open index.html for the correct operation. As of this client" frameborder="0"/> icon: 'book',
writing, the log-in window is not implemented – just click label: 'Tamoggemon',
Login to move into the desktop environment. Start menu Complex content is best created via an iframe: Deskible sub: [{
content is configured by startMenu array content will load it as if it were found in a website, displaying icon: 'wrench',
declared in app.js. One example looks like this: content in the area decorated by the window manager’s id: 'ohmcalc',
widgets. A custom installation of Deskible starts by label: 'OhmCalc',
startMenu: [{ removing unneeded elements: for most applications, a options: {
icon: 'book', YouTube player and an IRC client are overkill. Proceed to tabs: false,
label: 'Documentation', an iFrame-hostable web apps in the apps folder: content: {
sub: [{ <p> url: 'apps/ohmcalc.html'
icon: 'wrench', <script> } } },]}

108 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Telephonic enforcer
bit.ly/1VVXt3V
Users hate sharing their phone number with
random websites. This library contains a set of
Manage Cookies
validation routines aimed at catching miscreants
red-handed. Please keep in mind that with one provided by your legal department, and can
MobilePhoneNumber does not check whether the Plugin: CookieBar and js-cookie also modify the styling to make the cookie bar blend in
user really owns the phone in question – it merely bit.ly/1LdDLxR and bit.ly/1av6HUb better or stand out more.
keeps honest people honest by not allowing them Category: Cookie management In the next step, it is now time for us to actually persist
to enter malformed numbers. EU regulations have made cookie management some data. First of all, the cookies library must be
dificult: as Google recently decided to require included in the header:
EU compliance in its AdSense program,
developers need to conform to the regulations. <script src="js.cookie.js"></script>
Fortunately, a combination of these two cookie
plugins makes compliance and data handling JQuery’s js-cookie plugin provides a bunch of helper
really, really easy! methods for implementing a basic KV store – reading
data from it can be accomplished like this:

Achieving compliance in itself is really easy: cookieBar is $(document).ready(function() {


shipped with a stylesheet that contains the logic for a if(Cookies.get('imagineCookie')===undefined)
basic cookie bar that is easily dismissable by the user. {
Best of all, you don’t have to use any markup either! Start alert("No cookie there yet");
of by including the JS and the CSS file along with the }
main jQuery library: else
{
<html> alert("Found: " + Cookies.

www.fullengineeringbook.net
<head> get('imagineCookie'));
<script src="jquery-2.1.4.js"></ }
script> });
<script src="jquery.cookieBar. Js-Cookie
js"></script> For some quickfire Saving data is then done via the set
<link rel="stylesheet" information on js-cookie, make method. Cookies do not limit
type="text/css" sure you check out the Wiki themselves to basic types: you can
Protect your images href="cookieBar.css"> github.com/js-cookie/js-cookie. It also persist JSON objects by passing
bit.ly/1LdEGy9 </head> is written by one of the authors, them in.
Image theft happens more than you think. This Fagner Brack, and includes
little utility uses the HTML5 Canvas editing Displaying the actual bar can then be details on integration $(document).ready(function() {
capabilities to stamp images with a watermark on accomplished by invoking the with Angular. if(Cookies.get('imagineCookie')===
the client’s browser – a feature which can also be cookieBar() method. The plugin contains the undefined)
used to frame images, thereby strengthening your necessary logic to keep state: the user will not see {
website’s corporate identity. As with all other the bar twice if he does not delete the cookie: alert("No cookie there yet");
client-side security systems, be aware that Cookies.set('imagineCookie', "Hello
sophisticated attackers are able to work around it <body> Cookie");
with the most minimal of efort. <script type="text/javascript"> }
$(document).ready(function() {
$.cookieBar();
AUTHOR BOX:
});
Carl Woodhouse
</script> github.com/carlwoodhouse
</body> Klaus Hartl
</html> github.com/carhartl
Fagner Brack
CookieBar provides a variety of methods to aid in the github.com/FagnerMartinsBrack
customisation process: you can replace the default text

“ JQuery’s js-cookie plugin provides a


bunch of helper methods for implementing
a basic KV store
” HTML5 & CSS3 Genius Guide 109
Developer

Break and merge Find faces


images
Plugin: Face detection
<script src="jquery-2.1.4.js"></script> bit.ly/1jGT3BR
Plugin: ChunkIt <script src="jquery.chunkIt.js"></script> Category: Image analysis
bit.ly/1GK5ims <script> Finding faces in pictures is important for
Category: Image manager $( document ).ready(function() { multiple reasons: when digital cameras with
Breaking images down along rectangular $('#gridHouse').chunkIt({ imgURL : the feature were first introduced, getting
patterns has always been popular – the Pet 'flowers.jpg' , cellsInRow:5, perfectly exposed portraits became so
Shop Boys’ teaser for Love Etc in 2009 brought cellsInColum:5, shuffle:true}); much easier. This plugin allows you to look
the design pattern to public attention. This }); for faces in image files provided by your
plugin takes an image, renders it into a Canvas </script> users or a server of choice.
and then chops it down into tiny pieces which
you can arrange to create psychedelic The chunkIt() method takes a JSON object which Face detection is relatively ‘accepting’ of older jQuery
wallpaper designs. configures the actual behaviour of the tiling engine. versions – the plugin’s author specifies it with jQuery
ImgURL is a URL to the image, while cellsInRow and 1.11.1. We’ve used a recent edition for brevity reasons:
CellsInColum decide the size of the result. Setting
ChunkIt does its magic by creating a structure of li tags shufle to false arranges the <li> tags in line – you can <!DocType html>
contained in a ul tag: each one of them contains an always perform a correlation between their ID and the <html>
<img> tag which, in turn, contains its picture data as an part of the image contained within. <head>
inline image. In the case of our example, the structure generated <script src="jquery-2.1.4.js"></script>

www.fullengineeringbook.net
Since browsers decorate list tags with all kinds of looks like this: <script src="ccv.js"></script>
objects by default, we start out by declaring an <script src="cascade.js"></script>
embedded stylesheet which aims to calm these <div id="gridHouse"> <script src="jquery.facedetection.js"></
tendencies down. <ul class="grid" style="width: 1200px;"> script>
<li id="cell_25" class="cell"> </head>
<!DocType html> <img src="data:image/png;base64,"
<html> style="width: 240px; height: auto;"></img> Face Detection expects to find its source picture in a
<head> </li> <img> tag. We have used an image provided by the
<style> <li id="cell_22" class="cell"> developer here – feel free to swap out its URL to
ul.grid { <img src="data:image/png;base64,i" point to a photograph of choice:
padding: 0px; style="width: 240px; height: auto;"></img>
} </li> <img id="picture" src="picture.jpg">
ul.grid li { . . .
list-style: none; Now let’s invoke the actual processing function. As
display: block; Finally, a <div> tag must be erected. ChunkIt with most other jQuery plugins, Face Detection takes
border: 0px solid #CCC; Browser will use it as the ‘mother tag’ for the an array of elements which permit you to customise
float: left; support generated structure: plugin behaviour. Complete gets invoked once faces
line-height: 0px; ChunkIt uses HTML5 have been detected.
} Canvas internally, and thus <div id="gridHouse"></div> The method is provided with an array of face
</style> may not work on older versions objects, each of which exposes a group of properties
of browsers. Compatible ChunkIt should not be combined containing further information about the detected
In the next step, the actual browsers include Chrome, IE9, with very large images: sizes that face. Our code example restricts itself to outputting
instantiation of the plugin takes place. Firefox 12 and more. Read are any larger than about 1600 x some data to the debugger’s console:
The invocation of chunkIt() does the more at mzl. 1200 leads to long processing times.
actual work – expect the browser to stall la/1W8UMkX. This is especially harmful on single- $('#picture').faceDetection({
for a bit of time: threaded browser such as Firefox: the entire complete: function (faces) {
browser window shuts down when the tesselation for(i=0;i<faces.length;i++)
<body> process is running. {
console.log(faces[i].x + " " + faces[i].

“ The chunkIt() method takes a JSON width + " " + faces[i].y + " " +
faces[i].height);
object which configures the actual }
}
behaviour of the tiling engine
110 HTML5 & CSS3 Genius Guide
” });
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
“ At the time of writing, the recommended
CDN contained broken code
]

following version draws a significantly larger circle on top
next to behemoths such as the fearfully }, { of each data point of our line chart:
complex D3.js. Chartist difers from its fullwidth:true function makeFancyChart()
competitors in that it aims to combine the {
no-frills approach of Canvas-based renderers }); var chartRef=new Chartist.Line('.ct-chart',
with the print-ready quality provided by SVG. } {
. . .
Chartist’s diagram methods tend to take a pair of chartRef.on('draw', function (data)
Even though Chartist can – in theory – also be used parameters: the first variable contains the data to be {if(data.type==="point"){
without jQuery, most developers will settle with an displayed, while the second variable can provide data.group.append(new Chartist.
include structure similar to the following. At the time of you with a variety of display settings. Going Svg('circle', {
writing, the recommended CDN contained broken code on to change the display to create a pie SMIL cx: data.x,
– our example contains a copy of the code which works chart doesn’t require much extra efort support cy: data.y,
on Firefox: at all: Chartist.js supports all kinds of
animations: charts can be enriched r: 20

www.fullengineeringbook.net
<head> function makePieChart() with marching ants and similar }, 'ct-slice-pie'));
<link rel="stylesheet" href="chartist.min. { niceities. Sadly, this requires support }});
css"/> var data = { for SMIL – a feature sorely }
<script src="chartist.js"></script> series: [20, 30, 55] missing in all versions of Draw gets emitted every time a new
<script src="jquery-2.1.4.js"></script> }; Internet Explorer. element is created: its type subattribute
</head> var sum = function(a, b) { provides information about the type of
<body> return a + b }; element at hand.
<div class="ct-chart"></div> new Chartist.Pie('.ct-chart', data, { Some features – axis labels are a common example –
</body> 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
Our example contains a group of buttons which populate reduce(sum) * 100) + '%'; who pride themselves on the tiny 10KB total file size of
the <div> tag with various diagrams. First up is a humble } their product.
line chart generated by makeLineChart: });
} OTHER AUTHOR PLUGINS:
function makeLineChart() Gion Kunz
{ This example extends the diagram with custom labels github.com/gionkunz
new Chartist.Line('.ct-chart', { created by an interpolation function. It uses data.series. Plugin 1: Accessibility for Chartist
labels:[1,2,3,4,5], reduce to obtain the sum of the entire dataset, which is bit.ly/1GhD6MG
series: [ then applied to a simple percentage calculation. Plugin 2: Point Labels for Chartist
[12, 9, 7, 8, 5], Developers can use the events exposed by Chartist bit.ly/1NfSeKe
[2, 1, 3.5, 7, 3] to modify the look of the resulting diagram. The

To follow To follow To follow


John Resig JQuery Foundation JQuery Plugins
@jeresig @jquery @jqueryplugins_
Two words: jQuery.daddy==John. The jQuery Foundation is the body This Twitter account provides a
Follow him to enrich your Twitter which governs the jQuery product never-ending stream of interesting,
timeline with content more or less family. Follow the account for all the weird and/or useful jQuery plugins for
related to the big jQ! latest, oficial announcements. your perusal.

HTML5 & CSS3 Genius Guide 111


Developer

Tile interface
Simply changing
By default, jsTiles the background
renders its tiles colour is but part
right next to one of the solution;
another. Creating adding pictures
spacing is best makes your tiles
accomplished via look more natural.
CSS attributes.

The black borders


have the same
width across all JsTiles is based on
centre boxes: the Bootstrap: the
width diferences scaling behaviour
in the middle are of the boxes is
an optical illusion. 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 Waiting sucks. If the duration of a process is not known in advance, displaying a
application. Tapatar simplifies the avatar procurement process: it provides a small Windows Phone-inspired line of ‘marching ants’ is but a small acknowledgment of the
widget where customers can select their avatar of choice by uploading a file from user’s patience. ProgressDots lets you deploy a dotted line with but five lines of code:
their desktop, logging in on Facebook or using the Gravatar database. $( '#progressBox' ).dottify({
dotSize: '28px', //set size of dot
randomColors: true, //use random colors
numDots: 7, //number of dots
radius: '20%' //set dot corner radius
});

112 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

… 4: 'col-xs-6 col-md-3',
Plugin: jsTiles </div> 5: 'col-xs-6 col-md-3'
bit.ly/1GhDhro </div> }
Category: Tile manager }
Microsoft’s Windows Phone 7 introduced the A superficial inspection of the code on FileSilo reveals }
world to the concept of the tile: ever since, the that the tile management framework limits itself to the
design paradigm got more and more attention. arranging of the individual elements; their design, layout The most important part of the options array is the
Implementing tiles looks simple at first glance, and content lie in the responsibility of the developer. With tilesNum property: it must match the number of the
but tends to become tedious once attention is that out of the way, the template must be configured: <div> tags in the container. Rows sets up the size of the
paid to details. individual rows, while tiles configure the individual tile
var myTemplateObject = { widths. Js-tiles will need to work with Bootstrap: the class
myTemplate: { names used are taken from the template framework.
Getting started with jsTiles requires the presence of three tilesNum: 6, Next up we’ll apply the generated configuration. In our
support libraries: jQuery, jQuery Easing and Bootstrap. As rows: { example, the following bit of code shall sufice:
you can see in the full code on FileSilo, Style.css and 0: {
jstiles.js come from the jstiles distribution, while the rowClass: 'tl-row col-xs-12', var opt = {
remaining references come from support libraries. The start: '3', templateObj: myTemplateObject,
following container is to be created: end: '5' }
} $('#tiles-container').jstiles(opt);
<div id="tiles-container"> }, });
<div class="tl-page" data-tl- tiles: {
template="myTemplate"> 0: 'col-xs-6 col-md-3', With that, our example is done. Js-tiles provides a variety
<div style="background-color: #f00; 1: 'col-xs-6 col-md-3', of additional features for animation and card
border-style: solid; border-width: 2: 'col-xs-6 col-md-3', management: further information on these topics can be
5px;">Content</div> 3: 'col-xs-6 col-md-3', found in the documentation.

www.fullengineeringbook.net
Keep headers on top
z-index: 9999; </html>
Plugin: Headtacular }
bit.ly/1Lon5ld .header.is-stuck { Finally, the headtacular method must be invoked after
Category: GUI stack position: fixed; the DOM tree has been initialised. In the case of our
Keeping a header on top of scrolling content top: 0; snippet, we pass in an object showing one of the
can turn out to be a daunting task. This plugin is width: 100%; supported options – as the plugin contains sensible
a representative of the BYOS genre: the background-color: #f0f; defaults for all options, you can also call the method with
acronym stands for Bring Your Own Style, } an empty JSON object:
which means that it limits itself to the provision </style>
of display logic. </head> <script type="text/javascript">
$(document).ready(function() {
Headtacular permits you to use two styles: header is var innerHtml="Lorem Ipsum sic . . .<br>";
As always, our code example starts out by including both used when the user has not touched the scroll point, for(i=0;i<12;i++){innerHtml+=innerHtml;}
jQuery and the headtacular file. In the next step, shown while header.is-stuck’s turn comes once scrolling has $( "#myFill" ).html(innerHtml);
below, you can now see that a little stylesheet has been begun. In the next step, a small header – a b tag along $('#myHead').headtacular({ scrollPoint: 1
generated for us: with some text shall sufice – is created: });
});
<!DocType html> <body> </script>
<html> <div id="myHead" class="header"><b> My
<head> Header</b> and some text</div> The lorem ipsum code unfortunately bloats the page: an
<script src="jquery-2.1.4.js"></script> <div id="myFill"></div> empty website does not flow over the screen and thus
<script src="jquery.headtacular.js"></ </body> does not require scrolling.
script>

“ The acronym BYOS stands for Bring Your


<style>
.header {
transition: all 300ms;
background-color: #f00;
Own Style, which means that it limits itself to
the provision of display logic
position: relative;

” HTML5 & CSS3 Genius Guide 113


Developer

Timeline display {'time': 1398706771300, 'category': 'pings',


bit.ly/1NLSX96
Log file viewers benefit from a timeline view. This
timeline plugin takes a dataset, which is displayed in a
'line': "fred", 'label': "two"},
];
var options = {'categories': categories};
Footer
zoomable, double-clickable widget. The dots in the </script> Testing a footer management plugin requires the
timeline are presented horizontally and they presence of a footer – start out by creating the
can help users to visualise any graph Each event is made up of three tuples: a following example page, which self-populates with a
patterns, as part of their log analysis. Its Timeline lines Unix timestamp, a category (like colour bit of lorem ipsum and also contains a footer with
data structure looks like this: It’s important to specify your for example) and a line identifier some buttons:
var categories = { lines because if you don’t, which describes the timeline
'alarms': {'color': Timeline will automatically identify housing it. <html>
"rgba(255, 0, 0, 0.7)"}, your lines and plot them in the The Timeline plot uses the <body>
}; order in which the plugin finds options object that is passed in for <script src="jquery-2.1.4.js"></script>
var events = [ them (likely to be from configuration. The options object <script src="jquery.downboy.js"></script>
{'time': 1398706972000, bottom to top). currently supports attributes such as <script>
'category': 'alarms', 'line': categories, lines, lineLabels and $( document ).ready(function() {
12345, 'label': "one"}, sortLines. var innerHtml="Lorem Ipsum sic . .
.<br>";

“ This timeline plugin takes a data set, for(i=0;i<7;i++){innerHtml+=innerHtml;}


$( "#myFill" ).html(innerHtml);
which is displayed in a zoomable, double- });
</script>
clickable widget
Colour picker
bit.ly/1ReHcpt
” Integrating the colour picker is as easy as adding an
<div id="myFill"></div>
<div id="myFooter" style="background-
color: yellow;"><h1>This is a footer</
h1></div>

www.fullengineeringbook.net
input element to the site. A call to the jPipette() method </body></html>
The creation of colour pickers have always turned out to then makes sure that everything is set up correctly:
be a nuisance, but you can easily rectify this problem in <input type="text" name="myInput"> DownBoy is ofered in two versions. If your footer goes
our example by making an open source colour picker for $(document).ready(function(){ by the name #footer, simply embed downboy.auto.*.js
Windows Mobile. JPipette is a similar extension which lets $('input').jPipette(); in order to put the element in its place. Developers
users pick colours from an image on non-IE browsers. )} 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 TinyTip difers from other products due to its flexibility. A footer can makes web apps look much
sweefty.com/tinytip Tooltips can be styled via CSS; their appearance can more professional. Sadly, keeping content at
Forcing users to consult a manual is a sure-fire way to furthermore be triggered by mouse-over, click and even the bottom of a page can be a bit of a
drive them straight to the arms of your biggest certain custom gestures. One classic example involves daunting task for people who are not 100 per
competitors. This plugin strives to increase discoverability complex tooltip windows which get spruced up visually cent confident at working with CSS. This
by displaying tooltip windows with further information at via CSS-generated arrow shapes and/or custom plugin wants to help you out here.
strategic locations. background colours.

114 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

www.fullengineeringbook.net

Rain effect Scrolling indicator Superfast parallax


bit.ly/1NLRfVa bit.ly/1MHijDH bit.ly/1MtzLXU
This plugin uses wave theory to render a line, This plugin treats your users to a progress Research conducted by the Purdue University (docs.
which is then animated to simulate Substitute indicator informing them about how far lib.purdue.edu/cgttheses/27/) has produced results
raindrop impact seen from the side. with icons they have already scrolled down the that show that the presence parallax scrolling
Daniela Harel and Gred McAusland’s For the scrolling indicator, it’s page – coders working with Sublime significantly increases user satisfaction. Bring a few
plugin is dificult to describe – take a possible that you may Text will find the feature familiar right svelte panoramic shots and this little plugin by
look at the examples by going to the encounter roadblocks with the away. The viewport difers from Kaspars Jaudzems of Latvia can add the impressive
URL above. overview image. Should this classic IDEs in that you need to scrolling efect to your web projects with minimal
ever become a problem, feel provide the overview image. efort.
Virtual terminal free to substitute the
bit.ly/1GK5Qso image with icons.
This plugin simulates a Ubuntu-styled Circle calculations Creating and/or updating the widget is as easy as
terminal window by displaying a set of span bit.ly/1MtzZye calling the circularloader function like this:
elements according to a timing schedule. It is best suited Waiting for Godot is normal nowadays: why not ease the
to providing a visual guide for unsophisticated users wait by presenting your users with a snazzy little circular $("#divProgress").circularloader({
working on a command-line system – be aware that the progress bar? This plugin saves you from having to deal progressPercent: 35
plugin cannot handle user interaction. with the sine, cosine and tangent as found in circles. })

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 and JavaScript code. This allows these resources to be "description":"A peacock standing outside.",
guarantee to be known by any web developer reused by other pages if required. See FileSilo for more "url":"img/image4.jpg"
is jQuery. This is a favourite of many web information on where the jQuery library will be placed. },
developers for the simple reason that it helps to make {
writing code faster and easier – especially when first 3. Gallery container "title":"The Guy",
learning to write code in JavaScript. Use the <body> section to place the gallery content. The "description":"The guy.",
Much has changed in web development since jQuery’s gallery template will consist of an article element used as "url":"img/image5.jpg"
first introduction – particularly in webpage animation, a container for the diferent parts of the gallery – the }
which was controlled almost entirely through JavaScript navigation, details and picture display. These elements ];
at the time of jQuery’s introduction. In the era of CSS3 will be modified later by the jQuery JavaScript code.
with hardware-supported capabilities, it is easy to misuse 5. Wait until loaded
jQuery with outdated techniques for visual presentation; 4. JQuery: data It’s important to tell jQuery to wait until the page has
certainly when it comes to working with designers, The first step in using the jQuery component is to create loaded before we go on to trying to run any of the
keeping your presentation inside CSS avoids scenarios the file that the jQuery JavaScript code will be placed in instructions – otherwise it will return errors to say it can’t
where designers become restricted to when adapting – create this as ‘controls.js’. In this file, you should place find page elements. We do this by attaching a .ready
your website design. This tutorial looks at how jQuery can the following data structure that describes where each listener to the page document – which will hold a
be used to manage user interactions and eficient loading gallery image can be found, as well as the title and function that contains our code.
of image resources while keeping the presentation description to display: $(document).ready(function(){
functionality within the control of CSS. This approach to var pictures = [ //.. place code from next step here
using jQuery means that designers who don’t have { });
JavaScript skills can still contribute to adapting the design "title":"A Cottage",
of your website creations. Additionally, keeping your "description":"A little cottage.", 6. Read picture data
functionality separate from your design styling and "url":"img/image1.jpg" The first thing we want to do inside the function created
content formatting reduces the risk of introducing faults }, in the previous step is to initiate the reading of the
that break your website when you are making updates. { pictures’ data. We do this by selecting the pictures array
"title":"A Horse", with the jQuery $ selector and using jQuery’s .each
1. Initiate HTML page
www.fullengineeringbook.net
"description":"A horse eating hay.", functionality to loop through each of the data items.
As with any webpage, there is a requirement to define the "url":"img/image2.jpg"
page’s 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. "title":"Lake",
"description":"Water flowing down lake.",
Easy to misuse
Although jQuery exists to make programming
2. Load resources "url":"img/image3.jpg" easier, it’s easy to misuse it by not using it to its
The <head> section of your HTML should contain the }, full potential – especially when the library costs
links to any resources you are using for the page; in our { over 200k to download.
example, we’ll be using this to load the CSS stylesheet "title":"Peacock",

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 don’t appear by
default, but are ready interactions from jQuery and styling
from CSS

HTML5 & CSS3 Genius Guide 117


Developer

var count = 0; $(img).appendTo("figure"); created in Step 7, jQuery can be used to find the image
$(pictures).each(function(){ //.. code from next step goes here with the same index number as the thumbnail being
//.. place code for next step in here clicked on – and this is because it has the same details by
}); 9. Create thumbnails being a clone. Perform removeClass to take out “hidden”.
A thumbnail is required to show a selectable preview for $('figure img[data-index="'+this.
7. Page container navigating the gallery images. There is no need to reload getAttribute("data-index")+'"]').
Use the <body> section to contain the visible content. We images – jQuery can make a clone of each image and removeClass("hidden");
start this by placing the <main> page container inside the then append to the inside of the <nav> container. //.. code from next step goes here
body; this will be used to allow the controlled layout of var thumb = $(img).clone().appendTo("nav");
the content. Your page title, description and index count //.. code from next step goes here 13. Size up the height
will go inside this. The thumbnail will also have copies of the title and alt
var img = $(document.createElement("img")); 10. Thumbnail click reactions attributes from the image it has been cloned from. This
$(img).attr({ The thumbnail images we’ve cloned and appended to lets us easily place the image details inside the <h3> and
"src":this.url, the <nav> container need to react to any clicks received. <figcaption> elements. We set the content HTML by
"data-index":count, We do this by attaching a bind event listener for “click” using jQuery’s $() with its .html() functionality, which will
"title":this.title, – which activates a function we declare as a reaction. place text or HTML inside the selected element.
"alt":this.description $(thumb).bind("click",function(){ $('h3').html(this.getAttribute("title"));
}); //.. code from next step here $('figcaption').html(this.
//.. code from next step goes here }); getAttribute("alt"));
count++;
8. Image to container 14. Initialise CSS
After each image has been created as an element on the 11. Hide images At this point, the jQuery functionality is now complete,
webpage, it will then need to be placed inside the The first reaction we perform when a thumbnail click has but will not function because it lacks the CSS styling.
location where we will store every single image. Our been detected is to hide the images inside the <figure> Create a CSS file called ‘styles.css’ and place the following
example will use the page’s first <figure> element. The element being used as the gallery image container. We initiation styling for the <html> and <body> elements.
‘figure’ part of this code is a CSS rule that defines how to use the jQuery $ element finder with the CSS rule to find html,body{

www.fullengineeringbook.net
find the location. these – ‘figure img’. We loop through each element found background: #000;
and apply a function that will add a class called hidden. padding: 0;
$("figure img").each(function(){ margin: 0;

Fast and easy $(this).addClass("hidden");


});
font-family: monospace;
height: 100%;
JQuery helps to make writing code faster and
//.. code from next step goes here }
easier by providing shorthand for common tasks
in JavaScript such as referencing webpage
elements and iterating through information – like 12. Show selected image 15. Gallery container
with webpage elements that have been found. All images are set to hidden, so next we show the The HTML we’ve created uses an <article> tag to contain
selected image. By using the data-index attribute we the gallery content. We must use this to define the width,

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


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
world’s 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{
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
with the previous step’s transition rule, we will make
images fade out when their status changes.
figure img.hidden{
display: block; and have its images automatically change accordingly opacity: 0;
width: 75%; figure{ }
margin: 10% auto 0 auto; display: table-cell;
background: silver; position: relative; 20. Thumbnail container
padding: 1em; width: 75%; The thumbnail container is to be positioned at the side of
} margin-left: 25%; the main image spanning the full height of the gallery.
z-index: 1; We will also want to make sure that the thumbnail panel
16. Information container overflow: auto; will enable scrolling to show any images that don’t fit
The gallery uses a <div> element to contain the elements } onto the page.
used to display information of the current picture. We will nav{
style this to show a dark transparent background with 18. Image positioning display: inline-block;
white text to ensure that the content stands out from the The images inside the <figure> container are to be set to width: 100%;
gallery picture being shown. be displayed from the same position – we can set them height: 100%;
article div{ from the top left of the <figure> container because of the overflow: auto;
display: table-caption; relative positioning set in the previous step. A transition background: #777;
position: absolute; efect is also added for changing between pictures. padding: 0;
top: 0; figure img{ }
right: 0; position: absolute;
z-index: 2; top: 0; 21. Thumbnail sizing
width: 75%; left: 0; Thumbnail images are to be stacked above each other
text-align: right; transition: opacity 1s; – with their height not being a problem due to the <nav>
margin-left: 27%; width: 100%; container having overflow: auto to allow for scrolling if
background: rgba(0, 0, 0, 0.75); z-index: 1; required. These images were originally full-sized copies of
color: #fff; } the originals, but can be resized to be the same width as
} the container.
19. Hidden image property nav img{
17. Image container The jQuery code is set to add a “hidden” class to images display: inline-block;
The gallery image container will be placed at the side of that are to be hidden from view, hence there needs to be width: 100%;
the thumbnails and will use relative positioning so that a presentation rule set for this. By setting the opacity to 0 }

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 friction in forms and aiding understanding. We also messages but this can be complicated when there are
and the user’s life. Often forms capture want to try and make them as accessible as possible so many conditions. NgMessages was introduced in
sensitive data like your address, telephone we will include ngAria, too. Angular 1.3 so it doesn’t work with Internet Explorer 8
number, card details and so on. Angular’s ngMessages module provides developers or below.
Filling in forms is annoying, so as web developers with an easy way to present messages to a user. It’s In this tutorial you’ll learn how to create a form and
we want to try and make this process as pain-free as described by Angular as being “designed to handle the use Angular to validate it. Our example will be a
possible. One way we can do this is to show helpful, complexity, inheritance and priority sequencing based registration form for the fictitious ‘Lace & Order’ shop.
timely messages to the user to let them know if they’ve on the order of how the messages are defined in the It’ll feature custom validation directives, default
made a mistake. These are essential to reducing template”. You could use ngIf to toggle the visibility of messages and utilise ngModel to its full ability.

120 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

1. Install Angular and modules dependencies specific to the registration form.


First of we’re going to add ngMessages to our project
and our preferred method of adding this in is to use
angular.module('formApp', ['register.
module', 'ngAria', 'ngMessages',
Directive names
In real-world applications you should always
Bower (go ahead and visit bower.io/#install-bower if you 'ngAnimate']); prefix your directive names with a couple of
haven’t got it installed already). As well as the Messages letters. This diferentiates them from standard
module we’re also going to make use of the Animate and 4. The register module HTML elements.
ARIA modules. When we write custom directives you’ll also have to add
$ bower install angular-animate angular-aria them as a dependency to this module. It’s easy to forget
angular-messages to do this and find yourself spending minutes figuring form tag. Ng-attr-novalidate is an Angular directive which
out why your directive isn’t working! will only apply the novalidate attribute if the expression
2. Include script files angular.module('register.module', evaluates to true. We want to disable the native HTML5
Create a file called ‘index.html’ and then write the markup [‘register.controller']); validation if the Angular app has successfully loaded.
required for a skeleton HTML page (with the <head>, <form data-ng-attr-novalidate=“{{true}}"
<body> and so on). Next we’ll import the JavaScript files 5. Register controller data-ng-cloak>
that Bower had fetched for us just before the closing The controller for our registration form is very bare </form>
body tag. Even though we’re using the minified versions bones. So what we’ll do is we’ll add some specific uses to
here, the browser will map to the full source files. it later (namely to add dynamic text). Behind the scenes it 8. First name input
<script src="bower_components/angular/ will do the internal wiring to ensure our form works as we The first piece of data that we’ll capture from the user is
angular.min.js"></script> expect it to. their first name. NgModel is used to bind data to the
(function() { input field. This means that when the data changes, the
<script src="bower_components/angular- 'use strict'; model is immediately updated. The rest of the markup is
animate/angular-animate.min.js"></script> angular.module('register.controller', []) your regular HTML5.
.controller('registerController', ['$scope', <div class="row">
<script src="bower_components/angular-aria/ function ($scope) {}]); <label for="firstName">First name:</label>
angular-aria.min.js"></script> })(); <input id="firstName" name="firstName"
data-ng-model=“fields.firstName” required
6. Create the form tag
www.fullengineeringbook.net
<script src="bower_components/angular- />
messages/angular-messages.min.js"></script> The form tag is going to do a lot of work for us. It’s going
to be the root of our application and also the controller. </div>
<script src="scripts/app/app.js"></script> NgSubmit is evaluated each time the form is submitted
(either by the user clicking the submit button or by 9. ngMessages first name
<script src="scripts/app/modules/ pressing the Enter key). Here’s our first example of ngMessages in action.
registerModule.js"></script> <form name="register" Ng-messages takes an Angular expression which
data-ng-app="formApp" evaluates to a key/value object. This behaviour is just like
<script src="scripts/app/controllers/ data-ng-controller="registerController" a switch statement. In the example that we have here,
registerController.js"></script> data-ng-submit="submitForm(register)"> the object evaluated is the $error property from
ngModel in the firstName field.
3. The formApp module <h1>Register</h1> <div class="errors" data-ng-
The module that will contain all the application-wide </form> messages="register.firstName.$error">
dependencies is called formApp. As well as the Angular
modules that we included in the previous step 7. The ng-attr directive <!-- next step -->
register.module is also included. This will include the A couple of other attributes need to be added to the </div>

Left
This is the page that will contain our form, there’s not
much to it yet but the Angular’s ready to go

Top left
The initial bit of information we’ll want is their name so we
can address future communication
Top right
With just a bit of markup and Angular’s inner wirings
we’ve got a dynamic message box reacting to the input

HTML5 & CSS3 Genius Guide 121


Developer

10. ngMessages directive .error You can chain properties together on the same error
NgMessages does a great job of toggling specific { message to prevent repeating yourself.
messages but we also need to determine when to show color: #a94442; <div class="errors" data-ng-
them. Otherwise they’ll appear before the user has padding: 0.875em; messages="register.tel.$error" data-ng-
touched the form! The messages should only appear if background-color: #f2dede; if="register.tel.$dirty ||
the field is dirty (if it has been filled in) or the user width: 16em; register.$submitted" role="alert">
submits the form. border: 0.125em solid #ebccd1;
<div class="errors" data-ng- transition: 0.5s linear opacity; <p class="error" data-ng-
messages="register.firstName.$error" opacity: 0; message="required">Please enter your
data-ng-if="register.firstName.$dirty || margin: 0; telephone number.
register.$submitted”> } </p>
<p class="error" data-ng-message="tel,
<!-- next step --> 13. Submit the form pattern">Please enter a valid telephone
</div> To allow the user to submit the form we’re going to need number.
a submit button! This calls the submit handler that was </p>
11. The required property hooked up at the top of the form. However the user </div>
Within the ngMessages directive, we can now go ahead submits the form – be it by click, programmatically or
and list specific error conditions to show. This example pressing Enter – it calls the same function. 16. Postcode input markup
here has a simple paragraph tag, but you can use any <div class="row"> You wouldn’t think it but postcodes are actually quite
element as well as place any markup that you want <input type="submit" value="Register" /> hard to get right because there are so many variations.
inside of it. ‘Ng-message=“required”’ looks for the </div> Nonetheless, we’re going to create a custom directive to
‘required’ property on the object that we passed above. If try and validate one.
true, then it’ll show: 14. Telephone input <div class="row">
<p class="error" data-ng- Let’s take the concepts we’ve looked at and apply them <label for="postcode">Postcode:</label>
message="required">Please enter your first to a new field, a contact number. This time ngPattern <input id="postcode" name="postcode"
name.</p> allows us to match what the user types to a regular data-ng-model="fields.postcode" postcode

www.fullengineeringbook.net
expression. This regular expression checks that only required />
12. Style error messages numbers are typed. </div>
Our error messages deserve a bit of love so let’s apply <div class="row">
some CSS to them. The most important parts to note are 17. Postcode directive
the opacity and transition properties. NgAnimate will use <label for="tel">Contact number:</label> Create a new file under directives called ‘postcode.js’. By
them in conjunction with other classes to ease them in <input id="tel" name="tel" data-ng- requiring ngModel it’s passed as the fourth argument to
rather than abruptly appearing. model="fields.tel" type="tel" data-ng- the link function so that we can extend it. Remember to
pattern="/^[0-9]+$/" required /> add it as a dependency of the registration module.
<!-- next step --> angular.module('postcode.directive', [])

Debugging $errors </div> .directive('postcode', function() {


return {
A useful way to get a quick understanding of an
object in real-time is to output it onto the page: 15. Telephone error messages require: 'ngModel',
<pre>{{form.postcode.$error | json}}</pre>. This This time we’re going to use the same technique as scope: {
will show the object and format it as JSON. before to show a message. As well as ‘required’ there will postcode: '='
also be a ‘pattern’ property as ngPattern has been used. },

Top left
The telephone error message is shown when the input
doesn’t 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 they’re overridden by one further up in the markup

122 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Utilise ngMessage
expressions
NgMessages also supports dynamic
messages, that is, if you don’t know the
name of the message that might be fired
you can check it with a message
expression. In this example we’ve 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-message-
exp=”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); </div>


}; }
} }; 20. Custom message template
); Ng-messages-include looks for an element’s ID on the
19. Include message template page. Angular recommends including templates as a
18. Regular expression test The custom validator is then added as another property script tag with a custom type so that it doesn’t end up

www.fullengineeringbook.net
Within the link function we’ll write the postcode validator. to the $error object if it returns false. This means that it being parsed by the browser. The downside of this
logic, which validates most UK postcodes. To register a can be used within ng-message. We’re also going to use approach is the generic wording although this could be
new validator, add to $validators. Now close spaces and a template to fill in common error messages. This is paired with dynamic text.
see if the string passes REG_EXP. included with ng-messages-include. <script type="text/ng-template" id="default-
var REG_EXP = new RegExp(/^([g][i][r][0][a] <div class="errors" data-ng- error-messages">
[a])$|^((([a-pr-uwyz]{1} messages="register.postcode.$error" <p class="error" data-ng-
([0]|[1-9]\d?))|([a-pr-uwyz]{1}[a-hk-y]{1} data-ng-if="register.postcode.$dirty || message="required">This field is required.
([0]|[1-9]\d?))|([a-pr-uwyz]{1}[1-9] register.$submitted" role="alert"> </p>
[a-hjkps-uw]{1})|([a-pr-uwyz]{1}[a-hk-y]{1} <p class="error" data-ng- <p class="error" data-ng-
[1-9][a-z]{1}))(\d[abd-hjlnp-uw-z] message="postcode">Please enter a valid message="minlength">This field is too short.
{2})?)$/i); postcode. </p>
ctrl.$validators.postcode = function (value) </p> <p class="error" data-ng-
{ <div data-ng-messages-include="default- message="maxlength">This field is too long.
if (typeof value === 'string') { error-messages"> </p>
value = value.replace(' ', ''); </div> </script>

What’s new in Angular 1.4? Breathe life into ngMessages


You can add a sense of momentum to your messages with
Angular 1.3 introduced ngMessages as an
ngAnimate. We’ve already installed and included this
experimental module. This meant that module. When ng-messages is shown, a class of ng-enter
developers were free to use it but breaking and ng-active is added – the former when it’s being inserted
changes could be made to the API. The and the latter when it’s active. Our message boxes all have
a class of ‘error’ so we’ll target this and change the opacity.
main change in 1.4 is that
The CSS transition property will then smoothly animate the
ngMessagesInclude was removed as an box in and then out when it’s removed. You can use any
attribute on ngMessages. Instead it’s used sort of animation to be more creative here.
on a ngMessage directive, like we’ve used .error {
transition:
in this tutorial. Angular 1.4 also introduced
0.25s linear;
ng-message-exp and when-exp to evaluate opacity: 0;
expressions dynamically. Upgrading from 1.3 }
to 1.4 should be straightforward for most .ng-enter .error,
projects and you can find detailed .ng-active .error {
opacity: 1;
migration information at docs.angularjs. }
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 Web Audio API comes in. The Web Audio API is a everything we learn here can be taken and applied to
got our eager mitts on the <audio> tag. For the low-level API (which basically means it’s super fast any other kind of app that needs responsive audio
first time since the web’s inception, we could because a lot of the stuf is being done by the browser manipulation and playback.
insert rich multimedia content into our webpages rather than by our own JavaScript) that allows us to
without using any third-party plugins (no need for control and manipulate sounds at the millisecond level. 1. Grab the resources
Flash anymore). And all was good with the web With it, we can load sounds, create sounds and warp Before we dive into all of our Web Audio goodness,
development world. For its typical use <audio> is sounds to make alien-like noises with absolute ease, there are some things that we’re going to need. Grab
absolutely fantastic; with built-in GUI and JavaScript but it’s not as simple as including an <audio> tag in our the project resources from FileSilo and move them into
events we can do almost anything with the content HTML – we’ve got to deal with things such as Audio your project folder. In the sounds folder are the MP3
we’re playing. Thing is, <audio> was never designed to bufers and nodes (not Node.js) if we want to get the files that we’ll be using to make sounds for our drums,
be fast or to play lots of really brief content, which is best out of it. That’s what we’re going to make in this in the scripts/libraries folder is bl.js (a script written by
not a massive issue unless you want to create sounds tutorial, a Web Audio drum kit. Drums are great, Boris Smus) which we’ll use to load sound files and in
in games or in a data visualisation. That’s where the because we need to be able to play sounds quickly. but the assets/images folder is the image of our drums.

124 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

2. Markup for our drums position: fixed; console.log("Initialised");


In our ‘public’ folder is a bare-bones HTML file. We’re left: 50%; }
going to create some divs to bind some event listeners to top: 50%; return {
so that when we hit them, sounds play. Open it in your margin-left: -350px; init : init
favourite editor and add the following between the margin-top: -145px; };
<body></body> tags: background-color: rgba(255,0,0,.2); })();
<div id="drumHolder"> } (function(){
<div class="drum" data-sound="china"></div> __web_audio_drums.init();
<div class="drum" data-sound="crash"></div> 5. Position each drum element })();
<div class="drum" data-sound="floor tom"></ Now that we have our #drumHolder in the right place,
div> we can now do the custom styling for each individual 7. The Web Audio context
<div class="drum" data-sound="super kick"></ drum. Staying in styles.css now as well, add the following Before we start doing anything with Web Audio, we need
div> rules to your file: a context we can interact with. Think of it as an audio
<div class="drum" data-sound="super #drumHolder .drum{ background-color: analogue to a <canvas> context, it’s simply an interface
snare"></div> rgba(0,0,0,.5); position: absolute; } with which we deal in order to make our code do
</div> #drumHolder .drum:nth-child(1){ top: 14px; interesting things. Just after ‘use strict’; add:
<script src="scripts/libraries/bl.js"></ left: 235px; width: 87px; height: 69px; } // Web Audio Polyfill
script> #drumHolder .drum:nth-child(2){ left: 350px; window.audioContext = (window.AudioContext
<script src="scripts/core.js"></script> top: 7px; width: 108px; height: 86px; } || window.webkitAudioContext || window.
#drumHolder .drum:nth-child(3){ left: 274px; mozAudioContext || window.oAudioContext);
3. Style the <div> top: 145px; width: 158px; height: 114px; } …and inside our init function add:
Run the Node app included in the project resources. If #drumHolder .drum:nth-child(4){ right: 62px; context = new window.audioContext();
you head to http://localhost:8118/ you’ll see our HTML bottom: 84px; width: 144px; height: 104px; …Now we will also have an audio context that will work
page. It’s nothing special at the moment, just a } across all browsers.
background image of our drums and a bunch of invisible #drumHolder .drum:nth-child(5){ top: 103px;
<div> tags. We want to position those divs over each of left: 74px; width: 144px; height: 104px; } 8. Set our samples

www.fullengineeringbook.net
our drums so that when we hit each drum, they each In the /sounds folder of our project, there are a bunch of
make a diferent sound. 6. Core.js MP3 files. We’re going to add them to our code so we
Now that we have our elements in the right place, we can load them in just a little bit. Add the following just
4. Move the parent element can start writing some code to control them. When we after our Web Audio polyfill.
We have a div #drumHolder. We’re going to position this added in our <div> we also added two <script> elements, var samples = [{
over the middle of our page to position all of the divs one for our code, the other being our BuferLoader
inside it relative to their parent (#drumHolder). This method. Create a file called ‘core.js’ in our scripts folder
makes our life a little easier when it comes to doing and add the following to it:
things responsively. Just open up styles.css now and add var __web_audio_drums = (function(){
Buttons needed
Before anything will work through Web Audio, a
the following: 'use strict'; sound has to be triggered inside of an event
#drumHolder{ var context = undefined, handler triggered by a user, meaning you
width: 700px; bufferLoader = undefined; absolutely have to make a button.
height: 290px; function init(){

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 we’ll 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 : "china", 10. The BufferLoader sounds = list;


path : "/sounds/China.mp3" In order to load our samples into our project and make var theDrums = document.
}, them useful, we need to create audio bufers to store the getElementsByClassName('drum');
{ sound data from our MP3 files. Think of an audio bufer for(var y = 0; y < theDrums.length; y += 1)
name : "crash", as a bucket that you can put something into, but once {
path : "/sounds/Crash.mp3" you take it out again, you can’t get it back in. Normally, theDrums[y].addEventListener(touchOrClickEve
}, we would have to create all of the XHR and audio bufer nt(), function(){
{ code ourselves, but the BuferLoader method takes care for(var a = 0; a < samples.length; a += 1){
name : "floor tom", of that for us. if(samples[a].name === this.
path : "/sounds/Floor_Tom.mp3" getAttribute('data-sound')){
}, 11. Load our samples playSound(a);
{ In loadSamples, add the following: }
name : "super kick", bufferLoader = new BufferLoader(context, s, }
path : "/sounds/Super_Kick.mp3" function(list){ }, false);
}, sounds = list; }
{ console.log(sounds); console.log(sounds);
name : "super snare", }); ...
path : "/sounds/Super_Snare.mp3" bufferLoader.load();
}, ... and add the following to init(); 13. Detect events
], loadSamples(samples); On a lot of mobile devices (like iOS for example) ‘click’
sounds = []; BuferLoader takes an audio context, an array of paths to events have a 300ms delay before they are dispatched
…samples contain references that we’ll use to load our audio files and a callback as arguments. When we call to our event listeners. For sounds and media this is a
files and assign them to the right elements, sounds will buferLoader.load(); our BuferLoader instance will work disaster – timing is key! Fortunately, ‘touch’ events don’t
contain the audio bufers that will actually have the through the array we passed to it and load all of the have the same delay, so we’ll write a function that
sound data in them, but we’ll get to that later. sound files it can find. When all of the audio data has decides whether or not our device should use touch or
been loaded, the audio bufers that have been created click events;
9. Load our drum samples
www.fullengineeringbook.net
are passed into the callback that we passed. Here we set function touchOrClickEvent(){
Now that we know where we can find our drum samples the array of audio bufers as a global object, so we can if('ontouchend' in document){
it’s time to load them. Create a new function called access them elsewhere in the project. return "touchend";
‘loadSamples()’ and add the following code to it: } else {
function loadSamples(passedSamples){ 12. Event listeners return "click";
var s = []; Now that we have a bunch of audio bufers that contain }
for(var x = 0; x < passedSamples.length; x our sound data, we’re going to need a way to trigger }
+= 1){ them. Inside of our buferLoader callback, we’re going to
s.push(passedSamples[x].path); create a for loop that gets all of the drum elements on 14. Play our sounds
} our page, takes the data-sound attribute and looks for a Now that we’ve got the appropriate listeners, we need a
} sound with the same name. When our div is clicked or way to play our sound. Web Audio is not like <audio>, we
This will simply create an array of file paths that we can tapped, it will play that sound! can’t just call .play() on an audioBufer to make it do its
work through to load our samples into our project ... thing, we need to connect our audio bufer to our audio

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 aren’t all that interesting, it’s the nifty methods that
come with it that’s really interesting
Right
There’s 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


HTML5 & CSS3
Genius Guide

context in order to play it out through our speakers. <audio> vs. audio
So why do we need Web Audio if <audio> exists? Well,
Think of it as a digital version of plugging your <audio> is great at playing sound… in a limited context,
headphones into a computer, we need to connect to it’s not designed for audio manipulation – not in a
hear. Create a playSound() function and you then add low-level kind of way. The Web Audio API gives us direct
the following… access to the data of the audio content, and with this we
can run a ton of complex operations to evaluate and
function playSound(idx){ manipulate that data in next to no time at all. Compared
var src = context.createBufferSource(), to a fast fourier transform, or applying a band filter,
newBuffer = cloneAudioBuffer(sounds[idx]); playing audio content through Web Audio is a
src.buffer = newBuffer; comparative doddle – that’s why it can respond on a
microsecond time scale whereas <audio> can take
var gainNode = context.createGain(); seconds to begin playback, depending on the availability
gainNode.gain.value = 1; of the content. Deciding when it is appropriate to use
src.connect(gainNode); either interface is completely down to you!
gainNode.connect(context.destination);
src.start(0);
} audioBuffer.numberOfChannels, output will go through our gain node, to our context
audioBuffer.length, destination. If we can tell our bufer source at what point
15. Clone our buffers audioBuffer.sampleRate we want to play from, then can’t we just reset it to 0 and
Earlier, we noted that audio bufers can only be played ); play again rather than all of this cloning business? Well,
once, which is kind of useless unless we want to be able Finally, we have a brand-new bufer, but our bufer is nope. An audio bufer becomes mostly useless after it’s
to only hit each drum once. In order to play our drum empty so we fix that by working through our newly been played, and besides even if we could do that, the
sounds multiple times, we’re going to create copies of created bufer’s channels and setting them with the efect would be undesirable – by resetting the sound
our audio bufers that we play and then forget about. So channels we created just a moment ago. Then we return mid-play, we’d get a horribly jarring stutter efect. It’s
let’s create a new function with cloneAudioBufer();. our cloned audio bufer: much better to let the sound continue on its own and
function cloneAudioBuffer(audioBuffer){ for (var i = 0; i < numChannels; i++){ create a new instance of it.
var channels = [], newBuffer.getChannelData(i).
numChannels = audioBuffer.numberOfChannels; set(channels[i]); 20. Use on iOS

www.fullengineeringbook.net
for (var i = 0; i < numChannels; i++){ } If you want to use you iPad or iPhone to play sounds,
channels[i] = new Float32Array(audioBuffer. return newBuffer; you can, but if you get a little carried away and flick the
getChannelData(i)); screen instead of tapping it, it might start scrolling and
} 17. Play the sound refuse to do anything until it stops. In your init() function
var newBuffer = context.createBuffer( Now that we’ve got our brand-new cloned audio context, add the following code to stop this:
audioBuffer.numberOfChannels, it’s time to put it to work! In playSound, just before we // Stop iOS bouncing scroll
audioBuffer.length, cloned our audio bufer we created a bufer source in our window.addEventListener('touchstart',
audioBuffer.sampleRate context with context.createBuferSource(); This is our function(e){
); entry point to playing sounds through our speakers. To e.preventDefault();
for (var i = 0; i < numChannels; i++){ use our cloned audio bufer we set it as the source for }, true);
newBuffer.getChannelData(i). our bufer source.
set(channels[i]); src.buffer = newBuffer;
}
return 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
16. Clone walkthrough the pitch, filter frequencies and much more. We’re going
Every sound file has a number of channels: if the sound to use one of the simplest nodes to give our sound
is mono then there is one channel, and if the sound is volume, a gain node. We create a gain node like so:
stereo then there are two and so on. We want to clone all var gainNode = context.createGain();
of the audio data from our samples, so we need to create gainNode.gain.value = 1;
a bufer for each channel and clone that data. src.connect(gainNode); Garbage collection
var channels = [], Then we connect our src (our bufer source) to that gain In web development, we’ve got a fairly consistent
numChannels = audioBuffer.numberOfChannels; node. Now, any data that is in our bufer source will be expectation of what our content will do when it’s
loaded by somebody. While we don’t have a great deal
for (var i = 0; i < numChannels; i++){ passed through and these will be afected by our gain
of assets in this project, we have created many copies
channels[i] = new Float32Array(audioBuffer. node. If we wanted to double the volume of our sample, of them quickly. So do you take on the big or the little?
getChannelData(i)); we could set gainNode.gain.value to 2, if we wanted to Well, we don’t have to worry about that hypothetical,
} half it we could set the value to 0.5. because we have garbage collection. Garbage
collection is the process in which an application (our
Now that we have arrays with our data in it (a
browser in this case) realises an object or entity is
Float32Array is not like arrays as we usually know them, 19. Test the sound never going to be used again by the program and so
it’s more like a space in the computer’s memory) we can To play our sound, all that’s left to do is connect our gain it’s dereferenced and the memory it occupied is freed
create a brand-new bufer with all of the properties we node to our context’s destination (which could feasibly for use by other objects. Think of it like a bucket that
scoops up all of those big items when they turn their
need to describe our sounds, which we do with: be anything, but in this case it’s our speakers) and call
backs and deals with the problem of size for you.
var newBuffer = context.createBuffer( src.start(0). This will start our playback at 0 and the

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 git add --all


hosting by adding a link to content hosted at an git commit -m "Initial commit"
external website. Few coders know that each git push -u origin master
and every GitHub repository comes with a dedicated
area for files which are served via a normal web server. 6. Check if working
In fact, GitHub supports three diferent repository After this upload, our website is ready for testing. Open
types. A Project site acts as a deployment vector for the the URL <username>.github.io in a browser of your
above-mentioned cide examples. User and/or 3. Initialise the local copy choice. Be aware that all GitHub user names are lower
organisation sites difer from project sites in that they are The following steps are based on an Ubuntu workstation. case by force: even if you log in as TAMHAN, the correct
instead intended to represent a firm or an individual’s Open a Terminal window, and create a new and empty URL will still be tamhan.github.io.
web presence. folder. In the next step, enter the following commands to
From a technical point of view, taking GitHub’s ofering connect the folder to the GitHub server. During the 7. Create a 404 message
is interesting as long as websites remain static. GitHub process, a group of metadata files are spawned. All GitHub repositories can be equipped with a “default
does not provide databases or other “active” content – if echo "# TAMHAN.github.io" >> README.md 404 page” which is displayed to users who attempt to
you plan to host a forum or a WordPress-managed blog, git init access invalid or non-existing parts of the GitHub
this is not the host of choice. git add README.md repository. In the case of our example, the file 404.html
Please be aware that GitHub Pages is not a git commit -m "first commit" contains a friendly error message.
replacement for a classic web host. It is a hosting option git remote add origin https://github.com/ <html>
for placing GitHub-related content, which enables its TAMHAN/TAMHAN.github.io.git <body>
users to test code. git push -u origin master <h1>An error has occurred</h1>
</body>
1. Sign up! 4. Position your web content </html>
Using GitHub Pages requires a GitHub account. If you Your Terminal window’s working directory now contains
have not signed up yet, hit GitHub.com and click the big an empty file called README.md. Put a second file called 8. Deploy, the second
green Sign Up button at the top right. For GitHub Pages, index.html in the same folder: the location of README. As GitHub Pages are hosted in a Git repository,
purchasing a premium account is not necessary as there md shall be the “root” of the web host, while subfolders committing changes should be accompanied with a

www.fullengineeringbook.net
are no privacy options provided either way (see steps 20 below readme.md will go to a subfolder of the newly descriptive message such as the one shown in the code
and 21 for more information). created website.

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
From the point of view of the git client, a GitHub
Pages-hosted website is little more than an exposed Git
Attention: Unix!
GitHub Pages is hosted on a Unix operating
along the rest of the string shown in the window. If you repository. Due to that, the newly created page and any system. This means that paths and file names are
have not created a repository before, then set one up contained images must be pushed to the server before case sensitive – a nasty trap for people switching
according to the parameters in the image that follows. they can become visible to the World Wide Web. from Windows Server.

Left
Using GitHub Pages requires you to sign up at GitHub’s 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 “Launch automatic page generator” button in order to switch between the two groups with the arrow symbols
for username and password from time to time as a start the modification process. pointing to the left and right.
security precaution.
git add --all 12. Do the Markdown! 15. Go live
git commit -m "Add 404 page" In the next step, GitHub will open an editor where the Finally, click the Publish button in order to go live with the
git push -u origin master contents of the project’s homepage can be edited. The changes. GitHub will confirm the successful generation
product uses a Markdown-like syntax which is via a small banner at the top of the screen. You can go
9. It’s really just GIT well-known from a variety of CMSs and a few Mac ahead and open tamhan.github.io/
As we have stated earlier on, a GitHub Page is really little OS-based editors. ImagineProjPageTest in order to take a look at the
more than a publicly exposed Git repository. In the case results of our labour.
of our website, you can just open up github.com/ 13. Add Google Analytics
TAMHAN/TAMHAN.github.io in order to see the Tracking the successes of a GitHub repository is a
commit history along with a stub file left over from an process that is best accomplished via the use of
editor crash. Google Analytics. In the first step, you should work on
following the comprehensive instructions that have been
10. Let’s start a project outlined on the Analytics documentation at support.
While personal pages on GitHub might be nice, the real google.com/analytics/answer/1032385?hl=en in order
value lies in the creation of websites for projects. Let us to obtain the Google ID. Then, once you have the Google
set out by creating a new project containing a bit of C ID to hand, you can now enter it into the box at the
code – simply upload it in order to make GitHub show bottom of the Markdown editor.
the project contents view when the repository is opened
in the WebView. 14. Choose your layout
Presenting a bland website is no fun. Thus, click Continue
11. Automagic generation to Layouts in order to open a preview alongside with a 16. Do the branching
In the next step, click the wrench icon on the right-hand ribbon permitting you to select the style. GitHub The files intended for the GitHub page of a project are
side of the screen. Next, move down towards the provides a total of twelve diferent themes; you can not stored in the main branch. Instead, GitHub’s

www.fullengineeringbook.net
“Automatic page generator” segment and click the generator automatically generates a branch called
gh-pages which acts as the “host” containing the files
intended for the project’s homepage.

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 Google’s 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
GitHub’s 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 GitHub’s
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
Getting rid of a personal page is not dificult. Open the
repository containing its files, and switch into the Settings
19. Troubleshooting
The automatic page generator can be a bit troublesome
at times. Fortunately, the GitHub team provides a
20. The NSA’s best friend
While GitHub repositories can be declared private, this
flag does not apply to any Pages content found within.
pane. Then, move into the Danger Zone tab and click the selection of frequent issues which can be accessed by Be aware that any content uploaded to the Pages system
“Delete this repository” button. opening the URL help.github.com/categories/ is made publicly available – if someone finds it, consider
github-pages-troubleshooting/. 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 tasksPromise 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 Deploying Promises significantly reduces the eforts writing, care must be taken to ensure a consistent
induce JavaScript bloat: we know of some involved in callback and event handling. When done working environment. The examples presented in this
code examples where the accomplishment of right, core functions can be observed at a glance. tutorial worked well on a Firefox 42.0 hosted on a
a single task requires the presence of a dozen Furthermore, time becomes insignificant: if a Promise 64-bit Ubuntu workstation.
callbacks. Furthermore, callbacks are not a catch-all is invoked after the event it is intended to analyse has
solution for event handling. As the use of exceptions taken place, it will automatically transition through the 2. Create a model
spreads over to JavaScript, keeping an eye on the necessary states. A Promise class is a wrapper around an asynchronous
various error sources becomes tedious pretty quickly. As with all concurrent code, care must be taken to payload. To keep things ‘simple’, we will start out by
Even though Promises have not been fully avoid race conditions and similar problems. So, let us creating a simple model of a good friend of ours. Matz
formalised at the time of writing, they nevertheless be your guide and come along for a fascinating ride! will greet us with a friendly “Oi” message once a day
provide a fascinating alternative to callbacks. In – sadly, the time when the actual Oi takes place is not
principle, a Promise is but a state machine object 1. Set the stage predictable – so it could occur at any time.
whose state reflects the situation of the task at hand. As Promises are not fully standardised at the time of <html>

132 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

<body> (Math.random()*10000)); reject method, which gets invoked instead of resolve:


<script> }); <script>
function Matz() aMatz.then(function(){alert("Matz is window.doritIsHere=true;
{ here!")}); var aMatz=new Promise(
setTimeout(function(){ alert("Oi!"); }, </script> function Matz(resolve, reject)
(Math.random()*10000)); </body> {
} setTimeout(function(){
Matz(); 5. Transcendental Oi! if(window.doritIsHere==false)
</script> Classic event handlers sufer from a chicken/egg {resolve("Oi!");}
</body> problem: if the interesting event occurs before the else
</html> registration of the handler, information will be lost. As {reject ("Eeek!")}
Promises act as state machines, this problem can not }, (Math.random()*10000));
3. Adapt to Promise occur. Once Matz is done, it’s done forever, which means });
Adapting our Matz payload to a Promise involves the that the late alert will always pops up. aMatz.then(function(){alert("Matz is
creation of a method with two parameters. Both reject here!")});
and resolve can be invoked as normal members, along 6. Truly asynchronous alert("We're done here");
with a value containing further information about the Then does not interrupt program execution. Instead, the </script>
state of the event at hand. method stores the payload in an execution queue and
<body> returns afterwards. Running the example accompanying 8. Chain it up
<script> Step 6 a few times will lead to diferent alert dialog Step 6 established that then() does not wait for the
var aMatz=new Promise( sequences depending on the speed of your system and completion of the Promise. Thus, its returned context can
function Matz(resolve, reject) the random timeout value. be used to chain things up. In our example, the payload
{ <body> passed to catch() is executed only if Dorit’s presence
setTimeout(function(){ resolve("Oi!"); }, <script> causes Matz to bolt.
(Math.random()*10000)); var aMatz=new Promise( <html>
}); function Matz(resolve, reject) <body>

www.fullengineeringbook.net
</script> { <script>
</body> setTimeout(function(){ resolve("Oi!"); }, window.doritIsHere=true;
(Math.random()*10000)); var aMatz=new Promise(
4. Announce events }); . . .
Our Promise only actually becomes useful once we can aMatz.then(function(){alert("Matz is aMatz.then(function(){alert("Matz is
ensure that our code reacts on its completion. The here!")}); here!")}).catch(function(){alert("No, it's a
snippet accompanying this tutorial step announces the alert("We're done here"); Dorit!")});
Greeting event by displaying a message box once the Oi </script>
has been emitted. </body>
<body>
<script> 7. Dorit objects Don’t block
Promises are not a way to perform
var aMatz=new Promise( Real-world processes have the nasty habit of failing from multithreading. If your Promise contains blocking
function Matz(resolve, reject) time to time. We will model this via the presence of a code, the JavaScript runtime will stall just as if it
{ Dorit object: if she is around, Matz gets intimidated and were found in a normal function or member.
setTimeout(function(){ resolve("Oi!"); }, 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"); JavaScript, as the number of callbacks raises with a instantiation of the mage.
</script> growth rate of O(n)=2*n. Fortunately, a Promise can be <script>
</body> made to return another one: window.doritIsHere=true;
</html> { matzBuilder.then(undefined,function(){
setTimeout(function(){ alert("Unhandled Inner Error")
9. Clean me up if(window.doritIsHere==false) }).then(function(val){
Developers who are familiar with object-oriented {resolve("Oi!");} alert("Queueing completed! " + val);
programming languages know the concept of a finaliser: else });
it is a method that gets called on both success and {reject ("Eeek!")} </script>
failure of the underlying operation. Its position in }, (Math.random()*10000));
program execution is shown in the flowchart } 14. Promise arrays
accompanying this step. var matzBuilder=new Promise(function Pictures must be downloaded in bulk. We will ‘simulate’
MatzBuilder(resolve, reject) this problem via a Promise which – eventually – changes
10. Implement the finaliser { the colour of a table cell assigned to it:
With that, it’s time to get coding. Adding a finaliser is as setTimeout(function(){ <body>
easy as invoking the final method at the end of the call alert("Spawning new Matz!"); <script src="jquery-2.1.4.js">
queue: the execution engine will ensure that its payload resolve(new Promise(Matz)); </script>
gets invoked once the then or the catch payloads were },1500); <script>
given an opportunity to run. Unfortunately, this feature }); function DeltaColor(resolve, reject)
isn’t supported on Firefox, and requires the use of {
external libraries. 12. Gang them up, part one setTimeout(function(){
<script> With that, it’s time to show our MatzRaiser in action. The this.myElem.css( "color", "green" );
window.doritIsHere=true; following test fixture demonstrates how multiple then }, (Math.random()*10000));
var aMatz=new Promise( commands are chained. By the way: the ‘linear’ }
. . . indentation of the individual methods is recommended </script>
aMatz.then(function(){alert("Matz is in the standard. </body>

www.fullengineeringbook.net
here!")}).catch(function(){alert("No, it's a var matzBuilder=new Promise(function
Dorit!")}).finally(function(){alert("It's MatzBuilder(resolve, reject) 15. Set it up!
done!")}); { Demonstrating our code in action requires the presence
alert("We're done here"); setTimeout(function(){ of a table containing a batch of red cells. Furthermore,
alert("Spawning new Matz!"); one “master” cell is created. Finally, each cell is assigned
11. Cascade the processes resolve(new Promise(Matz)); with one instance of the Promise generated in Step 14.
In many cases, one asynchronous process kicks of },1500); function AddClosure(what)
another one. This is one of the main issues in classic }); {
matzBuilder.then().then(function(val) return function (resolve, reject)
{alert("Queueing completed! " + val);}) {

Advanced 13. Gang them up, part two


setTimeout(function(){
what.css( "color", "green" );
functionality
Check out the Promise RSVP library ofered at
If an error occurs in the “inner” part of the Promise and is
not handled in the first part of the then() chain, the
resolve();
}, (Math.random()*10000));
github.com/tildeio/rsvp.js second part handles it automatically. The little snippet };
shown here handles the fearsome Matz error in the }
$( 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();
Top left
var e5=new Promise(AddClosure($("#k5")));
The colours of the XXX-laden cells are changed as the e5.then();
individual Promises fire of their payloads window.myArray=[e1,e2,e3,e4,e5];
});
Top right
Failed invocations of the then() payload are indicated by </script>
the passing of undefined for val <table>
Right
<tr><th>Mater</th><td
A finaliser is run regardless of the success of the id="master">xxxxxxxxxxxxx</td></tr>
monitored operation <tr><th>Kid</th><td id="k1">xxxxxxxxxxxxx</

134 HTML5 & CSS3 Genius Guide


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> 17. Wait for one 19. Antipattern: recurring events


<tr><th>Kid</th><td id="k2">xxxxxxxxxxxxx</ If work should proceed after one of the Promise objects Promises change their state but once: in the example
td></tr> contained in the array is completed, the test harnish below, our Matz could say Oi once. Trying to shoe-horn
<tr><th>Kid</th><td id="k3">xxxxxxxxxxxxx</ must be modified along the lines shown in the code Promises into the role of a classic event bus as the one
td></tr> accompanying this step. shown in the image is not recommended – other tools
<tr><th>Kid</th><td id="k4">xxxxxxxxxxxxx</ window.myArray=[e1,e2,e3,e4,e5]; – like Radio.js – provide a faster, slimmer and more
td></tr> Promise.race(window.myArray).then(function() efective solution.
<tr><th>Kid</th><td id="k5">xxxxxxxxxxxxx</ {
20. Cancel and Query
www.fullengineeringbook.net
td></tr> $("#master").css( "color", "blue" );
</table> }); The basics of UI design dictate that users should be
}); provided with progress information to ‘shorten’ the wait.
16. Wait for all Sadly, this feature is not implemented in the A+ standard.
One especially interesting convenience function found in 18. Abbreviated then Instead, developers are recommended to use the Q
the standard involves awaiting the completion of an Most then() invocations contain a success and a failure library which, incidentally, also supports the termination
entire array of Promises. In our example, the “master” cell clause. The Promises standard contains a special method of Promise payloads.
gets coloured only after all the children have achieved taking two parameters – it prevents you from having to
readiness by changing their colours. invoke the failure method separately. 21. Promises for IE
. . . p.then(onFulfilled, onRejected); Analysing the compatibility of Promises on CanIUse
window.myArray=[e1,e2,e3,e4,e5]; p.then(function(value) { demonstrates that all versions of Internet Explorer don’t
Promise.all(window.myArray).then(function(){ // fulfillment support it. Fortunately, a large variety of alternative
$("#master").css( "color", "blue" ); }, function(reason) { libraries are available. ES6-Promise has become a bit of a
}); // rejection 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
T S R E V E A L THE PATH TO BUIL
EXPER UTIFUL DYNAMIC DESIGN DING
BEA S

138 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

What’s up with
web animation?
Ask any two designers what emphasise the stories you want the site
they think of animation, and to tell.
you’ll get six opinions. The web If the animation isn’t helping out, don’t
still hasn’t quite recovered from the Flash use it. You can make exceptions for
years, when loading and splash pages showcase and demo sites where you’re
stressed prebroadband modems and exploring a new technology. But for
made users wait for extravagant doodles. general public access, animation should
For designers, Flash was a brilliant way always be able to justify its existence.
to rack up the billable hours. It wasn’t so As the technology has improved, the
popular with visitors, who either learned limiting factor for motion design isn’t the
to click on the ‘Skip animation’ button as technology. You can use animation
soon as it appeared, or were left frameworks and plain CSS3 to do almost
wondering why they’d just spent two anything you want in 2D. 3D isn’t quite as
minutes watching a cartoon rocket land developed, but it doesn’t have as many
in a giant vector graphic cheesecake. clear use cases, and most sites work fine
Of course Flash is still around, but it
doesn’t seem to be winning new fans.
with 2D animation, perhaps with a few
understated 3D accents. Shane Mielke
Today, most clients and creative directors The challenges have more to do with Creative director at shanemielke.com
are going to look strangely at anyone clever design, creativity and – most of all

www.fullengineeringbook.net
who suggests a splash screen, whether it – efective communication. Animation isn’t


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
so much about moving divs as about
moving visitors. If it isn’t doing that, you
may need to rethink it.
To make life easy, we’ll pull out some of
the recent UI and UX design trends so
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
designer, animations have become more you can look at them in more detail.
about the design. There’s no need to start with a blank the right hands all of these tools can work
So what is animation for? It’s easy to editor and an equally blank expression.
magic. We’re just missing a standardised
make a site where everything moves all Modern animation design doesn’t mean
the time, but visitors will hate it. It’s more starting from scratch on every project. A timeline animation IDE like we had in Flash
that will output clean, lightweight code

useful to think of animation as a power few hints and suggestions go a long way,
tool you can use to enhance your site’s as does some knowledge of what the rest
production values, help users find their of the industry is doing. If you’re ready to
way to the content they’re looking for, and be moved, read on…
The state of browser support

CSS3 keyframes 10 4 16 4 15 7.1 4.1

CSS3 animation 10 4 16 4 15 7.1 4.1

jQuery 1.X animation 6 Current Current 5.1 12.1 6.1 4

jQuery 2.X animation 9 Current Current 5.1 12.1 6.1 4

Other JavaScript
frameworks 9 Current Current 5.1 12.1 6.1 4

The SmartWater site (drinksmartwater.com) WebGL [1]


has some charming animated interactive
11 31 31[2] 8 29[2] 8.3 40[2]
clouds that reinforce the brand’s message
[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 doesn’t 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
DreamTeam are Polish agency hooked. An attention-grabbing design is
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

www.fullengineeringbook.net
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 user’s attention.

The technologies & tools 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
Keep it simple with CSS3 There’s one catch. CSS3 runs eficiently inside the .animate function, which includes easings, durations, and
Knowing how to work with CSS3 animations is a core skill browser with superfast precompiled code. JavaScript the ability to animate any numerical CSS property.
now. CSS3 animations are split into two related tag animation is compiled on the fly, and it’s not nearly as But that’s not enough for some projects. For more
groups. The transform tags move things around the eficient. So if you do anything complicated you’ll kill the control, you can work with more advanced frameworks
screen, with simple support for 3D. The animation and battery life on mobile, and heat up the processor on such as paper.js (paperjs.org), Raphael.js (raphaeljs.com)
keyframe tags control the movement. desktops and laptops until the fans kick in. and Processing (there are two web versions –
But there are downsides, and these will include some Raw JS is a powerful option with a lot of creative processingjs.org and p5js.org). For those who want a
of the usual CSS gotchas. It’s easy to make animations potential. But you will need to handle it with a lot of care. Flash-like interface, there’s also the paid-for GreenSock
that almost work but it’s possible that they may just start framework (greensock.com).
or stop in the wrong place, or don’t quite loop as you Working with frameworks The big advantage over basic CSS3/HTML is support
want them to. And CSS3 simply isn’t very smart. You can JavaScript wouldn’t be JavaScript without more libraries for vector graphics and simplified animation loop that
link animations to events in a basic way, and you can than a human brain can remember. Luckily only a saves you from dealing directly with timers.
chain and link animations to create complex efects as handful are popular at a time. A few years ago MooTools’ Which should you choose? Processing is the most
well. But it’s dificult to make animations respond to FX Morph, Transition and Tween classes were widely sophisticated, and supports pixel-level manipulations –
surrounding content. used. (See mootools.net for details.) Yahoo’s YUI library although they’re buggy in processing.js – videos,
(yuilibrary.com) also found favour, inside and outside webcams and sound. It works with HTML5 Canvas tags,
JS & jQuery: the missing link

“ Raw JS is a powerful option with a lot of


JavaScript and jQuery can fill in the features that are
missing from CSS3. Do you need to make sure an
element won’t fall of the bottom of the screen, or cover
something important when the user reveals it?
creative potential. But you will need to handle
it with a lot of care
JavaScript is the solution.

140 HTML5 & CSS3 Genius Guide



HTML5 & CSS3
Genius Guide

Web animation
API: a new
solution?
If you’ve looked at native apps, you’ll know the
web doesn’t have anything quite like the slick
HTML5 technology and streamline native animation frameworks
Taking a peek at the source built into iOS and Android. The W3C’s web
code reveals a surprisingly slim
animation API is an attempt to fix this. It’s not a
page. It is the HTML5 Canvas
element where all the hard drop-in replacement for mobile animation, so
work is done. The animation don’t expect to make elements glide or fade more
sits quietly in the background easily than in the past. For better or worse, the
claiming all the glory while the W3C committee have gone in a diferent direction.
standard HTML creates the
The current proposal bundles the existing CSS3
crucial elements needed to
navigate and guide users animation features, extends them to allow simpler
around the site. 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. It’s also
going to be possible to start, stop, restart, and
pause animations using JavaScript code, which
And there’s more will fix some of the limitations of CSS3 animation.
The homescreen is If you’re thinking this sounds a little like Flash
undoubtedly the centrepiece
– it does. Or at least, the timeline and keyframe
of the DreamTeam site, but
complimentary and more features do. When web animation becomes widely

www.fullengineeringbook.net
constructive animation is supported it’s going to become easier to chain
incorporated into the site. animations, to create animated efects by
Simply scroll down the page to
flip-booking SVG files, and to make animations
see how subtle user interface
animations are introduced into respond to external events.
the site design. So it’s 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.
Motion The current API proposal has issues. One big
so it’s good for big animated emotion with it it will definitely take your data problem is lack of synchronisation. You can make
backgrounds and digital art. Don’t forget that many CSS tags vis skills up a couple of levels. events play together on the same timeline, but it’s
However it’s not so ideal for making – including older pre-CSS3 tags – hard to guarantee that animations on separate
UI elements and moving them can be animated. So animation can WebGL and 3D timelines will remain synchronised across a page.
around. Raphael and paper are mean creating opacity fades, animation Another problem is complexity. The API
simpler, and concentrate more on animated borders and text Waiting in the wings is 3D animation proposal tries to do so much it’s not a model of
vector graphic design with a hint of decoration. and rendering. This has a lot of elegance and clarity. It’s possible to create
animation. GreenSock is much used by potential, but it’s not quite there yet. The complex animations with it, but it’s not going to
corporates and adds useful functions that WebGL standard is a simplified version of the win awards for being easy to use. This is good
simplify CSS animation. They’re all worth looking at, OpenGL 3D graphics programming API used in news for designers with good code skills, who will
because knowing what’s out there can spark new ideas high-poly commercial games. continue to be in demand. But perhaps it’s not so
for existing designs. This sounds like a good thing. But not all platforms good for the state of web animation in general –
support all features, and some older hardware barely although it’s likely that as soon as the spec is
Visualising data supports WebGL at all. So you can’t rely on it. And it’s finalised, it’s going to be wrapped into a friendlier
If you’re working with data visualisation, the go-to hard to make it look awesome. Gamers are used to and simpler framework so more people can use it
framework is d3.js. (d3js.org.) d3 is a monster that chews high-poly rendering with advanced lighting efects, and without reaching for the paracetamol.
on data and spits it out in almost any shapes you can WebGL can’t match that. Whatever the limitations, the API is the most
imagine and a few you probably can’t. It’s immensely Finally, it’s hard to use. The three.js framework (threejs. exciting thing to happen to animation since CSS3.
powerful, but also has a steep learning curve. If you can org) makes it more accessible, and there are plenty of It should be ready for commercial use within a
hack it though, it’s ideal for making and animating UI demos to learn from (look out for the work of mrdoob year or two. Currently it’s ‘being considered’ by
elements, especially if you’re using them to display – you can follow him on Twitter @mrdoob). But it’s still a Microsoft. Chrome’s developer builds include it,
quantitative data. couple of levels up from plain CSS. and Firefox has a not-quite-there implementation.
To help you get started, the d3 site has a huge Is it worth it? For plain vanilla UI design, no. For more Older and more obscure browsers will play
selection of demos and examples. Don’t expect instant experimental projects, it’s certainly worth exploring to catch-up, as usual. If you want to know more,
results, but if you can spare a week or two to get familiar see what’s possible. check out w3c.github.io/web-animations.

HTML5 & CSS3 Genius Guide 141


Special effects

Make animation work for the user


In a world after Flash, the point of animation is to equivalent of the animated GIFs that haunt the ancient visual equivalent of an <important> tag. It highlights
enhance the user experience without distracting or underworld of amateur web design. something you want visitors to remember.
annoying your users. It’s not quite true that animation The next UX group are the attention-getters. When At the top of the animation tree are full-blown
should be unnoticeable – sometimes you want you want a user to focus on one point in the web sales infographics. The genius of motion design means you
something that stands out. But it should never clash with pitch, add some content-related animation to make that can make infographics interactive. This often works
the rest of the site design, it should never draw attention element stand out. These elements are the descendants better than leaving users passively looking at the screen
to itself without a good reason, and it should always of the old splash pages, but they’ve been toned down for as an animation plays through. It’s a huge win for all
provide a clear user benefit. modern sites so they don’t overwhelm visitors. They’re kinds of education and training sites, where you can
Modern motion design has split into three main areas. very popular on Bootstrap sites, where one item out of build a simulation and help users learn about a topic by
UI sweeteners add a hint of eye candy to plain vanilla UI two or three has added movement and maybe tells a interacting with it.
elements to raise production values without beating short story. Typically they’re spread over a third or a But animation isn’t an obligatory part. Adding a simple
visitors over the eyeballs with designer awesome. quarter of the page, and they’re more cute than splash or bounce tells the user they’re in a new part of
cinematic. The animation works a bit like a tiny video that the site, and you’re telling them a new chapter in your
Staying focused dramatises the point of the element it decorates, like the site’s 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
remember the motion than the content Speed up
you may want to rethink your design jQuery
strategy – especially if you start JQuery isn’t fast, and .animate
veering towards the sketchy end of is even slower. To make your

www.fullengineeringbook.net
town with insane animate- animations faster and more
everything excess, and overly eficient, try Velocity.js (julian.
bouncy, distracting image carousels com/research/velocity) for a
and sliders. These are the modern drop-in .animate
replacement.

Edwin
Europe
edwin-europe.
com
Check the Denim fit guide Vimeo
to see the 360-degree Cameo
view: animation with vimeo.com/
the wow factor. 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 decorations and pop-ups. Getting links right is always a colour. Apple’s ‘You got that wrong, so this text box looks
you keep it short though… challenge. A subtle mouseover underline animation can like it’s shaking its head’ is the classic example here.
help draw attention to a link without making the rest of Skeuomorphisms help make the site feel more
Make UI engaging the page look busy and link-heavy. Another example are physical. The aim here is to use visual metaphors to
Why spice up a UI with animation? Too much twitching form error notifications. Have you ever pressed Submit suggest physical objects. Often, just a hint of physicality
and blinking can give users a migraine. But just the right on a site and then wondered why nothing happened? is enough for more weight and presence.
amount of animation can make the diference between a Site designers realised it was helpful to highlight mistakes Attention seekers are the final UI group. They provide
boring site and one that users will keep coming back to. in red, so users can see problems immediately. important stand-out features that can’t be ignored, so
In outline, there are three kinds of UI animations. But sometimes this is too subtle. You can use they’re hard to get right. Examples include ‘FILL IN OUR
Highlighters decorate existing content to suggest an animation to draw attention to problems by making FEEDBACK FORM’ pop-ups, but you can also find them
afordance. The most obvious examples are link incorrect elements move a little, as well as changing scrolling up from the bottom of the page on news sites
to ofer breaking news.

“ The right amount of animation can make


the difference between a boring site and one
that users will keep coming back to
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

www.fullengineeringbook.net dragon.nl
Car manufacturer Peugeot
combine video, VR and
animation to create a
breath-taking
experience.

HTML5 & CSS3 Genius Guide 143


Special effects

Create a
www.fullengineeringbook.net that we will use to tween the position of each individual
dot. We are using 7px as the value for distance – you can

pulsating circle play around with this value to create a circle with less or
more dots in it.

HELLO MONDAY TECHNICAL LEAD 3. The init method


TORBEN DALGAARD JENSEN Here we are creating each individual dot. We need to
REVEALS HOW THEY CREATED THE convert the degrees to radians and then calculate the
EFFECTS ON REVELATOR.COM initial position using trigonometry. We find it easier to
The Revelator website is built on the idea that you only work with degrees than radians, but this step can be
need to use one platform if you want to run a music skipped and do all calculations with radians.
business. We wanted to showcase this idea by leading the
user through an animated story that breaks the features 4. Implode and pulse
into simple steps. Below we’ll explain how you can create These methods tween the radius value and update the
the type of animation we used for the Promote feature. position of the dots (see next step). In this example they
We’ll use trigonometry to create the pulsating efect will keep running each other when the tween completes
and write it entirely in JavaScript. GreenSock TweenMax is to create the pulsating efect.
used for the tweening, and we will be writing a JavaScript
object instance for the circle so that we can preserve 5. Update Torben Dalgaard Jensen
modularity and readability. Now what we’ll do is we will update the position of the Technical lead
dots based on the new radius value we are tweening. at hellomonday.com
1. Initial setup Then we will be delaying them incrementally to create


First what we will do is create a container and an array to the staggered efect.
hold the circles. Then we are centring the container We wanted to create a visual
within the window. Also we are writing some stub code 6. Ready to rock! representation and give a sense
that we will revisit later. Going back to the main script – we will now create three
instances of the DotCircle with incrementing radius. Then
of the excitement and relief
2. Create DotCircle.js we will start the animation, again using delay to stagger musicians feel when they
We will go through the methods for the stub code for the them. For the full code in this tutorial, make sure that you release their music and see the
DotCircle in the next steps. We calculate the distance in check out FileSilo (filesilo.co.uk/bks-887).


degrees between each dot and create a radius object mood of their fans rise

144 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Animations: keep it simple Resources


everything needs to animate. Animations have varying Interviewing Julian Shapiro
levels of expressiveness and personality. The most bit.ly/1Jzl5tX
colourful kind – like 3D flips, bounces or elastic
easing – can be a great way to make an interface more Find out what velocity.js author Julian Shapiro thinks
fun but since they’re so distinct it’s easy for them to be is going to happen next on the animated web. Read
visually fatiguing. It’s generally better to stick with simpler his comments about the diference between good
animations for things that people interact with frequently and bad animation design, learn about the imminent
and save the more playful ones for areas that are used speed and eficiency bump, discover how too much
more seldomly. Another rule of thumb I use is to show creativity can be a bad thing, and why education
slow and hide fast. For example, I might run a half- matters more than ever in motion design.
second intro animation for a modal dialog but hide it
without any animation at all. The rationale here is that Rachel Nabors’ UX Guide
you’re more willing to watch something you requested bit.ly/1R6UdWj
animate in than you are waiting for something you
dismissed to animate out. This excellent slide deck introduces the latest trends
in animated UX design from the perspective of a
Which web animation technologies currently excite trainer and designer. You may not necessarily agree
you and why? with all the points – especially the one about the
CSS transitions and animations are the technologies that return of splashy flash screens. But the rest is
I care most about. Combined they are flexible enough to definitely well worth reading for a creative and
achieve the efects I want and it’s been great seeing inspiring overview.
them gain broad support so quickly.
Hakim el Hattab Val Head’s Videos
vimeo.com/valhead/videos
www.fullengineeringbook.net
Web animation has vast potential. How do you see it
Designer and developer
hakim.se evolving over the next couple of years?
I expect tooling to get a lot better and I know that Not so much of the future, but you may as well get a
Q. The use of web animation in any project needs to be browser vendors are making good progress towards this. good guide to the state of the art in the present
carefully considered. What advice would you give to Working with animation is a visual process often before you go ahead and any higher – this collection
designers and developers? requiring many iterations of number tweaking and of tutorial videos covers all the CSS3 animation bases,
When working on a web app keep in mind that excessive previewing. If friction can be removed in that workflow and includes an impressive collection of design
and lengthy interface animations can reflect negatively we’ll see higher quality animations. examples. There’s only about half an hour here in total
on the app as a whole. If animations are too slow the app The Web Animations API is looking promising too. though, but it’s certainly time well spent, especially if
itself is perceived as sluggish. If there are too many There’s certainly a need for animations that can be you’re just starting out.
things animating too frequently it won’t feel reliable and controlled more explicitly via a script than what’s
robust. Keep animations brief and remember that not currently possible with CSS transitions and animations. Narayan Prusty’s Web
Animation Tutorial
qnimate.com/web-animation-
api-tutorial
What next for animation? If API specs make you dizzy you can find some simple
code examples of the Web Animation API here.
In the past, web design was split into epic splash same contemporary flat, minimal, cartoon-style design There’s a handy comparison with traditional CSS3
animations and relatively small and trivial UI tweaks, with language common on the web, but add an animated animation, so that you can see how to move from the
a few sliders in the middle. What happens when the web twist to highlight a feature or make it more memorable. old API to the new one. It’s not going to win any
animation API becomes more widely used and designers Eventually some icons will be animated as a matter of design awards, but it’s a good place to start if you’re
can work with more complex animations? course. Balance is key. Too much movement is confusing feeling lost and confused about where animation will
Some designers will stampede back towards epic for users. Animated GIFs were the bane of the early web, go in the future.
splash pages. Even though loading times and browser and animated icons could easily become the modern
speeds make splash pages more feasible than they were equivalent. But they probably won’t, because designers
in their heyday, it’s likely they’ll remain a sideline.
The trends in current design are clear: they’re all about
integrating animation with content – or rather, about
enhancing content with tasteful and relevant animation.
Parallax scrollers, minivideos, and animated icons do this
are more experienced now, and there’s more of a trend
towards minimal design, where designers keep removing
elements until they’re left with the bare essentials.
If those essentials happen to include some movement
that can justify its existence by telling a story about some
“ The trends in
current design are
clear: integrating
already, with varying degrees of success.
For examples of possible future trends, run a search
content or highlighting the afordances of an icon or
other UI element, that could potentially make the web
animation with
content
for the animation tag on Dribble. Most examples use the much more creative for everyone.


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

www.fullengineeringbook.net
pressed, the left side of
the menu slides down and
the right-hand side slides
up from the bottom.

Split screen
The page features a
split-screen styling,
divided into two halves,
vertically and used
throughout the site.

Slideshow The main image


The images that appear The homescreen has a full
on the homepage are a browser image. When the
giant slideshow that mouse moves, the image
slides upwards into view reacts and moves in a
on the screen. parallax-esque style.

146 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

The creators of the new By Association Only actually close to finishing a site, but because it had been
website state that the “hardest website to so long in the pipeline, they decided it would be better
build is your own site”. This is a statement that to start afresh and reimagine their brand.
would certainly ring true with many web designers. Realising that their own name was a bit of a
Client work always takes priority so it can be dificult mouthful, they rebranded their logo to an easier BAO
finding the time to create your own website, but at the letterform. The finished site features a consistent
same time you are always going to be judged by your two-panel approach that splits the screen in half
own site, so its importance is crucial when looking at vertically but this isn’t just for aesthetics though, as this
self-promotion. By Association Only were keen to create style is also used as part of the menu design. This
something innovative and diferent, but keeping a brings the form and functionality together into a
minimalist approach that emphasises usability, and so coherent whole that makes sense for the user rather
the process for creating their site had begun. They were than simply satisfying a design aesthetic.

Finding visual inspiration


“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
<comment> website and it turned out that one old Seventies movie poster just happened to
What our be that spark that informed the 50/50 design route.”
experts think
of the site
Joe Trippett – cofounder/creative at By Association Only

Technique position: absolute;


top: 0; left: 40%;
1. Create the sliding panels font-size: 3em;
In your HTML page add the tags that are shown here. z-index: 250;

www.fullengineeringbook.net
There are two panels for the left and right side of the }
screen and these will be hidden to start with, then a {
animated when the burger menu icon is pressed in the text-decoration: none;
third div. Another div is included just to show where the color: #fff;
page content would go. }
<div id = "left" class="hidden animated"> </ #content{ padding: 30px; }
div> .hidden{ display: none; }
<div id = "right" class="hidden animated"></ </style>
div>
<div id = "icon"><a href="#" 5. Set the styles
onclick="menu();">&#9776;</a></div> When the user clicks the burger icon the menu function
<div id = "content">Regular page here</div> is called. This code swaps out the hidden property of the
panels so that they become visible. The CSS styles that
2. Style the content are applied come from the animate.css file that was
Move to the head section of the site and link to the linked up in Step 2.
animate.css file from daneden.github.io/animate.css as <script>
they will be used to trigger the movement. Then some of var over = false;
our own CSS is added in so that we can style up the var left = document.getElementById( 'left'
background of the page. );
var right = document.getElementById( 'right'
3. Look left and right );
Let’s now add the style for the left and right panels, these function menu(){
are positioned on the page appropriately to the left and if (over==false){
right side of the screen. They are also positioned left.classList.remove('hidden');
absolutely so that they can appear above other content left.classList.remove('fadeOutDownBig');
EXPERT INSIGHT on the screen with a higher z-index. The sizing is then left.classList.add('fadeInDownBig');
The rise of the preloader handled by percentage to fit the diferent screens. right.classList.remove('hidden');
Many websites now feature
preloaders, all this does is present a
holding screen until all the content is 4. Finish the styling 6. Switch out
loaded. When using large images, it Now let’s add in the remaining CSS, which will style the The rest of the class swapping code is added. Notice that
is essential to wait until they have burger icon, link and the content that would appear on a variable is also used to hold for whether the menu is
loaded before presenting them to
the page. The final CSS style will hide any content that over or not. This is then used to apply the correct classes
the user, otherwise they would think
that the site isn’t working properly shouldn’t be seen until it is animated. to the code. This is all done without the need for jQuery,
with content missing. #icon{ through vanilla JavaScript.

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

www.fullengineeringbook.net
seem like a tribute site to
sci-fi, scrolling down
reveals that it is actually a
tribute to everything.

Retro stylings
Cameron’s World is
basically a love letter to
the internet’s infancy,
piled to the brim with
animated GIFs.

GIF collection GeoCities nostalgia


Scattered throughout It was one of the first
Cameron’s World is places for building
probably the largest homepages, that’s why so
collection of animated many GeoCities assets
GIFs in the universe. have been collected here.

148 HTML5 & CSS3 Genius Guide


HTML5 & CSS3
Genius Guide

Everybody loves a bit of retro, right? Nostalgia will recoil in horror and wonder what the hell we were EXPERT ADVICE
As you can see, there is a plethora of animated GIFs in
is as inherent to the human race as innovation thinking with these designs. Cameron’s World. For the purposes of this tutorial, we
and now, some 25 years after the invention of So how about taking one of those quaint, charming picked the relatively simple alien GIF, but we still took a
the World Wide Web, the internet is old enough to be animated GIFs and giving it the modern treatment? Let’s while deciding and then still had to figure out how to
able to look back fondly on its own infancy. bridge the gap between old and new by re-creating an translate a series of animated image layers into a
working, code-based animation. Maybe you can go one
One such website throwing its eyes back with animated GIF using SVG, HTML and CSS. Bearing in mind better. Why not choose one of the more complex GIFs
unabashed fondness is Cameron’s World. Anyone that this is a quick exercise and we don’t have a and see if you can re-create it using only HTML and
familiar with Nineties web browsing will recognise the wireframe 3D model of the USS Enterprise to hand, we’re CSS? Obviously, there will always be some that can’t be
bright lights, garish colours, autoplay music and going to be picking one of the simpler GIFs to re-create. mimicked to perfection in pure code, at least not yet,
but sometimes great leaps in coding development
practically no design ethic, all of which made us gasp See the alien, bottom left of the screen on initial page come from having to work with existing tools, but
with awe only 20 years ago. Some will see this site and load, just above the ironic coloured message? That’s our within very narrow confines.
smile fondly, yearning for simpler days. Others, of course, guy. Make sure you get the full tutorial code on FileSilo. Besides, even if you’re not about to usher in the next
big web development, solving a seemingly pointless
Animated changes HTML puzzle like this can be an extremely useful
method for keeping your brain agile and ensuring
“Despite Cameron’s obvious nostalgia for the animated GIF, advances in CSS those coding skills stay honed. Remaining within your
animation, and SVG imagery coupled with JavaScript, have seen the GIF slowly comfort zone, churning out the same template-based
sites time and time again, is an easy trap to fall into.
<comment> go the way of Flash animation. These days you’re more likely to see animated Sometimes it pays to challenge yourself and try your
What our GIFs relegated to loading icons and little else.” hand at what you think is beyond your skills. Maybe
experts think
of the site
Richard Lamb, freelance web designer at Inspired Lamb Design you’ll surprise yourself with what you can achieve.

Technique -5.677811,-66.79329 5.526856,-101 6.578432,- left: 140px;


20.08329 22.191729,-47.71784 38.032189,- float:left;
1. Create your alien 67.3146 30.93205,-38.267061 81.23502,- }
First we to make our alien in either Photoshop or 71.07202 131.41932,-85.704791
7. Position the eyes
www.fullengineeringbook.net
Illustrator. Build him with two layers by making the head 27.5954,-8.046286 48.45573,-10.899652
shape, the mouth and nose. The eyes will be created later 79.39131,-10.85949 28.27843,0.03671 We need to shape the eyes for a true alien efect, they’re
on. Once you have this done, save your layers. 41.98283,1.701767 68,8.261848 too human at present. Use the transform declaration to
93.39828,23.549846 167.53312,94.419523 rotate them at opposite angles to each other. Don’t forget
2. Create the SVG 185.44818,177.280353 9.2316,42.6981 to add vendor prefixes for browser compatibility.
There are numerous ways to do this step. You can create 3.71539,85.70185 -17.16761,133.83668
SVGs from your layers with the latest versions of -22.51033,51.88577 -69.35284,114.74745 8. Animate the eyes
Photoshop or if you are using Illustrator you can export -129.44543,173.7131 -54.55723,53.5341 In order to create the blinking efect, we are going to use
your layers as SVGs directly. If you have neither of these -86.61074,70.62438 -119.33514,63.62707 z" the box-shadow value to ‘fill’ each eye with a darker grey
you can use Inkscape, an open source software available id="alienHead" stroke="#1f1f1f" stroke- colour and back again over three seconds. The
for free. You should end up with an SVG for the head and width="4" /> keyframes are set at irregular intervals to create a slower
one for the mouth and nose shapes. </path> end to the blink.
</svg> .eye-left, .eye-right {
3. Base HTML animation: eye 3s ease-in-out infinite;
Now we’re going to begin putting together our index. 5. Start adding CSS }
html, placing a number of feature-named divs within a The base CSS for the facial features is very simple. Float @keyframes eye {
main container div. The two eye divs will have content the head div left and then add the eyes and face divs 0% {box-shadow: 0px 0px 0px 0px #585757
created entirely in CSS. with absolute positioning, plus a zero value top inset;}
declaration. You will see your head and facial features 2.38% {box-shadow: 0px 140px 0px 0px #585757
4. Place your SVGs shapes fit together, sort of. Now we need eyes. inset;}
Place the SVG code for the head shape inside the head 34.13% {box-shadow: 0px 0px 0px 0px #585757
div. You should have a grey shape but you can add a 6. Build the eyes inset;}
black stroke value to it for an outline. Then place the Both eyes are built purely in CSS and, apart from one 36.51% {box-shadow: 0px 0px 0px 0px #585757
mouth and nose shape into the face div. diference, share the same basic values. With relative inset;}
<div id="head"> positioning and left float we can then slot them one next 100% {box-shadow: 0px 0px 0px 0px #585757
<svg version="1.1" xmlns="http://www.w3. to the other. inset;}
org/2000/svg" xmlns:xlink="http://www.w3. .eye-left, .eye-right { }
org/1999/xlink" width="682" height="643" width: 200px;
viewBox="0 0 682 643"> height: 100px; 9. Animate the head
<path style="fill:#707070" d="M background: #1f1f1f; Now we’ve re-created the original GIF, we’re going to
329.29383,595.34017 C 303.59048,589.84415 border: 2px solid #1f1f1f; surpass it a little by adding an extra animation using the
278.06846,571.34223 230.24763,523.53768 border-radius: 100px / 50px; rotate value to tip the head slightly from side to side. This
147.90032,441.21841 101.01898,368.99175 position: relative; is optional, so you can even try putting in some values of
87.424155,303.5 c -7.385818,-35.58047 top: 175px; 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

www.fullengineeringbook.net
the page, the content
within the sections slide
into place for maximum
impact with the user.

Scroll arrow
When the site first loads,
the image of the down
arrow slides onto the
screen showing that there
is more content below.

Motion backdrop Rollover arrow


The background to the The arrow indicating
top of the page is a movie more content has a
file showing ISL’s projects, rollover effect that dips
with some impressive the arrow down with a
camera moves. colour transition.

150 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

ISL is part of a new breed of digital agency – Universal’s Mr. Robot and an internet-controlled arcade
there is a growing trend that doesn’t see them crane for Nickelodeon’s SpongeBob SquarePants.
exclusively tied to the desktop screen. Sure, When it comes to their own website, it becomes a
there are a lot of agencies that make content responsive place where they can show of their skills and talents for
to diferent devices, and some of those even make apps their varied work and approach to solving problems.
as well. Rather than just state what they’ve done for their clients,
ISL goes beyond those conventions and also creates they take a case study approach that defines the
hardware installations for clients and as digital devices problem, the solution that they have taken and the most
become ever more present in our lives, brands demand important part of all, the results that this has given their
that something completely new is created to engage clients. It’s no use to make awesome use of technology
them with their audience. They’ve created a physical unless it actually works in what it’s trying to achieve. You
mentions box for Facebook, a launch campaign for NBC can get the full code for this tutorial on FileSilo.

A lesson in over-caffeinated, youthful exuberance


“ISL.co, like the agency itself, is a balance between designerly minimalism and
over-caffeinated, youthful exuberance. In practice, this meant a combination of
<comment> vast white space and simple, clear typography, paired with tons of movement
What our — from background videos to fluid, bouncy UI animations.”
experts think
of the site
Zach Goodwin, creative director

Technique top with an animated down arrow scrolling down, which


triggers the animated elements onto the page.
1. Scroll-triggered animation <div id="top">
To trigger animation by code, the Waypoints.js <div class="os-animation btm" data-os-

www.fullengineeringbook.net
(imakewebthings.com/waypoints) library and the animation="fadeInLeft" data-os-animation-
Animate.css (daneden.github.io/animate.css) library will delay="0s">
be used. Download and add them to your document. <img src="img/arrow.png">
Then add the first CSS rule to position the top element. </div>
</div> ...
2. Style up the page
Continue adding CSS as this will provide some classes for 5. Add JavaScript
us that position elements at the bottom of a div and float Now the JavaScript is added and placed in a jQuery
elements left and right on the page. The final style here ‘document ready’ function to allow all elements to load.
creates a section that has a yellow background so it can Then the function that will be called when the user scrolls
be seen on the page. is added. This checks elements on the screen for certain
data attributes and applies CSS accordingly.
3. Final CSS <script type="text/javascript">
As in the previous step the CSS here creates blue and $(function(){
black sections on the page so that they can easily be function onScrollInit( items, trigger ) {
seen to demonstrate what is happening. The final two items.each( function()
rules turn animated elements on and of by giving them {
opacity values. var osElement = $(this),
.blue{ osAnimationClass = osElement.attr('data-os-
background-color: #00baff; animation'),
height: 200px; osAnimationDelay = osElement.attr('data-os-
} animation-delay');
.black{ osElement.css({
background-color: #282f31; '-webkit-animation-delay': osAnimationDelay,
height: 200px; '-moz-animation-delay': osAnimationDelay,
} 'animation-delay': osAnimationDelay
EXPERT ADVICE .os-animation{ opacity: 0; } });
Animation trickery .os-animation.animated{ opacity: 1; }
The main point of animating content </style> 6. Listen to the scroll
is to draw attention to it. As content When an element is triggered, the appropriate CSS is
doesn’t appear in its entirety in the 4. HTML content added from the Animate.css library. Here the listeners are
user’s viewport, it is important to
Move to the HTML section of the page as this is where created that tie the onScrollInit function to the scrolling
capture when it actually is present
and make it animate at that point to the content will be added. This is all styled up via the CSS action by the user. Save this and test in the browser to
give maximum impact to the user. that has been added. A full-screen section will be at the see the animation triggered on the user’s 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 – it’s well
known for its almost-
universal compatibility.

Minimal width
Our example does not

www.fullengineeringbook.net
enforce a minimum width
for convenience. But
adding this feature does
not require much code.

Touch suggestion
Tilting the movement
gems to the side provides
the users with a visual cue
to motivate them to move
the widgets around.

Static backgrounds Another drawer


Arkivert uses cute Adding another drawer is
illustrations but you can not particularily
replace the backgrounds complicated: simply
with any content you duplicate the <div>s and
consider to be interesting. add a bit of resizing logic.

152 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

Research has repeatedly proven that humans data model of the application. This, however, is but one
often have their fair share of problems when application for movable columns. As websites strive to
attempting to interpret numbers. However, if replace classic desktop applications, multicolumn views
data is spruced up visually, keeping tabs on information is gain importance: for example, an email client could
much easier. display three panes containing the folder’s content, an
This instalment of our never-ending series on web email’s content and a folder structure next to one
techniques was inspired by one particular website another. Providing draggable windows is a sure-fire way
(sparetime.arkivert.no/en), which makes use of to endear such an application to its users: as of this
draggable columns to represent an amount of writing, most web-based programs lack capabilities for
information visually. the flexible positioning of their contents.
Users arranged the width of multiple columns on the Fortunately, getting started is really easy and you can
screen in order to map their behavioural patterns to the find all the code for this Web Workshop on FileSilo.

Putting a value on time


“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.
<comment> Arkivert’s Sparetime calculator attempts to value your free time by asking a
What our group of questions, which are then algorithmically parsed into a surprisingly
experts think
of the site accurate estimate.” Tam Hanna

Technique }
function handleDragStart2( event, ui ) {
1. Div tags console.log( "Drag starts!" + event);
Let’s get started by erecting the scafolding of our }

www.fullengineeringbook.net
website. It consists of three <div> tags, which are function handleDrag2( event, ui ) {
arranged next to one another via the width and console.log( "Drag !" + event);
padding-left properties. Describing the spaces with }
relative values ensures that the page remains fullscreen </script>
even if the user changes his window size.
4. Do some maths
2. Add a draggable handle The next step involves the dynamic recalculation of the
Ofering resizable panels is fun only if the user can column widths as the position of the element is modified.
actually change their size. This is best accomplished via This is relatively easy: the element’s initial location is
two handles displayed in the middle of the borders. For stored as onDragStart fires. After that, the CSS properties
now, adding simple boxes via a <span> tag and some are recalculated dynamically.
CSS magic shall sufice.
5. Provide a helper object
3. Add draggability As of this writing, the user can move the handles up and
JQuery UI contains a robust drag-and-drop capability down. This is unsatisfactory, but can be solved by
which works better than the one found in HTML5. Our providing a helper object, which gets dragged across the
example loads jQuery UI from the oficial CDN, and it screen in place of the original object.
adds event handlers which dumps the supplied
information into the browser’s debugger console. 6. Tilt the handles
<script type="text/javascript"> Now transform the handles to an oblong shape in order
$( init ); to give our users a visual cue that they can use them to
function init() { drag around. This is easily accomplished via a transform
$('#box1').draggable({ order, which gets added to the stylesheet of the boxes.
start:handleDragStart, <style type="text/css">
drag:handleDrag}); div span.myBox{
EXPERT INSIGHT $('#box2').draggable({ position: absolute;
Not for mobile start:handleDragStart2, top: 50%;
Even though our slider looks
awesome on a desktop, be aware drag:handleDrag2}); right:-25px;
that it is not particularily well suited } width: 50px;
to the needs of mobile phone users. function handleDragStart( event, ui ) { height: 50px;
Most smartphones are used in console.log( "Drag starts!" + event); background-color: lavender;
portrait mode, where horizontal
space is at a premium. Drag and
} border: solid 1px silver;
drop also requires a level of accuracy function handleDrag( event, ui ) { transform: rotate(45deg);
dificult to achieve on touchscreens. console.log( "Drag !" + event); }

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 Mozilla’s 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 </div> }


with animations, overlays or other content </div> audio { display:none; }
could be done quite easily with Flash, but since
the demise of that plugin it’s become harder to achieve 2. Link to popcorn 5. CSS animation
this kind of efect. HTML5 has given us a great way to Change the text inside the <h1> tag for each of those Now the code adds some very simple CSS3 animation.
natively play audio or video in the browser but it’s still a copied sections and you can refer to the text in the The hide class has been applied to all the content in the
hassle to try and get something to happen at a key point finished file or add your own. A little further down the body section of the page. A transition for the opacity is
in your media. Fear not though because Mozilla has body section you will see a bunch of script tags for the applied, which sets the length to half a second. When
come to the rescue with their media library Popcorn.js. 3D animation, add this at the bottom to link to the content needs to fade in, the show class can be applied
This has a very simple premise to enable the developer to Popcorn library. to the div and it will fade in, taking half a second to do so.
code content that can be triggered at various times .hide {
during the playback of their media. If you’ve ever seen 3. Add the music file opacity: 0;
interactive music videos by Arcade Fire and Rome for Scroll back up the page to just under the div tags from transition: opacity .5s ease-in-out;
example, then this is the sort of library that enables the Step 1 and add this HTML5 audio tag to link to the MP3 -moz-transition: opacity .5s ease-in-out;
triggering of new scenes or animations at key points in audio. Later on, this audio tag will be hidden on the -webkit-transition: opacity .5s ease-in-out;
their music videos. screen using CSS and the Popcorn.js library will link to }
In the tutorial we are going to have a 3D scene in the this so that animation can be triggered based on the .show {
background of the page, created in WebGL with three.js. current time of the song playing. opacity: 1;
Over the top of that will be some regular DOM content, <audio id="myAudio"> }
which will be hidden. Popcorn will be used to load audio, <source src="autumn-leaf.mp3" type="audio/
play it and then trigger camera moves in the 3D content, mpeg"> 6. Position the messages
while also fading in with CSS transitions, with the regular </audio> As there will be animated 3D content using WebGL in the
div-based content over the top. background, any new content to be displayed needs to
4. Start styling be shown over the top of this. As such the z-index, which
1. Up and running In the head tag on the page, add an opening and closing is like the height, is set to be higher than the rest of the
Open the start project folder in Brackets or a similar code style tag, then add the following CSS into that. Here the page. This section is set to fill the browser width and

www.fullengineeringbook.net
editor and open index.html. Scroll down to the body tag body tag gets the padding and margin removed and the height, positioned absolutely in the top left.
and add the following div tags for our on-screen right typeface is set for all content. Any content that .outer {
messages that will be shown at key points with the overflows the page will be set to hidden, as is the audio
music. Copy and paste this code three more times and from the previous step.
change the id to two, three and four.
<div id="one" class="outer hide">
body {
padding:0;
Familiar terminology
If you’ve ever worked with audio or video the
<div class="middle"> margin:0; term ‘cue’ means to start a piece of media and
<h1>&ldquo;Globally, loss-related floods overflow:hidden; hence the code to start something happening is
have more than tripled since 1980&rdquo;</ font-family: 'Oswald', sans-serif; also ‘cue’ in Popcorn.
br><small>Munich Re Insurance</small></h1> color:#ffba00;

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; help it stand out against the background. The size of the which was added way back in Step 3. Once the link is
width: 100%; text is also increased and centred horizontally. established, the audio is set to play. Save the document
height: 100%; h1{ and try this in the web browser, the music will start to
position: absolute; font-size: 3.8em; play and the 3D scene is visible in the background.
top: 0; left: 0; display: inline-block; function initMusic(){
} width: 40%; popcorn = Popcorn( "#myAudio" );
margin: 0 auto; popcorn.play();
7. Vertical alignment text-align: center; }
Inside the fullscreen div of the outer created in the text-shadow: 3px 3px #000;
previous step is another div. The text inside here should } 12. Call the first animation
appear in the centre of the screen horizontally and The scene needs a little movement so that the first
vertically. The middle class here will ensure that happens 9. Wait for the audio message can be displayed. Add the line below inside
by aligning it on the vertical axis with the page centre. Before the audio is set to play, it is important to ensure initMusic. This is calling a function on line 111 of the scene.
.middle{ that it has fully loaded and can be played. Add the code js file if you want to look at it. Save this and refresh your
min-height: 100%; here to just under the existing script tags on the page. browser and the camera will move forward in the scene.
min-height: 100vh; This will load all of the scripts and content in the body camMove1();
width: 100%; tags before calling the init function. The init function will
display: -webkit-flex; show the 3D background, so test that in the browser. 13. Cache the divs
display: flex; <script> To speed up DOM manipulation of adding and removing
align-items: center; document.addEventListener("DOMContentLoad classes, variables are created to hold the four div tags
-webkit-align-items: center; ed", function () { that contain text. The ‘show’ class will be added and
} init(); removed and this will make the appropriate message
}, false); fade in or fade out at the appropriate time. Add this code
8. Set the headings </script> inside the initMusic function.
All of the text on the page is set with headings so here, var one = document.getElementById( 'one' );
the CSS for that is set. Because the background has a 10. Calling the music var two = document.getElementById( 'two' );

www.fullengineeringbook.net
number of colours, there is a text shadow on the text to If you’ve loaded the content from a local server or var three = document.getElementById( 'three' );
webhost, the 3D scene will show, but no music is playing var four = document.getElementById( 'four' );
just yet. Just under the init(); line in the previous step add
the next line, which will call a function to play the music. 14. Sync to music
Additional plugins
There are additional plugins for Popcorn that
This hasn’t been created yet so don’t run it in a browser.
initMusic();
All of the remaining code in this tutorial is added before
the closing bracket of the initMusic function at each
allow you to run video from hosted sources such subsequent step. To make something happen in time to
as Vimeo, YouTube and SoundCloud. It’s even 11. Link and play music, the following code is used. This calls its own
possible to open Google Maps. Before the closing script tag in Step 9, add the following function after one second of the music playing. Test in
function. This links to the audio with the id of myAudio, the browser to see the message show after one second.

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


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');
});
lightOn();
});
popcorn.cue( 17.6, function() {
message displays. You’ll 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
lightOff(); relevant to that.
15. Move forward }); popcorn.cue( 30.2, function() {
Adding the next code causes the camera to start to three.classList.add('show');
move forward to the next section in the 3D scene by 18. Slight change to the colour });
calling camMove2 inside the scene.js file. The text on the Let’s do the same again on the second bass stab. The
screen is made to fade out by removing the ‘show’ CSS code here gets the timing just right for that. There are 21. Final camera movement
class, and so the opacity is removed to 0 again. more bass stabs a little later and you can add more by Once the car has driven past the screen it’s time to move
popcorn.cue( 13.3, function() { listening to the audio and noting the times yourself. the camera forward again to the final destination. At just
camMove2(); popcorn.cue( 18, function() { after 40 seconds the final camera move is called, and the
one.classList.remove('show'); lightOn(); third message fades out on the screen by removing the
}); }); ‘show’ CSS class. The camera swings up to the mountain
popcorn.cue( 18.4, function() { for the final text to display.
16. Add the message lightOff(); popcorn.cue( 40.5, function() {
If you looked at the last move in the browser you will }); camMove4();
have seen the camera move forward towards the three.classList.remove('show');
buildings and the rain. Now the next code will show the 19. Continuing the journey });
text in the div with the id of ‘two’. This takes place after Now we wait for the song to be almost 28 seconds in to
almost 16 seconds. Save and test to see the efect. call the camera to move again with camMove3. The 22. Finish off
popcorn.cue( 15.8, function() { second message is faded out on the screen as the As the camera eases into the final position in the
two.classList.add('show'); camera moves forward. Save and refresh now. background, the final text is displayed on the screen. At
}); popcorn.cue( 27.7, function() { 43 seconds the fourth text block gets the CSS class of
camMove3(); ‘show’ added so that it fades in, and shortly after this the
17. Lightning flashes two.classList.remove('show'); music finishes playing. Now just save and test the
Just after the last message displays on the screen you }); document in your browser to see the full animation and
will hear two bass stabs as part of the music. It’s possible music sync up together.
to use this with a lightning efect in the 3D scene to make 20. The next message popcorn.cue( 43, function() {
it more dramatic. Here we turn a flash of light on for just Just after the camera arrives at the bridge, the next four.classList.add('show');
less than half a second in time with the first bass stab. message needs to display on the screen, so in this code });
popcorn.cue( 17.2, function() { the function is called at just after 30 seconds so that the

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

www.fullengineeringbook.net
an HTML5 Canvas Tag
that contains the
illustration, this way it can
easily be changed.

Drag downwards
As the user drags down
the shirt starts to ride up
the torso, showing that
the shirt is actually being
lifted up.

Belting up Finish the drag


As the shirt lifts, the belt is As the drag reaches the
revealed with a variation bottom, the shirt moves
of the site title. Notice back and tucks into the
how it stands out against jeans. It then fades out to
the illustration. reveal the real site behind.

158 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

Fruit of the Loom have recently conducted a The website features an animated film to report these
survey about the way men dress and found findings that was created by the agency Porter &
some fascinating results. It seems that men Bogusky while the microsite that holds this was created
who tuck their shirts in are happier, wealthier and by Legwork Studio.
generally more successful all-round. The site itself features some lovely interaction around
This study was done to promote the brand’s new tucking in a shirt in order to get into the site, which has
undershirt. Coincidentally this new Fruit of the Loom both great illustration and animation that highlights Friut
undershirt is specially made so that it stays in place of the Loom’s findings in a neat way. Once the shirt is
tucked into clothes. Researchers and scientists have no tucked safely away behind the belt and trousers the user
real idea why this is found to be true but it does provide is let into the real site as the illustration fades away. An
a great way to market a new shirt that adheres to these ingenious way to tie in illustration, interaction and a
new findings. brand strategy in one easy activity!

Slide to unlock
“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 campaign’s
<comment> animated spots was a great opportunity to establish the tone of the site while
What our simultaneously reinforcing the goal: encourage tucking.”
experts think
of the site
Dave Soderberg, creative director, Legwork Studio

Technique var end = start + 300;


window.onload = addListeners;
1. Create the pull-down transition function addListeners(){
In your HTML page add the tags as shown here. The div.addEventListener('mousedown', mouseDown,

www.fullengineeringbook.net
main part is that the container will cover the screen until false);
the drag element is dragged downwards, then the div window.addEventListener('mouseup', mouseUp,
below will be revealed. This is actually just held false);
underneath the other content. }
<div id = "container">
<div id = "drag"></div> 5. On and off
</div> When the mouse is pressed down a mouse move
<div>Your real site goes here</div> listener is registered then when it is released this listener
is removed. The idea behind this is that it keeps the
2. Style the container movement purely restricted to when it moves and stops
Move to the head section of the site and add some style it being dragged and sticking to the mouse even when
tags then the container CSS can be added to those. This let go, which can happen!
positions the container above the page content and function mouseUp(){
positions it absolutely to fill the screen so that the site window.removeEventListener('mousemove',
cannot be seen below it. divMove, true);
}
3. Such a drag function mouseDown(e){
The drag element is made into a circle by adding a window.addEventListener('mousemove',
border radius to it and by changing the width and height divMove, true);
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. 6. Tidy it up
Now the function of when the mouse moves is ran and
4. Add the behaviour this really does all the work. It constrains the object to be
Just before the closing body tag in your document, add dragged on the y axis only and for 300 pixels. When it
script tags and then add in the JavaScript code shown reaches 300 pixels the ‘container’ div is faded out using
EXPERT ADVICE here. A reference to the elements are stored for use in CSS transitions.
Clean outlines the code, then the starting and ending position are function divMove(e){
The canvas element is able to draw recorded. Event listeners are added for the mouse down if (e.clientY < end && e.clientY >= start){
very clean lines, which looks good and mouse up events. div.style.top = e.clientY + 'px';
but can be a little dificult to make var div = document.getElementById("drag"); }
look unique. The Tuck Efect site
var outer = document. if (e.clientY >= end){
gives the lines a hand-drawn look to
avoid this and uses texture to add a getElementById("container"); outer.classList.add("fadeOut");
little shading to the arms and torso. var start = div.style.top; } }

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
Content can be placed in Changes on scroll
the content element in The main content is
the header. This will be placed under the header
placed above the image and will become
background image. visible as the user scrolls
down the page.

Zooming image
The main photo is placed

www.fullengineeringbook.net
on the bottom layer and is
resized based on the
scroll position to give the
illusion of zooming in.

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 it’s used just for fun or to emphasise interactions are managed with JavaScript while the EXPERT ADVICE
something serious, this sinister on-scroll efect default styling settings are defined in regular CSS. Note Adapting the sinister effect
can be exploited in web design in order to that for this Web Workshop we have placed both CSS Sinister features
Additional features can be added to the efect by
capture the attention of your viewers and to set the and JavaScript in separate files so that the efect can be adding new JavaScript code within the scroll listener.
tone for the rest of their experience. With this in mind, reused across multiple pages without any code This tutorial uses the greyscale filter property as an
there can be justified use of this efect for user duplication taking place. example of changing the image colour, but other
experience design as well as using it from a graphic The CSS filter property is fairly versatile and allows for options are also available for experimenting.
design perspective. many other options, in addition to or instead of, the
This animation efect makes use of HTML, CSS and greyscale property that has been incorporated into this
Calculations
The calculations for the transition are made using
JavaScript. This is important because CSS alone can’t be particular tutorial. So here’s your starting point for playing percentages so that it works the same in diferent
used to detect page-scrolling events, hence these around with the efect. resolutions. This is important to ensure that the efect
doesn’t break with high-res screens. You can test this
using the zoom-out features of your web browser to
Making something look serious simulate a higher resolution.

“The sinister effect can be used to emphasise something serious and is ideal for Limitations
use on webpages promoting a serious topic. In the case of the Bloomberg Step 8 shows a condition that stops the overlay resizing
Business website, it is used to set the tone of a Fifties gangster movie, which once its horizontal position exceeds -10 pixels. This
<comment>
prevents the illusion from being broken by larger
What our have been the stage for of many stories about corruption.” resolutions that stops the overlay covering full width,
experts think
of the site
Leon Brown, freelance web developer keeping the webpage adaptable and future-proof.

Technique $(window).on('scroll', header{ </script>


display: block;
1. Main page setup position: relative; 7. Initiate listening code
The main page requires the standard HTML, head and height: 100%; With the styling now complete, we are ready to add the

www.fullengineeringbook.net
body containers to be defined. This also enables us to text-align: center; code to trigger changes as the page scrolls. This is
insert the page components in the following steps in a overflow: hidden; achieved by adding JavaScript code that waits for a
way that keeps the JavaScript and CSS separate from the margin-top: 25%; page-scroll event. We put this inside another listener for
page body content. } the completion of the page loading to avoid an error.
header h1{
2. CSS file linking font-size: 6em; 8. Activate image zooming
This HTML markup will link the files that the CSS and color: #c00; The sinister efect is primarily made from two animations
JavaScript code are contained in to the page so that the text-shadow: 2px 2px #000 – the main picture made bigger and the overlay made
styling and functionality can be shared across multiple } smaller to focus its inverted transparent circle around the
pages. It also enables us to keep the code clean by header img, image. We use a query selector to target the images to
separating content, styling and functionality. header .content{ apply sizing and positioning calculations based on the
position: absolute; scroll position.
3. Content containers top: 0; //-- PUT THIS INSIDE THE SCROLL LISTENER
Insert the sinister header and the main page content left: 0; document.querySelector("header img").style.
inside the page <body> tag. The sinister <header> margin: 0 auto 0 auto; width = (100+(window.scrollY/20))+"%";
contains the background photo image, an overlay image width: 100%;} document.querySelector("header img").style.
used for the zoom and a content container for the left = (0-(window.scrollY/50))+"%";
additional text content – in this case it’s a title. 6. Style individual images if(-200+(window.scrollY/3) < -10){
Two images are used in our layout: the main photo document.querySelector("header img:nth-
4. Initiate page styling image and the sinister zoom overlay. We’ve avoided child(2)").style.width = (500-(window.
Now that the HTML elements are in place, we can move over-complicating the HTML with class name and are scrollY/1.5))+"%";
to the styles.css file to start styling the page. We start this using their position in the <header> container to define document.querySelector("header img:nth-
file with the default styling of the main page – mainly the positioning styles. child(2)").style.left = (-200+(window.
page background and the <main> content container, $( "#header" ).click(function() { scrollY/3))+"%";
which we want to use to ensure that the content is if (menuOn == false){ }
centred and has readable text. $('#menu').animate({"bottom": -100}, 500 ); if(-180+(window.scrollY/3.5) < -20)document.
menuOn = true; querySelector("header img:nth-child(2)").
5. Sinister styling } else { style.top = (-180+(window.scrollY/3.5))+"%";
The header’s styling needs to stretch across the page $('#menu').animate({"bottom": "-100%"}, 500
and have a visible height. It will also need to hide any ); 9. More sinister colouring
overflow from the zooming images we are using. Images menuOn = false; The main photo can change from full colour to black and
and the content container will be posited at the top left of } white as the efect takes place by using the scroll position
the <head>, which is made possible with the header using }); to afect the greyscale property. For the full code on this
relative positioning. }); 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
user’s 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.

Hidden animations On page load


Scrolling past the first Once the initial load
screen will reveal some animation (featuring a
beautifully crafted dollar) is done, the title
animations. These unfold elements begin their
as the users scrolls down. step-by-step animation.

162 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

So you’re looking for a good way to engage Internet security company Kaspersky have put
your website users from the moment the together this wonderful-looking microsite, designed to
homepage loads. Grabbing the diminishing educate users on the dangers of online payments and
attention spans of web users is an on-going battle for the many related cyber attacks that users can fall prey to.
developers. There are all sorts of options, from autoplay Featuring some great scroll-activated animations and
videos to pop-ups which demand user interaction. fullscreen videos (worth checking out for the transport-
Sometimes, though, you can keep the user’s attention for based demonstrations of Trojans and the like), One Dollar
those first few vital seconds with a simple animation. Lesson opens with a perfect example of the efect we
Nothing too over the top, just a little something that are going to re-create in this workshop. Once the
keeps them watching. homepage background has loaded, the site title and the
How about an animation that delivers the site title in Kaspersky logo ease into view, one at a time. Simple
steps, over a short period of time? efect, but one that keeps you watching.

Make the wait interesting


“These days it’s a brave website that asks the user to sit through a content-
loading percentage bar, however short the wait. The desire for instant content
<comment> is relentless. If this is unavoidable you better make sure your loading icons are
What our interesting and different enough to hold users fast.”
experts think
of the site
Richard Lamb, owner and web designer at Inspired Lamb Design

Technique Num Num!’. Place one apiece into the four yums. Then
give each of div an individual class name, corresponding
1. Background image to the image names.
The first step for our food-related example is to put in
5. Individual animation times
www.fullengineeringbook.net
place the fullscreen background image. We’ve selected
an image which places content focus on the left, so that We’ll concentrate on writing the keyframes which will
we can place our animated content on the right. Ensure animate our title. First, set animation durations specific to
that you include your vendor prefixes. each of our individual divs.
.um {
2. The base HTML animation-duration: 2s;
Create an intro div that will sit on the left side of the }
canvas (using Bootstrap CSS makes it simpler). Within this .num-one {
we need four title divs, each containing a div class we’re animation-duration: 4s;
calling yum. The yum classes will contain the animations. }
<div class="intro col-md-3 col-md-push-8"> .num-two {
<div class="title"> animation-duration: 6s;
<div class="yum"></div> }
</div> .underline {
<div class="title"> animation-duration: 7s;
<div class="yum"></div> }
</div>
<div class="title"> 6. Write the keyframes
<div class="yum"></div> The keyframes re-creates the efect from our inspiration
</div> site causing the four title elements to slide up from the
<div class="title"> bottom, with a slight bounce on arrival.
<div class="yum"></div> @keyframes rise {
</div> 0%, 60%, 75%, 90%, 100% {
</div> transition-timing-function: cubic-
bezier(0.215, 0.610, 0.355, 1.000);
EXPERT ADVICE 3. The initial CSS }
Content delivery The intro div should be given some slight padding at the 0% {opacity: 0; transform: translate3d(0,
Packaging important information
into an entertaining, easily top. The title div needs to assign an overflow:hidden 3000px, 0);}
consumable format has become one property. We need the child elements invisible until they 60% {opacity: 1; transform: translate3d(0,
of the primary challenges for reach the confines of their parent. We’ll call this ‘rise’. -20px, 0);}
websites, especially when delivering 75% {transform: translate3d(0, 10px, 0);}
information that has not necessarily
been sought out. One Dollar Lesson
4. Insert the title images 90% {transform: translate3d(0, -5px, 0);}
employs just the right mix of Create four PNG images for the three words and an 100% {transform: translate3d(0, 0, 0);}
interaction and spectacle. underline, of equal width, which make up our title, ‘Um }

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 background: #35483e; 4. Add the CSS for the SVG
been the ability to write behaviours for background-image: url(img/bg.jpg); Move back to the CSS section of the page and add the
transitions and animations. These animated background-size: cover; rule for the SVG. This will display the object as a block
efects are a must-know for any designer or front-end font-family: Arial; element so that it can be centred on the page with the
developer as they unlock all kinds of interactive } margin set to auto. The font for this element is set to
possibilities and visual feedback options. Oswald and a large text size.
In this tutorial the focus is on text with three diferent 2. Write an SVG graphic
efects that ofer some great possibilities. The first actually As SVG graphics are written with tags they can be easily 5. Style specific text
will not use standard text on the page, but will instead authored without any graphics application. Move to the Now the CSS is targeting the specifics of the text and the
create the text inside an SVG element. The reason for this body tag and add the start of this SVG graphic, which fill is turned of while a white stroke is added to the text.
is that SVG enables strokes on text which is not possible creates text to display in the browser. Later this will get The stroke isn’t applied all the way around the text by
to do with regular HTML text, and sometimes you may styling from the CSS that will animate this. using the dash array. The stroke is widened and told to
just need strokes with text. Using the SVG right in your <svg viewBox="0 0 960 300"> take five seconds to apply the animation.
HTML will keep your text accessible and will stop you <symbol id="s-text">
having to rely on GIFs. Once the stroke is in place, it will be <text text-anchor="middle" x="50%" 6. Start the animation
given five diferent colours and set to march around the y="80%">Kinetic Design</text> By adding keyframes the stroke will immediately start
text with animation. The next text efect shows how to </symbol> animating around the edge of the text. Now each
make a text rotator so that diferent words can be cycled graphic element is given colour and a slight delay in its
through on the screen. The final efect will use text clip to 3. Create graphic lines movement to create the basis for the rotating stroke
clip the image to the text so that the image only shows The next code that is added finishes of the SVG, more around the outside. At present there are orange and dark
inside the text. This will be turned into a call-to-action importantly though it creates five graphics nodes that red strokes.
button with a sliding image efect. will be styled using CSS to create five diferent coloured @keyframes stroke-offset {
strokes. These target the text that was created in Step 2. 100% { stroke-dashoffset: -35%;}
1. Set up the document <g class="g-ants"> }
Open the project folder in Brackets or a similar code <use xlink:href="#s-text" class="text- .text-copy:nth-child(1) {
editor and then open start.html. Create style tags in the copy"></use> stroke: #5c0404;

www.fullengineeringbook.net
head section and add the CSS shown. This will import the <use xlink:href="#s-text" class="text- animation-delay: -1s;
right typeface that will be used from Google and sets up copy"></use>
the basic HTML settings for the pages. <use xlink:href="#s-text" class="text-
@import url(http://fonts.googleapis.com/ copy"></use>
css?family=Oswald:400,700);
html, body {
<use xlink:href="#s-text"
copy"></use>
class="text-
CSS keyframes
The CSS keyframes rule enables the designer to
height: 100%; <use xlink:href="#s-text" class="text- specify either ‘from’ or ‘to’ values, or alternatively
font-weight: 800; copy"></use> it enables them to use a percentage that states
} </g> what should happen.
body { </svg>

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

} setup of a text rotator that will move through the 12. Set the unordered list
.text-copy:nth-child(2) { diferent list elements with animation, great for showing Now with this rule targeting the unordered list, you will
stroke: #d6801c; of a range of skills. notice that the text for the first element is sitting
animation-delay: -2s; alongside the static text. The other list elements are
} 9. Style up the text below this but because the overflow is cut, it isn’t being
With the next content in place, move back to the CSS displayed until the animation is added.
7. Finish the stroke style tags and our code on FileSilo places the text in the ul {
As in the previous step, the CSS here is targeting the centre of the page under the animated heading created margin-top: 0;
diferent children of the graphics object and they are earlier. At the moment this still looks like a list, but that will padding-left: 130px;
given diferent colours and ofset in their own animation. all change as more CSS is added to complete the efect. text-align: left;
This now gives the efect of five diferent colours list-style: none;
marching around the edge of the text. 10. Static section animation: 6s linear 0s normal none infinite
.text-copy:nth-child(4) { The text is made to float left, where one half of the text is change;
stroke: #ffff9e; static, ie not moving, hence the name of the class that is }
animation-delay: -4s; controlling it here. Once floated to the left, the overflow is
} hidden. The height is set up so that only one line of the 13. Size up the height
.text-copy:nth-child(5) { moving section can be seen. Styling up the list elements applies the right colour for
stroke: #55981b; .static { these elements and more importantly sets the line
animation-delay: -5s; float: left; height so that the text moves to the right section and
} overflow: hidden; can only see that section at any one given time. If the
@keyframes stroke-offset { height: 40px; line height was smaller it might be possible to see parts
100% { stroke-dashoffset: -35%;} } of the other text on the screen.
}
11. Paragraph style 14. Make it move
8. Second effect The paragraph tag is targeted and given a light yellow The final setup for the CSS part is to make it move by
That completes the first efect that is being added to text, colour that has also been used in one of the strokes defining the keyframes called ‘change’. Step 12 calls for

www.fullengineeringbook.net
so now move down to the body tag and add our code around the edge of the previous text, just to keep these keyframes and adding these will immediately start
from FileSilo to the SVG added earlier. This readies the consistency with the colours. Again this text is floated to the text rotator sliding up and down to show the text.
the left so that the list can sit alongside it. Because the animation was set to infinite, this will just
p { keep looping.
display: inline; @keyframes change {
Naming keyframes float: left;
margin: 0;
0% { margin-top: 0; }
15% { margin-top: 0; }
Notice that the keyframes in Steps 14 and 6 have
been given a unique name so that they can be color: 25% { margin-top: -40px; }
called by the right piece of animation. #ffff9e; 40% { margin-top: -40px; }
} 50% { margin-top: -80px; }

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


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, transition-
property, transition-
duration, transition-timing-
function 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; }
font-size: 3em;
font-family: 'Oswald';
text-align: center;
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
100% { margin-top: 0; } } position: relative; text. The downside at this point is that the text is invisible
display: block; as the image is there. The final step will correct this.
15. Call to action .clip-text:before {
That completes the second animation that we are 18. Apply the image z-index: -2;
exploring. Now it’s time to add the final animation, which Now for the real nuts and bolts of the process. Here the top: 0;
will be for an animated rollover button, using a newer clip-text rule is continued and the background image is right: 0;
CSS command: clip text. In the body add the HTML from set to display, however instead of it being in the bottom: 0;
FileSilo below the other content that is on the page. background like normal, the text is set to clip it. This left: 0;
means that the background only appears inside the text. background-image: inherit;
16. Centre the box background-image: url(img/text-bg.jpg); background-position: bottom;
The first part of this is simply to centre the box and for us background-position: bottom; background-size: cover;
to clear the floated elements in the content above. This background-size: cover; transition: 2s ease all;
box is going to be quite small on the screen so it is being -webkit-background-clip: text; }
made to be 400 pixels wide. The auto margin centres -webkit-text-fill-color: transparent;
the div box on the screen. transition: 2s ease all; 21. Clip the image
.wrapper{ } The final part is to place a semitransparent background
clear:both; colour behind the text and to give this a slightly smaller
width: 400px; 19. Rollover effect size than the box. The result is that the text and border
margin: 0.5em auto;} Adding the code here will set the rollover for the text and now both clip the image so that it is only visible where
the background image. The image will be set to be they are. Save this now and test it in the browser.
17. Start the clipping positioned at the top in the background. Previously it was .clip-text:after {
The next rule will set up the clipping of the text. Firstly set to the bottom so the text will have the image slide position: absolute;
the right typeface is applied to this and the type is given through the text as the user rolls over it with the mouse. z-index: -1;
quite a prominent size of 3ems. The text is centred with .clip-text:hover, .clip-text:hover::before { top: .125em;
the block and some margin and padding sets this up background-position:top; right: .125em;
nicely on the screen. } .clip-text:before, .clip-text:after { bottom: .125em;
.clip-text{ position: absolute; left: .125em;
margin-top: 4em; content: ''; background-color: rgba(214, 128, 28, 0.9);
padding: 0.3em; } }

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 <html> container having their content placed within them. The
make use of can often be pretty limited, <head> front card will have a style added to the main element
especially when the website is being viewed on <title>3D Card Navigation</title> that sets the background image to use.
a small screen. With the diferent information ** Step 2 goes here <div class="front" style="background-
components in your design competing for screen space, </head> image:url(img/burger.jpg)">
it is important to make sure that you give each element <body> <h3>Burger</h3>
the most appropriate placement in the design of the ** Step 3 goes here </div>
page or the screen. </body>
A more recent addition to the CSS specification is the </html> 5. Back content
use of 3D elements. We are all familiar with the default 2D This element will appear when the card is flipped. Like
presentation of webpage elements, in which we can 2. Load resources the front element, it is a container for any content that is
position them on the page by using their horizontal and The <head> section of your HTML is used to contain links to appear at the back. Using a container like this allows
vertical coordinates; the 3D presentation features takes to resources you are using. Our example will contain a CSS to rotate everything from the same place.
this one step further by allowing elements to be CSS file for styling and a JavaScript file for detecting <div class="back">
presented with depth perspective, which can then be when the user taps on the navigation cards. *** Step 6 here
used for rotation and making the elements appear <link rel="stylesheet" type="text/css" </div>
further into the distance. href="styles.css" />
This tutorial will look at how the use of 3D presentation <script src="code.js"></script> 6. Content inside
can be used to the advantage of user experience design The content to be placed inside the front and back is just
of websites and web apps by allowing additional 3. Card container regular HTML. We will add some text descriptions and
information to be expanded from the same space The easiest way to ensure consistency and simplicity to navigation links to the back content container inside the
without the need to scroll or load a new page. Our control all elements of the 3D navigation card is to place card. Upon completion of this step, you can now repeat
example uses 3D page elements that will allow users to them inside a container. Two types of container are used Steps 3 to 6 to add new navigation cards.
hover or tap to access additional information and – the main container will control the origin for 3D rotation <h3>A Tasty Burger</h3>
navigation links – similar to how game cards are while the card container will contain the content <p>This is a tasty burger served with
presented. To keep this tutorial uncluttered, we will avoid elements that will display relative to the card. cheese, tomato and lettuce.</p>

www.fullengineeringbook.net
using browser vendor tags such as -webkit. If you require <div class="container"> <nav>
compatibility with older versions of Safari and Firefox, <div class="card">
simply add these for CSS commands such as transform, ** Step 4 goes here
perspective and backface-visibility. ** Step 5 goes here

1. Initiate HTML page


</div>
</div>
Better use of space
Using 3D elements for user experience design
As with any webpage, there is a requirement to define the can allow you to include more information in
page’s HTML, head and body structure. Use the head 4. Front content limited space without disorienting the user by
section to contain any meta data such as the page title The card will have two sides – we place a container for taking them to a diferent part of the page.
for SEO and accessibility that you may need. 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> display: inline-block; position: relative;


<a href="#">Link 2</a> transform: rotateY(0deg); display: block;
<a href="#">Link 3</a> perspective: 500px; transition: 1s;
</nav> margin: 2em; transform-style: preserve-3d;
} }
7. CSS initiation
With all of your HTML set up, the next step is to initiate 9. Container interactions 12. Front and back containers
the CSS. The page is already expecting to load a file Interactions will be triggered whether either a :hover is The front and back containers will be used to contain
called ‘styles.css’, so create this file and add the following detected on the main container or a hover class has content that are to be shown specifically when the front
initial CSS for the standard page styling: been applied to the container. The reaction to these will or backside of the card is visible. We need to make sure
var img = $(document.createElement("img")); be a transformation that rotates the inner contents by that the backside of these elements are not visible when
$(img).attr({ 180 degrees around the y axis. they are in reverse. We also need to position them at the
"src":this.url, .container:hover .card, top left of the card.
"data-index":count, .container.hover .card{ .front, .back {
"title":this.title, transform: rotateY(180deg); backface-visibility: hidden;
"alt":this.description } position: absolute;
}); top: 0;
//.. code from next step goes here 10. Set card size left: 0;
We can set the size of the navigation card by setting the }
8. Container definition size of the foundation container and the inner content
The first of the containers is used to set the foundations containers. We used pixel-based measurements but you 13. Content box sizing
from which any 3D calculations are performed from. This can experiment with percentages. In addition to the previous content container settings, we
includes setting the position, display mode, initial rotation, .container, also want to ensure that any future padding or border
margin and also view perspective – ie distance from the .front, additions don’t make their sizing out of sync with what
viewer. We use a display of inline-block to allow multiple .back{ we’ve already set up. We can achieve this by telling them
cards to be placed next to each other. width: 300px; to include padding and border size as part of their width

www.fullengineeringbook.net
.container { height: 500px; and height settings.
} .front, .back {
box-sizing: border-box;
11. Card container }

Different effects
Other efects can be achieved with 3D rotation by
The next container to define rules for is the card
container, which is used to activate 3D transformation 14. Front image settings
changing settings such as the transform-origin rules, animation transition time and also to set The front of the card will have its background image set
and perspective. Add and change these values to positioning to relative so that any absolute positioning is to cover the full size of the element. It will also need to
see what efects you can produce. relative to the card – and not the main screen. guarantee its placement on top of the back element,
.card{ hence why a z-index is set to 2. An initial rotation of 0

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


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 {
17. Navigation container
The navigation links of each card are placed inside a
<nav> container. This means we can apply styling to their
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.
z-index: 2; container – in this case to set the font size, padding and nav a:hover{
transform: rotateY(0deg); the display mode to ensure that links appear separate to background: #333;
background-size: cover; the main content. }
} nav{
display: block; 20. JavaScript get cards
15. Front title padding: 2em; We now need to add some JavaScript to activate
The front of the card makes use of a <h3> title tag to margin: 0; detection of taps on the cards when used on mobile
present the introduction title of the card. The title will } devices. Create a file called ‘code.js’ and add the following
have a semitransparent black background with white code to fetch all elements with a class name of ‘container’
text. We want to make sure that the styling for this is 18. Navigation links when the page loads:
specific to <h3> tags inside of the front class. Navigation links will appear in darker grey boxes with window.addEventListener("load", function(){
.front h3{ white text. Each element will use padding to make the var containers = document.
background: rgba(0,0,0,0.5); boxes appear more prominent and margin to make querySelectorAll(".container");
color: #fff; them appear separate to each other. ** Step 21 code here
text-align: center; nav a{ });
padding: .5em; display: block;
} list-style: none; 21. Touch start listener
background: #aaa; With JavaScript now having all of the container elements,
16. Back card color: #fff; it can now loop through each of the elements and apply
The presentation of the back of the card will have a plain font-size: 1.5em; a listener for each time one of these elements are
grey colour background and will require some padding margin-top: .5em; touched. Our code will toggle the addition or removal of
to ensure that there is some spacing between text and padding: .5em; a “hover” class – of which the presentation rules were
the edges of the card. The element will need to be text-align: center; defined in Step 9.
initially rotated by 180 degrees. } for(var i=0; i<containers.length; i++){
.back { containers[i].addEventListener("touchstart",
padding: 1em; 19. Navigation hover function(){
transform: rotateY(180deg); Changing the colour of navigation options that are being this.classList.toggle('hover');
background: #eee; hovered over is a really good way to indicate to the user })
} that the item is an option that is available to be selected. }

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)

www.fullengineeringbook.net
automatically scrolls the
page down to the next
section, this fits the
browser window exactly.

Shrinking images
The graphical content on
the screen animates
down in size, giving a
pleasing shrink effect as
the page scrolls upwards.

Reverse in size Varied navigation


Returning back through The homepage combines
the navigation dots a one-page style site and
causes the page to slide a slide show. The scrollbar
back up and the graphic is hidden but navigation
content to expand in size. dots are still visible.

172 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

As a web design and development agency it’s the user slides down are the neat show-of points in this
very important that you can show of what site. Each browser-sized screen on the homepage is like a
your skills are; if you can combine samples of diferent slide in a slide show, but you click the navigation
your work into an innovative presentation on your site dots on the right-hand side to move down rather than
then that’s even better. That’s exactly what Devstars right to left. The scrollbar is hidden away so this nifty
have done on their site. Devstars.com is a full multipage navigation is a great way to explore the screens that
site but use the one-page style website idea for the follow. As you slide down to the next section, the graphic
homepage to show of exactly what they do. The site’s content on the screen animates, shrinking down in size
homepage has a number of navigation dots that you and moving of the top of the page. The real menu is
immediately associate with a slideshow and these hidden behind the burger icon so what this presents is
contain the latest work oferings, while giving an an unusual slideshow of important content that Devstars
overview of the company. The little animation touches as wants users to see.

Making your work the star


“Bright bold colours make this site stand out with just enough negative space to
make the logo and site content stand out. The homepage’s featured content
<comment> has an animated effect that draws attention to the care the team put into the
What our small details of their site.”
experts think
of the site
Mark Shufflebottom, professor of Interaction Design, Sheridan College

Technique 3. Finish the style


The image with the ID of ‘shrink’ will be scaled down
1. Create the shrinking logo effect when it hits the top of the page – this shrink will then be
When making this efect work, the logo needs to be detected through jQuery code later. The image is

www.fullengineeringbook.net
placed within a page. As there is no page content here, displayed as a block element to enable the centring of
some div tags are being added, which will have 600 the image horizontally.
pixels of height added to them. When the image reaches #shrink{
the top of the page, it will be shrunk down. display: block;
<div class="space"></div> margin: 0 auto;
<img id="shrink" src="img/Wikimedia-logo. }
png" /> </style>
<div class="space"></div>
<div class="space"></div> 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 When the image is within the space of the top of the
In the head section of the page, the script tag calls the page, the ‘shrink’ image is animated down to 0 on the
jQuery library so that we can detect the position of the width and height over half a second. Now go ahead and
page and make DOM changes based on that. The CSS save the page, then you can test the efect in the browser
EXPERT ADVICE styling gives the ‘space’ class a height of 600 pixels, as to see the efect in action as you scroll the image to the
Reinforcing the brand the comment states this is purely for demonstration only. top of the page.
A logo can say a lot about any
company and Devstars’ logo features <script type="text/javascript" src="js/ if ( topDistance < scrollTop ) {
a series of stars laid out horizontally. jquery.js"></script> $('#shrink').animate({"width": 0, "height":
For their showcase content, Devstars <style> 0}, 500 );
uses the shape of the logo as a mask .space{ }
for images of work that they’ve
produced. This not only looks good
height:600px; });
but also reinforces the brand in the /*Purely Demonstration Purposes*/ });
homepage design. } </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 colour-
changing background.

Beyond home
Try the Projects page out
to see some clever
scrolling techniques, with
slower scrolling in the

www.fullengineeringbook.net
centre column.

Portfolio section
A little further down you
will find, in bold black and
white, a Current Projects
section with nice hover
effects and links.

The scrolling text Site Overview


Scroll down to find The Deux Huit Huit site
another (and simpler) combines carefully-
version of the scrolling thought-out parallax
text animation, we are effects, CSS animations
emulating in this tutorial. and subtle hover effects.

174 HTML5 & CSS3 Genius Guide DOWNLOAD TUTORIAL FILES


www.filesilo.co.uk/bks-887
HTML5 & CSS3
Genius Guide

Web design agencies building their own colour-changing backgrounds. Probably the most EXPERT ADVICE
showcase websites must always manage the impressive efect that Deux Huit Huit utilise is found
Sleight of hand
This particular Web Workshop is a great example of
balance between building a website which will directly after the intro message on the homepage. Set using CSS trickery to create the impression of
impress and engage potential clients, while also over a monotone image of Château Frontenac (or a something happening which actually isn’t. While it may
building a website that will impress other web model of it, anyway) are the scrolling words ‘Featured appear that a single line of scrolling text is changing
colour, in fact there are two lines of scrolling text, one
designers. French Canadian digital agency Deux Huit Project’, continuously moving across the screen in
on top of the other, strategically set to appear and
Huit have put together a website that is simple and ticker-tape style. disappear at concurrent points. It is actually a very
unfussy, but designed to have enough fireworks to What is most striking is how the words appear to clever piece of trickery when you think it through and
dazzle browsing clientele without leaving them change from dark grey to white as they hit the boundary understand the method. And it raises an interesting
point about how we should approach CSS animations
completely intimidated. Among the bells and whistles on of the image and then back again as they leave it. So,
and efects.
ofer are some neat parallax efects, particularly on the how is this efect achieved? As ever, we learn by doing. Sometimes you don’t have to figure out how to
Projects page, and a few sections that burst into life with Let’s re-create the scrolling text with colour change. make a particular HTML efect or animation work.
Sometimes you are better of figuring out how to
simply make it look like it’s working. Sure, an element
Stop trying to impress your peers scrolling into frame on page-load is actually scrolling
into frame. That’s a simple efect to achieve. But if you
“As mentioned in the intro, web designers can make the mistake of building are striving to create an efect that is more complex,
their websites with too much of an eye on impressing other web designers, don’t rule out the possibility of trying diferent
rather than luring in potential clients. It’s an easy trap to fall into, leaving you techniques that create the illusion of the efect, rather
<comment>
than the efect itself. It’s not cheating to use a little
What our with a website that is inscrutable to the layman and useless as a marketing tool.” trickery, the efect is just as good and it may just make
experts think
of the site
Richard Lamb, freelance web designer at Inspired Lamb Design your work a little simpler.

Technique bsp;Our&nbsp;Words</span>&nbsp; box-sizing:border-box;


<span class="scrText light">These&nbsp;Are&n }
1. First layer bsp;Our&nbsp;Words</span>&nbsp; .scroll-image {
The efect is achieved with a series of layers arranged </span> position: relative;

www.fullengineeringbook.net
over each other. We build our layers from back to front, z-index: 10;
beginning the first set of text. To ensure that the text 4. First layer CSS }
flows on one line, spaces should be coded using &nbsp The initial CSS here sets the vital hidden overflow for the
and two sets of text per layer should be used. wrapper, so the text does not break the boundaries of 7. Second layer CSS (cont)
<div id="wrapper"> the screen space. Absolute positioning for the scroller The image itself should be given a 100% width value to
<span class="scroller"> builds the base for our construct. The animation keep it from breaking its boundary. The overflow-hidden
<span class="scrText dark">These&nbsp;Are&nb keyframes will follow. relative div, with its self-explanatory values, can easily be
sp;Our&nbsp;Words</span>&nbsp; combined into one class, if need be. The hidden overflow
<span class="scrText dark">These&nbsp;Are&nb 5. Animation keyframes keeps the white text within the confines of the image.
sp;Our&nbsp;Words</span>&nbsp; Set your animation keyframes for a smooth transition .scroll-image img {
</span> across the screen, creating an endless loop for the width:100%;
</div> scrolling text. Remember to include all vendor prefixes height:auto;
for browser variations, including on the animation }
2. Second layer declaration in the scroller div. .overflow-hidden {
Below the above code, but within the wrapper, add the @keyframes scroll-left { overflow:hidden;
following divs and the image which will interact with the 0% { }
text. While it may seem like we are using a few transform: translate(0, -50%) .relative
superfluous divs, the CSS applied to each, with z-indexes } {
and positioning, will hold the entire construct together. 100% { position:relative;
<div class="scroll-container"> transform: translate(-50%, -50%) }
<div class="scroll-image"> }
<div class="overflow-hidden relative"> } 8. Third layer CSS
<img src="img/bg.jpg"/> The final layer, containing the front set of scrolling text, is
</div><!--overflow-hidden--> 6. Second layer CSS assigned the following values, not applied to the initial
</div><!--scroll-image--> Use padding to set the boundaries of the container text layer. A z-index to keep it at the front and a left value
</div><!--scroll-container--> which will hold both the image and the front text. Using that mirrors the padding of the image container, bring
the relative rem measurements will allow us to easily the text in line with that in the first layer.
3. Third layer match subsequent values on the front scroller later on.
The third layer represents the second set of text, which The scroll-image div is given a z-index value to keep it 9. Text colours
will scroll above the image. This should be placed below behind the front text. Finally we have come to the last step. Assign colours to
the image, within the three divs applied in the previous .scroll-container { the dark and light classes, so that each layer of text has
step. This should have a unique identifier, front. padding-left:8rem; the colour diferences which create the illusion of a single
<span class="scroller front"> padding-right:8rem; layer changing colour. A little piece of HTML sleight of
<span class="scrText light">These&nbsp;Are&n width:100%; hand has been pulled of.

HTML5 & CSS3 Genius Guide 175


ffe l
l o ia
r
ia c
tr Spe

Enjoyed
this book?
Exclusive offer for new
www.fullengineeringbook.net

Try
3 issues
for just
£5 *

* 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
Every issue is packed with step-by-step tutorials
for Flash, Dreamweaver, Photoshop and more
About In-depth features
the Discover the latest hot topics in the industry

mag 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 company’s 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
02 Once you have
logged in, you are
free to explore the wealth of
03 You can access
FileSilo on any
desktop, tablet or
04 If you have any
problems with
accessing content on
account with our secure content available on smartphone device using FileSilo, or with the
FileSilo system, log in and FileSilo, from great video any popular browser (such registration process, take a
unlock the bookazine by tutorials and online guides as Safari, Firefox or Google look at the FAQs online or
answering a to superb downloadable Chrome). However, we email filesilohelp@
simple question resources. And the more recommend that you use a imagine-publishing.co.uk.
about it. You can bookazines you purchase, desktop to download
now access the the more your instantly content, as you may not be
content for free accessible collection of able to download files to
at any time. digital content will grow. your phone or tablet.

www.fullengineeringbook.net

NEED HELP WITH


THE TUTORIALS?
Having trouble with any of the techniques in this bookazine’s tutorials? Don’t 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

www.fullengineeringbook.net
Tools & Techniques
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

Você também pode gostar