HTML5CSS3G3niusGuidevol3 PDF
HTML5CSS3G3niusGuidevol3 PDF
HTML5CSS3G3niusGuidevol3 PDF
NEW
Volume 3
HTML5
CSS3
The professional guide to programming
for web design and development
#FCD905
A comprehensive masterclass in
becoming an instant expert
Welcome to
Making a website is something that just isnt possible without the aid of HTML. It is
the basic framework of the World Wide Web and we rely on CSS to make the styling
consistent and easier to manage. In this new volume we ofer you the tools you need
to become a web design master. Within these pages you will learn the art of
responsive design and how it will only serve to make your websites more user
friendly, therefore more efective. Add pop-up modal boxes, integrate payments and
incorporate a plethora of dynamic animations that will add extra pizazz to your
designs. Take inspiration from the experts and recreate some of their more ingenious
ideas and ind out what works for you and your designs. You also have access to
FileSilo, where there is a wealth of free content online, just waiting for you to
download and use, as well as hours of video tuition to aid you in your completion of
the tutorials inside. Enjoy the book!
HTML5
CSS3
Publishing Director
Aaron Asadi
Head of Design
Ross Andrews
Edited by
Jen Neal & Fiona Hudson
Senior Art Editor
Greg Whitaker
Assistant Designer
Steve Dacombe
Printed by
William Gibbons, 26 Planetary Road, Willenhall, West Midlands, WV13 3XT
Distributed in the UK, Eire & the Rest of the World by
Marketforce, 5 Churchill Place, Canary Wharf, London, E14 5HU
Tel 0203 787 9060 www.marketforce.co.uk
Distributed in Australia by
Network Services (a division of Bauer Media Group), Level 21 Civic Tower, 66-68 Goulburn Street,
Sydney, New South Wales 2000, Australia Tel +61 2 8667 5288
Disclaimer
The publisher cannot accept responsibility for any unsolicited material lost or damaged in the
post. All text and layout is the copyright of Imagine Publishing Ltd. Nothing in this bookazine may
be reproduced in whole or part without the written permission of the publisher. All copyrights are
recognised and used specifically for the purpose of criticism and review. Although the bookazine has
endeavoured to ensure all information is correct at time of print, prices and availability may change.
This bookazine is fully independent and not affiliated in any way with the companies mentioned herein.
HTML5 & CSS3 Genius Guide Volume 3 2016 Imagine Publishing Ltd
ISBN 978 1785 462 603
Part of the
bookazine series
Contents
18
VR + THE WEB
92
Front-end
10
52
Stripe API
techniques
34
26
34
6 HTML5
Mac OS&XCSS3
Genius
Genius
GuideGuide
74
76
p5.js library
Developer
70
Genius Guide
132
60
Special effects
98
164
154
HTML5
Mac
& CSS3
OS X Genius Guide 7
10
18
26
30
34
38
42
46
20
tools you
need now
Get learning with these essential APIs and
specifications for contemporary practices
10 HTML5 & CSS3 Genius Guide
Genius Guide
2 Text to
speech API
Scenarios
Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
URL: bit.ly/1L5Hbpj
Scenarios
LISTENABLE BLOG POSTS
A great feature for the visually impaired, blog
posts that people can listen to would make
for a really compelling experience.
TURN-BY-TURN DIRECTIONS
Put your phone in your pocket and you can
then be audibly guided to your destination by
the browsers voice.
STEP-BY-STEP RECIPES
Sticky marks on touchscreens while weighing
out ingredients could be a thing of the past.
Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
43+
44+
N/A
8+
N/A
7.1+
WebSockets API
URL: mzl.la/1j9X55Q
Tools
Scenarios
REAL-TIME PROPERTY UPDATES
A forward-thinking estate agent implements
real-time property updates, providing an
ever-changing map of property to let.
REAL-TIME CHAT
WebSockets could make a reasonable
replacement for the aging IRC, enabling richer
media to be used in discussion.
SOCKET.IO
SOCKET.IO
Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
TORNADO
GITHUB.COM/TORNADOWEB/TORNADO
Python networking library and framework.
PLINK
DINAHMOELABS.COM/PLINK
31+
4.4 +
38+
8+
10+
7.1+
History API
URL: mzl.la/1KzFuKx
URL: mzl.la/1VafzyW
Browser Support
CHROME
FIREFOX
SAFARI
CHROME
FIREFOX
SAFARI
<video autoplay></video>
var video = document.
querySelector('video');
navigator.getUserMedia({
video: true,
audio: true
}, function(s) {
video.src = window.URL.createObjectURL(s);
video.play();
});
The DOM is queried for the video element. The script
then requests permission to capture video and audio
streams via the getUserMedia API. Finally, the stream
returned is given to the video element, which begins
playback in the browser.
URL: mzl.la/1iLRLWp
Parameters
CONSTRAINTS
Takes an object describing the stream constraints,
such as width, height, frame rate and more.
SUCCESSCALLBACK
If the request for a users media was successful, this
function is invoked and the stream is passed.
ERRORCALLBACK
If the request for media fails due to permissions, or
lack of sources, this function is invoked.
Browser Support
Browser Support
31+
38+
8+
GetUserMedia API
31+
38+
N/A
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
44+
38+
N/A
12+
N/A
Genius Guide
The MediaElement
interface allows the
developer to control
the playback of media.
Here the developer has
combined a play/pause
as one button rather
than having two
separate ones.
HTML5 VIDEO AND AUDIO HAVE PHASED OUT FLASH. ITS TIME
TO THINK ABOUT USING EMBEDDED MEDIA MORE CREATIVELY
The HTML5 Media API provides a standard JavaScript
API for interacting with the HTMLMediaElement
interface. HTMLVideoElement and HTMLAudioElement
are both children of the HTMLMediaElement and inherit
its properties.
Media Elements have properties for manipulating the
playback of media, including load, play and so on.
The scenarios for using this capability at first may
seem obvious. Any media that Flash would have been
used for before can now be done without browser
plugins but there are other benefits.
Its now easy to combine video and audio with other
HTML5 technologies such as Canvas for the production
of more engaging and grander interactive experiences.
Canvas lets developers manipulate video pixels and
apply bespoke efects.
Video thats more integrated with the surrounding
webpage is also now possible. The JavaScript interface
allows for play buttons to be separate from the traditional
video user interface, opening up brand new possibilities
for user experience designers to make use of.
Incorporating supporting animation to control
elements, such as expanding/revealing a video on a
button click, is now not only possible but also easy.
<video>
<source src="example.mp4" type="video/mp4"
/>
</video>
<button>Play</button>
var video = document.querySelector('video');
var button = document.
querySelector('button');
button.addEventListener('click', play,
false);
function play() {
if(video.paused) {
video.play();
} else {
video.pause();
}
}
First, DOM references are made to the video and button
elements. Then, a click handler called Play is then bound
to the button. The play function provides playing and
pausing functionality to the video by making use of the
HTMLMediaElement API interface.
Going on to build more advanced controls that
incorporate volume, seeking, playback speed and
tracking functions are all possible through the API. What
this means is that its much easier to bring a visual style
or brand to embedded media on the web than it ever
has been before.
Finally, the media element interface lets developers
create autoplaying media, giving rise to silent video as a
design element in a webpage or transparent media.
Scenarios
STANDARD VIDEO EMBED
Browser support for HTML5 media is so good
there really is no excuse for not using it as
standard for media embedding.
SILENT VIDEO
Use silent video instead of images to capture
human emotion and make emotional
connections with users.
HYPERREALITY
Shoot a video that contains very little
movement, but more than a photograph.
Hyperreal scenes can bring a page to life.
Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
4.1+
38+
8+
9+
7.1+
URL: mzl.la/1NM0jYk
Navigation
Timing API
function criticalRenderPath() {
var t = window.performance.timing;
// Converting to seconds
return {
interactiveAt: (t.domInteractive t.
domLoading) / 1000,
domContentLoaded:
(t.domContentLoadedEventStart t.
domLoading) / 1000,
complete: (t.domComplete t.domLoading) /
1000
}
}
This references the performance.timing metrics, then
determines the metrics for each stage in the critical
render path to provide stats on when the page was
10 User Timing
API
Network
Information API
Scenarios
ANALYSIS OF ANY GIVEN PAGE
The navigation timing API should be used as a
quick reference to determine the critical render
path of any webpage.
COMPARATIVE ANALYSIS
Store the performance timing results when
conducting a series of improvements as a
benchmark for subsequent tests.
URL: mzl.la/1KAJcV4
Browser Support
Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
4.1+
38+
8+
9+
9+
11 Page Visibility
API
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
12 Battery
13 IndexedDB
Status API
URL: bit.ly/1MIIXwN
URL: mzl.la/1Fu21wh
URL: mzl.la/UlVKw7
Browser Support
Browser Support
CHROME
FIREFOX
SAFARI
31+
38+
N/A
CHROME
FIREFOX
SAFARI
Browser Support
31+
38+
8+
CHROME
FIREFOX
SAFARI
N/A
44+
N/A
N/A
N/A
N/A
Browser Support
43+
38+
N/A
CHROME
FIREFOX
SAFARI
31+
38+
8+
Genius Guide
<div class="item"
draggable=true></div>
function dragStart(e) {
this.style.opacity = '0.6';
return false;
}
function dragEnd(e) {
item.classList.remove('dragging');
}
var i = document.querySelectorAll('.
item');
i.addEventListener('dragstart',
dragStart, false);
i.addEventListener('dragenter',
dragEnter, false);
i.addEventListener('dragover', dragOver,
false);
i.addEventListener('dragleave',
dragLeave, false);
i.addEventListener('drop', drop, false);
i.addEventListener('dragend', dragEnd,
false);
First the various functions are set up to handle events.
DragStart() reduces the opacity of the dragged
element. DragEnter() and dragLeave() manage
classes used to style the item when its colliding with
another item. Drop() stops all of the current event
propagation. DragEnd() ensures the class used to
style collisions is removed.
URL: mzl.la/1ENGVEq
Scenarios
MANAGING CALENDAR ENTRIES
Rather than editing specific times and dates
when managing a calendar, its much easier to
drag and drop appointments.
LIST SORTING
Sorting lists is better done with drag and drop
than the little arrow buttons that are sometimes
seen on older websites.
TASK PRIORITISATION
Prioritising tasks is an excellent use case for drag
and drop, which enables the swift reordering of
items.
IMAGE SORTING
Visual sorting is also useful. Being able to sort
images into two piles, such as suitable and
unsuitable, means that image organisation
could be vastly improved by drag and drop.
Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
N/A
38+
8+
8+
N/A
18 WebRTC Spec
CONNECTING DEVICES TO EACH OTHER
URL: mzl.la/1KAJDyK
Scenarios
SPREADSHEET APPLICATION
Spreadsheets can require an immense amount of
calculation if theyre large enough. Hand that
computation to another thread.
VIDEO ENCODING
Video encoding is an intensive computational
task and is not something that should be done in
the main thread.
Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
4.4+
38+
8+
10+
7.1+
17 Vibration API
URL: webrtc.org
URL: mzl.la/1j9YZDr
URL: mzl.la/1MIJ77B
Browser Support
CHROME
FIREFOX
SAFARI
Scenarios
window.navigator.vibrate(250);
This line of code will cause the device to vibrate for 250
milliseconds. If an array is passed to vibrate, it will vibrate
and then pause for every other argument.
Browser Support
31+
38+
8+
CHROME
FIREFOX
SAFARI
31+
38+
N/A
PEER-TO-PEER GAMING
Games designed without a centralised server can
use WebRTC to connect peers with low latency.
Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
44+
38+
N/A
N/A
N/A
Genius Guide
19 Web Components
Scenarios
MULTISITE EVENTS WIDGET
20 Shadow DOM
IMAGE CAROUSEL
Implement a carousel in a Web Component
and never write another carousel. Import the
old one that uses Custom Elements.
ACCORDION COMPONENT
You can turn any piece of markup into an
accordion by importing an accordion Web
Component and surrounding the item in a
Custom Element.
Browser Support
CHROME
CHROME FOR ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
41+
44+
N/A
N/A
N/A
N/A
Parameters
ELEMENT.SHADOWROOT
<style>
.directions-widget { ... }
</style>
<article class="directions-widget">
<header>
<h2>Directions to my house</h2>
</header>
<p>Turn left</p>
</article>
But with Shadow DOM, they can write this:
<article class="directions-widget">
<header>
<h2>Directions to my house</h2>
</header>
<p class="directions">Turn left</p>
</article>
</template>
<script>
var s = document.
querySelector('#directions').
createShadowRoot(),
t = document.querySelector('#directionsTempl
ate'),
c = document.importNode(t.content, true);
s.appendChild(c);
</script>
The presentation code here is now inside a template, so
it wont be rendered by the browser. The script at the
bottom clones the template to the Shadow DOM, with
the presentation initially intended.
<CONTENT SELECT=>
The content element used inside of the
Shadow DOM is an insertion point, only to be
used in Web Components
<SHADOW>
Much like the <content>, the <shadow>
parameter is also an insertion point but it can
also be used for older shadow roots on the
same shadow host.
Browser Support
CHROME
ANDROID
FIREFOX
SAFARI
EDGE/IE
IOS
31+
4.4+
N/A
N/A
N/A
N/A
URL: bit.ly/1WsX3nM
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 ?
Genius Guide
Jerad Bitner
Technical project manager
and VR enthusiast
Socialising
Were already connected with each other through
Twitter, Google+, Facebook, and other social networks.
Imagine logging in and walking around in these sites
with their own architecture and content with your
friends. Check out Beloola.com to get an insight into
one companys vision.
Relaxation
Wouldnt it be great to re-visit your most relaxing
vacation spot anytime you wanted? With capture
devices becoming ubiquitous in the form of mobile
phones, and lately 360 cameras, you may be able to
visit wherever you like from the comfort of your home.
Creation
VR is rapidly becoming a new and exciting medium for
artists, both young and old. For examples, see this
video of a classic Disney animator drawing in VR
(vimeo.com/138790270), and check out this
augmented reality colouring book for children
(youtube.com/watch?v=SWzurBQ81CM).
Exploration
So many countries, so little time. With 360 videos
being taken worldwide of some of the most beautiful
and remote places, you can now fully immerse
yourself into these places to make you feel like you are
really there.
5 VR
headsets
A LOOK AT SOME OF THE MAJOR
PLAYERS IN THE HMD MARKET
Virtual reality is currently nothing without a headset to
make the magic happen. There are various headsets in
various stages of development, but most are set to come
to the consumer in 2016. The big name in the world of
virtual reality is Oculus Rift, and Facebooks purchase of
Palmer Luckeys device means it will reach every corner
of the market. As with any new tech, the pleasure of
owning such a device will cost you dearly. But, the
budget option (less than 5) is already out there in the
shape of Google Cardboard. So go get your hands on
one now!
Oculus Rift
Samsung Gear VR
oculus.com/en-us/rift/
oculus.com/en-us/gear-vr/
VR COMES WITH A NEW SET OF EXPECTATIONS FROM USERS, AND TOOLS WITH WHICH WE
CAN CONNECT THEM TO OUR MEDIUM
Interfaces will no longer constrain themselves to
two-dimensional screens sitting on a desk. The screen
appears to disappear with a screen mounted to your
head. As you move your head there is new canvas
space available all around. The head-mounted display
gives a sense of depth and scale, and we can have
browsers and apps all around us.
Additionally we should consider how to organise
these apps in the space around us. Spatial organisation
of our UI components can help a user remember
where they can find things. Or it could degrade into the
nightmare desktop weve all seen with a massive clutter
of icons. But even then, our brains are capable of
making sense of that chaos.
Genius Guide
Google Cardboard
HTC Vive
Razer OSVR
google.com/get/cardboard/
htcvr.com
razerzone.com/osvr
Creating memorable
experiences
Create beautiful
scenes
A new shopping
experience
Advertising in VR is a whole new field, and
companies are just starting to wrap their minds
around the possibilities of connecting with their
intended audiences in a whole new way.
Advertisers and marketers have been trying
new ways of selling products for ages. One of the
basic principles of selling or marketing is making
the consumer identify on a personal level with a
product in order for them to want to buy it. Many
tactics are engineered and employed to get
people to buy things, but almost all of them come
down to this one over-arching goal of having a
person identify with the product.
VR could be a huge catalyst for achieving this
goal. Visiting a shop in virtual reality where you
can walk around the wares, see their size and
shape, hold them up with your virtual hands to
really identify the products dimensions, and even
obtain additional information through a display of
information attached to the product all of these
are possible. Or perhaps youre taken to a whole
new place when you pick up the object to
experience the use and operation of the product.
All of these are additional ways that a person can
identify with a product on a deeper level than a
two-dimensional representation allows.
There are some great examples of how VR is
being used in the commercial space. Trillenium
(trillenium.com) is just one of the many. They are
looking to bring the retail experience to shoppers
by creating virtual stores that allows users to
browse through shops as in real life.
WEBVR in
action
STANDARD EXAMPLES OF USING WEBVR FOR
CREATING VIRTUAL ENVIRONMENTS
Unity 3D
Blender
SketchUp
GearVRf
The GearVR framework (GearVRf) is an open source VR
rendering library for application development on
VR-supported Android devices. While many of the other
tools can export Android or iOS applications to use with
your phone, this is an Android native framework for
developing VR applications. You can dig into this one
more at gearvrf.org.
Three.js
This is a JavaScript library which works as a layer on top
of WebGL. It has many helpers and abstractions that
make working with WebGL much easier than the WebGL
API alone. WebGL is an OpenGL implementation within
modern browsers such as Chrome, Firefox, and Safari.
There are some excellent applications being developed
with Three.js which utilise 3D design to create anything
from fun demos, to multiplayer worlds and games.
Most WebVR implementations are built using Three.js
due to its ease of use and in part due to how popular
JavaScript has become. Doing 3D graphics in the
browser is hardly done without Three.js. Check out
github.com/borismus/webvr-boilerplate to get started.
Most browsers are still struggling with headset device
support, but theyre getting much closer to being
included in the main builds of modern browsers like
Genius Guide
SceneVR
scenevr.com
With multiuser support, this metaverse is built on Three.js
and NodeJS, with its own HTML-like markup.
INSPIRIT
Quake 3
mozvr.com/projects/inspirit
media.tojicode.com/q3bsp
Vizor.io
Vizor is an interesting take on a WebVR editor in your
browser built with NodeJS and Three.js. Its a visual
programming environment for WebGL, WebVR and
other HTML5 APIs. It features live preview, data flow
visualisation, network communication, publishing,
unlimited undo, and presets that can be used as modular
building blocks. Complex logic can be nested in
subgraphs and they can be rendered directly to a
specific render target, or simply used as a texture. Loops
are modelled as nested graphs that are evaluated once
per loop iteration. All within your browser. To give it a try,
head to vizor.io.
SceneVR
Scene is an open source platform built using WebGL and
Three.js for the client and NodeJS for the server side and
multiplayer component. With Scene you can create
virtual reality scenes using a simple HTML-like markup,
JanusVR
Janus is more like an actual web browser for VR than a
development tool. Its a platform in the way that SceneVR
is a platform, and while the client is closed source and
built in QT5, the server-side component is open source
and written in NodeJS. Janus has full Oculus Rift support
with avatars and some hand control via the leapmotion.
com Leap Motion controller. Virtual environments are
written in much the same way as a more traditional
website is created. An HTML-like syntax is used to set up
rooms with basic JavaScript support. As virtual
environments are just websites in Janus, you can serve
them up like a traditional site, using whatever server you
like, hosting it anywhere. Its distributed just like the web
of today.
Sharing the VR
experience
Many apps are built with VR in mind anything
from video games, increasingly implementing VR
support, to desktop apps that enable you to have
a VR desktop. While much of the UX and usability
side of VR is being explored, many of these
applications are already extremely compelling.
A great place to start is the Oculus Share site,
with hundreds of games and demos for VR already
in the making, and thats just for the Oculus Rift.
There are many more being created for your
browser in WebVR, and for Android and iOS
devices in their respective app stores.
You can also check out some exploration into
journalism with VR. Theres a great piece created
for LA Times on graphics.latimes.com/marsgale-crater-how-we-did-it/ which was created in
WebGL for WebVR. You can experience this in VR
using your phone and Google Cardboard, or
simply go to the website graphics.latimes.com/
mars-gale-crater-vr.
The countdown
to WebVR
Genius Guide
Essential VR
Resources
A COLLECTION THAT WILL
MAKE YOUR VR BETTER
WebVR Information
webvr.info
This is a convenient website that has lots of
links to information regarding the WebVR
specification, how to try it out, and how to
contribute to its formation. Its a great quick
stop for getting into the nitty gritty of the
idea behind WebVR and why.
James
Deeley
Creative strategy director at Amaze
Virtual Reality has attracted a lot of excitement and
buzz recently. Yet, for it to be around for the long
term, brands are going to have to start getting
smarter in how they use it, particularly if it is to avoid
being another gimmick. We all expect VR to have a
big future in gaming, and in immersive brand and
retail experiences, but to reach the everyday it will
also need to ofer something for the home and
contribute to the way in which we live our lives today,
and also tomorrow.
The smart approach is to see VR as a part of a
wider technology evolution, all built around the
Integrate payments
with the Stripe API
Learn how to develop a custom Stripe form into
an online web store and handle the Stripe API
with Node.js
E-Commerce is huge, and everywhere, no
retailer from before the time of the web hasnt
either felt its impact or been gobbled up by
web-born goliaths that have adopted their business
models for the internet era. E-commerce is also hard,
sure, you pay for things online all of the time, but the
credit card details arent going straight from us to the
service youre paying, often a payment gateway service is
used somewhere along the line to process your credit
card and pass along the information to the retailer that
you just made a purchase from.
If youre the owner of a small web store, or just want to
take payments for some reason or another on your own
website, integrating with one of these payment gateways
can be tough and complicated.
Fortunately for us, theres Stripe, a simple but powerful
API that allows us to process and receive monies from
card payments without too much hassle. In this tutorial,
youre going to take a demo web-store and implement
Stripe.js and the Stripe API into it.
<script src="https://code.jquery.com/
jquery-1.11.3.min.js"></script>
<!-- Add this -->
<script type="text/javascript" src="https://
js.stripe.com/v2/"></script>
<!-- -->
<script src="scripts/storeUI.js"></script>
8. Back to core.js
function init(){
store = new store_events;
Stripe.setPublishableKey('YOUR_TEST_
PUBLISHABLE_STRIPE_KEY');
}
<script src="scripts/core.js"></script
function init(){
store = new store_events;
}
This will create all of the event listeners youll need.
Genius Guide
<label>
<span>Card Number</span>
<input type="text" size="20" />
</label>
<label>
<span>CVC</span>
<input type="text" size="4" />
</label>
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" />
<span> / </span>
<input type="text" size="4" />
</label>
<input type="submit" value="Pay" />
</div>
</div>
</label>
<label>
<span>CVC</span>
<input type="text" size="4" datastripe="cvc"/>
</label>
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" datastripe="exp-month"/>
<span> / </span>
<input type="text" size="4" datastripe="exp-year"/>
</label>
<input type="submit" value="Pay" />
</div>
</div>
order_form.addEventListener('submit',
function(){
Stripe.card.createToken(order_form,
function(status, res){
if(status !== 200){
alert("Something went wrong. Sorry");
order_form.reset();
}
else
{
submitOrder(res.id, function(response){
store.closeForm();
store.showReceipt
(response.thingsBought);
});
}
});
});
Right now, if you add some items to the cart and enter
your card details into the form, the page will reload. you
need to prevent the submit event and work some AJAX
magic with Stripe to get the card details of in a usable
way. Add the following code to the addEvents function
of core.js. Using the Stripe.js library, send of the card
details the user has entered to the Stripe API to be
Store keys
Instead of switching keys every time you want to
deploy to your production environment, save
them as environment variables. One for your
development and one for your live platforms.
Left
product-id'),
price : thisItem.getAttribute('data-price')
});
payload.total += parseInt(thisItem.
getAttribute('data-price'));
}}
function submitOrder(){
if(token === undefined){ throw "No Stripe
card token has been passed"; }
var items = document.
getElementById('purchase_list').
getElementsByTagName('li');
payload = { items : [], total : 0 };
for(var g = 0; g < items.length; g += 1){
var thisItem = items[g];
payload.items.push({
productID : thisItem.getAttribute('data-
jQuery.ajax({
type : "POST",
url : window.location.origin + "/order",
data : {
order : payload,
stripe_token : token
},
success : callback,
error : function(err){
console.log(err);
},
dataType : "json"
}
)
;
Top left
stripe.charges.create
({
amount: price,
currency: "gbp",
source: card_token,
description: "Customer cheese order"
}, ...
Genius Guide
Why tokens?
So why are you using tokens
instead of just handling card
details ourselves? Surely you can
better look after our own
customers data? Well, no.
Security is hard, no matter how
hard you, as an individual try, its
unlike youll ever be able to
match the strength of security
ofered by an enterprise-level
payments platform. Stripes job
is to keep their API running and
their data safe, your job is to sell
delicious cheeses. Let these
guys take on the card stuf, its
what theyre really good at. On a
side note, say you do store card
details on your service and you
get hacked, youre liable for that
datas security, not only does it
suck being hacked, but if the
data was stored poorly, you may
be subject to legal action from
your customers. Ouch. Is it
worth it?
res.set(500);
res.json({
status : "ERR",
message : "Something has gone horribly
wrong"
});
}
else
{
res.json({
status : "OK",
thingsBought : itemisedItems
});
}
});
confirmed by Stripe the Node server sends a JSONencoded itemised list in its response. the helper library
thats been handling all of the store logic kicks in here
again. Once that the confirmation has finally been
received, it will reset and close the card details overlay
and if you pass the itemised list that the server sends
back, then it will generate a receipt to show the customer
what they have ordered. This will happen in the callback
you passed as part of the submitOrder function call, as
we have shown below:
submitOrder(res.id, function(response)
{
store.closeForm();
store.showReceipt(response.thingsBought);
Detecting fraud
Stripe uses machine learning algorithms to
detect potential fraudulent purchases. If you
know a payment was genuine you can tell Stripe
and theyll process the payment.
Remembering your
customers
In this tutorial, you generate a token for
each purchase you want to make, and
seeing as the tokens are single-use only, it
means that wed have to get the user to
enter their card details every single time
they want to buy something. That is going
to become a frustration for them very
quickly. So, how do you store card details
for the customer without storing card
details? The Stripe API allows you to create a
Customer object that you can associate
with card details by passing in the charge
token before you process a payment.
Though you can only use this token once to
make a charge, you can access the
customer any time you like and make a
charge to them without them ever having to
make a payment.
Master responsive
image techniques
Learn how to use <picture> and srcset, and bring art direction
to responsive images
Genius Guide
<img src="image.jpg"
alt="text for screen readers" />
img
{
max-width: 100%;
}
<img src="small.jpg"
alt="text for screen readers"
srcset="medium.jpg 600w,
large.jpg 1200w" />
<img src="small.jpg"
alt="text for screen readers"
srcset="medium.jpg 500w,
large.jpg 800w"
sizes="66vw" />
<img src="small.jpg"
alt="text for screen readers"
srcset="medium.jpg 600w,
large.jpg 1200w"
sizes="(min-width: 500px) 66vw,
100vw"
/>
Top left
<picture>
<source
media="(min-width: 500px)"
srcset="wideLarge.jpg 800w,
wideMedium.jpg 500w" />
<source
srcset="squareLarge.jpg 800w,
squareMedium.jpg 500w" />
<img src="fallback.jpg" alt="" />
</picture>
Comment sources
With so many diferent sources required for each
responsive image being implemented, it pays
dividends to write HTML comments to help keep
track of the images being sourced.
Top left
picture img
{
max-width: 100%;
}
<picture class="album">
<source
media="(min-width: 801px)"
srcset="wide1200.png 1200w" />
<!-- ... -->
<img src="fallback.jpg" alt="" />
</picture>
<source
media="(max-width: 800px) and (minwidth:501px)"
srcset="wide800.png 800w,
<source
media="(max-width: 500px)"
srcset="square500.png 500w,
square500-2x.jpg 2x" />
.album {
display: block;
width: calc(100% 40px);
margin: 0 auto;
box-shadow: #A39A9A 0 0 30px;
position: relative;
}
.album:before
{
Genius Guide
Picture explained
The ultimate goal behind
using things like srcset,
picture, sizes, source, and
media is to enable
designers and developers
to deliver the best possible
image for a given
environment, rather than
have a one-size-fits-all
image that scales
proportionately but will
look completely terrible at
the extreme ends of
viewport sizes.
Picture allows the build
team finite control over
what, how, and when any
given variant of an image
displays. Each source can
have a media attribute. Its
the media attribute that
controls when a source
should be used via a media
query. The srcset attribute
is then left to simply list out
the available variants for
the image in question
either in width descriptors
(eg 250w) or DPI
descriptors (eg 2x).
content: '';
position: absolute;
width: 100%;
height: 100%;
background:linear-gradient(...);
}
picture img {
border-radius: 3px;
}
picture {
border-radius: 3px;
}
picture:hover img {
opacity: 0.5;
cursor: pointer;
}
picture img {
-webkit-filter: contrast(1.25);
}
{
display: flex;
align-items: center;
justify-content: center;
}
body
{
margin: 0;
padding:0;
position: absolute;
height: 100%;
width: 100%;
background-color: #E1E4E2;
}
body
<head>
<script>
// Picture element HTML5 shiv
document.createElement( "picture" );
</script>
<script src="picturefill.js" async>
</script>
</head>
Create animated
infographics with
Snap.svg
Genius Guide
<style>
svg{
display: block;
margin: 0 auto;
background-image: url(bg.jpg);
}
</style>
3. Start up Snap.svg
After the CSS styling in the head section, script tags are
added with an onload function that detects if the page
has finished loading. Once the page has been loaded up,
two variables will be declared. One of these variables will
hold a timer that waits a fraction of a second before
starting the animation and another variable holds the
Snap SVG file.
<script>
window.onload = function () {
var timer;
var s = Snap(1280, 800);
};
</script>
<script src="js/snap.svg-min.js"></script>
6. More references
Notice that each line of the code shown below has the
variable that is then followed by the letter f. If you take a
look at Step 4s code, you will notice that the f included
there appears inside the brackets of the function, and all
of this code is in that function. The letter f simply stands
for file and it is a reference to the SVG file that we had set
to load from before.
header = f.select("#header"),
icons = f.select("#icons"),
base = f.select("#base"),
baseText = f.select("#baseText"),
Coding Snap.svg
Snap.svg uses JavaScript to manipulate the still
SVG images that you import into it. The code
adds animation and interactivity to the graphics
for a rich user experience.
Snap.load("scene.svg", function(f) {
//TUTORIAL CODE GOES HERE
});
Left
map = f.select("#map"),
people = f.select("#peopleBtn"),
chat = f.select("#chatBtn"),
burger = f.select("#burgerBtn");
s.append(f);
Animating scale
If you want to animate the scale of an image,
then SVG is the perfect graphic to scale as it is a
vector and it can be blown up in size without any
loss of quality.
Top left
baseText.animate({transform: "t0,-130"},850,
mina.backout);
base.animate({transform: "t0,-100"},550,
mina.backout);
map.animate({transform: "t0,-70"},450, mina.
backout);
Genius Guide
function thumbUp()
{
thumb.animate( {transform: "t0,-210"},800,
mina.easeinout, function() {thumbDown()} );
into the graphic and bounce onto the map. The pin was
made invisible in Step 9. Save your code and view it in a
browser to test the click.
function thumbDown()
{
thumb.animate( {transform: "t0,-160"},800,
mina.easeinout, function(){thumbUp()} );
}
chat.click(function () {
chatPin.animate({opacity:1, transform:
"t0,280"},900, mina.backout);
});
Right back at the start there was a menu that was made
invisible. Now lets make the burger icon a button that
can be clicked and this will bring the of-canvas menu
into the app. Add this code below, which will animate this
onto the screen. Then save this and try clicking the icon
in the browser.
burger.click(function () {
menu.animate({opacity:1, transform:
"t150,-70"},900, mina.backout);
});
chatPin.animate({opacity:0, transform:
"t0,0"},900, mina.backin);
pin.animate({opacity:0, transform:
"t0,0"},900, mina.backin);
menu.click(function () {
menu.animate({opacity:0, transform:
"t0,0"},900, mina.backin);
});
Build with
AngularJS
5 best
libraries
and tools
Start building
START WITH THE DATA, FIND APIS, READ THE DATA THAT THEY PROVIDE
AND THATLL GIVE YOU IDEAS
lodash.com
Lodash is a very useful utility library. It has an
extensive documentation and it does all sorts of
things for you. Lodash is focused on performance
so its a good idea to use it instead of some slower
AngularJS methods.
Angular UI
angular-ui.github.io
AngularUI is an amazing set of tools, frameworks
and even directives to help you build your Angular
apps faster.
UI Router
github.com/angular-ui/ui-router
UI Router is part of Angular UI and has become
the de facto routing framework that everyone
uses. Its much more powerful than ngRoute the
one provided by Angular. It allows you to manage
your applications interface by states bound to
named, nested and parallel views, providing a lot
of flexibility.
UI Bootstrap
angular-ui.github.io/bootstrap/
Another component of Angular UI is UI Bootstrap,
a very useful set of AngularJS directives that
mimics Bootstrap components. If you use
Foundation theres an unoficial port of UI
Bootstrap called Angular Foundation.
Genius Guide
Bootstrapping
ANGULARJS IS NOT BASED ON CONVENTIONS LIKE OTHER FRAMEWORKS
Rafa Garcia-Lepper
Lead front-end engineer
AngularJS is an amazing
framework for creating
data-driven SPAs. Working
with it is a lot of fun and I love
that it encourages me to
write better code.
Performance
IT CAN BE EASY TO MESS UP THE DIGEST CYCLE
Every model in AngularJS is represented as a $scope
object and these will make use of an array called
$$watchers, which can then be utilised to store
functions. Every single time that $watch is called or a
value is bound from the DOM (using ng-repeat, ng-class,
ng-show and so on) a
new function will be
stored in $$watchers.
Every single time that
one of these values in the
$scope object is modified,
the digest cycle will go
through the $$watchers
array and it will then run
all of the functions in it.
If any of the functions
in the array changes any
watched value in the
scope, then the cycle will
run again.
Security
ANGULARJS INTRODUCES SOME
RISKS WORTH NOTING
CSRF
If theres a cookie called XSRF-TOKEN, AngularJS will
recognise it and automatically convert it into a request
header X-XSRF-TOKEN. This will be sent on every request
sent by $http for the server to validate the token.
Using a data-service
ABSTRACT CRUD OPERATIONS INTO SERVICES SO THEY CAN BE ACCESSED
To communicate with
the backend, use a
factory, inject $http
and return an object
exposing all the
public methods.
Create a function
getExample to call
the service for the
data and wait for the
promise; next, set
the data and resolve
the promise.
Genius Guide
Models, controllers
and views
IF YOU ARE NOT FAMILIAR WITH THE MVC PATTERN THIS MIGHT BE
CONFUSING AT FIRST, BUT ITS A LOT EASIER THAN IT LOOKS
AngularJS is structured around data which should
bloating the controller by using $scope methods
come from services and you want to display
that would be better of in a factory.
your data in the views, so what you do is
If you do this, dont forget to capture
Avoid
use a controller. A controller is bound
this
into a variable like vm, which
ng-controller
to a view and the data model is
stands for View Model, so it doesnt
Ng-controller doesnt
represented as the $scope object.
change by context.
enforce one-to-one coupling,
The $scope object is accessible from
In the HTML you can display the
its not reusable and its not
the view so you can have any data
elements
in the model ($scope or
flexible. Attach a controller
by adding it to $scope.
vm), all by using double curly braces
to a template using a route
Its a good idea to avoid the $scope
like this {{vm.example}}. If you decide
definition or a directive.
you dont want to bother with the
object though and to use controllerAs
controllerAs syntax, $scope is implicit so that
syntax instead. ControllerAs binds this to
the $scope object which will help you to avoid
you can just use {{example}}.
Register functions
EXECUTE ASYNCHRONOUS OPERATIONS WITH PROMISES, CHOOSE THE
MOST APPROPRIATE TEST TOOL AND FIND OUT HOW TO ROUTE
Promises
Unit tests
End to end
Unit tests alone arent enough. If you really want to
minimise risks you will need to run end-to-end tests in
actual browsers. The AngularJS team provides a useful
NodeJS program called Protractor to run end-to-end
tests. It uses WebDriver for controlling web browsers and
simulating user interactions.
Running tests
Karma is framework agnostic and very configurable tool
provided by the AngularJS team to run tests. It works well
Services
LEARNING TO USE SERVICES IS
KEY TO MASTERING ANGULAR
In AngularJS there are services, providers,
factories and constants that create a lot of
confusion as they are all diferent types of
services. They are all singletons, so just use
factories, forget about the rest. One exception is in
the config block, where only providers are
allowed. Other than that, stick to factories.
Put in services any logic that could be shared
across the app. Then all you need to do when you
need some functionality is to inject it.
Dependency injection is a key feature of
AngularJS and its really nice to work with.
Make multiple small factories with one
responsibility each. Services can be injected into
other services so any functionality can be reused.
This is a really nice way of working; it will keep
your code clean and clearly defines the diferent
parts of your app.
Routing
Ideally your app should be organised by feature
modules, and every single module that needs a route will
also have its own module. When you are working with a
UI router, you will need to declare states instead of routes
a state may or may not have a route and you can also
nest states.
Declare the routes in the config block of each of your
modules and then inject $stateProvider and
$urlRouterProvider.
Use $stateProvider to declare the diferent states, and
$urlRouterProvider to declare the route alternatives. Give
a name to the state and pass an object with the diferent
parameters for it.
If you find that you need to do things in-between the
routes, then you can make use of the run block. You can
also create links to states in your HTML by first utilising
ui-sref as an attribute.
Use $stateParams if you need to access the
parameters of the routes, but keep in mind they are not
inherited by nested routes.
Its also a good idea to lint your code as a build task, and even
better to do it as a pre-commit Git hook
Genius Guide
4. Select device
Look at the play button in the top left of Xcode, just to
the right of it there should be a small icon with iPhone 4s
or something similar, click it and select iPhone 5s or
iPhone 6 (depending on your version of Xcode) from the
dropdown that appears and hit play.
5. Fix errors
If you get errors, the fix is simple. Click on the tabs
showing the error and select the first fix thats suggested.
Hit play and the app should run. The iOS simulator might
throw an error so select iOS simulator in the menubar
and click reset content and settings and hit play again.
This React Native project has one view, but we need two
views for this tutorial: one for listing our categories, and
another for viewing the photos in that category. Delete
everything in index.ios.js and insert the following in its
place to import the required modules for our project.
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
Image,
ListView,
TouchableHighlight,
NavigatorIOS,
View,
} = React;
var CatViewing = require('./catViewing');
var List = require("./list")
9. Stylings
Lets create a simple stylesheet. React doesnt use CSS, it
uses a JavaScript polyfill to emulate a limited subset CSS
with native components, and as such we define styles
like so. AppRegistery exposes our React class to our
native code, its our true entry point to the application.
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
Image,
ListView,
TouchableHighlight,
View,
} = React;
var cats = require("./cats"),
thumbCats = [];
var CatViewing = require('./catViewing');
just after that, were going to create the List class and all
of the functions that it will use to build our view:
Learn once,
write everywhere
Weve all heard of write once, deploy
everywhere but theres rarely an instance where
that actually works out. Facebooks suggested
philosophy is learn once, write everywhere.
Once youve learned React, you can write it for
any platform, rather than maintaining one
codebase that has to accommodate everything.
...
for(var key in cats){
thumbCats.push({
image : cats[key][0],
title : key
});
}
renderCatThumb : function(cat){
return (
<TouchableHighlight onPress={() => {this.
loadCat_egory(cat.title)}} underlayColor="rg
ba(0,0,0,0.1)">
<View style={styles.cell} >
<Image source={{uri : cat.image}}
style={styles.thumbnail} />
<ListView dataSource={this.state.dataSource}
renderRow={this.renderCatThumb}
style={styles.listView} />
</View>
);
},
<View style={styles.rightContainer}>
16. Rendering
var ds = new ListView.
DataSource({rowHasChanged: (r1, r2) => r1
!== r2});
return { dataSource: ds.
cloneWithRows(thumbCats),
};
...
<Text style={styles.title}>{cat.title}
Cats</Text>
</View>
</View>
</TouchableHighlight>
);
},
Is it honestly native?
Yes! Facebook have yanked out the JavaScript
engine from the WebViews and run it in a separate
thread. Your app logic runs in JS but everything
you see on the screen is completely native.
Top left
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
render: function() {
return (
<View style={styles.container}>
...
var catsToView = cats[category];
this.props.navigator.push({
title: category + " Cats",
component: CatViewing,
Genius Guide
JsCSS WAT?
Aligning objects on a
screen is a tough business,
just ask any iOS developer
whos done a lot of manual
positioning, it can be a
nightmare. Facebook
looked around for a
solution to aligning things
intuitively and it found
one, CSS! Problem is,
implementing CSS for iOS
was not a prospect they
fancied much, instead,
they opted to create a
JavaScript subset of CSS
styles that could be used
to position native iOS
elements in and around
native iOS views so it has
all the goodness of CSS
and JavaScript and full
speed of a native. One of
the coolest things about
JsCSS? It has Flexbox, not
the full Flexbox, but
something very close and
easy to use. Check out the
Facebook Developers
YouTube channel for more
information on React
Native bit.ly/1AK9zmZ.
passProps: {catsToView},
});
...
18. catViewing.js
With loadCategory() weve passed everything we need
to render our images, but where did we pass it to? What
about the CatViewing class were about to create in
catViewing.js? CatViewing works just the same as our list
class worked, except instead of being a ListView, were
using a ScrollView which gives us a little more flexibility
when it comes to how we lay content out. Add the
following code to catViewing.js to get started:
'use strict';
var React = require('react-native');
var
{
Image,
PixelRatio,
ScrollView,
StyleSheet,
Text,
View,
} = React;
var CatViewing = React.createClass({
render: function() {
},
});
module.exports = CatViewing;
render: function() {
var catsToShow = this.props.catsToView;
return (
<ScrollView contentContainerStyle={styles.
contentContainer}>
{catsToShow.map(createThumbRow)}
</ScrollView>
);
},
render: function() {
return (
<View style={styles.centering}>
<Image style={styles.imageHolder}
source={{uri:this.props.uri}} />
</View>
);
}
});
21. Finish up
Were almost ready to view all of our cats. If you refresh
the iOS simulator, we get a nice big error (we might even
crash Xcode!) because we havent added styles for the
Picture or CatViewing classes. But, thats simple, if we just
add the following after our Picture class closes, were all
done. Now we can take our Cat-alogue, and put it
wherever we want it to be.
Modernizr?
AFTER YEARS WITHOUT A MAJOR RELEASE, MODERNIZR 3 WAS PUBLISHED IN
SEPTEMBER 2015, JAM-PACKED WITH NEW FEATURES AND IMPROVEMENTS
Genius Guide
Whats new?
THE LATEST VERSION IS BIGGER AND BETTER. HERES WHY
up the more you use it, and keeps it working even if you
are ofline! The constant build also gives you the ability to
check on just how much bloat (or lack thereof) your build
has, with the compressed and uncompressed file size
listed on the left-hand side of the page at all times.
Remember that every byte you add, every single one of
your users has to download. Be kind to your network and
theirs keep it as small as possible. The site even has a
fully responsive design, allowing you to generate your
build or check the documentation on your mobile.
But having to go to the site to recreate the build every
single time you want to make a small change can quickly
become tedious and boring. Its 2015 robots should be
doing boring junk like this. That is why version 3 has
added new ways to integrate Modernizr into your build.
Patrick Kettner
Lead Modernizr developer
Thats it! Every time you run Bower or npm update, it will
check to ensure you have the latest and greatest version
modernizr --config config.json --dest
of Modernizr, complete with all bug fixes and
custom_modernizr.min.js
performance improvements. The only caveat to using
the download service is that if you ever want to add or
You dont have to generate the configuration by hand
remove detects from your build, you will need to either
grabbing the build URL that is included by default
update or remove the existing entry in your package/
in the header of all builds of Modernizr (like
bower.json. Since the new dependencies
modernizr.com/download?emoji) will
would mean you are using a diferent
Keep an eye
take you to a version with all of your
URL, you would end up with duplicate
detects, already checked. From there
on file size
versions of Modernizr in your project.
Its all too easy to bloat your
you can tap on the BUILD button
Code it forward
build by adding too many new
and grab the generated Command
So you have created your build of
features always remember to
Line Config. Using the above URL,
Modernizr, but now you have
keep an eye on the overall file
you get the following JSON file:
{
discovered that, horror of horrors, it
size to make sure your
"minify": true,
doesnt detect something you need!
website stays fast.
"feature-detects": [
How can you remedy that situation? The
"test/emoji"
Modernizr team has thought of this too, and
]
created generator-modernizr-detect. Yet another
}
nodejs package, generator-modernizr-detect is a plugin
for the popular Yeoman tool. It will ask you a few
The tool works in Windows, Linux, and OS X, and can be
questions to generate all of the scafolding you need to
integrated into any system that has the ability to call
...
create a new feature detect. Once you have created and
modernizr: {
command line programs.
added it to your site, go ahead and create a Pull Request
"parseFiles": true,
But maybe your builds dont ever change. Or maybe
on GitHub to share your discoveries with the rest of the
"customTests": [],
you just dont want to have you entire team install (or
Modernizr community. Most of the detects that are
"outputFile": "/my/awesome/project/
know how to use) the CLI tool. Cant there just be a way
maintained were contributed by folks outside of the
modernizr-output.js",
to download the prebuilt file? With Modernizr 3, there is!
project, many with little to no open source experience. It
"tests": [
is a great way to show of your research and knowledge
"emoji"
Npm and Bower, at your service
to a kind and caring community that helps power a huge
],
The days of downloading a script from a random place
chunk of the web.
"uglify": true
on the web have long since passed. We have proper
} ...
dependency management in the JavaScript world
Looking forward
Version 3 is far from the end. Since its release in
thanks to the likes of Bower and npm.
Since Grunt/gulp-modernizr searches for
September 2015, there have already been dozens of
One of the most frequent requests the Modernizr
references to the Modernizr detects, you
improvements, with many more to come. One of the
team has received is the ability to treat it like
almost never need to actually include
things that is quickly becoming the most requested is
any other JavaScript dependency, and be
the tests portion. If you ever want
support for new module syntaxes. Between npm, ES7s
installable via one of these package
Modernizr.on
to force the inclusion of certain
managers. But, due to its highly
Modernizr 3 adds the idea of
detects, you can always add them
modular nature, it was simply not
asynchronous feature detects.
to that array.
possible (let alone practical) to
Check out the Modernizr.on API to
If you really like the idea of the
publish every possible
react to feature detects that take
Grunt and gulp versions, but use
combination. It would require
some extra time.
one of the other build systems,
nearly a centillion individual
such as Broccoli, Brunch or Mimosa,
packages! That didnt stop the
you can get the same results by
Modernizr team instead of registering
creating a wrapper around the customizr
and maintaining that number of modules, it
npm package.
has created a Bower and npm download service.
Also created by Herrera, customizr is the abstracted
As a result, what this means is that, rather than
crawl-and-build mechanism that powers the Grunt and
install a hosted package from Bower or npm like you
gulp packages. If you prefer getting closer to the metal,
normally would do (eg bower install modernizr), you
and want to eschew the built-in automation of Grunt and
can go ahead and install directly from the same
gulp, Modernizr now includes a command line tool to
The new modernizr.com has a brand new look,
custom URL that is included by default in the header
help get stuf done.
and a ton of new features
of every Modernizr build.
Genius Guide
when you can use them. But today is not that day, and
tomorrow likely wont be either. Adding the latest version
of Modernizr to your project can save hours trying to
research and debug diferent ways to handle tiered
browsing experiences. Version 3 has added a ton of new
ways to easily integrate an updated version to your
existing toolchain. Whether you grab it from the website
as you always have, generate it via Grunt or Gulp, or
download a prebuilt version through npm or Bower via
the download service, Modernizr wants to make it as
easy as possible to stop worrying about cross-browser
issues, and start making the next amazing website.
.cssgradients .header {
background-image: lineargradient(cornflowerblue, rebeccapurple);
}
.no-cssgradients .header {
background: url("images/glossybutton.
png");
}
Working with JS
QUICKLY QUERY THE RESULTS OF ANY FEATURE DETECTS
if (Modernizr.awesomeNewFeature) {
showOffAwesomeNewFeature();
} else {
getTheOldLameExperience();
}
Version 3 adds a few of new APIs that you can leverage
on your code. Modernizr.on was added as a way to hook
into all of the new asyncronous feature detects. Since the
code you write may execute before the results of the
detect are known, you can register a callback to run once
Modernizr has finished.
Modernizr.on(videoautoplay,
function(supportsAutoplay) {
if (supportsAutoplay) {
//replace static image with video
}
});
if ( !(Modernizr.atRule(keyframes) ) {
// load JS powered animation lib
}
Modernizr.prefixedCSS is similar to the older Modernizr.
prefixed, but will return the (possibly) prefixed version of
a value in kebab-case rather than prefixeds camelCase
Modernizr.prefixed(backfaceVisibility)
webkitBackfaceVisibility
Modernizr.prefixedCSS(backfaceVisibility)
-webkit-backface-visibility
{
"classPrefix": "webdesignermag-",
"feature-detects": ["css/gradients"]
}
Now, rather than this
<html class=cssgradients>
you get this
<html class=webdesignermag-cssgradients>
One final change with the CSS in Modernizr 3 is the
no-js class. Previously, Modernizr would remove the
no-js class from the root element if it existed, and
then always add a js class. As of version 3, it will
continue to remove the no-js class unless the
enableJSClass option is false in your config. It will
also only add the JS class if a no-js class is found.
This lets you decide on whether or not a client has
enough JavaScript to really say it supports it.
Modernizr GitHub
source code
customizr
bit.ly/1IegIzt
bit.ly/1P6HFgh
bit.ly/1SikoG0
bit.ly/1LxUIzM
Front-end
52
60
66
70
74
76
80
84
88
92
Front-end
Genius Guide
5 new F6 features
New look
A11y friendly
Starter projects
Front-end
stronger to allow devs to build custom rows with any
number of columns they need. If a design needs a
four-column grid inside a five-column grid inside a
twelve, new mixins will make that super quick and easy.
Users can still use the mixins for almost every
component and rename the classes to match their
necessary names. This means developers can convert
presentational classes from prototypes to semantic
markup and not need to import those classes into their
final code. This has always been a great part about
Foundation with Sass, but the team is taking care to
make it even more powerful.
Finally, Foundation 6 will be ofering not only the CSS
versions and the regular Sass versions, but a souped-up
stack complete with a custom static site generator
named Panini to help flatten files into single HTML
documents. Devs can spin up a browser sync server
with tons of ways to optimise code with UNCSS and
UglifyJS. This is the same stack ZURB uses to build for
their client work and they are making it available for the
first time to the Foundation community.
Motion UI
Genius Guide
Imran Oozeerally
Doug Macklin
Nick Pettit
Barclays
Team Treehouse
Prototype to production
THE TENETS OF FOUNDATION 6
Foundation for Sites 6 is aimed at helping people get
their projects from prototype to production. To make
sure every decision was working towards that goal, the
Foundation team came up with specific tenets that
include the following:
Prototyping in Foundation 6 should...
s Get me running with minimal dependencies, but
give me tools that modern sites need.
s Be able to rapidly produce a proof of concept in
code with easily readable presentational classes.
s)BWFBCBTFTUZMFUIBUJTBTVOPQJOJPOBUFEBTUIF
wireframes were replacing them with.
s(JWFNFBDPNNPOSBOHFPGQMVHJOTUIBUDBOCF
easily configured without writing JavaScript.
Production in Foundation 6 should...
sBe able to easily streamline code by using Sass
mixins to create semantic classes.
s-FUNFRVJDLMZQBSFEPXOUIFTUSFBNMJOFEJMFTJ[F
by selectively importing the components I used.
s#FTUZMFEUPNBUDINZDVTUPNEFTJHOTXJUIPVUUIF
need to override code or change tons of variables.
Yeti launch
The hassle-free
setup it provides is
unparalleled
Front-end
Foundation.MediaQuery
This utility library has a few helper functions such as
Foundation.MediaQuery.
atLeast('breakpointString');
as well as an event emitter that triggers when a
breakpoint is hit.
Foundation.util.swipe.js is a file in the JS folder that
adds a swipe event emitter to jQuery elements. We will
Foundation.Motion.animateOut($element,
animationClass, function(){
//optional callback
//do stuff
});
This file is dependent on another helper file: foundation.
util.animationFrame.js,
which has one function to utilise hardware acceleration
to improve animation efects. This will be called with:
};
Plugin.prototype._events = function(){
//add event listeners
};
//add logic functions here \/...
Plugin.prototype.destroy = function(){
//remove event listeners
//remove elements from the DOM
Foundation.unregisterPlugin(this);
};
Foundation.plugin(Plugin);
These are the non-optional methods for each plugin, and
naming conventions should be followed (otherwise
Foundation._reflow() wont work!). Everything else is
completely up to you.
Now that we know how to start a plugin, we can build
our Tind...er, Card Swiping plugin, for succinctness and
humour, were going to call it Swipin. We know how to
build the skeleton of a plugin already, so lets look at the
_init function in detail.
Swipin.prototype._init = function(firstTime)
{
this.$element.addClass(this.options.
containerClass);
this.$cards = this.$element.find('.' +
Foundation.util.triggers.js is an event listener/
this.options.cardClass);
emitter helper file. This listens for click
if(this.options.hasDetail &&
firstTime){
Custom
events on:
[datathis._makeModals();
columns
close="idOfThingToClose"],
}
You can use the gridcolumn
[dataif(this.$element.find('.' +
function in order to create a
open="idOfThingToOpen"],
this.options.
column class with a custom size:
[databtnContainerClass).length){
@include gridtoggle="idOfThingToToggle"]
this.options.hasBtns = true;
column(4 of 5) makes an
as well as listening for any other events
}
80%wide column.
if(!Foundation.MediaQuery.
you may want to tap into.
atLeast(this.options.unstackOn)){
Next up is foundation.reveal.js. We want
this._stack();
details for our little image-filled cards, so lets
}
programmatically create some modals that will open
this._events();
when we click or tap on our cards. Reveal has its own
};
dependencies as well, including foundation.util.
Foundation.Move(timeOfAnimationInMS,
$element, function(){
//apply animations/transitions here.
});
new Foundation.Reveal($element);
and add a few elements within them.
That covers the basic components were going to
need, so lets see how a plugin is built. The basic
structure of each and every JS-based plugin is this:
Swipin.prototype._makeModals = function(){
var _this = this,
Genius Guide
$modals = $modals.add(reveal.$element); //
modal = '<div class="reveal" data-reveal></
we dont need the elements, so $modals is
div>', //declare our reveal markup
a temporary variable
closeBtn = '<button class="close-button"
});
aria-label="Close alert"
$(document.body).append($modals);// attach
type="button"><span>×</span></
them to the DOM all at once.
button>', //utilize a Foundation helper CSS
};
class close-button
lorem = '<p>This is just some lorem ipsum
Now we have our modals, they are attached to the
for this tutorial</p>'; //and generate some
DOM, and they have open and close triggers applied to
generic text for the sake of this lesson.
them, thanks to our handy triggers library. Next, check
var $modals = $(); //create an empty jQuery
out the _events function. It manages triggers from
collection, well need that in a minute
media query changes and applies event listeners to our
this.reveals = []; //save our shiny new
cards. It will need to delegate some tasks to helper
modals to our current plugin, we need that
functions, but well leave those out for brevity.
too!
Swipin.prototype._events = function(){
this.$cards.each(function(){ //iterate
var _this = this;
through all our cards
$(window).on('changed.zf.mediaquery',
var $card = $(this),
function(){
imgSrc = $card.find('img').attr('src'), //
_this._handleMQChange();
since each card has an image, grab the src
});
attr
if(this.stacked){
id = this.id || Foundation.
this._addSwipe();
GetYoDigits(6, 'card-detail'), //
}
we need an id for our triggers
this.$cards.off('click.zf.swipin
Responsive
utility functions, so lets
tap.zf.swipin')
typography
make one. GetYoDigits gives
.on('click.zf.swipin tap.zf.
Change the values in the
you a psuedo-random string.
swipin', function(e){
$headersizes variable in
reveal = new Foundation.
_this._handleClick(e,
order to create responsive
Reveal($(modal).attr('id',
$(this));
typographic scales that change
id)),//generate our modal
});
to adapt themselves to a
for this card
};
variety of diferent
$closeBtn = $(closeBtn).
Here, were applying a listener to the
screen sizes.
attr('data-close', id); and
window, for media query events, and
update our close button with the
adding the click handler for our cards. Since
data-close attr for our triggers utility
we only add the swipe listener when the cards are
$card.attr('data-open', id);
stacked, lets take a look at our card markup, CSS, and
reveal.$element.append($closeBtn, '<img
stacking logic.
src=" + imgSrc + "/>' + lorem);//append
The markup:
our elements to the modal we just created
<div class="row medium-up-3" data-swipin>
_this.reveals.push(reveal); // and save our
<!-- this data attribute is what foundation
new modals to their proper place
looks for to initialize your plugin -->
<ulclass="menu"id="menuBar"data toggler=".
expanded">
<li><ahref="#">One</a></li>
<li><ahref="#">Two</a></li>
<li><ahref="#">Three</a></li>
<li><ahref="#">Four</a></li>
</ul>
<p><adata-toggle="menuBar">Expand!</a></p>
<div class="column card"> <!-- repeat as
many of these as you like -->
<div class="thumbnail">
<img src="http://placehold.it/450x650">
<div class="button-group expanded">
<a class="button tiny alert">No Thanks</a>
<a class="button tiny success">Yes Please</
a>
</div>
</div>
</div>
</div>
The Sass:
.swipin {
position: relative;
top: 50px;
.thumbnail .button-group {
margin-bottom: 0;
margin-top: .25em;
Front-end
.button {
border: 1px solid #FEFEFE;
border-radius: 0px;
}
}
}
.is-stacked .column {
position: absolute;
left: 0;
width: auto;
transition: transform .5s ease;
transform: scale(0.6) translate(0px, -30%);
}
.is-stacked .column:first-child {
transform: scale(1) translate(0px, 0);
}
.is-stacked .column:nth-child(2) {
transform: scale(0.9) translate(0px, -10%);
}
.is-stacked .column:nth-child(3) {
transform: scale(0.8) translate(0px, -20%);;
}
.is-stacked .column:nth-child(4) {
transform: scale(0.7) translate(0px, -30%);
}
$(this).css('z-index', '')
.find('.' + _this.options.btnClass).show();
});
this.$element.removeClass('is-stacked')
.trigger('unstacked.zf.swipin');
this.stacked = false;
};
While our cards are unstacked we get:
Swipin.prototype._unstack = function(){
var _this = this;
this.$cards.each(function(){
this.$cards.off('swiperight.zf.swipin
swipeleft.zf.swipin')
.on('swiperight.zf.swipin', function(e){
e.preventDefault();
_this._swipe($(this), 'Right');
}).on('swipeleft.zf.swipin', function(e){
e.preventDefault();
_this._swipe($(this), 'Left');
});
Which calls this:
Swipin.prototype._stack = function(){
var counter = this.$cards.length,
_this = this;
this.$cards.each(function(){
$(this).css('z-index', counter)
.find('.' + _this.options.btnClass).hide();
counter--;
});
this.$element.addClass('is-stacked')
.trigger('stacked.zf.swipin');
this.stacked = true;
};
};
Because the whole card has an event listener, we
need to see if one of the buttons was clicked, and if it is
then we will stop propagation so our event doesnt
bubble to our [data-open] listener and open our modal. If
it wasnt a button though, lets allow that modal to open.
Our swipe listener will look like this:
Swipin.prototype._handleClick = function(e,
$card){
var $target = $(e.target),
isBtn = $target.hasClass(this.options.
btnClass);
if(isBtn){
e.stopImmediatePropagation();
var isYes = $target.hasClass(this.options.
yesClass);
this.dismissCard($card, isYes, this.options.
animOut);
}
.hinge-in {
@include mui-hinge(
$from: right,
$fade: true,
$duration: 0.25s,
$timing: easeInOut
);
}
.hinge-out {
@include mui-hinge(
$state: in,
$from: right,
$fade: true,
Swipin.prototype._swipe = function($card,
dir){
var isYes = dir === 'Right';
this.dismissCard($card, isYes, 'slideOut' +
dir);
};
And this dismisses our card with the slideout animation
to the left or right. This function, is the bread and butter
of this whole plugin. We wanted to make two common
user interactions, click buttons and swiping right or left,
and combine them in a responsive way with a
recognisable layout.
Swipin.prototype.dismissCard =
function($card, isYes, animOut){
var trigger = (isYes ? 'yesplease' :
'nothanks') + '.zf.card',
idx = this.$cards.index($card),
_this = this;
Foundation.Motion.animateOut($card, animOut,
function(){
$card.trigger(trigger, [$card]).remove();
if(_this.options.hasDetail){
_this.reveals[idx].destroy();
}
});
};
$duration: 0.25s,
$timing: easeInOut
);
}
Lastly, in
plugin.js
, replace the references to
Genius Guide
Responsive emails
GET ALL-SCREEN FRIENDLY
Brandon Arnold
Foundation Lead, ZURB
We wanted to learn how people actually used
Foundation, so we travelled around the world and
hopped on hundreds of calls to actually watch how the
community used the Framework and discussed what
they needed from it. It was amazing!
<row>
<columns large=8 small=4>
</columns>
<columns large=4 small=8>
</columns>
</row>
A better solution than this:
<table class="row">
<tr>
<td class="wrapper">
<table class="six columns">
<tr>
<td class="expander">
</td>
</tr>
</table>
</td>
<td class="wrapper last">
<table class="six columns">
<tr>
<td class="expander">
</td>
</tr>
</table>
</td>
</tr>
</table>
<row>
<columns large='6' small='12'>
</columns>
<columns large='6' small='12'>
</columns> </row>
Front-end
Is your
content
king?
Content-led design is the future. Get ready for
your brand to succeed with a seven-step plan
Genius Guide
Natasha Spice
Designer at Folk
@natashalindblum
airbnb airbnb.co.uk
Airbnbs content courses through the site. Belonging is everything, so
customers feel at home anywhere in the world.
Warby Parker warbyparker.com
Everything feels like part of a whole. Consumer empowerment, the
cool but not over-the-top previews. Shame theyre stateside though.
Hatchet + Bear hatchetandbear.co.uk
Homely, rustic, unique Hatchet + Bear know themselves. They
understand consistency of personality, which is why theyre always
out of stock.
Go Pro gopro.com
Go Pros genius hinges on cleverly showcasing its users footage
throughout the site experience its marketing that makes itself.
General Electric ge.com
By creating content linked to vision, the story General Electric tells
goes from boring to brilliant, fostering genuine community and
action around a greater cause.
HTML5 & CSS3 Genius Guide 61
Front-end
Getting
started
THE BASICS OF A KILLER CONTENT
STRATEGY, IN LINE WITH YOUR
BRAND VISION
So, youre about to design a website. Hold it. First, we
need to hail back to the old school and draw up a
scenario to really think about the process.
Case study
ASOS
asos.com
Sitemapping
Before you start writing any content, or drawing up any
designs, youll need a comprehensive map of the pages
you need, an idea of what theyll contain, and how theyll
interact with each other.
A logical sitemap enables you to maximise your user
experience; to see the bigger picture ahead. It also
makes it infinitely easier to delegate content generation
tasks to freelancers when youve got every item of detail
listed out. Moreover, the impact of call to actions can be
clearly distinguished for an excellent site journey with
admirable click-rates. This same concept is true when it
comes to actually designing each page and page
Genius Guide
Plot an effective
analysis
You need a solid understanding of a number of
things in your competitor analysis. This ranges
from homepage meta descriptions and tone of
voice, to content themes, objectives, and how
efective these appear to be. When youre
confident in this, you can plot it and put this to use.
Youll need to select two scales, set against axes,
eg in a cross-section of cosmetics brands,
sustainability/technology vs. fun/professional. Put
an X for each brand studied according to how they
fare on these scales. Once youve plotted eight to
12 Xs, youll notice a significant gap in this
spectrum. Thats the flavour your content needs to
have to secure a space in the market.
Front-end
Youll
never get it
straightaway
Genius Guide
to
Desktop vs mobile Nine
Follow
SHOULD CONTENT DIFFER FROM DESKTOP TO MOBILE? YES. ABSOLUTELY
50.3%
49.7%
Content Strategy
for the Web
contentstrategy.com
@BrainTraffic
Written by Kristina Halvorson and Melissa Rach,
this is one of the best books about content
strategy available today. It gives so much
information and many tips to make what could be
a complicated process very simple, and it gives
some totally solid reasons to share with clients
about why its best to get the content parts sorted
first above all else. Its a manual that provides you
with the knowledge to deliver meaningful and
efective content when and where its most
relevant to your clientele. It also helps you
understand processes, teaches you to make better
decisions and plan for the long term.
Alistapart
@alistapart
For people who make websites some fantastic
resources and authors.
Ian Lurie
@portentint
Ian provides great tips for optimising everything to do
with web and design.
Jonathon Colman
@jcolman
The content strategist at Facebook shares his
thoughts and insights about everything you do.
Kristina Halvorson
@halvorson
Author of one of the most useful books on content
strategy, Content Strategy for the Web, Christina
knows her stuf.
Melissa Rach
@melissarach
The co-author of Content Strategy for the Web,
regularly posts about the latest content case studies.
Melissa describes herself as a content nerd.
Contents magazine
@contents
A digital magazine dedicated to the art of content
strategy & online publishing. It hasnt been updated
since 2013 but still divulges some must-know topics.
We Live Content
@welivecontent
This account shares timely and useful resources for
content marketers and content strategy professionals.
Something new appears daily.
Karen McGrane
@karenmcgrane
Karen is an experienced content strategist who on a
good day makes the web more awesome. She is also
the author of Content Strategy for Mobile.
Front-end
Genius Guide
1. Download files
The ZIP file provided on FileSilo for this tutorial contains
all the assets that we will be using along with a basic
boilerplate setup. Were going to use an npm package
called http-server to serve our files.
.aspect[data-ratio="1:1"] {
max-width: 100%;
height: 0;
padding-bottom: 100%;
overflow:hidden;
background: rgb(211, 22, 22);
color: #fff;
}
.aspect-content {
margin: 20px;
}
6. Add imagery
Working with images in aspect ratios is tricky. We want
the image to scale, but we dont want to distort it. With
this in mind, we will need to write markup that enables us
to crop it if necessary.
4. Harder ratios
Using 4:3 is a little more complicated because we have to
do some maths to figure out this ratio. The way to
calculate how much padding you need to give an
element is by dividing the height by the width and
multiplying by 100. So for example we would use in this
case: 3 / 4 = 0.75 * 100 = 75.
.aspect[data-ratio="4:3"] {
max-width: 100%;
height: 0;
padding-bottom: 75%;
background: rgb(223, 28, 66);
overflow: hidden;
color: #fff;
}
The content inside any given aspect box will look bad if it
sits flush against the edges of the box. We can get
around this by giving a margin to the .aspect-content div,
which should wrap all written content in a given box.
.aspect {
position: relative;
}
.aspect img {
max-width: 100%;
Compress images
The images provided in this tutorial are
uncompressed they weigh 4MBs each. Images
can be compressed in Photoshop with the save
for web dialog or an npm module like imagemin.
Left
The image weve put in is far too large. Lets make it fit
our page better
Top left
This is what you should see when serving the files from
the start-here folder
Front-end
position: absolute;
right: 0;
bottom: 0;
z-index: 0;
}
.aspect-content {
z-index: 1;
position: relative;
}
.directions .aspect-content {
width: 100%;
Avoid styling
Large images with CSS styles on (like opacity)
can take longer to render which makes
animations slow. Try avoid applying styles to
images and instead animate simpler elements.
Top left
height: 100%;
margin: 0;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}
.directions .aspect-content {
color: rgb(55, 55, 55);
background-color: rgba(255, 255, 255, 0.83);
transition: all .5s cubic-bezier(0, 1.14, 1,
1);
}
.directions:hover .aspect-content {
background-color: rgba(47, 47, 47, 0.8);
color: #fff;
}
.directions img {
transition: opacity .5s cubic-bezier(0,
1.14, 1, 1);
}
.directions:hover img {
opacity:.5;
}
<div class="one-half">
<a href="#directions" title="Directions to
event" class="directions">
<div class="aspect" data-ratio="2:1">
<!-- -->
</div>
</a>
</div>
.one-half {
width: 50%;
float: left;
}
<!-- Nesting to get quarters! -->
<div class=one-half>
<div class=one-half>
</div>
</div>
Genius Guide
Changing aspect
ratio sizes
Unfortunately, aspect
ratios dont work across all
screen resolutions so
when we go responsive
we may actually end up
with a bad looking UI.
There are a few options
available to us to fix this
problem: write JavaScript
to group the elements
diferently under diferent
.one-half boxes, write
JavaScript to modify the
data-ratio attribute as
required or write CSS to
change up the aspect
ratios themselves.
These diferent
approaches all have pros
and cons. The upside of
using this pure CSS
solution is that it performs
really well across all
devices, but it also means
that you have elements
which say that they are 1:1
but in reality they will have
many diferent aspect
ratios as and when the
page resizes.
{
1:1
<div class="one-half">
<a href="#sponsors" title="Sponsors"
class="sponsors">
.sponsors .aspect:after {
content: '';
width:13px;
height:20px;
background-image:url('./img/arrow.png');
position:absolute;
right:20px;
bottom:20px;
transition: right .5s cubic-bezier(0, 1.14,
1, 1); }
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
Genius Guide
2. Open sketch.js
After installation, the app is usually extracted. The main
code for our project will be found in sketch.js this is a
function setup() {
// put setup code here
}
function draw() {
// put drawing code here
}
createCanvas(windowWidth, windowHeight);
background(0);
smooth();
4. A new function
background(0);
translate(windowWidth/2, windowHeight/2);
function drawEllipse() {
noFill();
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
Front-end
7. Rotate again
Now as the drawing point is 200 pixels out from the
centre of the screen, p5 will draw an orbit around that
point but first it will rotate again here. The whole drawing
will be scaled but it will also be based on a sine wave
that modulates between 1 and 1 so that the result is a
very organic shape.
rotate(radians(i*3));
scale(map(sin(radians(i*6)), 1, 1, 0.5,
1), map(sin(radians(i*3)), 1, 1, 0.5,
1));
var
var
var
var
var
var
scaleX;
scaleY;
min;
max;
radius;
r, g, b;
drawEllipse();
pop();
}
scale(map(sin(radians(i*scaleX)), 1, 1,
min, max), map(sin(radians(i*scaleY)), 1,
1, min, max));
Top left
scale(map(sin(radians(i*scaleX)), 1, 1,
0.5, 1), map(sin(radians(i*scaleY)), 1, 1,
0.5, 1));
r = random(255);
g = random(255);
b = random(255);
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!
stroke(r, g, b, 28);
function mouseMoved() {
if (mouseX < (windowWidth/3)){
r = random(255);
//r = map(mouseY, 0, windowHeight, 0, 255);
}
//r = random(255);
r = map(mouseY, 0, windowHeight, 0, 255);
radius = 150;
translate(0, radius);
background(0);
fill(0, 25);
rect(0, 0, windowWidth, windowHeight);
Front-end
Code 3D zoom
effects with CSS
As seen on scholzandfriends.ch/de
Menu overlay
The burger icon will
reveal the menu. Clicking
this brings a full-screen
overlay so that the menu
can be navigated.
Zooming 3D effect
As the images move at
different speeds, they
create an effective effect
that looks as though the
camera is moving.
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
Genius Guide
Producing content for the image slider in the site requires a fresh approach,
almost every site on the web has featured content displayed at the top of the
site. To show off Scholz & Friends, a zooming effect was used on the images to
freshen up the dated parallax look.
Mark Shufflebottom, professor of Interaction Design
Technique
1. Creating 3D zoom effects
To create some of the 3D zoom efects found on the
Scholz & Friends site, create a new HTML document and
add this code to the body. This will display two images on
the webpage.
<div id="wrapper">
<img src="img/bg.jpg" id="bg">
<img src="img/fg.png" id="fg">
</div>
2. Wrap them up
Now create style tags in the head section of the
document and add the CSS rule for the wrapper. This
holds both images and centres them on the page. As the
images zoom in, the overflow is set to hidden.
@-webkit-keyframes back {
from {transform: scale(1);}
to {transform: scale(1.2);}
}
5. No prefix code
Newer browsers that dont require the vendor prefix
should also be catered for, so here is the code for those.
Its slightly smaller because it doesnt have -webkit- in
front. Notice the keyframes have the label back which is
picked up in Step 3s code.
@keyframes back {
from {transform: scale(1);}
to {transform: scale(1.2);}
}
6. Foreground image
#bg {
position: absolute;
-webkit-animation-name: back;
-webkit-animation-duration: 6s;
-webkit-animation-fill-mode: forwards;
animation-name: back;
animation-duration: 6s;
animation-fill-mode: forwards;
}
4. Add keyframes
Safari, Chrome and Opera use the webkit prefix on CSS
so here the keyframes are added. As you can see the
#fg {
position: absolute;
bottom: 0;
left: 100px;
-webkit-animation-name: fore;
-webkit-animation-duration: 6s;
-webkit-animation-fill-mode: forwards;
EXPERT ADVICE
Controlling CSS keyframes
As the 3D zooming parallax efect is the focus of this
site it can be reproduced using HTML and CSS alone
without any JavaScript. This is down to the use of CSS
keyframes, which enable us to specify how something
will look on frame one and in the final frame of
animation. The duration is also controlled in seconds
as opposed to milliseconds in JavaScript.
CSS keyframes normally loop, so in the workshop
the animation takes place over six seconds and the
default would be for it to start again and loop through.
There are some commands that enable us to control
exactly what happens with the keyframes and they can
be set to play in reverse, play just once, loop a certain
number of times or play back and forth.
Using the animation fill mode, the keyframes can be
set to forward, meaning they play once and hold on the
final frame of animation. Set this to backward and they
will play in reverse order. Change this to both and it will
double the duration, playing it forward and backwards.
Using the animation iteration count, the amount of
times it loops can be controlled. This will reset on the
first frame of animation so be careful of your content
jumping back to the start.
animation-name: fore;
animation-duration: 6s;
animation-fill-mode: forwards;
}
8. First keyframes
The foreground keyframes animate two diferent
properties at once. They increase the scale and move the
image slightly to the left, this helps to give a 3D efect as
this zooms in more than the background to make it look
like its in front.
@-webkit-keyframes fore {
from {
transform: scale(1);
left: 100px;
}
to {
transform: scale(1.4);
left: 40px;
}
}
9. Final keyframes
Add the last keyframes to the CSS and then save the
document. Opening this in your web browser will show
you the efect running over six seconds and you will see
the foreground and background moving separately to
complete this 3D zoom efect.
@keyframes fore {
from {
transform: scale(1);
left: 100px;
}
to {
transform: scale(1.4);
left: 40px;
}
}
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
Genius Guide
1. Get started
First, declare the main HTML page structure, including
the head and body section within the HTML page. We
will need a content container made from a div element
with an ID called container to control page content flow.
2. Content overview
With the main layout elements in place, we can insert the
main content inside the container element. The page will
have a descriptive title and introduction text to provide
the main overview of the information contained on the
3. Option navigation
Next insert the available options that will provide the user
with access to additional information. These options will
be regular <a> links contained inside a <nav> container.
Unlike regular <a> tags that use their href to link to
external pages, these <a> links will link to ID components
on this page using a # symbol in their href attribute
preceding the ID name being linked to.
<nav>
<a href="#alpha">Alpha</a>
<a href="#bravo">Bravo</a>
<a href="#charlie">Charlie</a>
<a href="#delta">Delta</a>
<a href="#echo">Echo</a>
</nav>
<article id="alpha">
</article>
<article id="bravo" data-transition="left">
</article>
<article id="charlie" datatransition="right">
</article>
<article id="delta" data-transition="zoom">
</article>
<article id="echo" data-transition="fade">
</article>
Multiple transitions
Use data attributes to enable multiple transitions
to be defined that can be easily added to
individual modal boxes without having to
overcomplicate your CSS.
Left
Front-end
9. Options container
html,body{
display: block;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
html,body{
font-family: "Trebuchet MS", Helvetica,
sans-serif;
background: rgb(21, 34, 47);
}
#container{
display: block;
width: 1000px;
height: 100%;
background: #ccc;
margin: 0 auto 0 auto;
padding: 1em;
}
Top left
nav{
display: block;
padding: 1em;
border: 3px solid #000;
margin: 2em 0 2em 0;
}
nav
a {
display: inline-block;
padding: 1em;
margin-left: 1em;
font-size: 1.5em;
border: 3px solid #fff;
background: #333;
color: #fff;
}
nav
a:hover{
border-color: #333;
background: #fff;
color: #333;
}
article{
display: block;
position: fixed;
z-index: 9999;
left: 25%;
top: 100%;
width: 40%;
height: 50%;
padding: 2em 5% 0 5%;
border-radius: 1em;
background: #000;
color: #fff;
overflow: auto;
}
article{
padding-bottom: 1em;
Genius Guide
:target {
visibility: visible !important;
left: 25% !important;
top: 25% !important;
width: 40% !important;
height: 50% !important;
opacity: 1 !important;
}
[data-transition="fade"]{
left: 25%;
top: 25%;
opacity: 0;
visibility: hidden;
}
[data-transition="left"]{
left: -100%;
top: 25%;
}
[data-transition="right"]{
left: 100%;
top: 25%;
}
[data-transition="zoom"]{
visibility: hidden;
left: 50%;
top: 50%;
width: 0;
height: 0;
opacity: 0;
}
article [data-button="close"]{
display: block;
float: right;
background: #c00;
color: #fff;
border: 3px solid #fff;
border-radius: 1em;
padding: 1em;
text-decoration: none;
}
article [data-button="close"]:hover{
background: #fff;
color: #c00;
border: 3px solid #c00;
}
img{
display: block;
float: left;
height: 100%;
}
article img{
margin-right: 1em;
}
article img{
display: block;
float: left;
height: 100%;
}
Front-end
Genius Guide
1. Get support
Service Workers arent supported everywhere yet, and
wont be for a while. So the first step whenever dealing
with new APIs is to do an existence check. Tools like
Modernizr make this easy for trickier APIs, but Service
Workers are quite simple to check for without it
navigator.serviceWorker.register('/sw.js')
// .register() is async, and it
// returns a promise
.then(registration => {
// we're installed!
}).catch(err => {
// there was some kind of error
})
3. Use Promises
Service Workers are completely asyncronous, and so
they use Promises everywhere. Promises are a new-ish
browser API that makes it easier to reason about async
code. If you havent brushed up on them before now, it
would be a great time to do so all new async APIs will
be based on them.
functionReturningAPromise()
.then((result) => {
// All Promises have a `then` method
// where can do something with the
// result of the function
}).catch((e) => {
// Always make sure to define a catch
// on your promise, otherwise you
// won't know if there was an err
})
self.addEventListener('fetch', ev => {
ev.respondWith(
caches.match(ev.request)
.then(response => {
return response || fetch(ev.request)
})
)};
4. HTTPS only
Lets encrypt!
Left
Front-end
7. Add responses
You may have noticed that we never actually added to
the Cache. Since Cache is not the same as the
browsers HTTP cache we have to manually add the
responses as they come in. You may only want to do
this for only certain items, though, otherwise none of
your REST calls would ever update!
return cache.addAll([
'/logo.svg',
'/fallback.jpg',
])
});
)
})
9. Fallbacks failing
In our app, we are going to load a number of images,
and on slow connections, they may take a long time to
load. We can add a fallback to the fetch call that we just
made, so that we can show our default image rather
than an empty spot.
return fetch(ev.request)
.then(response => {
cache.add(ev.request);
}).catch(err => {
// reply with the precached image
return cache.match('/fallback.jpg')
})
let cL = document.body.classList
let toggle = () => {
// add the class hideSearch to the
// body tag when nav.onLine is false
cL.toggle('hideSearch', !navigator.onLine)
}
window.addEventListener('online', toggle);
window.addEventListener('offline', toggle);
caches.match(request)
.then(response => {
if (response) return response;
if (request.url.match('/article/') &&
!navigator.onLine) {
// if the request isn't cached and we
// are offline, serve this instead
cache.match('/crossword.html')
}
)})
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
source: caniuse.com
Genius Guide
if ("applicationCache"
in window) {...
Here is the tricky bit app
cache is added through the
manifest attribute on a
HTML element:
<html manifest="cache.
appcache">
But you cant add the manifest
attribute via JS it has to be
there on page load. We get
around this by creating a blank
page that only has the
manifest, then add it here via
an iframe:
// sw.js
self.onmessage = (message) => {
// the string passed to the worker
// exists on the `data` prop
let msg = message.data;
console.log('msg from the DOM ' + msg)
}
// index.js
navigator.serviceWorker
.controller.postMessage('HELLO WORLD!')
event.waitUntil(
caches.keys().then((names) => {
return Promise.all(
names.map((name) => {
caches.delete(name);
})
);
})
);
})
Front-end
Model a unique
mobile 3D interface
Build an augmented menu that hooks into the mobiles device orientation
controls to create a bespoke browsing experience with three.js
Genius Guide
<script src="js/three.min.js"></script>
<script src="js/DeviceOrientationControls.
js"></script>
<script src="js/CSS3DRenderer.js"></script>
<script>
var camera, scene, renderer;
var circle1, circle2;
position: [ 0, 512, 0 ],
rotation: [ Math.PI / 2, 0, Math.PI ]
},{
function init() {
camera = new THREE.PerspectiveCamera( 75,
window.innerWidth / window.innerHeight, 1,
1000 );
controls = new THREE.
DeviceOrientationControls( camera );
scene = new THREE.Scene();
var sides = [{
url: 'img/scene-right.jpg',
position: [ -512, 0, 0 ],
rotation: [ 0, Math.PI / 2, 0 ]
},{
url: 'img/scene-base.jpg',
position: [ 0, -512, 0 ],
rotation: [ Math.PI / 2, 0, Math.PI ]
},{
url: 'img/scene-front.jpg',
position: [ 0, 0, 512 ],
rotation: [ 0, Math.PI, 0 ]
},{
Overlapping sides
The skybox cube is really 1024 pixels by 1024
pixels but it has been set to display at 1026 by
1026 so that there is a slight overlap in all of the
sides, as CSS 3D transformations are not as
accurate as WebGL.
url: 'img/scene-left.jpg',
position: [ 512, 0, 0 ],
rotation: [ 0, -Math.PI / 2, 0 ]
},{
url: 'img/scene-top.jpg',
Left
Looking towards the floor shows the area that will contain
an interactive Google Map later in the tutorial
Front-end
url: 'img/scene-back.jpg',
position: [ 0, 0, -512 ],
rotation: [ 0, 0, 0 ]
}];
var cube = new THREE.Object3D();
scene.add( cube );
for ( var i = 0; i < sides.length; i ++ ) {
7. Icon images
Now that the background is in place, our attention will
turn to creating icons that will sit in front of that. Another
3D CSS transforms
Anything can be displayed in the 3D scene that
can be displayed on a regular webpage, such as
video, maps, text and images, because the scene
is all controlled with CSS 3D transforms.
Top left
object.lookAt( vector );
scene.add( object );
}
Genius Guide
cssObject.position.y = -400;
cssObject.rotation.x = -Math.PI/2;
scene.add(cssObject);
animate();
}
init();
</script>
function animate() {
requestAnimationFrame( animate );
circle1.rotation.z += 0.001;
circle2.rotation.z -= 0.002;
controls.update();
renderer.render( scene, camera );
}
body {
background-color: #ffffff;
margin: 0;
cursor: move;
overflow: hidden;
font-family: helvetica, arial, sans-serif;
}
The size of the pictures is set here using the width and
height properties. Without this the image icons are just
too big on the screen, but its useful to have the images a
little bigger as most mobiles and tablets have high-pixel
resolution screens. Save the file and place on a server
then connect with your mobile device.
Front-end
Create an interactive
mobile 3D interface
Part two of our tutorial takes an augmented menu that uses the mobiles device
orientation controls and adds interaction to create a fully working site experience
Genius Guide
2. Content panels
There are going to be four content panels in the project
these will appear when the user clicks on one of the
icons in the menu inside the 3D scene. Add the code as
weve below to the body of the page just above the script
tags. This creates a top bar section and an area for text.
3. Panel details
You can fill the text with your own content or even
images. You may notice that there is a strange code in
the link tag, this is actually the code to create the three
lines of the burger icon for the menu button. This will
take the users back to the 3D menu screen.
Positioning above
The new panels added in this tutorial are
positioned on a z plane above the background
CSS panels so that they appear in front of the 3D
scene as 2D panels.
4. Panel power
The panels are constructed from regular HTML elements
and will be hidden from the site using CSS. Then linking
up the CSS Animate code when the user selects the
Left
The 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
Front-end
6. Responsive srcset behaviour
Save the HTML document for now and open the project.
css file from the CSS folder. Add on the code in the next
few steps to style the content in the panels appropriately.
The first content merely creates the generic style for all
of the panels that place this above the other content on
the page.
.hidden{
display: none;
}
.visible{
display: block;
}
allows for the head section to have the right height for
both of those elements.
.head{
height: 45px;
}
.head a {
display: inline-block;
float: left;
width: 10%;
padding: 10px 0 0 10px;
text-decoration: none;
}
Top left
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
.head h2{
display: inline-block;
width: 70%;
margin: 0;
padding: 7px 10px 0 0 ;
float: right;
text-align: right;
}
p{
padding: 5px 10px;
}
Genius Guide
background: #714c6e;
}
#info3 .head a{ color: #eed8ec; }
#info3 p{ color: #584356; }
function fade1(){
var change = document.getElementById(
'info1' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');
}
function fade2(){
var change = document.getElementById(
'info2' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');
}
function fade3(){
var change = document.getElementById(
'info3' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');}
function fade4(){
var change = document.getElementById(
'info4' );
change.classList.remove('bounceInLeft');
change.classList.add('bounceOutLeft');
}
Front-end
Genius Guide
this to load the CSS stylesheet and JS code. This lets the
resources to be reused by other pages if required.
3. Page container
Use the <body> section to contain the visible content. We
start this by placing the <main> page container inside the
body; this will be used to allow the controlled layout of
the content. Your page title and introduction content will
go inside this.
4. Fullscreen: controls
The controls to access the full-screen elements are
placed as content inside the <main> container element.
Each of these items have a [data-screen] attribute that
stores the element ID of the item to open.
$ = function(cssRule){
return document.querySelector(cssRule);
}
$$ = function(cssRule){
return document.querySelectorAll(cssRule);
}
5. Fullscreen: elements
Some elements will be displayed directly in full-page
mode. These elements are to be added to the content
inside the <main> container. We add a selection of
images that will be selectable, as well as a number of
iframe pages with class=fullscreen to be called on later.
2. Load resources
6. Fullscreen: containers
8. JS full-screen activation
Our example will use a single function to activate any of
the full-screen presentation of the elements passed to it.
This allows the control of full-screen requests to be
managed from one place, with it being easy to upgrade
later if this is required.
Left
Front-end
function fullscreen(element){
if(element.requestFullscreen) {
element.requestFullscreen();
} else if(element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if(element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if(element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}
function fullscreen_exit(){
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
Top left
}
}
});
window.addEventListener("load",function(){
var screenTriggers = $$('[data-screen]');
for(var i=0; i<screenTriggers.length; i++){
screenTriggers[i].addEventListener("click",f
unction(){
fullscreen( $('#'+this.getAttribute("datascreen")) );
});
}
});
window.addEventListener("load",function(){
var screenTriggers = $$('[dataaction="exit"]');
for(var i=0; i<screenTriggers.length; i++){
screenTriggers[i].addEventListener("click",f
unction(){
fullscreen_exit();
});
}
html,body{
background: #000;
padding: 0;
margin: 0;
font-family: monospace;
height: 100%;
}
main{
display: block;
width: 75%;
margin: 10% auto 0 auto;
background: silver;
padding: 1em;
}
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.
[data-screen]{
display: inline-block;
padding 1em;
font-size: 2em;
background: #333;
color: #fff;
transition: background-color 1s;
-webkit-transition: background-color 1s;
}
[data-screen]:hover{
background-color: #777;
}
.fullscreen [data-action="exit"]{
display: block;
width: 100%;
height: 5%;
background: #c00;
color: #fff;
transition: background-color 1s;
-webkit-transition: background-color 1s;
}
.fullscreen [data-action="exit"]:hover{
background-color: #fff;
color: #c00;
}
.fullscreen iframe{
display: block;
width: 100%;
height: 95%;
}
width and height are set for when the elements are later
displayed in full-screen mode avoiding the need to
repeatedly define this under the diferent browser vendor
full-screen selectors.
.fullscreen{
display: none;
width: 100%;
height: 100%;
}
.fullscreen:-webkit-full-screen{display:
block;}
.fullscreen:-moz-full-screen{display:
block;}
.fullscreen:-ms-fullscreen{display: block;}
.fullscreen:full-screen{display: block;}
.fullscreen:fullscreen{display: block;}
h1{
text-decoration: underline;}
Developer
98
116
Developer
be a
code master
We reveal the core techniques for the library, integration
with ES6 and cheat sheets for easy referencing
Genius Guide
Daniel Jenkins
Development lead
JQuerys easy-to-understand
syntax allows me to introduce
experience-enhancing features on
websites quickly and efficiently that
work across multiple web browsers
and devices.
Developer
selectors
$(selector)
Attributes
& CSS
.attr()
api.jquery.com/all-selector/
api.jquery.com/attr/
api.jquery.com/innerHeight/
Gets the height of first matched
element, This will include the
padding as well but does not
include the border.
.innerWidth()
.class
Browser
Events
.innerHeight()
.resize()
api.jquery.com/resize/
Binds event handler on resizing.
event
preventDefault()
api.jquery.com/class-selector/
.data()
api.jquery.com/innerWidth/
api.jquery.com/data/
Store data associated with
matched element or return the
first matched elements.
.prop()
.outerHeight()
api.jquery.com/prop/
api.jquery.com/outerHeight/
.scroll()
api.jquery.com/scroll/
#id
api.jquery.com/id-selector/
Selects a single element with the
given id.
selector1, selector2,
selector3
bit.ly/1Cs2xEX
Selects the combined results of all
the specified selectors.
api.jquery.com/event.
preventDefault/
If this method is called, then the
default action of the event will not
be triggered.
.load()
.val()
api.jquery.com/val/
.outerWidth()
api.jquery.com/load/
api.jquery.com/outerWidth/
bit.ly/207g9md
.addClass()
element
api.jquery/ready/
api.jquery.com/addClass/
.width()
api.jquery.com/width/
bit.ly/207gbdS
.css()
ancestor descendant
bit.ly/1PPT039
api.jquery.com/css/
.offsetParent()
.on()
api.jquery.com/on/
Attaches an event handler for one
or more events.
.trigger()
api.jquery.com/trigger/
.position()
.blur()
api.jquery.com/position/
api.jquery.com/blur/
Binds to the form Blur event.
.removeClass()
.hasClass()
:first
api.jquery.com/hasClass/
:last
api.jquery.com/removeClass/
api.jquery.com/last-selector/
.scrollLeft()
api.jquery.com/offsetParent/
api.jquery.com/first-selector/
.ready()
.change()
api.jquery.com/change/
Binds to the change event handler.
api.jquery.com/scrollLeft/
:first-child
.toggleClass()
bit.ly/1LXfv4A
api.jquery.com/toggleClass/
.focus()
api.jquery.com/focus/
Binds or triggers to the form
Focus event.
Genius Guide
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';
</module>
//jquery.js
module.exports = {
$ : jQuery()
}
This module pattern would enable jQuery to remove
the method $.fn.extend() and allow plugin developers to
still hook into the jQuery core.
ES6 controversially introduces classes, constructors
and extend into the language something back-end
developers will rejoice about. Regardless of opinion the
new inheritance model could be put to good use with
jQuery becoming class-based, with plugins extending
the base jQuery class.
Developer
JQuery provides a
multitude of helpful
functions, that should have
been included in JavaScript
from day one
Matt Leach
Head of development, Thinking Juice
Progressive enhancements
JQuery was initially introduced to enhance the world of
web development and, like all open source eforts, to
enhance the framework users experience. In the real
world these enhancements can be measured by trivial
$(#contact).addClass(sent);
The jQuery method has enabled this functionality in
minimal code for working across multiple browsers.
Now try writing that in native JavaScript:
document.getElementById(contact).
classList.add("sent");
Now this is nearly double the length and works in
modern browsers, looking back to older versions of IE
this would cause an error. To ensure cross-browser
compliance look at this code (and its length):
var d = document.getElementById("contact");
d.className = d.className + " sent";
One line of code may sufice if the project only uses
JavaScript for this single action loading in a library
Genius Guide
5 jQuery features
you need to know
METHODS THAT ARE WELL
WORTH USING
.promise()
You can use this method to
return a Promise object to
observe when all actions of a
certain type that are bound to the
collection, regardless of whether
it is queued or not, have
finished.
.ajaxSetup()
api.jquery.com/jQuery.ajaxSetup/
This little-known method allows variables to be
predefined for all AJAX requests. For example
using a defined URL route for all requests in an
application could be set via:
$.ajaxSetup({
url : /requestMe
})
.grep()
api.jquery.com/jQuery.grep/
Grep is a Unix command and jQuery provides
this as a helper that is great for searching
through arrays for specific values.
would then be overkill. JQuery gives developers a set of
tools that keeps all levels focused on the end goal.
Deadline-driven development
Deadlines, much like taxes, are unavoidable in most
walks of life, and a day-to-day occurrence. Known for
causing many a grey hair, working smart can make the
approach much more bearable. Its all too common to
see more junior developers looking at a current project
or application and then announce Hey, we should
rewrite that in this cool framework. This doesnt mean
they are incorrect and their enthusiasm shouldnt be
rewarded, but taking on board a new library has to be
carefully considered. It needs to ensure a return on
investment whether thats personal or financial. There
will be companies pushing products live with a new
library, built by a freelance resource that their internal
developers cant support. In a development team, at
crunch time, everyone will be expected to help and
chances are nine out of ten developers in the team will
be able to help iterate on any code wrote in jQuery. If
written in the cool framework the resource pool may
be slightly smaller. When starting any project be aware
that at some point in the future, other developers will
have to support it.
$(.btn).addClass(in-use);
$(.btn).attr(disabled, true);
$(.btn).data(used, true);
JQuery provides a smart developer the ability to chain
these methods, using the prototype inheritance model (a
paradigm widely used JavaScript):
$(.btn).addClass(in-use).
attr(disabled, true).data(used,true);
.closest()
api.jquery.com/closest/
This method traverses upwards from the
current DOM element to a documents root
element. It accepts a jQuery object as an
argument and if included when traversing,
jQuery returns the first matching element.
.holdReady()
JQuery provides a multitude of helpful functions, that
should have been included in JavaScript from day one.
Replicating functionality that other languages contain
from the outset, a lot of very similar libraries exist purely
to fulfil these tasks. Many JQuery utility methods are a
secret toolset that a lot of developers dont mention
frequently.
The jQuery library may not be the fastest or the
lightest but a community of thousands can continue
producing interfaces in an ever-changing world of
technology. Being a good developer isnt about being
an early adopter its about writing well-formed code that
works when required, whilst knowing the tools to get
the best out of the platform.
api.jquery.com/jQuery.holdReady/
This is a relatively unknown method that holds
or releases the .ready() function. Use cases for
this may seem far-fetched, but there can be
times where the DOM is ready but other
functionality should happen first.
$.holdReady( true );
$.getScript( "myplugin.js", function()
{
$.holdReady( false );
});
$.merge()
api.jquery.com/jQuery.merge
Developers used to PHP (array_merge) will
recognise this as a fast way of merging two
arrays this neat helper provides functionality
that native JavaScript doesnt provide.
Developer
Advanced jQuery
REGARDLESS OF EXPERIENCE, THESE ADVANCED METHODS OF ARE DEFINITELY WORTH CHECKING OUT
Filters
Utilities
Deferred
Object
AJAX
.eq()
inArray()
api.jquery.com/eq/
bit.ly/1MgB8c6
deferred.always()
api.jquery.com/jQuery.ajax/
api.jquery.com/deferred.
always/
jQuery.isArray()
jQuery.ajaxSetup()
jQuery.ajax()
.filter()
bit.ly/1GvAzz8
api.jquery.com/filter/
deferred.done()
.jQuery.
isEmptyObject()
bit.ly/1Nyv0zh
.first()
.has()
api.jquery.com/first/
Reduces the set of matched
elements to the first one that is in
the set.
api.jquery.com/deferred.
done/
jQuery.isFunction()
api.jquery.com/jQuery.
isFunction/
api.jquery.com/jQuery.get/
api.jquery.com/deferred.
notify/
jQuery.getJSON()
api.jquery.com/jQuery.
getJSON/
jQuery.isNumeric()
deferred.progress()
api.jquery.com/jQuery.
isNumeric/
api.jquery.com/deferred.
progress/
jQuery.getScript()
api.jquery.com/is/
jQuery.makeArray()
api.jquery.com/jQuery.
makeArray/
deferred.reject()
.is()
bit.ly/1GIgIMT
api.jquery.com/last/
jQuery.merge()
api.jquery.com/jQuery.
merge/
deferred.resolve()
.map()
api.jquery.com/deferred.
resolve/
jQuery.now()
.slice()
jQuery.parseHTML()
api.jquery.com/slice/
api.jquery.com/jQuery.
parseHTML/
api.jquery.com/map/
api.jquery.com/jQuery.now/
Returns a number representing
the current time.
bit.ly/1RdOJVI
.on()
api.jquery.com/on/
.last()
jQuery.get()
Loads data from the server using a
HTTP GET request.
deferred.notify()
api.jquery.com/has/
Reduces the set of matched
elements to those that have a
descendant that matches the
selector or DOM element.
api.jquery.com/jQuery.
ajaxSetup/
.trigger()
api.jquery.com/jQuery.
getScript/
Loads a JavaScript file from the
server using a GET HTTP request,
then executes it.
.load()
api.jquery.com/jQuery.load/
deferred.
resolveWith()
api.jquery.com/deferred.
resolveWith/
jQuery.post()
api.jquery.com/jQuery.post/
Loads data from the server using a
HTTP POST request.
Genius Guide
1. Relying on $(document).ready(); the browsers cache, which would reduce bandwidth and
Including JavaScript in the <head></head> tags and then
page-load time.
waiting for jQuery to run when the DOM is fully loaded
3. Faster selectors
can cause the end user a headache-inducing wait.
With the introduction of CSS preprocessors, its become
Executing JavaScript code when the browser has loaded
a bit of an issue with overly specific CSS declarations yet
the complete DOM is in itself inherently dificult and
with jQuery we find the opposite happening. Look at
troublesome. Each browser tells JavaScript when the
this navigation code:
DOM is ready at a diferent time and jQuery has a
<ul id="navigation">
helpful method .ready() that does a
<li><a class="nav-item"
The
multitude of things in the background to
href='#home'>Home</a></li>
$var syntax
ensure the DOM is loaded before firing.
<li><a class="nav-item"
Use the dollar $var syntax to
JavaScript is a blocking script
href='#about'>about</a></li>
let others know its a jQuery
meaning when the browser finds
<li><a class="nav-item"
object. If the variable is in the
the <script> tag it wont do anything
href='#contact'>contact</a></
correct scope, then jQuery will be
else until that code has loaded in.
li>
able to access the element
Any assets, photos, CSS and other
</ul>
without having to search for
JavaScript files, wont execute until
<script>
the DOM again.
this file is loaded. Its considered best
$('.nav-item').click(function(){
practice to place all JavaScript assets in
//code to scroll to location
the footer as JavaScript should enhance a
})
page, not build the UI. If code is required to execute
</script>
when all assets in the webpage are ready, it would be
The lack of specificity here means that jQuery has to
convenient to do this:
traverse the whole DOM to find .nav-item on big pages
The code doesnt get executed until the whole DOM is
this can reduce performance greatly. Its like going
ready large images slow down the time from page load
shopping and having to look at every item in the shop to
to the JavaScript firing.
//code//
find a specific item. You can increase performance by
(function($) {
increasing selector specificity:
//fire code
})(jQuery);
Initialising any functions this way enables the JavaScript
to execute when its possible. The end user will see the
page being usable sooner perceiving a faster load time.
If specific code needs to ensure a certain element is
completely loaded before being executed, use .load():
$(img).load(function(){
//execute code
})
<head>
<script src='/jQuery.js'></script>
</head>
For every new visitor to a website they have to download
this file from the server, which slows down the initial page
load and introduces an extra drain on bandwidth.
Reference jQuery from a CDN and the chances are that
when someone visits the website, they will previously
have visited a website that hosts jQuery with that CDN
(Google for example) and already have jQuery stored in
<ul id="navigation">
<li><a class="nav-item"
href='#home'>Home</a></li>
<li><a class="nav-item"
href='#about'>about</a></li>
<li><a class="nav-item"
href='#contact'>contact</
a></li>
</ul>
<script>
$('#navigation .nav-item').
click(function(){
//code to scroll to location
})
</script>
$('#navigation').addClass('visible');
//execute other code
$('#navigation').removeClass('visible');
Every time jQuery wants to alter the navigations class
attributes, it has to traverse the whole DOM and find the
element with the id #navigation, alter its class then
continue processing the next line of JavaScript. Each
time the $(selector) is used, jQuery has to look for this
element in the DOM. Assign the jQuery $(selector)
object to a variable increases performance, as a
reference to that element is now available in memory.
$('.changeHeight').animate({
'height' : 250
}, 650);
Developer
discove
r the top jquery add - ons for
m ak i
ng you
ience
r websites and apps A bet ter exper
Expert speaks
Tam Hanna works with Symbian
software products and a variety of
coding languages. He reveals the best
plugins for powering up jQuery
Genius Guide
Tweak Photos
<body>
<div id="editor-window"></div>
<script type="text/javascript">
$("#editor-window").imageEditor({
'source': '/img/demo.jpg',
"maxWidth": 500,
"onClose": function () {
}
});
</script>
</body>
Manage UIs
bit.ly/1GK1Ub7
Tree views provide a way to manage complex user
interfaces: if options are grouped up, the UI
appears less daunting at first glance. EasyJSTrees
tree structures start out as a group of list tags,
which are then spruced up by invoking the
easytree() method on the mother element.
Pop-up dialogs
bit.ly/1MWNFGr
Palm OS graced developers with the popup: a
complex modal dialog which could be invoked to
get a result. Prompt21 obviously was inspired by
the golden oldie. Invoke the popup after calling the
var p = $(.popup).prompt21(); method on it, and
feast your eyes on a JSON object containing the
values entered in the dialogs widgets.
Tab bars
bit.ly/1OHWpjG
Tab bars are a classic: if theres little screen real
estate, multiply it by introducing some tabbing.
TurboTabs expects you to feed it with a structure
of <ul> and <div> elements alongside a
configuration object that can be set up via a tool
on the plugins website. Your input will then be
transformed into a svelte-looking and nicely
animated tab bar.
Sticky cursors
bit.ly/1RMbaSs
Making a widget stick to the cursor is helpful when
a drag-and-drop-like interface is to be
implemented. ObeyCursor transforms this task
into a no-brainer: simply configure a <div> tag of
choice, and configure it with a call to the
obeyCursor method:
<script type="text/javascript">
$(function() {
$("#slave").obeyCursor(opts);
});
</script>
Developer
Plugin: Deskible
bit.ly/1PwPvyu
Category: Window manager
Ever found yourself sufering from MDI envy
while working on a web app? This proof of
concept creates a relatively full-featured
Window Manager based on your favourite web
technologies. It helps developers to create and
manage a number of dynamic windows inside
their web applications.
startMenu: [{
icon: 'book',
label: 'Documentation',
sub: [{
icon: 'wrench',
id: 'docu-setup',
label: 'Setup and Layout',
options: {
tabs: false,
content: {
url: 'apps/documentation/setup.html'
} } }, {
Higher-level folders are created as simple array elements,
while their subelement contains the actual content.
Looking at /apps/examples/irc.html reveals that the IRC
client consists of but the following line:
<p>
<script>
function tmgnBtnClicked()
{alert ("Hello World!");}
</script>
R: <input type="text" name="r" ><br>
U: <input type="text" name="u" ><br>
I: <input type="text" name="i" ><br>
<button onclick="tmgnBtnClicked()">Calcula
te</button>
</p>
Next, add the relevant entry to the start menu. Our
resistance calculating widget will sit in Tamoggemon ->
OhmCalc, accomplished via the following snippet:
startMenu: [{
icon: 'book',
label: 'Tamoggemon',
sub: [{
icon: 'wrench',
id: 'ohmcalc',
label: 'OhmCalc',
options: {
tabs: false,
content: {
url: 'apps/ohmcalc.html'
} } },]}
Genius Guide
Telephonic enforcer
bit.ly/1VVXt3V
Users hate sharing their phone number with
random websites. This library contains a set of
validation routines aimed at catching miscreants
red-handed. Please keep in mind that
MobilePhoneNumber does not check whether the
user really owns the phone in question it merely
keeps honest people honest by not allowing them
to enter malformed numbers.
Manage Cookies
Plugin: CookieBar and js-cookie
bit.ly/1LdDLxR and bit.ly/1av6HUb
Category: Cookie management
EU regulations have made cookie management
dificult: as Google recently decided to require
EU compliance in its AdSense program,
developers need to conform to the regulations.
Fortunately, a combination of these two cookie
plugins makes compliance and data handling
really, really easy!
<script src="js.cookie.js"></script>
JQuerys js-cookie plugin provides a bunch of helper
methods for implementing a basic KV store reading
data from it can be accomplished like this:
$(document).ready(function() {
if(Cookies.get('imagineCookie')===undefined)
{
alert("No cookie there yet");
}
else
{
alert("Found: " + Cookies.
get('imagineCookie'));
}
});
<html>
<head>
<script src="jquery-2.1.4.js"></
script>
<script src="jquery.cookieBar.
Js-Cookie
js"></script>
For some quickfire
<link rel="stylesheet"
information on js-cookie, make
type="text/css"
sure you check out the Wiki
href="cookieBar.css">
github.com/js-cookie/js-cookie. It
</head>
is written by one of the authors,
Cookies.set('imagineCookie', "Hello
Cookie");
}
<body>
<script type="text/javascript">
$(document).ready(function() {
$.cookieBar();
});
</script>
</body>
</html>
AUTHOR BOX:
Carl Woodhouse
github.com/carlwoodhouse
Klaus Hartl
github.com/carhartl
Fagner Brack
CookieBar provides a variety of methods to aid in the
customisation process: you can replace the default text
github.com/FagnerMartinsBrack
Developer
Find faces
Plugin: Face detection
Plugin: ChunkIt
bit.ly/1GK5ims
Category: Image manager
Breaking images down along rectangular
patterns has always been popular the Pet
Shop Boys teaser for Love Etc in 2009 brought
the design pattern to public attention. This
plugin takes an image, renders it into a Canvas
and then chops it down into tiny pieces which
you can arrange to create psychedelic
wallpaper designs.
<!DocType html>
<html>
<head>
<style>
ul.grid {
padding: 0px;
}
ul.grid li {
list-style: none;
display: block;
border: 0px solid #CCC;
float: left;
line-height: 0px;
}
</style>
In the next step, the actual
instantiation of the plugin takes place.
The invocation of chunkIt() does the
actual work expect the browser to stall
for a bit of time:
<body>
<script src="jquery-2.1.4.js"></script>
<script src="jquery.chunkIt.js"></script>
<script>
$( document ).ready(function() {
$('#gridHouse').chunkIt({ imgURL :
'flowers.jpg' , cellsInRow:5,
cellsInColum:5, shuffle:true});
});
</script>
The chunkIt() method takes a JSON object which
configures the actual behaviour of the tiling engine.
ImgURL is a URL to the image, while cellsInRow and
CellsInColum decide the size of the result. Setting
shufle to false arranges the <li> tags in line you can
always perform a correlation between their ID and the
part of the image contained within.
In the case of our example, the structure generated
looks like this:
<div id="gridHouse">
<ul class="grid" style="width: 1200px;">
<li id="cell_25" class="cell">
<img src="data:image/png;base64,"
style="width: 240px; height: auto;"></img>
</li>
<li id="cell_22" class="cell">
<img src="data:image/png;base64,i"
style="width: 240px; height: auto;"></img>
</li>
. . .
Browser
support
bit.ly/1jGT3BR
Category: Image analysis
Finding faces in pictures is important for
multiple reasons: when digital cameras with
the feature were first introduced, getting
perfectly exposed portraits became so
much easier. This plugin allows you to look
for faces in image files provided by your
users or a server of choice.
Face detection is relatively accepting of older jQuery
versions the plugins author specifies it with jQuery
1.11.1. Weve used a recent edition for brevity reasons:
<!DocType html>
<html>
<head>
<script src="jquery-2.1.4.js"></script>
<script src="ccv.js"></script>
<script src="cascade.js"></script>
<script src="jquery.facedetection.js"></
script>
</head>
Face Detection expects to find its source picture in a
<img> tag. We have used an image provided by the
developer here feel free to swap out its URL to
point to a photograph of choice:
$('#picture').faceDetection({
complete: function (faces) {
for(i=0;i<faces.length;i++)
{
console.log(faces[i].x + " " + faces[i].
width + " " + faces[i].y + " " +
faces[i].height);
}
}
});
Genius Guide
Responsive charts
Plugin: chartist-js
bit.ly/1GhA775
Category: Data visualisation
Libraries that make diagrams come a dime a
dozen: ultrasimple Canvas-based ones stand
next to behemoths such as the fearfully
complex D3.js. Chartist difers from its
competitors in that it aims to combine the
no-frills approach of Canvas-based renderers
with the print-ready quality provided by SVG.
<head>
<link rel="stylesheet" href="chartist.min.
css"/>
<script src="chartist.js"></script>
<script src="jquery-2.1.4.js"></script>
</head>
<body>
<div class="ct-chart"></div>
</body>
Our example contains a group of buttons which populate
the <div> tag with various diagrams. First up is a humble
line chart generated by makeLineChart:
function makeLineChart()
{
new Chartist.Line('.ct-chart', {
labels:[1,2,3,4,5],
series: [
[12, 9, 7, 8, 5],
[2, 1, 3.5, 7, 3]
function makeFancyChart()
{
});
var chartRef=new Chartist.Line('.ct-chart',
}
{
. . .
chartRef.on('draw', function (data)
Chartists diagram methods tend to take a pair of
{if(data.type==="point"){
parameters: the first variable contains the data to be
data.group.append(new Chartist.
displayed, while the second variable can provide
Svg('circle', {
you with a variety of display settings. Going
cx: data.x,
SMIL
on to change the display to create a pie
cy: data.y,
support
chart doesnt require much extra efort
Chartist.js supports all kinds of
r: 20
animations: charts can be enriched
}, 'ct-slice-pie'));
function makePieChart()
with marching ants and similar
}});
{
niceities. Sadly, this requires support
}
var data = {
for SMIL a feature sorely
series: [20, 30, 55]
Draw gets emitted every time a new
missing in all versions of
};
element is created: its type subattribute
Internet Explorer.
var sum = function(a, b) {
provides information about the type of
return a + b };
element at hand.
new Chartist.Pie('.ct-chart', data, {
Some features axis labels are a common example
labelInterpolationFnc: function(value) {
might be required in some jurisdictions like Austria, but
return Math.round(value / data.series.
are not considered important enough by the developers
reduce(sum) * 100) + '%';
who pride themselves on the tiny 10KB total file size of
}
their product.
at all:
});
}
github.com/gionkunz
Plugin 1: Accessibility for Chartist
bit.ly/1GhD6MG
Plugin 2: Point Labels for Chartist
bit.ly/1NfSeKe
To follow
To follow
To follow
John Resig
JQuery Foundation
JQuery Plugins
@jeresig
Two words: jQuery.daddy==John.
Follow him to enrich your Twitter
timeline with content more or less
related to the big jQ!
@jquery
The jQuery Foundation is the body
which governs the jQuery product
family. Follow the account for all the
latest, oficial announcements.
@jqueryplugins_
This Twitter account provides a
never-ending stream of interesting,
weird and/or useful jQuery plugins for
your perusal.
Developer
Tile interface
Simply changing
the background
colour is but part
of the solution;
adding pictures
makes your tiles
look more natural.
By default, jsTiles
renders its tiles
right next to one
another. Creating
spacing is best
accomplished via
CSS attributes.
JsTiles is based on
Bootstrap: the
scaling behaviour
of the boxes is
determined by
attributes taken
from Bootstrap.
Progress dots
bit.ly/1VWCIKO
bit.ly/1jGTzzS
$( '#progressBox' ).dottify({
dotSize: '28px', //set size of dot
randomColors: true, //use random colors
numDots: 7, //number of dots
radius: '20%' //set dot corner radius
});
Genius Guide
Plugin: jsTiles
bit.ly/1GhDhro
Category: Tile manager
Microsofts Windows Phone 7 introduced the
world to the concept of the tile: ever since, the
design paradigm got more and more attention.
Implementing tiles looks simple at first glance,
but tends to become tedious once attention is
paid to details.
<div id="tiles-container">
<div class="tl-page" data-tltemplate="myTemplate">
<div style="background-color: #f00;
border-style: solid; border-width:
5px;">Content</div>
</div>
</div>
A superficial inspection of the code on FileSilo reveals
that the tile management framework limits itself to the
arranging of the individual elements; their design, layout
and content lie in the responsibility of the developer. With
that out of the way, the template must be configured:
var myTemplateObject = {
myTemplate: {
tilesNum: 6,
rows: {
0: {
rowClass: 'tl-row col-xs-12',
start: '3',
end: '5'
}
},
tiles: {
0: 'col-xs-6 col-md-3',
1: 'col-xs-6 col-md-3',
2: 'col-xs-6 col-md-3',
3: 'col-xs-6 col-md-3',
4: 'col-xs-6 col-md-3',
5: 'col-xs-6 col-md-3'
}
}
}
The most important part of the options array is the
tilesNum property: it must match the number of the
<div> tags in the container. Rows sets up the size of the
individual rows, while tiles configure the individual tile
widths. Js-tiles will need to work with Bootstrap: the class
names used are taken from the template framework.
Next up well apply the generated configuration. In our
example, the following bit of code shall sufice:
var opt = {
templateObj: myTemplateObject,
}
$('#tiles-container').jstiles(opt);
});
With that, our example is done. Js-tiles provides a variety
of additional features for animation and card
management: further information on these topics can be
found in the documentation.
<!DocType html>
<html>
<head>
<script src="jquery-2.1.4.js"></script>
<script src="jquery.headtacular.js"></
script>
<style>
.header {
transition: all 300ms;
background-color: #f00;
position: relative;
z-index: 9999;
}
.header.is-stuck {
position: fixed;
top: 0;
width: 100%;
background-color: #f0f;
}
</style>
</head>
Headtacular permits you to use two styles: header is
used when the user has not touched the scroll point,
while header.is-stucks turn comes once scrolling has
begun. In the next step, a small header a b tag along
with some text shall sufice is created:
<body>
<div id="myHead" class="header"><b> My
Header</b> and some text</div>
<div id="myFill"></div>
</body>
</html>
Finally, the headtacular method must be invoked after
the DOM tree has been initialised. In the case of our
snippet, we pass in an object showing one of the
supported options as the plugin contains sensible
defaults for all options, you can also call the method with
an empty JSON object:
<script type="text/javascript">
$(document).ready(function() {
var innerHtml="Lorem Ipsum sic . . .<br>";
for(i=0;i<12;i++){innerHtml+=innerHtml;}
$( "#myFill" ).html(innerHtml);
$('#myHead').headtacular({ scrollPoint: 1
});
});
</script>
The lorem ipsum code unfortunately bloats the page: an
empty website does not flow over the screen and thus
does not require scrolling.
Developer
Timeline display
bit.ly/1NLSX96
Colour picker
bit.ly/1ReHcpt
Footer
Testing a footer management plugin requires the
presence of a footer start out by creating the
following example page, which self-populates with a
bit of lorem ipsum and also contains a footer with
some buttons:
<html>
<body>
<script src="jquery-2.1.4.js"></script>
<script src="jquery.downboy.js"></script>
<script>
$( document ).ready(function() {
var innerHtml="Lorem Ipsum sic . .
.<br>";
for(i=0;i<7;i++){innerHtml+=innerHtml;}
$( "#myFill" ).html(innerHtml);
});
</script>
<div id="myFill"></div>
<div id="myFooter" style="backgroundcolor: yellow;"><h1>This is a footer</
h1></div>
</body></html>
DownBoy is ofered in two versions. If your footer goes
by the name #footer, simply embed downboy.auto.*.js
in order to put the element in its place. Developers
working with a custom footer must instead deploy
downboy.*.js, which requires the following bit of extra
code to be used:
<script src="jquery.downboy.min.js"></
script>
<script>
$(function() {
downBoy('#myFooter'); // Run on load
window.onresize = function() { // On
Resize
downBoy('#myFooter'); // Run Again
};
});
</script>
Keep in mind that DownBoy can handle scrolling only
if the DocType is set like this::
<!DocType html>
Plugin: jQuery.downBoy
bit.ly/1PlZesf
Category: Footer management
Tooltip windows
sweefty.com/tinytip
Forcing users to consult a manual is a sure-fire way to
drive them straight to the arms of your biggest
competitors. This plugin strives to increase discoverability
by displaying tooltip windows with further information at
strategic locations.
Genius Guide
Rain effect
bit.ly/1NLRfVa
Scrolling indicator
bit.ly/1MHijDH
Superfast parallax
bit.ly/1MtzLXU
Research conducted by the Purdue University (docs.
lib.purdue.edu/cgttheses/27/) has produced results
that show that the presence parallax scrolling
significantly increases user satisfaction. Bring a few
svelte panoramic shots and this little plugin by
Kaspars Jaudzems of Latvia can add the impressive
scrolling efect to your web projects with minimal
efort.
$("#divProgress").circularloader({
progressPercent: 35
})
Developer
Produce a picture
gallery with jQuery
Use jQuery for managing user interactions with CSS to
support visual presentation
Genius Guide
2. Load resources
The <head> section of your HTML should contain the
links to any resources you are using for the page; in our
example, well be using this to load the CSS stylesheet
3. Gallery container
Use the <body> section to place the gallery content. The
gallery template will consist of an article element used as
a container for the diferent parts of the gallery the
navigation, details and picture display. These elements
will be modified later by the jQuery JavaScript code.
var pictures = [
{
"title":"A Cottage",
"description":"A little cottage.",
"url":"img/image1.jpg"
},
{
"title":"A Horse",
"description":"A horse eating hay.",
"url":"img/image2.jpg"
},
{
"title":"Lake",
"description":"Water flowing down lake.",
"url":"img/image3.jpg"
},
{
"title":"Peacock",
$(document).ready(function(){
//.. place code from next step here
});
Easy to misuse
Although jQuery exists to make programming
easier, its easy to misuse it by not using it to its
full potential especially when the library costs
over 200k to download.
Left
Developer
var count = 0;
$(pictures).each(function(){
//.. place code for next step in here
});
7. Page container
Use the <body> section to contain the visible content. We
start this by placing the <main> page container inside the
body; this will be used to allow the controlled layout of
the content. Your page title, description and index count
will go inside this.
$(img).appendTo("figure");
//.. code from next step goes here
9. Create thumbnails
A thumbnail is required to show a selectable preview for
navigating the gallery images. There is no need to reload
images jQuery can make a clone of each image and
then append to the inside of the <nav> container.
$(thumb).bind("click",function(){
//.. code from next step here
});
count++;
8. Image to container
After each image has been created as an element on the
webpage, it will then need to be placed inside the
location where we will store every single image. Our
example will use the pages first <figure> element. The
figure part of this code is a CSS rule that defines how to
find the location.
Top left
$('figure img[data-index="'+this.
getAttribute("data-index")+'"]').
removeClass("hidden");
//.. code from next step goes here
$('h3').html(this.getAttribute("title"));
$('figcaption').html(this.
getAttribute("alt"));
$("figure img").each(function(){
$(this).addClass("hidden");
});
//.. code from next step goes here
html,body{
background: #000;
padding: 0;
margin: 0;
font-family: monospace;
height: 100%;
}
Genius Guide
What is jQuery?
JQuery is a general
purpose code library
created to help make
programming in
JavaScript faster and
easier. It is used by
advanced JavaScript
programmers as well as
web designers who know
the basics for tweaking
jQuery code as jQuery is
often easier to understand
than raw JavaScript. In
addition to making JS
faster to code, there are
many website components
that have been created
with jQuery for purposes
ranging from user
interface animation
through to searchable
data tables and games
creation, which often can
be customised without
advanced programming.
JQuery is possibly the
worlds most commonly
used general purpose JS
library, with it often being
listed as a requirement for
web development jobs.
article{
display: block;
width: 75%;
margin: 10% auto 0 auto;
background: silver;
padding: 1em;
}
article div{
display: table-caption;
position: absolute;
top: 0;
right: 0;
z-index: 2;
width: 75%;
text-align: right;
margin-left: 27%;
background: rgba(0, 0, 0, 0.75);
color: #fff;
}
figure{
display: table-cell;
position: relative;
width: 75%;
margin-left: 25%;
z-index: 1;
overflow: auto;
}
figure img{
position: absolute;
top: 0;
left: 0;
transition: opacity 1s;
width: 100%;
z-index: 1;
}
figure img.hidden{
opacity: 0;
}
nav{
display: inline-block;
width: 100%;
height: 100%;
overflow: auto;
background: #777;
padding: 0;
}
nav img{
display: inline-block;
width: 100%;
}
Developer
Genius Guide
<script src="bower_components/angular/
angular.min.js"></script>
<script src="bower_components/angularanimate/angular-animate.min.js"></script>
<script src="bower_components/angular-aria/
angular-aria.min.js"></script>
<script src="bower_components/angularmessages/angular-messages.min.js"></script>
<script src="scripts/app/app.js"></script>
<script src="scripts/app/modules/
registerModule.js"></script>
<script src="scripts/app/controllers/
registerController.js"></script>
Directive names
angular.module('formApp', ['register.
module', 'ngAria', 'ngMessages',
'ngAnimate']);
angular.module('register.module',
[register.controller']);
5. Register controller
The controller for our registration form is very bare
bones. So what well do is well add some specific uses to
it later (namely to add dynamic text). Behind the scenes it
will do the internal wiring to ensure our form works as we
expect it to.
(function() {
'use strict';
angular.module('register.controller', [])
.controller('registerController', ['$scope',
function ($scope) {}]);
})();
<form name="register"
data-ng-app="formApp"
data-ng-controller="registerController"
data-ng-submit="submitForm(register)">
<h1>Register</h1>
</form>
<form data-ng-attr-novalidate={{true}}"
data-ng-cloak>
</form>
<div class="row">
<label for="firstName">First name:</label>
<input id="firstName" name="firstName"
data-ng-model=fields.firstName required
/>
</div>
Left
This is the page that will contain our form, theres not
much to it yet but the Angulars ready to go
Top left
Developer
10. ngMessages directive
NgMessages does a great job of toggling specific
messages but we also need to determine when to show
them. Otherwise theyll appear before the user has
touched the form! The messages should only appear if
the field is dirty (if it has been filled in) or the user
submits the form.
Debugging $errors
A useful way to get a quick understanding of an
object in real-time is to output it onto the page:
<pre>{{form.postcode.$error | json}}</pre>. This
will show the object and format it as JSON.
Top left
.error
{
color: #a94442;
padding: 0.875em;
background-color: #f2dede;
width: 16em;
border: 0.125em solid #ebccd1;
transition: 0.5s linear opacity;
opacity: 0;
margin: 0;
}
<div class="row">
<input type="submit" value="Register" />
</div>
<div class="row">
<label for="postcode">Postcode:</label>
<input id="postcode" name="postcode"
data-ng-model="fields.postcode" postcode
required />
</div>
<div class="row">
angular.module('postcode.directive', [])
.directive('postcode', function() {
return {
require: 'ngModel',
scope: {
postcode: '='
},
Genius Guide
Utilise ngMessage
expressions
NgMessages also supports dynamic
messages, that is, if you dont know the
name of the message that might be fired
you can check it with a message
expression. In this example weve got an
array in the controller called
errorMessages which contains a list of
objects. These objects represent diferent
error states and their corresponding text.
<div data-ng-messages=register.
test.$error role=alert>
<div data-ng-repeat=errorMessage
in errorMessages>
<div data-ng-messageexp=errorMessage.type>
<p
The ngMessages documentation has
pages on each directive:
docs.angularjs.org/api/ngMessages.
return REG_EXP.test(value);
}
};
</div>
org/guide/migration.
Developer
Genius Guide
<body></body> tags:
<div id="drumHolder">
<div class="drum" data-sound="china"></div>
<div class="drum" data-sound="crash"></div>
<div class="drum" data-sound="floor tom"></
div>
<div class="drum" data-sound="super kick"></
div>
<div class="drum" data-sound="super
snare"></div>
</div>
<script src="scripts/libraries/bl.js"></
script>
<script src="scripts/core.js"></script>
#drumHolder{
width: 700px;
height: 290px;
position: fixed;
left: 50%;
top: 50%;
margin-left: -350px;
margin-top: -145px;
background-color: rgba(255,0,0,.2);
}
6. Core.js
Now that we have our elements in the right place, we
can start writing some code to control them. When we
added in our <div> we also added two <script> elements,
one for our code, the other being our BuferLoader
method. Create a file called core.js in our scripts folder
and add the following to it:
console.log("Initialised");
}
return {
init : init
};
})();
(function(){
__web_audio_drums.init();
})();
var samples = [{
Buttons needed
Left
Developer
name :
path :
},
{
name :
path :
},
{
name :
path :
},
{
name :
path :
},
{
name :
path :
},
],
sounds
"china",
"/sounds/China.mp3"
"crash",
"/sounds/Crash.mp3"
"floor tom",
"/sounds/Floor_Tom.mp3"
"super kick",
"/sounds/Super_Kick.mp3"
"super snare",
"/sounds/Super_Snare.mp3"
= [];
function loadSamples(passedSamples){
var s = [];
for(var x = 0; x < passedSamples.length; x
+= 1){
s.push(passedSamples[x].path);
}
}
This will simply create an array of file paths that we can
work through to load our samples into our project
Top left
...
sounds = list;
var theDrums = document.
getElementsByClassName('drum');
for(var y = 0; y < theDrums.length; y += 1)
{
theDrums[y].addEventListener(touchOrClickEve
nt(), function(){
for(var a = 0; a < samples.length; a += 1){
if(samples[a].name === this.
getAttribute('data-sound')){
playSound(a);
}
}
}, false);
}
console.log(sounds);
...
function touchOrClickEvent(){
if('ontouchend' in document){
return "touchend";
} else {
return "click";
}
}
Genius Guide
function playSound(idx){
var src = context.createBufferSource(),
newBuffer = cloneAudioBuffer(sounds[idx]);
src.buffer = newBuffer;
var gainNode = context.createGain();
gainNode.gain.value = 1;
src.connect(gainNode);
gainNode.connect(context.destination);
src.start(0);
}
function cloneAudioBuffer(audioBuffer){
var channels = [],
numChannels = audioBuffer.numberOfChannels;
for (var i = 0; i < numChannels; i++){
channels[i] = new Float32Array(audioBuffer.
getChannelData(i));
}
var newBuffer = context.createBuffer(
audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
for (var i = 0; i < numChannels; i++){
newBuffer.getChannelData(i).
set(channels[i]);
}
return newBuffer;
}
audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
Finally, we have a brand-new bufer, but our bufer is
empty so we fix that by working through our newly
created bufers channels and setting them with the
channels we created just a moment ago. Then we return
our cloned audio bufer:
src.buffer = newBuffer;
Garbage collection
In web development, weve got a fairly consistent
expectation of what our content will do when its
loaded by somebody. While we dont have a great deal
of assets in this project, we have created many copies
of them quickly. So do you take on the big or the little?
Well, we dont have to worry about that hypothetical,
because we have garbage collection. Garbage
collection is the process in which an application (our
browser in this case) realises an object or entity is
never going to be used again by the program and so
its dereferenced and the memory it occupied is freed
for use by other objects. Think of it like a bucket that
scoops up all of those big items when they turn their
backs and deals with the problem of size for you.
Developer
Genius Guide
6. Check if working
3. Initialise the local copy
The following steps are based on an Ubuntu workstation.
Open a Terminal window, and create a new and empty
folder. In the next step, enter the following commands to
connect the folder to the GitHub server. During the
process, a group of metadata files are spawned.
1. Sign up!
<html>
<body>
<h1>An error has occurred</h1>
</body>
</html>
Attention: Unix!
GitHub Pages is hosted on a Unix operating
system. This means that paths and file names are
case sensitive a nasty trap for people switching
from Windows Server.
Left
Developer
featured in this step. Do not wonder if the client will ask
for username and password from time to time as a
security precaution.
Analytics caveat
Deploying Google Analytics is complex from a
legal point of view: in many countries, users need
to be notified that their data is collected and/or
forwarded to Googles servers.
Top left
15. Go live
Genius Guide
Do the domain!
One way to make GitHub
Pages a little more
professional is through the
use of subdomains. You
can add a CNAME record
at your web or domain
provider in order to
redirect trafic to GitHub
Pages as the system is
based on DNS names, your
site will continue to
benefit from GitHubs
optimisation and CDN
service. For example,
orgname.github.io/
projectname could be
redirected to project.
tamoggemon.com.
If your domain provider
does not ofer the CNAME
option, you can
alternatively use an apex
domain which forwards to
the IP adress of GitHub.
GitHub oficially advises
against the use of apex
domains as they do not
permit the use of a CDN
further information on the
topic can be found at
bit.ly/1NpCaZX.
19. Troubleshooting
Developer
Manage JS with
asynchronous tasks
Promise objects aim to remove redundant and/or excessive
callback functions from background tasks
2. Create a model
A Promise class is a wrapper around an asynchronous
payload. To keep things simple, we will start out by
creating a simple model of a good friend of ours. Matz
will greet us with a friendly Oi message once a day
sadly, the time when the actual Oi takes place is not
predictable so it could occur at any time.
<html>
Genius Guide
<body>
<script>
function Matz()
{
setTimeout(function(){ alert("Oi!"); },
(Math.random()*10000));
}
Matz();
</script>
</body>
</html>
3. Adapt to Promise
Adapting our Matz payload to a Promise involves the
creation of a method with two parameters. Both reject
and resolve can be invoked as normal members, along
with a value containing further information about the
state of the event at hand.
<body>
<script>
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){ resolve("Oi!"); },
(Math.random()*10000));
});
</script>
</body>
4. Announce events
Our Promise only actually becomes useful once we can
ensure that our code reacts on its completion. The
snippet accompanying this tutorial step announces the
Greeting event by displaying a message box once the Oi
has been emitted.
<body>
<script>
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){ resolve("Oi!"); },
(Math.random()*10000));
});
aMatz.then(function(){alert("Matz is
here!")});
</script>
</body>
5. Transcendental Oi!
Classic event handlers sufer from a chicken/egg
problem: if the interesting event occurs before the
registration of the handler, information will be lost. As
Promises act as state machines, this problem can not
occur. Once Matz is done, its done forever, which means
that the late alert will always pops up.
6. Truly asynchronous
Then does not interrupt program execution. Instead, the
method stores the payload in an execution queue and
returns afterwards. Running the example accompanying
Step 6 a few times will lead to diferent alert dialog
sequences depending on the speed of your system and
the random timeout value.
<body>
<script>
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){ resolve("Oi!"); },
(Math.random()*10000));
});
aMatz.then(function(){alert("Matz is
here!")});
alert("We're done here");
</script>
</body>
<script>
window.doritIsHere=true;
var aMatz=new Promise(
function Matz(resolve, reject)
{
setTimeout(function(){
if(window.doritIsHere==false)
{resolve("Oi!");}
else
{reject ("Eeek!")}
}, (Math.random()*10000));
});
aMatz.then(function(){alert("Matz is
here!")});
alert("We're done here");
</script>
8. Chain it up
Step 6 established that then() does not wait for the
completion of the Promise. Thus, its returned context can
be used to chain things up. In our example, the payload
passed to catch() is executed only if Dorits presence
causes Matz to bolt.
<html>
<body>
<script>
window.doritIsHere=true;
var aMatz=new Promise(
. . .
aMatz.then(function(){alert("Matz is
here!")}).catch(function(){alert("No, it's a
Dorit!")});
Dont block
7. Dorit objects
Left
Developer
alert("We're done here");
</script>
</body>
</html>
9. Clean me up
Developers who are familiar with object-oriented
programming languages know the concept of a finaliser:
it is a method that gets called on both success and
failure of the underlying operation. Its position in
program execution is shown in the flowchart
accompanying this step.
<script>
window.doritIsHere=true;
var aMatz=new Promise(
. . .
aMatz.then(function(){alert("Matz is
here!")}).catch(function(){alert("No, it's a
Dorit!")}).finally(function(){alert("It's
done!")});
alert("We're done here");
Advanced
functionality
Check out the Promise RSVP library ofered at
github.com/tildeio/rsvp.js
Top left
{
setTimeout(function(){
if(window.doritIsHere==false)
{resolve("Oi!");}
else
{reject ("Eeek!")}
}, (Math.random()*10000));
}
var matzBuilder=new Promise(function
MatzBuilder(resolve, reject)
{
setTimeout(function(){
alert("Spawning new Matz!");
resolve(new Promise(Matz));
},1500);
});
<script>
window.doritIsHere=true;
matzBuilder.then(undefined,function(){
alert("Unhandled Inner Error")
}).then(function(val){
alert("Queueing completed! " + val);
});
</script>
<body>
<script src="jquery-2.1.4.js">
</script>
<script>
function DeltaColor(resolve, reject)
{
setTimeout(function(){
this.myElem.css( "color", "green" );
}, (Math.random()*10000));
}
</script>
</body>
function AddClosure(what)
{
return function (resolve, reject)
{
setTimeout(function(){
what.css( "color", "green" );
resolve();
}, (Math.random()*10000));
};
}
$( window ).load(function() {
var e1=new Promise(AddClosure($("#k1")));
e1.then();
var e2=new Promise(AddClosure($("#k2")));
e2.then();
var e3=new Promise(AddClosure($("#k3")));
e3.then();
var e4=new Promise(AddClosure($("#k4")));
e4.then();
var e5=new Promise(AddClosure($("#k5")));
e5.then();
window.myArray=[e1,e2,e3,e4,e5];
});
</script>
<table>
<tr><th>Mater</th><td
id="master">xxxxxxxxxxxxx</td></tr>
<tr><th>Kid</th><td id="k1">xxxxxxxxxxxxx</
Genius Guide
Do the closure
Setting parameters on the Promise object
returned by the constructor is not a valid
way to pass them into the function
responsible for the actual handling of the
payload. Instead, parameters must be
passed using a closure which returns the
function body. In the case of the code
shown in Step 15, the element at hand is
stored as a parameter passed to
AddClosure. The inner function can
access it as if it were a global variable, as
a closure is erected around it during the
returning of the function body. It will
remain valid for the entire life cycle of
that reference: as long as someone can
invoke the function, its closure remains
alive. JavaScript newbies should be aware
of this behaviour, as it is the prime source
of excessive memory consumption.
td></tr>
<tr><th>Kid</th><td
td></tr>
<tr><th>Kid</th><td
td></tr>
<tr><th>Kid</th><td
td></tr>
<tr><th>Kid</th><td
td></tr>
</table>
id="k2">xxxxxxxxxxxxx</
id="k3">xxxxxxxxxxxxx</
id="k4">xxxxxxxxxxxxx</
id="k5">xxxxxxxxxxxxx</
window.myArray=[e1,e2,e3,e4,e5];
Promise.race(window.myArray).then(function()
{
$("#master").css( "color", "blue" );
});
});
. . .
window.myArray=[e1,e2,e3,e4,e5];
Promise.all(window.myArray).then(function(){
$("#master").css( "color", "blue" );
});
});
p.then(onFulfilled, onRejected);
p.then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});
Top left
Special effects
172
174
Special effects
Presenting
Genius Guide
Whats up with
web animation?
Ask any two designers what
they think of animation, and
youll get six opinions. The web
still hasnt quite recovered from the Flash
years, when loading and splash pages
stressed prebroadband modems and
made users wait for extravagant doodles.
For designers, Flash was a brilliant way
to rack up the billable hours. It wasnt so
popular with visitors, who either learned
to click on the Skip animation button as
soon as it appeared, or were left
wondering why theyd just spent two
minutes watching a cartoon rocket land
in a giant vector graphic cheesecake.
Of course Flash is still around, but it
doesnt seem to be winning new fans.
Today, most clients and creative directors
are going to look strangely at anyone
who suggests a splash screen, whether it
uses Flash or a more recent technology.
That could be because modern
animation has calmed down and tried to
make itself more of a team player. Instead
of being all about the technology or the
designer, animations have become more
about the design.
So what is animation for? Its easy to
make a site where everything moves all
the time, but visitors will hate it. Its more
useful to think of animation as a power
tool you can use to enhance your sites
production values, help users find their
way to the content theyre looking for, and
Shane Mielke
Creative director at shanemielke.com
10
16
15
7.1
4.1
CSS3 animation
10
16
15
7.1
4.1
Current
Current
5.1
12.1
6.1
Current
Current
5.1
12.1
6.1
Other JavaScript
frameworks
Current
Current
5.1
12.1
6.1
WebGL [1]
11
31
31[2]
29[2]
8.3
40[2]
Special effects
Animation in Action
Dreamteam
dreamteam.pl
The use of web animation needs to considered and have value. Alternatively, it
can be something to adore and be admired. DreamTeam by Polish creatives
BrightMedia sits very much in adore and admire. The homepage animation reveals
itself with a simple straight line before blossoming into a fully fledged animation.
The fun doesnt stop at the homescreen, scroll down and watch more smart design
unveil itself.
All for show
The opening animation has no real purpose other
Keeping up
than to engage and excite the user. The
The creatives behind
moment the animation starts, the user is
hooked. An attention-grabbing design is
DreamTeam are Polish agency
guaranteed to give the creators attention
BrightMedia. Keep up with their
right across the web design community.
UI animation
Simple navigation animation is used to enhance the
overall site. To reinforce the common purpose of the site
each menu item has a rollover efect. A solid white
background eases in with a subtle animation and
immediately draws the users attention.
Genius Guide
Web animation
API: a new
solution?
HTML5 technology
Taking a peek at the source
code reveals a surprisingly slim
page. It is the HTML5 Canvas
element where all the hard
work is done. The animation
sits quietly in the background
claiming all the glory while the
standard HTML creates the
crucial elements needed to
navigate and guide users
around the site.
Motion
so its good for big animated
emotion
with it it will definitely take your data
Dont forget that many CSS tags
backgrounds and digital art.
vis skills up a couple of levels.
including older pre-CSS3 tags
However its not so ideal for making
WebGL and 3D
UI elements and moving them
can be animated. So animation can
animation
mean creating opacity fades,
around. Raphael and paper are
Waiting in the wings is 3D animation
simpler, and concentrate more on
animated borders and text
and rendering. This has a lot of
decoration.
vector graphic design with a hint of
potential, but its not quite there yet. The
animation. GreenSock is much used by
WebGL standard is a simplified version of the
corporates and adds useful functions that
OpenGL 3D graphics programming API used in
simplify CSS animation. Theyre all worth looking at,
high-poly commercial games.
because knowing whats out there can spark new ideas
This sounds like a good thing. But not all platforms
for existing designs.
support all features, and some older hardware barely
Visualising data
supports WebGL at all. So you cant rely on it. And its
If youre working with data visualisation, the go-to
hard to make it look awesome. Gamers are used to
framework is d3.js. (d3js.org.) d3 is a monster that chews
high-poly rendering with advanced lighting efects, and
on data and spits it out in almost any shapes you can
WebGL cant match that.
imagine and a few you probably cant. Its immensely
Finally, its hard to use. The three.js framework (threejs.
powerful, but also has a steep learning curve. If you can
org) makes it more accessible, and there are plenty of
hack it though, its ideal for making and animating UI
demos to learn from (look out for the work of mrdoob
elements, especially if youre using them to display
you can follow him on Twitter @mrdoob). But its still a
quantitative data.
couple of levels up from plain CSS.
To help you get started, the d3 site has a huge
Is it worth it? For plain vanilla UI design, no. For more
selection of demos and examples. Dont expect instant
experimental projects, its certainly worth exploring to
results, but if you can spare a week or two to get familiar
see whats possible.
Special effects
Staying focused
Edwin
Europe
edwin-europe.
com
Check the Denim fit guide
to see the 360-degree
view: animation with
the wow factor.
Vimeo
Cameo
vimeo.com/
cameo
Subtle, simple and
efective animations that
work on diferent levels
on diferent
devices.
Genius Guide
Make UI engaging
Why spice up a UI with animation? Too much twitching
and blinking can give users a migraine. But just the right
amount of animation can make the diference between a
boring site and one that users will keep coming back to.
In outline, there are three kinds of UI animations.
Highlighters decorate existing content to suggest an
afordance. The most obvious examples are link
colour. Apples You got that wrong, so this text box looks
like its shaking its head is the classic example here.
Skeuomorphisms help make the site feel more
physical. The aim here is to use visual metaphors to
suggest physical objects. Often, just a hint of physicality
is enough for more weight and presence.
Attention seekers are the final UI group. They provide
important stand-out features that cant be ignored, so
theyre hard to get right. Examples include FILL IN OUR
FEEDBACK FORM pop-ups, but you can also find them
scrolling up from the bottom of the page on news sites
to ofer breaking news.
Attention seekers tend to annoy users, so consider
using animation to make them less distracting. Make
pop-ups appear at the side instead of the middle of the
viewport, and put breaking news in a window. The
animation should always help the user, not distract them.
Catch
the dragon
catchthe
dragon.nl
Car manufacturer Peugeot
combine video, VR and
animation to create a
breath-taking
experience.
Special effects
Create a
pulsating circle
HELLO MONDAY TECHNICAL LEAD
TORBEN DALGAARD JENSEN
REVEALS HOW THEY CREATED THE
EFFECTS ON REVELATOR.COM
The Revelator website is built on the idea that you only
need to use one platform if you want to run a music
business. We wanted to showcase this idea by leading the
user through an animated story that breaks the features
into simple steps. Below well explain how you can create
the type of animation we used for the Promote feature.
Well use trigonometry to create the pulsating efect
and write it entirely in JavaScript. GreenSock TweenMax is
used for the tweening, and we will be writing a JavaScript
object instance for the circle so that we can preserve
modularity and readability.
1. Initial setup
First what we will do is create a container and an array to
hold the circles. Then we are centring the container
within the window. Also we are writing some stub code
that we will revisit later.
2. Create DotCircle.js
We will go through the methods for the stub code for the
DotCircle in the next steps. We calculate the distance in
degrees between each dot and create a radius object
5. Update
Now what well do is we will update the position of the
dots based on the new radius value we are tweening.
Then we will be delaying them incrementally to create
the staggered efect.
6. Ready to rock!
Going back to the main script we will now create three
instances of the DotCircle with incrementing radius. Then
we will start the animation, again using delay to stagger
them. For the full code in this tutorial, make sure that you
check out FileSilo (filesilo.co.uk/bks-887).
Genius Guide
Hakim el Hattab
Designer and developer
hakim.se
Q. The use of web animation in any project needs to be
carefully considered. What advice would you give to
designers and developers?
When working on a web app keep in mind that excessive
and lengthy interface animations can reflect negatively
on the app as a whole. If animations are too slow the app
itself is perceived as sluggish. If there are too many
things animating too frequently it wont feel reliable and
robust. Keep animations brief and remember that not
The trends in
current design are
clear: integrating
animation with
content
Special effects
Menu trigger
The burger menu features
a nice transition as it
animates into an X to
remove the menu from
the screen.
The menu
Once the burger has been
pressed, the left side of
the menu slides down and
the right-hand side slides
up from the bottom.
Split screen
The page features a
split-screen styling,
divided into two halves,
vertically and used
throughout the site.
Slideshow
Genius Guide
Technique
1. Create the sliding panels
In your HTML page add the tags that are shown here.
There are two panels for the left and right side of the
screen and these will be hidden to start with, then
animated when the burger menu icon is pressed in the
third div. Another div is included just to show where the
page content would go.
EXPERT INSIGHT
The rise of the preloader
Many websites now feature
preloaders, all this does is present a
holding screen until all the content is
loaded. When using large images, it
is essential to wait until they have
loaded before presenting them to
the user, otherwise they would think
that the site isnt working properly
with content missing.
Lets now add the style for the left and right panels, these
are positioned on the page appropriately to the left and
right side of the screen. They are also positioned
absolutely so that they can appear above other content
on the screen with a higher z-index. The sizing is then
handled by percentage to fit the diferent screens.
position: absolute;
top: 0; left: 40%;
font-size: 3em;
z-index: 250;
}
a {
text-decoration: none;
color: #fff;
}
#content{ padding: 30px; }
.hidden{ display: none; }
</style>
<script>
var over = false;
var left = document.getElementById( 'left'
);
var right = document.getElementById( 'right'
);
function menu(){
if (over==false){
left.classList.remove('hidden');
left.classList.remove('fadeOutDownBig');
left.classList.add('fadeInDownBig');
right.classList.remove('hidden');
6. Switch out
Now lets add in the remaining CSS, which will style the
burger icon, link and the content that would appear on
the page. The final CSS style will hide any content that
shouldnt be seen until it is animated.
#icon{
Special effects
Slow scrolling
When you first get to the
site you may find yourself
a little overwhelmed. We
suggest taking it one
animated item at a time.
Multiple themes
Although it may at first
seem like a tribute site to
sci-fi, scrolling down
reveals that it is actually a
tribute to everything.
Retro stylings
Camerons World is
basically a love letter to
the internets infancy,
piled to the brim with
animated GIFs.
GIF collection
GeoCities nostalgia
Scattered throughout
Camerons World is
probably the largest
collection of animated
GIFs in the universe.
Genius Guide
Animated changes
<comment>
What our
experts think
of the site
Despite Camerons obvious nostalgia for the animated GIF, advances in CSS
animation, and SVG imagery coupled with JavaScript, have seen the GIF slowly
go the way of Flash animation. These days youre more likely to see animated
GIFs relegated to loading icons and little else.
Richard Lamb, freelance web designer at Inspired Lamb Design
Technique
1. Create your alien
First we to make our alien in either Photoshop or
Illustrator. Build him with two layers by making the head
shape, the mouth and nose. The eyes will be created later
on. Once you have this done, save your layers.
3. Base HTML
Now were going to begin putting together our index.
html, placing a number of feature-named divs within a
main container div. The two eye divs will have content
created entirely in CSS.
<div id="head">
<svg version="1.1" xmlns="http://www.w3.
org/2000/svg" xmlns:xlink="http://www.w3.
org/1999/xlink" width="682" height="643"
viewBox="0 0 682 643">
<path style="fill:#707070" d="M
329.29383,595.34017 C 303.59048,589.84415
278.06846,571.34223 230.24763,523.53768
147.90032,441.21841 101.01898,368.99175
87.424155,303.5 c -7.385818,-35.58047
.eye-left, .eye-right {
width: 200px;
height: 100px;
background: #1f1f1f;
border: 2px solid #1f1f1f;
border-radius: 100px / 50px;
position: relative;
top: 175px;
EXPERT ADVICE
As you can see, there is a plethora of animated GIFs in
Camerons World. For the purposes of this tutorial, we
picked the relatively simple alien GIF, but we still took a
while deciding and then still had to figure out how to
translate a series of animated image layers into a
working, code-based animation. Maybe you can go one
better. Why not choose one of the more complex GIFs
and see if you can re-create it using only HTML and
CSS? Obviously, there will always be some that cant be
mimicked to perfection in pure code, at least not yet,
but sometimes great leaps in coding development
come from having to work with existing tools, but
within very narrow confines.
Besides, even if youre not about to usher in the next
big web development, solving a seemingly pointless
HTML puzzle like this can be an extremely useful
method for keeping your brain agile and ensuring
those coding skills stay honed. Remaining within your
comfort zone, churning out the same template-based
sites time and time again, is an easy trap to fall into.
Sometimes it pays to challenge yourself and try your
hand at what you think is beyond your skills. Maybe
youll surprise yourself with what you can achieve.
left: 140px;
float:left;
}
.eye-left, .eye-right {
animation: eye 3s ease-in-out infinite;
}
@keyframes eye {
0%
{box-shadow: 0px 0px 0px 0px #585757
inset;}
2.38% {box-shadow: 0px 140px 0px 0px #585757
inset;}
34.13% {box-shadow: 0px 0px 0px 0px #585757
inset;}
36.51% {box-shadow: 0px 0px 0px 0px #585757
inset;}
100% {box-shadow: 0px 0px 0px 0px #585757
inset;}
}
Special effects
Main menu
The menu has a simple
but effective animated
rollovers, with an
expanding line appearing
below the link.
Panel content
As the user scrolls down
the page, the content
within the sections slide
into place for maximum
impact with the user.
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
Genius Guide
ISL.co, like the agency itself, is a balance between designerly minimalism and
over-caffeinated, youthful exuberance. In practice, this meant a combination of
vast white space and simple, clear typography, paired with tons of movement
from background videos to fluid, bouncy UI animations.
Zach Goodwin, creative director
Technique
1. Scroll-triggered animation
To trigger animation by code, the Waypoints.js
(imakewebthings.com/waypoints) library and the
Animate.css (daneden.github.io/animate.css) library will
be used. Download and add them to your document.
Then add the first CSS rule to position the top element.
<div id="top">
<div class="os-animation btm" data-osanimation="fadeInLeft" data-os-animationdelay="0s">
<img src="img/arrow.png">
</div>
</div> ...
3. Final CSS
As in the previous step the CSS here creates blue and
black sections on the page so that they can easily be
seen to demonstrate what is happening. The final two
rules turn animated elements on and of by giving them
opacity values.
EXPERT ADVICE
Animation trickery
The main point of animating content
is to draw attention to it. As content
doesnt appear in its entirety in the
users viewport, it is important to
capture when it actually is present
and make it animate at that point to
give maximum impact to the user.
.blue{
background-color: #00baff;
height: 200px;
}
.black{
background-color: #282f31;
height: 200px;
}
.os-animation{ opacity: 0; }
.os-animation.animated{ opacity: 1; }
</style>
4. HTML content
Move to the HTML section of the page as this is where
the content will be added. This is all styled up via the CSS
that has been added. A full-screen section will be at the
5. Add JavaScript
Now the JavaScript is added and placed in a jQuery
document ready function to allow all elements to load.
Then the function that will be called when the user scrolls
is added. This checks elements on the screen for certain
data attributes and applies CSS accordingly.
<script type="text/javascript">
$(function(){
function onScrollInit( items, trigger ) {
items.each( function()
{
var osElement = $(this),
osAnimationClass = osElement.attr('data-osanimation'),
osAnimationDelay = osElement.attr('data-osanimation-delay');
osElement.css({
'-webkit-animation-delay': osAnimationDelay,
'-moz-animation-delay': osAnimationDelay,
'animation-delay': osAnimationDelay
});
Special effects
jQuery UI-powered
Our drag and drop engine
comes from the jQuery UI
framework its well
known for its almostuniversal compatibility.
Minimal width
Our example does not
enforce a minimum width
for convenience. But
adding this feature does
not require much code.
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
Genius Guide
Figuring out how much one hour of your work day is worth is relatively easy.
Performing a similar computation for spare time tends to be more involved.
Arkiverts Sparetime calculator attempts to value your free time by asking a
group of questions, which are then algorithmically parsed into a surprisingly
accurate estimate. Tam Hanna
Technique
1. Div tags
Lets get started by erecting the scafolding of our
website. It consists of three <div> tags, which are
arranged next to one another via the width and
padding-left properties. Describing the spaces with
relative values ensures that the page remains fullscreen
even if the user changes his window size.
}
function handleDragStart2( event, ui ) {
console.log( "Drag starts!" + event);
}
function handleDrag2( event, ui ) {
console.log( "Drag !" + event);
}
</script>
4. Do some maths
2. Add a draggable handle
Ofering resizable panels is fun only if the user can
actually change their size. This is best accomplished via
two handles displayed in the middle of the borders. For
now, adding simple boxes via a <span> tag and some
CSS magic shall sufice.
EXPERT INSIGHT
Not for mobile
Even though our slider looks
awesome on a desktop, be aware
that it is not particularily well suited
to the needs of mobile phone users.
Most smartphones are used in
portrait mode, where horizontal
space is at a premium. Drag and
drop also requires a level of accuracy
dificult to achieve on touchscreens.
<script type="text/javascript">
$( init );
function init() {
$('#box1').draggable({
start:handleDragStart,
drag:handleDrag});
$('#box2').draggable({
start:handleDragStart2,
drag:handleDrag2});
}
function handleDragStart( event, ui ) {
console.log( "Drag starts!" + event);
}
function handleDrag( event, ui ) {
console.log( "Drag !" + event);
<style type="text/css">
div span.myBox{
position: absolute;
top: 50%;
right:-25px;
width: 50px;
height: 50px;
background-color: lavender;
border: solid 1px silver;
transform: rotate(45deg);
}
Special effects
Sync animations to
audio and video
with Popcorn.js
Trigger events easily at any timeframe and play back music or
video by using Mozillas Popcorn.js
Genius Guide
</div>
</div>
2. Link to popcorn
5. CSS animation
Change the text inside the <h1> tag for each of those
copied sections and you can refer to the text in the
finished file or add your own. A little further down the
body section you will see a bunch of script tags for the
3D animation, add this at the bottom to link to the
Popcorn library.
<audio id="myAudio">
<source src="autumn-leaf.mp3" type="audio/
mpeg">
</audio>
4. Start styling
1. Up and running
Open the start project folder in Brackets or a similar code
editor and open index.html. Scroll down to the body tag
and add the following div tags for our on-screen
messages that will be shown at key points with the
music. Copy and paste this code three more times and
change the id to two, three and four.
}
audio { display:none; }
.hide {
opacity: 0;
transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-webkit-transition: opacity .5s ease-in-out;
}
.show {
opacity: 1;
}
.outer {
Familiar terminology
body {
padding:0;
margin:0;
overflow:hidden;
font-family: 'Oswald', sans-serif;
color:#ffba00;
Left
Special effects
z-index: 10;
width: 100%;
height: 100%;
position: absolute;
top: 0; left: 0;
}
7. Vertical alignment
Inside the fullscreen div of the outer created in the
previous step is another div. The text inside here should
appear in the centre of the screen horizontally and
vertically. The middle class here will ensure that happens
by aligning it on the vertical axis with the page centre.
.middle{
min-height: 100%;
min-height: 100vh;
width: 100%;
display: -webkit-flex;
display: flex;
align-items: center;
-webkit-align-items: center;
}
Additional plugins
There are additional plugins for Popcorn that
allow you to run video from hosted sources such
as Vimeo, YouTube and SoundCloud. Its even
possible to open Google Maps.
Top left
h1{
font-size: 3.8em;
display: inline-block;
width: 40%;
margin: 0 auto;
text-align: center;
text-shadow: 3px 3px #000;
}
<script>
document.addEventListener("DOMContentLoad
ed", function () {
init();
}, false);
</script>
initMusic();
function initMusic(){
popcorn = Popcorn( "#myAudio" );
popcorn.play();
}
camMove1();
var
var
var
var
);
);
);
);
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.
popcorn.cue( 1, function() {
one.classList.add('show');
});
lightOn();
});
popcorn.cue( 17.6, function() {
lightOff();
});
Special effects
Make a draggable
fading effect
As seen on tuckeffect.com/
Enticing object
As the page loads the site
is hidden away behind an
illustration. A button
beckons the user to drag
down to reveal more info.
Background
The background image is
an HTML5 Canvas Tag
that contains the
illustration, this way it can
easily be changed.
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
Genius Guide
Slide to unlock
<comment>
What our
experts think
of the site
Technique
1. Create the pull-down transition
In your HTML page add the tags as shown here. The
main part is that the container will cover the screen until
the drag element is dragged downwards, then the div
below will be revealed. This is actually just held
underneath the other content.
<div id = "container">
<div id = "drag"></div>
</div>
<div>Your real site goes here</div>
3. Such a drag
The drag element is made into a circle by adding a
border radius to it and by changing the width and height
to 150px. This is centred horizontally on the page ready
to be dragged downwards and given a light grey
background so that it can be seen.
5. On and off
When the mouse is pressed down a mouse move
listener is registered then when it is released this listener
is removed. The idea behind this is that it keeps the
movement purely restricted to when it moves and stops
it being dragged and sticking to the mouse even when
let go, which can happen!
function mouseUp(){
window.removeEventListener('mousemove',
divMove, true);
}
function mouseDown(e){
window.addEventListener('mousemove',
divMove, true);
}
6. Tidy it up
Now the function of when the mouse moves is ran and
this really does all the work. It constrains the object to be
dragged on the y axis only and for 300 pixels. When it
reaches 300 pixels the container div is faded out using
CSS transitions.
function divMove(e){
if (e.clientY < end && e.clientY >= start){
div.style.top = e.clientY + 'px';
}
if (e.clientY >= end){
outer.classList.add("fadeOut");
} }
Special effects
Changes on scroll
Zooming image
The main photo is placed
on the bottom layer and is
resized based on the
scroll position to give the
illusion of zooming in.
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.
Genius Guide
The sinister effect can be used to emphasise something serious and is ideal for
use on webpages promoting a serious topic. In the case of the Bloomberg
Business website, it is used to set the tone of a Fifties gangster movie, which
have been the stage for of many stories about corruption.
Leon Brown, freelance web developer
Technique
1. Main page setup
The main page requires the standard HTML, head and
body containers to be defined. This also enables us to
insert the page components in the following steps in a
way that keeps the JavaScript and CSS separate from the
page body content.
3. Content containers
Insert the sinister header and the main page content
inside the page <body> tag. The sinister <header>
contains the background photo image, an overlay image
used for the zoom and a content container for the
additional text content in this case its a title.
5. Sinister styling
The headers styling needs to stretch across the page
and have a visible height. It will also need to hide any
overflow from the zooming images we are using. Images
and the content container will be posited at the top left of
the <head>, which is made possible with the header using
relative positioning.
$(window).on('scroll', header{
display: block;
position: relative;
height: 100%;
text-align: center;
overflow: hidden;
margin-top: 25%;
}
header h1{
font-size: 6em;
color: #c00;
text-shadow: 2px 2px #000
}
header img,
header .content{
position: absolute;
top: 0;
left: 0;
margin: 0 auto 0 auto;
width: 100%;}
$( "#header" ).click(function() {
if (menuOn == false){
$('#menu').animate({"bottom": -100}, 500 );
menuOn = true;
} else {
$('#menu').animate({"bottom": "-100%"}, 500
);
menuOn = false;
}
});
});
EXPERT ADVICE
Adapting the sinister effect
Sinister features
Additional features can be added to the efect by
adding new JavaScript code within the scroll listener.
This tutorial uses the greyscale filter property as an
example of changing the image colour, but other
options are also available for experimenting.
Calculations
The calculations for the transition are made using
percentages so that it works the same in diferent
resolutions. This is important to ensure that the efect
doesnt break with high-res screens. You can test this
using the zoom-out features of your web browser to
simulate a higher resolution.
Limitations
Step 8 shows a condition that stops the overlay resizing
once its horizontal position exceeds -10 pixels. This
prevents the illusion from being broken by larger
resolutions that stops the overlay covering full width,
keeping the webpage adaptable and future-proof.
</script>
Special effects
Sobering statistics
The animations deliver
some frightening stats
about the levels of
cybercrime targeting
users bank details.
Hidden animations
On page load
Genius Guide
These days its a brave website that asks the user to sit through a contentloading percentage bar, however short the wait. The desire for instant content
is relentless. If this is unavoidable you better make sure your loading icons are
interesting and different enough to hold users fast.
Richard Lamb, owner and web designer at Inspired Lamb Design
Technique
1. Background image
Num Num!. Place one apiece into the four yums. Then
give each of div an individual class name, corresponding
to the image names.
EXPERT ADVICE
Content delivery
Packaging important information
into an entertaining, easily
consumable format has become one
of the primary challenges for
websites, especially when delivering
information that has not necessarily
been sought out. One Dollar Lesson
employs just the right mix of
interaction and spectacle.
.um {
animation-duration:
}
.num-one {
animation-duration:
}
.num-two {
animation-duration:
}
.underline {
animation-duration:
}
2s;
4s;
6s;
7s;
@keyframes rise {
0%, 60%, 75%, 90%, 100% {
transition-timing-function: cubicbezier(0.215, 0.610, 0.355, 1.000);
}
0% {opacity: 0; transform: translate3d(0,
3000px, 0);}
60% {opacity: 1; transform: translate3d(0,
-20px, 0);}
75% {transform: translate3d(0, 10px, 0);}
90% {transform: translate3d(0, -5px, 0);}
100% {transform: translate3d(0, 0, 0);}
}
Special effects
Animate typography
and text effects
Give your typography the attention it deserves with these
must-see animated effects with CSS3
Genius Guide
@import url(http://fonts.googleapis.com/
css?family=Oswald:400,700);
html, body {
height: 100%;
font-weight: 800;
}
body {
background: #35483e;
background-image: url(img/bg.jpg);
background-size: cover;
font-family: Arial;
}
<g class="g-ants">
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
<use xlink:href="#s-text"
copy"></use>
</g>
</svg>
class="textclass="text-
@keyframes stroke-offset {
100% { stroke-dashoffset: -35%;}
}
.text-copy:nth-child(1) {
stroke: #5c0404;
animation-delay: -1s;
class="text-
CSS keyframes
class="text-
class="text-
Left
The next text elements are added to the HTML and given
some basic styling for us to place the text under the
animated heading
Top left
Special effects
}
.text-copy:nth-child(2) {
stroke: #d6801c;
animation-delay: -2s;
}
.text-copy:nth-child(4) {
stroke: #ffff9e;
animation-delay: -4s;
}
.text-copy:nth-child(5) {
stroke: #55981b;
animation-delay: -5s;
}
@keyframes stroke-offset {
100% { stroke-dashoffset: -35%;}
}
8. Second effect
That completes the first efect that is being added to text,
so now move down to the body tag and add our code
from FileSilo to the SVG added earlier. This readies the
Naming keyframes
Notice that the keyframes in Steps 14 and 6 have
been given a unique name so that they can be
called by the right piece of animation.
Top left
.static {
float: left;
overflow: hidden;
height: 40px;
}
ul {
margin-top: 0;
padding-left: 130px;
text-align: left;
list-style: none;
animation: 6s linear 0s normal none infinite
change;
}
p {
display: inline;
float: left;
margin: 0;
color:
#ffff9e;
}
@keyframes change {
0% { margin-top: 0; }
15% { margin-top: 0; }
25% { margin-top: -40px; }
40% { margin-top: -40px; }
50% { margin-top: -80px; }
Genius Guide
CSS animation
To take advantage of the
CSS animation, instead of
relying on JavaScript, it is
important to understand
exactly what is going on.
Transitions provide a
change from one state to
another, while animations
can set multiple keyframes
of transition.
Transitions must have a
change in state, and you
can do this with :hover,
:focus, :active and :target
pseudo-classes. The most
popular is hover as this
provides rollover changes.
There are four transition
related uses, transitionproperty, transitionduration, transition-timingfunction and
transition-delay.
Animations set multiple
keyframes that tell an
element what change they
should undergo with @
keyframes and called by
the animation using it.
Only individual properties
may be animated.
font-size: 3em;
font-family: 'Oswald';
text-align: center;
position: relative;
display: block;
.wrapper{
clear:both;
width: 400px;
margin: 0.5em auto;}
.clip-text{
margin-top: 4em;
padding: 0.3em;
background-image: url(img/text-bg.jpg);
background-position: bottom;
background-size: cover;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
transition: 2s ease all;
}
.clip-text:hover, .clip-text:hover::before {
background-position:top;
} .clip-text:before, .clip-text:after {
position: absolute;
content: '';
}
.clip-text:before {
z-index: -2;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image: inherit;
background-position: bottom;
background-size: cover;
transition: 2s ease all;
}
.clip-text:after {
position: absolute;
z-index: -1;
top: .125em;
right: .125em;
bottom: .125em;
left: .125em;
background-color: rgba(214, 128, 28, 0.9);
}
Special effects
Create a 3D navigation
menu with HTML
Learn how to use 3D page elements to reveal content on hover
Genius Guide
<html>
<head>
<title>3D Card Navigation</title>
** Step 2 goes here
</head>
<body>
** Step 3 goes here
</body>
</html>
2. Load resources
The <head> section of your HTML is used to contain links
to resources you are using. Our example will contain a
CSS file for styling and a JavaScript file for detecting
when the user taps on the navigation cards.
3. Card container
The easiest way to ensure consistency and simplicity to
control all elements of the 3D navigation card is to place
them inside a container. Two types of container are used
the main container will control the origin for 3D rotation
while the card container will contain the content
elements that will display relative to the card.
<div class="container">
<div class="card">
** Step 4 goes here
** Step 5 goes here
</div>
</div>
5. Back content
This element will appear when the card is flipped. Like
the front element, it is a container for any content that is
to appear at the back. Using a container like this allows
CSS to rotate everything from the same place.
<div class="back">
*** Step 6 here
</div>
6. Content inside
The content to be placed inside the front and back is just
regular HTML. We will add some text descriptions and
navigation links to the back content container inside the
card. Upon completion of this step, you can now repeat
Steps 3 to 6 to add new navigation cards.
4. Front content
The card will have two sides we place a container for
each of these inside the card container, with each
Left
The full HTML content is now ready for styling with CSS
and interaction listeners via JavaScript to be applied
Top left
Special effects
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
</nav>
display: inline-block;
transform: rotateY(0deg);
perspective: 500px;
margin: 2em;
}
position: relative;
display: block;
transition: 1s;
transform-style: preserve-3d;
}
7. CSS initiation
With all of your HTML set up, the next step is to initiate
the CSS. The page is already expecting to load a file
called styles.css, so create this file and add the following
initial CSS for the standard page styling:
8. Container definition
The first of the containers is used to set the foundations
from which any 3D calculations are performed from. This
includes setting the position, display mode, initial rotation,
margin and also view perspective ie distance from the
viewer. We use a display of inline-block to allow multiple
cards to be placed next to each other.
.container {
9. Container interactions
.container:hover .card,
.container.hover .card{
transform: rotateY(180deg);
}
.container,
.front,
.back{
width: 300px;
height: 500px;
}
Different effects
Other efects can be achieved with 3D rotation by
changing settings such as the transform-origin
and perspective. Add and change these values to
see what efects you can produce.
.card{
Top left
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front, .back {
box-sizing: border-box;
}
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.
.front {
z-index: 2;
transform: rotateY(0deg);
background-size: cover;
}
.front h3{
background: rgba(0,0,0,0.5);
color: #fff;
text-align: center;
padding: .5em;
}
.back {
padding: 1em;
transform: rotateY(180deg);
background: #eee;
}
nav{
display: block;
padding: 2em;
margin: 0;
}
nav a{
display: block;
list-style: none;
background: #aaa;
color: #fff;
font-size: 1.5em;
margin-top: .5em;
padding: .5em;
text-align: center;
}
nav a:hover{
background: #333;
}
window.addEventListener("load", function(){
var containers = document.
querySelectorAll(".container");
** Step 21 code here
});
Special effects
Make a screen
shrink on scroll
As seen on devstars.com
Hidden menu
The regular menu is
hidden behind the burger
menu and sits over the
entire page on the screen
when activated.
Resizing sections
Clicking the dots (right)
automatically scrolls the
page down to the next
section, this fits the
browser window exactly.
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
Genius Guide
the user slides down are the neat show-of points in this
site. Each browser-sized screen on the homepage is like a
diferent slide in a slide show, but you click the navigation
dots on the right-hand side to move down rather than
right to left. The scrollbar is hidden away so this nifty
navigation is a great way to explore the screens that
follow. As you slide down to the next section, the graphic
content on the screen animates, shrinking down in size
and moving of the top of the page. The real menu is
hidden behind the burger icon so what this presents is
an unusual slideshow of important content that Devstars
wants users to see.
Bright bold colours make this site stand out with just enough negative space to
make the logo and site content stand out. The homepages featured content
has an animated effect that draws attention to the care the team put into the
small details of their site.
Mark Shufflebottom, professor of Interaction Design, Sheridan College
Technique
1. Create the shrinking logo effect
When making this efect work, the logo needs to be
placed within a page. As there is no page content here,
some div tags are being added, which will have 600
pixels of height added to them. When the image reaches
the top of the page, it will be shrunk down.
<div
<img
png"
<div
<div
class="space"></div>
id="shrink" src="img/Wikimedia-logo.
/>
class="space"></div>
class="space"></div>
#shrink{
display: block;
margin: 0 auto;
}
</style>
<script >
$(function () {
$(window).on('scroll', function() {
var scrollTop = $(this).scrollTop();
var topDistance = $('#shrink').offset().top;
EXPERT ADVICE
Reinforcing the brand
A logo can say a lot about any
company and Devstars logo features
a series of stars laid out horizontally.
For their showcase content, Devstars
uses the shape of the logo as a mask
for images of work that theyve
produced. This not only looks good
but also reinforces the brand in the
homepage design.
In the head section of the page, the script tag calls the
jQuery library so that we can detect the position of the
page and make DOM changes based on that. The CSS
styling gives the space class a height of 600 pixels, as
the comment states this is purely for demonstration only.
Special effects
Intro
The site opens with a
striking piece of animated
text, set against an
eye-catching colourchanging background.
Beyond home
Try the Projects page out
to see some clever
scrolling techniques, with
slower scrolling in the
centre column.
Portfolio section
A little further down you
will find, in bold black and
white, a Current Projects
section with nice hover
effects and links.
Site Overview
Genius Guide
As mentioned in the intro, web designers can make the mistake of building
their websites with too much of an eye on impressing other web designers,
rather than luring in potential clients. Its an easy trap to fall into, leaving you
with a website that is inscrutable to the layman and useless as a marketing tool.
Richard Lamb, freelance web designer at Inspired Lamb Design
Technique
1. First layer
The efect is achieved with a series of layers arranged
over each other. We build our layers from back to front,
beginning the first set of text. To ensure that the text
flows on one line, spaces should be coded using  
and two sets of text per layer should be used.
<div id="wrapper">
<span class="scroller">
<span class="scrText dark">These Are&nb
sp;Our Words</span>
<span class="scrText dark">These Are&nb
sp;Our Words</span>
</span>
</div>
2. Second layer
Below the above code, but within the wrapper, add the
following divs and the image which will interact with the
text. While it may seem like we are using a few
superfluous divs, the CSS applied to each, with z-indexes
and positioning, will hold the entire construct together.
<div class="scroll-container">
<div class="scroll-image">
<div class="overflow-hidden relative">
<img src="img/bg.jpg"/>
</div><!--overflow-hidden-->
</div><!--scroll-image-->
</div><!--scroll-container-->
3. Third layer
The third layer represents the second set of text, which
will scroll above the image. This should be placed below
the image, within the three divs applied in the previous
step. This should have a unique identifier, front.
bsp;Our Words</span>
<span class="scrText light">These Are&n
bsp;Our Words</span>
</span>
5. Animation keyframes
Set your animation keyframes for a smooth transition
across the screen, creating an endless loop for the
scrolling text. Remember to include all vendor prefixes
for browser variations, including on the animation
declaration in the scroller div.
@keyframes scroll-left {
0% {
transform: translate(0, -50%)
}
100% {
transform: translate(-50%, -50%)
}
}
.scroll-container {
padding-left:8rem;
padding-right:8rem;
width:100%;
EXPERT ADVICE
Sleight of hand
This particular Web Workshop is a great example of
using CSS trickery to create the impression of
something happening which actually isnt. While it may
appear that a single line of scrolling text is changing
colour, in fact there are two lines of scrolling text, one
on top of the other, strategically set to appear and
disappear at concurrent points. It is actually a very
clever piece of trickery when you think it through and
understand the method. And it raises an interesting
point about how we should approach CSS animations
and efects.
Sometimes you dont have to figure out how to
make a particular HTML efect or animation work.
Sometimes you are better of figuring out how to
simply make it look like its working. Sure, an element
scrolling into frame on page-load is actually scrolling
into frame. Thats a simple efect to achieve. But if you
are striving to create an efect that is more complex,
dont rule out the possibility of trying diferent
techniques that create the illusion of the efect, rather
than the efect itself. Its not cheating to use a little
trickery, the efect is just as good and it may just make
your work a little simpler.
box-sizing:border-box;
}
.scroll-image {
position: relative;
z-index: 10;
}
.scroll-image img {
width:100%;
height:auto;
}
.overflow-hidden {
overflow:hidden;
}
.relative
{
position:relative;
}
9. Text colours
Finally we have come to the last step. Assign colours to
the dark and light classes, so that each layer of text has
the colour diferences which create the illusion of a single
layer changing colour. A little piece of HTML sleight of
hand has been pulled of.
tr Spe
ia c
l o ia
ffe l
r
Enjoyed
this book?
Try
3 issues
for just
* This offer entitles new UK Direct Debit subscribers to receive their first 3 issues for 5. After these issues, subscribers will then pay
25.15 every 6 issues. Subscribers can cancel this subscription at any time. New subscriptions will start from the next available issue.
Offer code ZGGZINE must be quoted to receive this special subscription price. Direct Debit Guarantee available on request.
This offer will expire on 28 February 2017.
** This is a US subscription offer. The USA issue rate is based on an annual subscription price of 65 for 13 issues which is equivalent
to $102 at the time of writing compared with the newsstand price of $14.99 for 13 issues being $194.87. Your subscription will start
from the next available issue. This offer expires on 28 February 2017
Uncover the
secrets of
web design
Practical projects
About
the
mag
In-depth features
subscribers to
www.imaginesubs.co.uk/wed
Or telephone: UK 0844 848 8413 Overseas +44 (0) 1795 592 878
* Calls will cost 7p per minute plus your telephone companys access charge
HOW TO USE
LOG IN TO FILESILO.CO.UK/BKS-887 AND
DOWNLOAD YOUR GREAT RESOURCES NOW!
01
Follow the
on-screen
instructions to create an
account with our secure
FileSilo system, log in and
unlock the bookazine by
answering a
simple question
about it. You can
now access the
content for free
at any time.
02
03
04
facebook.com/ImagineBookazines
facebook.com/WebDesignerUK
178
A comprehensive masterclass
in becoming an instant expert
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