Web Design Tips, Tricks & Fixes - Vol.3 2015
Web Design Tips, Tricks & Fixes - Vol.3 2015
Web Design Tips, Tricks & Fixes - Vol.3 2015
E
N
unlock the
potential
of web design
HTML5
CSS3 RWD
JavaScript
WordPress
Welcome to
The complexity of modern websites is a far cry from the early days of the Web.
Current trends for interactivity, animation and responsive design have expanded
the arsenal of skills needed to build exciting, cutting-edge sites. New frameworks
and JavaScript libraries are springing up everywhere, and it can be challenging at
times to keep pace with the industry. Thats where this book comes in. Throughout
each section youll find guides on how best to harness modern tools, add
excitement to pages, and enhance the efficiency of your workflow. For everything
from designing for mobile devices to building your first online shop, read on.
Publishing Director
Aaron Asadi
Head of Design
Ross Andrews
Edited by
Dan Collins
Senior Art Editor
Greg Whitaker
Designer
Abbi Denney
Printed by
William Gibbons, 26 Planetary Road, Willenhall, West Midlands, WV13 3XT
Distributed in the UK, Eire & the Rest of the World by:
Marketforce, Blue Fin Building, 110 Southwark Street, London, SE1 0SU
Tel 0203 148 3300 www.marketforce.co.uk
Distributed in Australia by:
Network Services (a division of Bauer Media Group), Level 21 Civic Tower, 66-68 Goulburn Street,
Sydney, New South Wales 2000, Australia Tel +61 2 8667 5288
Disclaimer
The publisher cannot accept responsibility for any unsolicited material lost or damaged in the
post. All text and layout is the copyright of Imagine Publishing Ltd. Nothing in this bookazine may
be reproduced in whole or part without the written permission of the publisher. All copyrights are
recognised and used specifically for the purpose of criticism and review. Although the bookazine has
endeavoured to ensure all information is correct at time of print, prices and availability may change.
This bookazine is fully independent and not affiliated in any way with the companies mentioned herein.
Web Design Tips, Tricks & Fixes Volume 3 Revised Edition 2015 Imagine Publishing Ltd
ISBN 978-1910439784
Part of the
bookazine series
Contents
Tricks
Tips
64
Animate CSS
16
72
24
78
30
82
34
86
38
90
42
94
46
50
97
102
104
108
54
58
82
Scrolltriggered
animation
34
Build a
responsive
theme
110
112
116
166
170
Fixes
122
128
134
Modernizr masterclass
138
142
146
150
154
158
162
16
Responsive
design
GET IN TOUCH
facebook.com/ImagineBookazines
twitter.com/Books_Imagine
8
How to
tailor your
content
128
Learn about
text and
type
IS
YOUR
CONTENT
KING?
10 MOVES TO PERFECT
YOUR STRATEGY
CONTENT IS EVERYTHING
A
CREATE A PLAN
When it comes to the creation of websites, there are
endless tutorials that can be found online dedicated
to designing and building the perfect site structure.
Web design and web development practices are being
constantly perfected, updated and refined. However,
there is one area of web creation that too often remains illconsidered and badly planned the content itself. Content
is the driving force behind any website. It doesnt matter
how well-built and functional your site structure is, if
the content it houses is sub-standard and fails to do
the job for which it is intended, then youve wasted
your time.
Creation and analysis of web content should be as
important a primary stage of the development of a
website as determining the technology in which the site
will be built, but quite often the content is treated as a
secondary concern. When you think about it, this really
makes no sense at all. The content is the reason that the
site exists in the first place. People have come to your site
for a reason, and its not to click those perfectly scripted
button animations or simply sit and watch the expertly
executed page transitions you spent time on.
Your site only exists to deliver your content, so you
have to question whether your content is the best it can
be. For example, have you actually considered who your
target audience is? This may well be one of the most
overlooked and yet essential factors of content strategy.
How can you design a site that will appeal to a group of
Find out why you should care about content and its
place in the users experience of your site
WHAT QUESTIONS
SHOULD YOUR
STRATEGY ADDRESS?
A basic content
strategy plan
s%FUFSNJOFZPVSBVEJFODF
This is the most important starting
point. Who is the content for? Who are
you trying to attract to your site, service
or product?
s'JOEZPVSUIFNFBOENFTTBHF
What is the message that you want
to communicate to site visitors? What
do you want to tell or show to the
audience you have identified?
s%FWFMPQUIFBQQSPQSJBUFWPJDF
What tone of voice will best deliver the
message and resonate with the chosen
audience, to bridge the gap between
need and solution?
s#FVTFGVM
Does your content serve the purpose
for which it is intended? Is it actually
useful to those for whom you have
identified a need?
s.BJOUBJODPOTJTUFODZ
Is your content consistent in tone of
voice throughout the site? Does your
site communicate with one voice?
RIK BARWICK
Creativitea.co.uk
www.theguardian.com
adobe.ly/19x04z8
WHO Adobe
WHAT Devising a content
strategy using Marketing Cloud
WHY To promote and
demonstrate the effectiveness
of the new software
INCLUDE A SUB-HEADLINE
CASE STUDY:
VIRGIN.COM
How Virgin streamlined their main site to
better appeal to their customers
WHO Virgin.com
WHAT A major relaunch and content strategy for
Virgins main website
WHY To expand on the purpose of the parent site
and unite all Virgin businesses
Media, travel and banking giant Virgin brought in
digital agency Beyond to overhaul their website
and online brand strategy. Virgin.com had
functioned as a portal site to the various branches.
The goal was to boost the already successful
business model by giving the parent site a content
purpose, incorporating Virgins companies and
values into one strategy and theme, aligning that
strategy with current social trends, and increasing
the amount of time users spend on the page.
Working with Virgins digital manager Bob
Fear, Beyond analysed metrics and analytics from
Google, Hootsuite and social media channels to
ascertain the digital marketing approaches yielding
the best responses. They researched Virgins
core audience, deciding which customers had the
QVirgin is keen to cater to its core audience by updating its main website
USEFUL RESOURCES
GOOGLE TRENDS
www.google.co.uk/trends
Google provides a mighty armada of tools and
resources that can help you tailor your content.
Webmaster Tools and Analytics give you
everything you could possibly need to monitor
your sites traffic, while Trends gives you up-todate information on the popularity of particular
keywords and search terms, allowing you to fine-tune the keywords that you end up
using in your content. You can also make use of Hot Searches to see which topics are
currently trending and make sure you ride that wave with some focused content and
social media links. Measure your service or product against a competitors and alter
your marketing approach accordingly.
LISTLY
HOOTSUITE
list.ly
hootsuite.com
Tips
16
24
30
34
38
42
46
50
54
58
24
30
Design sites
in your
browser
Learn to
code with
Brackets
38
50
Build a
responsive
slider
Add angled
page
designs
16
Discover key
RWD tips
and tools
EXPERT INSIGHT
Nearly every brief I see asks
for support for mobile and, with
the proliferation of devices over
recent years, this cannot be ignored.
Responsive design takes focus away
from which handset or what system,
allowing teams to focus on crafting
great experiences and how they can be
enhanced by available technology.
Damian Proctor
Executive creative director
Q Redweb
START PLANNING
The standard next step in any
website project would be to map out
the IA, but with a responsive build it
helps to take this a little further. Once
the site structure is mapped out
and key content elements defined,
these content elements need to be
prioritised. This will be really beneficial
when you get to the build, as it helps define the markup structure and content flow for small screens.
You can now start sketching out the page layouts;
start with the global elements like the header, footer
and site navigation and cover small, medium and
With good
planning and
RS \WbW]\Wbya
[cQVSOaWS`
b]Q`SObS
a][SbVW\U
W[^`SaaWdS
Balsamiq
Chalkmark
www.xmind.net
A great application for mapping out site and
content structure using a drag-and-drop
interface, allowing quick and easy iteration.
balsamiq.com
A rapid wireframing tool with a wide range of predefined
common components to choose from. This makes it easy
to lay out ideas as if you are sketching on paper.
www.optimalworkshop.com/chalkmark.htm
An online tool thats great for sharing your
wireframes and setting up quick click testing
and feedback for users.
BUILD CONSIDERATIONS
From using
the right
responsive
framework
to ensuring
ST QWS\b^OUS
load times
eWbVQ]\QWaS
8OdOAQ`W^b
Q]RS
Page performance
In terms of performance, todays browsers are a far
cry from the days of IE8 and below. Its important to
remember that, although a browser can run JavaScript
and render complex designs efficiently, not all devices
will have the best connection speeds. It is paramount
that the page load times are kept as low as possible,
there are a few simple things to consider that ensure
your site build performs for all screens.
Using CSS3 shapes instead of images
It is standard practice to use image sprites to save on
the number of images loaded within a page. For simple
icons and shapes you can replace these images with
CSS3 shapes. A great resource to check out is css-tricks.
Adapting functional
components
Run through your list of functional components,
created during the planning phase, and ascertain what
is possible for each screen size and/or device to be
supported. Try not to restrict functionality for all users
BOOTSTRAP
FOUNDATION
SKELETON
getbootstrap.com
Probably the most popular and longest-standing
framework available, with extensive input from
the open source community.
foundation.zurb.com
A powerful and well-structured framework with
some very impressive plug-ins.
www.getskeleton.com
An easy and lightweight grid framework with
simple styles to get working quickly.
PROS
CONS
CONS
CONS
PROS
CONS
CONS
CONS
;]PWZS `ab
When taking this approach you can be sure that you
will not be building complex page layouts that are
difficult to adapt when the screen width is reduced. It
also will ensure that the mark-up structure you write
will follow the content prioritisation defined as part of
the IA. As you will be primarily focused on touchscreen
devices you will inevitably cater for touchscreen events
from the outset, creating a more efficient and tailored
solution for these devices. You may find, however, that
when viewed on desktop or larger screens, the layouts
seem very simple and not that creative or interesting.
2SaYb]^4W`ab
When catering for larger screens first you will not
be restricted in terms of creative page layouts and
functionality. You can be confident that those users
with larger screens will have the best experience of
your site as possible. It is easy, however, to not cater
for touch interactions and have to code these in later,
which is more difficult. It is also common to cause
yourself problems when reducing the screen size
as the mark-up may not be ordered by the correct
prioritisation, which means a certain amount of DOM
manipulation is required to cater for these particular
sizes. Some of the functional components will not
work on smaller screens and, if you havent accounted
for these in your planning, this can severely increase
the time the site takes to build.
BVS@WUVb
/^^`]OQV
be aware of the
dO`W]caPS\S ba
and pitfalls in
taking either
approach and
decide which
works best for
your project
Fullsize screens
offer the option to
add all the relevant
navigation elements
including search.
Think how to include
on the small screen
All interactions
are bound using
touch events to
reduce perceived
lag and provide a
smooth interface
Images are
loaded when
needed to
ensure page
load speeds
are maintained.
The amount of
images in each
section of this
gallery layout
is adjusted for
mobile devices
0]bVbVS ZbS`
and navigation
elements are
toggled from
view on smaller
devices, allowing
more room for
the core site
content but still
providing clear
site controls to
the user
Collapsible menus
With responsive
sites the design
process can be
daunting, but it
doesnt have to be
Slide-out menus
This particular approach has been made
popular by the Facebook application on
many devices. The menu is displayed off
the screen and with a swipe or button tap,
it slides into view. This is really useful for
nested links, as tapping a menu item can
slide a list of child pages into view.
Anchor linking
SETTING UP A FRAMEWORK
TOUCH
CONSIDERATIONS
01
02
03
04
05
get creating
ADAPTIVE
JAVASCRIPT
Use Matchmedia and window.
onresize events to adjust your
JavaScript functionality
Inevitably you will need to change either
some markup based on the screen size eg,
you may have a sliding carousel of images
and on smaller screens not want it to slide
automatically. You could achieve this by
checking the window width on page load and
then setting up the functionality to match.
This, however, wont run again when the
window is resized, so will only implement
the functionality based on the initial window
size. To achieve this youll have to update the
functionality on either a window.onresize
or Matchmedia event. The window.onresize
event is triggered for every pixel change in
window size, so itll be intensive to run checks
every time it fires. This makes the Matchmedia
event a more efficient solution. These events
are only triggered when the window is resized
to the matching rules set, the same event that
CSS media queries listen to.
This technique gives the added benefit of
matching your CSS media queries, so aligning
JavaScript adaptations with your layout
changes is easy to manage. If you use window.
innerWidth the value returned doesnt match
the value that triggers the CSS media queries.
TIME TO TEST
How to be
Q]\ RS\b
that your
PcWZReWZZ
work across
RSdWQSa
without
costing too
much time
in the browser from 320px and up. If you just catered for the
screen widths of specific devices, the final solution will not be
future-proof. Devices with new screen widths are coming out
all the time, so we cant assume that the most popular devices
now will remain so. In these browsers you can also emulate
touch events, but this doesnt really give you the tangible
feedback that using a touchscreen does.
Test as you go
This is a simple approach, just as relevant for desktop browsers,
you test each layout and component on a tablet and phone
as you create them. Make sure that with both devices you are
covering the Android and iOS platforms this way when you get
to the end of the build you shouldnt have any bugs that affect all
devices or are linked to a specific platform.
EM ULATORS VS DEVICES
There is
a host of
emulators
OdOWZOPZST]`
testing, but
can they be
`SZWSRc^]\-
emulators
PROS
CONS
CONS
Adobe Edge
Inspect
html.adobe.com/edge/inspect
If you already use Adobe software
you will probably have a license
for this application. It allows you
to connect multiple devices to
your Chrome browser and then
synchronise page loads across
them from your desktop. A range
of debugging tools are provided,
giving you access to the DOM, CSS
and Console for each device.
Ghost Lab
vanamco.com/ghostlab
This application was initially only
available on Mac OS, but is now
available for Windows users too. It
not only synchronises page loads,
but also page interactions. This
tool also provides some really
useful debugging tools, making
the process of fixing your bugs
that much quicker.
devices
TOOLS
TO TEST
Its really satisfying to see something you are building running seamlessly
across a range of devices. Whether you have a range on hand to build with
or use devices from an open device lab, you can be confident that users will
have a great experience when visiting a site you have built.
CONS
PROS
CONS
CASE
STUDY
RESOURCES
Useful tools that will make
the RWD process easier
Survs
inspiration.farrow-ball.com
Farrow & Ball creates unparalleled paints and
handcrafted wallpapers, distributing them
around the world. Known for the quality of its products Farrow
& Ball has a large and varied customer base, from the home
decorator to interior design and corporate clients.
WHO
WHAT
WHY
The industry
is always
changing what can we
expect from
the future
of RWD?
www.survs.com
Provides the ability to create online surveys
and add them to a clients existing site. You
can then gather vital information from their
current users, without the cost and time of
holding focus groups with users.
PlaceIt
placeit.net
Upload your site designs or scrape straight from
an existing URL and then have your image placed
within a range of screens and devices. Excellent
for visualising the final product to clients.
Window Resizer
for Chrome
chrome.google.com/webstore/detail/
window-resizer
Test your CSS layouts quickly with this simple,
but very useful, free extension for Google
Chrome. There is a range of quick links to
resize the browser to specific device sizes and
also the ability to extend with your own sizes.
JS Console
jsconsole.com
Not the most exciting-looking tool but one of
the most useful. This gives you access to the
JavaScript console of a device with a simple
script injection. There are straightforward
instructions and demonstrative videos on how
to use it included on the site.
Discover the web browser development tools that will help you to
prototype, test and optimise your website to perfection
TOP TOOLS
Qgetfirebug.com
The Firebug extension allows you
to inspect HTML elements directly
within the DOM, including procedurally
generated nodes.
FireFTP
Q
mzl.la/1cArbIa
A simple debugging tool is built in,
allowing you to create JavaScript
breakpoints and check whats going on
as your code executes.
Fireshot
Q
mzl.la/1hM6cWU
01
02
Edit HTML
03
EASILY EDIT A
PAGE IN CHROME
Editing HTML markup and
styles is straightforward in
Chrome using the built-in
developer tools provided
01
Open Developer
Tools panel
TOP TOOLS
Pendule
Q
02
Style it up
03
Delete elements
bit.ly/1f6nXMu
MeasureIt!
Q
bit.ly/1bvfNZv
When youre converting
a mockup from a static
Photoshop comp into a
working HTML page or
deconstructing a design, it can be tricky to get everything
perfect. MeasureIt! simplifies this with a measuring ruler.
The process is simple: draw out a ruler across the browser
window, and MeasureIt! will feed back the width and height
of any elements on the page. By using this in combination
with the built-in developer tools, you can quickly resize and
reposition elements to achieve a perfect representation of
the mockup. Its also handy for getting an at-a-glance reading
on the dimensions of a particular element within the page.
LEARN THE
SHORTCUTS
Qbit.ly/1d7Livt
Inspect an
element
Inspect devices
Q
bit.ly/1d7LSJK
01
TOP TOOLS
02
Edit HTML
and CSS
03
ySlow
Q
yhoo.it/1kyCH7W
The ySlow extension, developed
by Yahoo!, is available for all the
common browsers, so youre
not limited to using Safari. ySlow
allows you to inspect a pages
performance, marking it against
a series of tests and making
recommendations to improve
page performance.
There are a core 20-plus rules
to ensuring the best performance
of your page, and each time the
extension runs it checks the page
against these criteria. These are
techniques that many developers
employ, but if youve overlooked
one or more, ySlow will alert you.
TOP TOOLS
Qbit.ly/IENotW
Just as with all the other tools available,
the newly refreshed Internet Explorer
F12 developer tools offers a full web
inspector and console.
UI Responsiveness
Q
bit.ly/1golD73
Emulation tools
Q
bit.ly/18lF9P4
01
02
Edit a node
03
USE OPERAS
DRAGONFLY TOOLS
Use our quick-start guide to get
going with Opera
01
Inspect an
element
TOP TOOLS
Chromiumbased
extensions
Q
QCross-platform
development
www.opera.com/dragonfly
Opera is a big player
in the mobile world. If
youre targeting devices
outside desktop, it makes
a lot of sense to test and develop your site using Opera.
Happily, Dragonfly works across all devices, so you can use
the same toolset to inspect and query your page whether
youre testing against a tablet, smartphone, or desktop.
This is especially useful when it comes to older phones or
embedded devices such as TV set-top boxes. The former are
especially prevalent across the developing world, where the
latest versions of Android or iOS arent nearly as relevant or
universal as they are in the UK.
02
03
bit.ly/1bHfcbG
Since Opera
dropped its Presto
rendering engine
and moved to the Chromium engine, which also
powers Google Chrome, Opera is now compatible with
a range of plug-ins for the Chrome browser. This means
any extensions youre already using and familiar with
on Chrome will likely work in Opera too. Similarly, any
specific-to-Opera extensions that have been converted
to use the Chromium engine will work in Chrome.
An example of such a tool is the Accessibility
Developer tools, provided by Google Accessiblity. This
adds an accessibility audit to the developer toolset, and
an additional accessibility sidebar in the Elements tab
inside Chromes developer tools, or Operas Dragonfly.
01 Download Brackets
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
a
<Above>
sBrackets is a great option for
developers who want an easier time
and who wouldnt?
03 Instant help
04 Image management
05 Live Preview
Useful extensions
01 _____________Markdown Preview
This adds a new menu icon visible when editing
Markdown fi les. A panel will display the
rendered output of your .md fi le contents
directly within the editor.
09
Highly extensible
02_____________PageSuck
Ever needed to copy source code from a live
site? This extension will draw in the contents of
a provided URL and create a new fi le for you to
work with.
03_____________Git Control
There are a number of extensions that manage
Git processes and resources. Brackets Git adds Git
control directly into the editor for a cleaner
workflow solution.
10 Theseus debugging
11 Theseus in action
With the extension installed and Live Preview running, lets start to add some jQuery code
to the document and place a $(document).ready() function call. As soon as it is saved and
automatically reloaded you will see updates in the left margin of the editor to represent the live
callback from the code.
12 Multiple functions
If we continue to add JavaScript functionality within the script block we will start to see how Theseus works
in a little more detail. Here we have added a click handler to a button element. Once saved, the callback count will
update with every click of the button, and the initial .ready function stays at 1 as expected.
Developing extensions
Creating your own extensions for Brackets is
incredibly easy. It is essentially based upon a
single JavaScript file that manages the event
handlers and callbacks, and taps into the core
API components available. These include file
system integration, menu management to
apply extension menu items to the editor itself
and document manipulation and that is
13 Inspect callbacks
14 Asynchronous calls
15 Enable Theseus
17 CSS hinting
19 JavaScript linting
Object
inspection
Theseus allows you to dig
deeper into the returned
objects and arguments
within your JavaScript
code directly within the
Brackets editor to
help identify and
manage data.
21 Customise it
The Brackets Extension APIs have been heavily refactored in the later releases to give
developers more power to interact with the file system and the option to harness the full power of
the Node services. Build your own extensions quickly and easily and follow the detailed
documentation available from github.com/adobe/brackets/wiki/How-to-Write-Extensions.
Build a
responsive
WordPress
theme
01 Download FoundationPress
02 Custom stylesheet
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
T
< Above>
sStart building responsive WordPress themes using Zurbs own
advance Foundation framework starter theme, conveniently
called FoundationPress
< Above>
s:PVDBOdownload Zurbs Foundation WordPress starter theme,
FoundationPress, with ease over on GitHub
005
</div>
006 </div>
007 </header>
001 .main-head {
002 margin-bottom: 2em;
003 padding: 1.2em;
004 background: #00b3d3;
005 background: -moz-radial-gradient(center,
ellipse cover, #00b3d3 0%, #007295
100%);
< Above>
sWe used Foundations grid system on the
search form, which will auto scale down for
mobile and tablet devices
< Top>
sIn WordPress, activate FoundationPress
starter theme. This theme includes all the
Foundation framework library
006
007
background: -webkit-gradient(radial,
center center, 0px, center center, 100%,
color-stop(0%,#00b3d3), color-stop
(100%,#007295));
background: -webkit-radial-gradient
(center, ellipse cover, #00b3d3 0%,
#007295 100%);
008 }
009 .main-head h1 {
010 text-align: center;
011 font-weight: 900;
012 text-transform: uppercase;
013 letter-spacing: 10px;
014 text-shadow: 1px 1px 2px rgba
015
016
017 }
06 Add a search
07 Customise search
< Left>
sEnabling navigation to appear on mobile
devices can be controlled all through the
Menus panel in WordPress
< Bottom>
sFoundationPress allows you to order
menus to be on the left or right side of the
menu and enable for mobiles
Update Foundation
with Bower
005
006
007
008
009
searchform_top); ?>
<div class=large-8 columns searchbox>
<input type=text value= name=s
id=s placeholder=<?php esc_attr_e
(Search, FoundationPress); ?>>
</div>
<?php do_action(foundationPress_
searchform_before_search_button); ?>
<div class=large-4 columns
searchbutton>
<input type=submit id=searchsubmit
value=<?php esc_attr_e(Search,
FoundationPress); ?> class=prefix
button>
</div>
08 Modify index.php
09 Blog post
003
004
005
006
007
< Above>
s)FSFXFIBWFPVSfully responsive WordPress site, resizing to
perfectly display on all screen sizes
< Top left>
sEasily set up and use shortcodes in your site to take advantage of
Foundations library of components
< Bottom left>
sUsing WordPress shortcodes, we were able to add Foundations
alert box components throughout the site
008
009
010
011
012
(large); } ?></a></figure>
<?php the_excerpt(); ?>
<p>Posted on <?php the_time(F jS, Y
); ?> in <?php the_category(, );
?></p>
<p class=byline author>Written by
<?php the_author_posts_link(); ?>
</p>
<a href=<?php the_permalink(); ?>
class=button>Read more</a>
</div>
001
002
003
004
005
006
007
008
009
010
.panel {
box-shadow: 0 1px 5px #D5DEE5;
}
figure {
margin: 0;
}
.entry-content figure img {
margin: 10px 0;
}
@media only screen and
(min-width: 40.063em) {
011 h2 {
012
font-size: 1.8rem;
013 }
014 }
equalizer>
<?php do_action(foundationPress_
before_sidebar); ?>
<?php dynamic_sidebar(sidebarwidgets); ?>
<?php do_action(foundationPress_
after_sidebar); ?>
</aside>
</div>
13 Widgets
001 .bottom-sidebar {
002 padding-top: 10px;
15 Set up shortcodes
16 Shortcode array
001
002
003
004
005
17 Shortcode markup
002
003
003 }
004 add_action(init, register_shortcodes);
19 Shortcodes to use
20 Alert boxes
21 Footer
before_footer); ?>
<?php dynamic_sidebar(footerwidgets); ?>
<?php do_action(foundationPress_
after_footer); ?>
</div>
</footer>
require_once(library/foundationshortcodes.php);
You could even store all of your shortcodes
within a separate plugin. That way, in the event
that you switch themes, they will always be
available and working.
001
002
003
004
005
006
007
008
009
010
011
012
.main-footer {
padding: 10px 0;
background-color: #9c9c9c;
}
.pagenav ul {
margin: 10px 0 0 0;
}
.main-footer li {
float:left;
margin-right: 10px;
list-style: none;
}
Build a
responsive
slider using
bxSlider
Learn how to use the bxSlider jQuery
plug-in to install and customise a
responsive slider onto your website
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
003
004 <!-- bxSlider Javascript file -->
005 <script src=//ajax.googleapis.com/ajax/
libs/jquery/1.10.2/jquery.min.js></script>
001
002
003
004
005
006
007
008
009
010
011
012
013
<div class=sliderwrap>
<ul class=bxslider>
<li><img src=img/slide1.jpg /></li>
<li><img src=img/slide2.jpg /></li>
<li><img src=img/slide3.jpg /></li>
<li><img src=img/slide4.jpg /></li>
</ul>
</div>
.sliderwrap{
float:left;
width:100%;
}
06 Fire it up
03 Grab BXSlider
001
002
003
004
005
<script>
$(document).ready(function(){
$(.bxslider).bxSlider();
});
</script>
<Left>
sThe bxSlider plug-in makes creating
responsive sliders as simple as can
be. A basic slider can be installed
within only a few minutes
<Below>
sUse the caption feature for
annotated slides, and customise the
elements to suit your needs
Mix it up
07 CSS conflicts
001 ul.bxslider{
002 margin:0;
003 }
08 Other styling
but there are also options for vertical and fade. Set your
transition option, as well as the sliders transition speed (set
to 500 by default), by declaring them as follows:
001 <script>
002 $(document).ready(function(){
003 $('.bxslider').bxSlider({
004
mode: 'fade',
005 speed: 2000
006 });
007 });
008 </script>
10 Add captions
011
012
013
014
015
016
017
</script>
@media screen and (min-width: 769px) {
.bx-wrapper .bx-caption span {
font-family: 'Open Sans', sans-serif;
font-size:22px;
}
}
Lizard"/></li>
002
003 <script>
004 $(document).ready(function(){
005 $('.bxslider').bxSlider({
006
mode: 'fade',
007 speed: 2000,
008 captions: true
009 });
010 });
001 <script>
002 $(document).ready(function(){
003 $('.bxslider').bxSlider({
004
adaptiveHeight: true,
005
mode: 'fade'
006 });
007 });
008 </script>
12 Thumbnail navigation
src=img/thumbs/thumb2.jpg /></a>
004 <a data-slide-index=2 href=><img
src=img/thumbs/thumb3.jpg /></a>
005 <a data-slide-index=3 href=><img
src=img/thumbs/thumb4.jpg /></a>
006 </div>
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
<script>
$(document).ready(function(){
$(.bxslider).bxSlider({
pagerCustom: #bx-pager
});
});
</script>
#bx-pager {
text-align: center;
margin-top: -30px;
float: left;
width: 100%;
}
#bx-pager img{
padding:5px;
}
Responsive carousels
Three values are required to create a basic
responsive carousel; slideWidth, maxSlides and
minSlides. SlideWidth sets the maximum width of
each slide in the carousel. If this value is not set,
Full width
Remember that bxSlider is
responsive, and 100% can
mean bigger as well as
smaller. Make sure there are
max-widths in place for
full-width sliders on
larger screens.
003
<li><img src="img/ticker/ticker2.jpg"
14 Callback API
001 <script>
002 $(document).ready(function(){
003 $('.bxslider').bxSlider({
004
onSliderLoad: function(){
005
alert('The slider is ready to go.
Click OK right now!');
},
onSlideAfter: function(){
alert('One slide down. Click OK to
see the next one!');
009
}
010 });
011 });
012 </script>
006
007
008
013
15 Easing alternatives
/></li>
004
<li><img src="img/ticker/ticker3.jpg"
/></li>
005
<li><img src="img/ticker/ticker4.jpg"
/></li>
006
<li><img src="img/ticker/ticker5.jpg"
/></li>
007 </ul>
008
009 <script>
010 $(document).ready(function(){
011 $('.bxslider').bxSlider({
012
minSlides: 4,
013
maxSlides: 4,
014
slideWidth: 362,
015
slideMargin: 10,
016
ticker: true,
017
speed: 6000
018 });
019 });
020 </script>
004
005
006
007
008
009
010
011
012
013
014
015
016
017
019
020
.controls {
width: 200px;
margin: auto;
text-align: center;
}
<script>
$(document).ready(function(){
$('.bxslider').bxSlider({
nextSelector: '#slider-next',
prevSelector: '#slider-prev',
nextText: 'Onward ',
prevText: ' Go back'
});
021 });
022 </script>
023
005
006 .bx-prev{
007 width:100px;
008 height:100px;
009 background:url(img/butterfly-left.png)
no-repeat;
010 background-size:cover;
011 float:left;
012 }
013 .bx-next {
014 width:100px;
015 height:100px;
016 background:url(img/butterfly-right.png)
no-repeat;
017 background-size:cover;
018 float:left;
019 }
020
021 <script>
022 $(document).ready(function(){
023 $(.bxslider).bxSlider({
024
nextSelector: #slider-next,
025
prevSelector: #slider-prev,
026
nextText: ,
027
prevText:
028 });
029 });
030 </script>
18 Multiple slideshows
007
008
li>
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
19 Standard carousel
008
009
010
011
012
013
014
015
016
017
018
<script>
$(document).ready(function(){
$('.slider1').bxSlider({
slideWidth: 320,
minSlides: 2,
maxSlides: 3,
slideMargin: 10
});
});
</script>
li>
004
<li><img src="img/slide3.jpg" /></li>
005 </ul>
006 <ul id="slider2">
20 Vertical carousel
001
002
003
004
005
006
007
008
009
010
011
<script>
$(document).ready(function(){
$('.slider1').bxSlider({
mode: 'vertical',
slideWidth: 600,
minSlides: 2,
slideMargin: 10
});
});
</script>
21 Using video
22 Reload slider
004
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
<script>
var slider = $('.bxslider').bxSlider({
mode: 'horizontal'
});
$('#reload-slider').click(function(e){
e.preventDefault();
slider.reloadSlider({
mode: 'fade',
auto: true,
pause: 1000,
speed: 500
});
});
</script>
Code a
stunning
mobile app
with Ionic
Build feature-rich HTML or mobile
apps using the new Ionic framework,
offering both style and substance
01 Install Ionic
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
m
<Above>
sThe Ionic framework is built for
simplicity, speed, aesthetics and
great user interaction and experience
on the mobile level. The library is
open source and contributions are
widely appreciated by the
community. Get involved and help
shape the framework as
you use it
02 Starter applications
03 Generated structure
04 Add a platform
<Left>
sThe Ionic command line script generates a
new application for you in the requested
directory location
<Above>
sTo use the existing code base/application
structure as a PhoneGap mobile application you
will need to add a platform entry for each
platform you wish to generate a build for
Built for
Angular.js
06 CSS components
09 Icons included
<Far left>
s)FSFXFBSFVTJOHBOJOTUBMMFE
emulator to view a representation of
the iOS app were building, as
outlined in Step 5
<Left>
s*OLFFQJOHXJUIQPQVMBSNPCJMF
layouts a footer element is created.
This is populated with a set of icons
UPDMFBSMZEFOPUF)PNFBOE4FUUJOHT
controller=appController>
<ion-refresher pulling-text=Pull to
refresh... on-refresh=refreshList()>
</ion-refresher>
<ion-list>
<ion-item ng-repeat=item in items>
</ion-item>
</ion-list>
</ion-content>
12 Angular controller
10 JavaScript API
003
004
005
Help is at hand
While still a young framework,
Ionic has a number of great
resources from which to
learn. They even have an
online book, which is
definitely worth checking out.
Find it at ionicframework.
com/docs.
009
});
010 };
011 });
Code library
A closer look
Lets dig a little deeper into some of the available features
and functions on offer through the Ionic framework
You can obtain platform
and device information
through the onReady
function if you have the
Cordova device plugin installed
15 Device testing
16 Community support
001 ionic.Platform.ready(function(){
002 var thisDevice = ionic.Platform.device();
003 var model = thisDevice.model,
004
platform = thisDevice.platform,
005
version = thisDevice.version;
006 console.log(ionic.Platform.isCordova());
007 console.log(ionic.Platform.isIPad());
008 console.log(ionic.Platform.isIOS());
009 console.log(ionic.Platform.isAndroid());
010 });
001 document.getElementById(exitButton).onclick =
exitApplication;
002
003 function exitApplication() {
004 ionic.Platform.exitApp();
005 }
001 var app = angular.module(myApp, [ionic]);
002 app.config(function($stateProvider) {
003 $stateProvider
004 .state(index,
005 {
006
url: /,
007
templateUrl: welcome.html
008 })
009 .state(about,
010 {
011
url: /about,
012
templateUrl: about.html
013 });
014 });
Create
animated
buttons
with CSS3
Using the transform property,
well create some cool-looking
3D buttons that will add that
extra polish to your site
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
01 Get ahead
content=IE=edge,chrome=1>
<meta name=viewport content=
width=device-width, initial-scale=1.0>
<title>Creative 3D Buttons</title>
<link rel=stylesheet type=
text/css href=css/main.css />
<script src=js/modernizr.custom.js>
</script>
</head>
02 Content body
001 <body>
002 <div class=container>
003
004
005
006
007
<section class=3d-buttons>
</section>
</div><!-- END container -->
</body>
</html>
03 Button HTML
001
002
003
004
005
006
007
008
009
010
<body>
<div class=container>
<section class=3d-buttons>
<p class=btn_perspective>
<button class=btn btn-3d btn-3da>Submit
</button>
</p>
</section>
</div><!-- END container
</body>
</html>
001 <body>
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
<div class=container>
<section class=3d-buttons>
<h2>Creative 3D buttons</h2>
<p class=btn_perspective>
<button class=btn btn-3d btn-3da>Submit
</button>
</p>
<p class=btn_perspective>
<button class=btn btn-3d btn-3db>Submit
</button>
</p>
<br />
<p class=btn_perspective>
<button class=btn btn-3d btn-3dc>Submit
</button>
</p>
<p class=btn_perspective>
<button class=btn btn-3d btn-3dd>Submit
</button>
</p>
</section>
</div><!-- END container -->
</body>
</html>
05 The CSS
001
002
003
004
005
006
007
008
009
010
011
012
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body, html {
font-size: 100%;
padding: 0;
margin: 0;
height: 100%;
}
06 Body styles
001
002
003
004
005
006
007
008
009
010
011
012
013
body {
font-family: Arial, sans-serif;
background: #0e83cd;
}
a {
color: #888;
text-decoration: none;
}
a:hover,
a:active {
color: #333;
}
07 Contain it
09 Button styles
001
002
003
004
005
006
007
008
009
010
.container {
height: 100%;
position: relative;
}
.container > section {
margin: 0 auto;
padding: 6em 3em;
text-align: center;
color: #fff;
}
08 Heading styles
001 h2 {
002 color: #fff;
003 margin: 20px;
004 text-align: center;
005 text-transform: uppercase;
006 }
007
10 Button pseudo
Adding
media queries
Use media queries at
breakpoints in your design
for approximations of when
the design changes by
different devices,
reformatting
the content accordingly.
Transform property
There are several different
transform functions, each
applying a different visual effect.
Be sure to experiment
and find your
favourites.
001 .btn:after {
002 content: ;
003 position: absolute;
004 z-index: -1;
005 -webkit-transition: all 0.4s;
006 -moz-transition: all 0.4s;
007 transition: all 0.4s;
008 }
11 Button perspective
001 /* Button */
002 .btn_perspective {
003 -webkit-perspective: 800px;
004 -moz-perspective: 800px;
005 perspective: 800px;
006 display: inline-block;
007 }
12 Button 3D
14 Hover state
001
002
003
004
005
006
007
008
009
001 .btn-3da:hover {
002 transform: rotateX(-45deg);
003 }
.btn-3d {
display: block;
background: #5cbcf6;
outline: 1px solid transparent;
transform-style: preserve-3d;
}
.btn-3d:active {
background: #55b7f3;
}
13 3D animation
001 .btn-3da:after {
002 width: 100%;
003 height: 42%;
004 left: 0;
005 top: -40%;
006 background: #53a6d7;
007 transform-origin: 0% 100%;
008 transform: rotateX(90deg);
010 }
15 Button B
16 Hover state B
007
008
009
010
011
012
013
014
015
016 }
background: #53a6d7;
-webkit-transform-origin: 100% 0%;
-webkit-transform: rotateY(-90deg);
-moz-transform-origin: 100% 0%;
-moz-transform: rotateY(-90deg);
-ms-transform-origin: 100% 0%;
-ms-transform: rotateY(-90deg);
transform-origin: 100% 0%;
transform: rotateY(-90deg);
18 C button animation
001 .btn-3dc:hover {
002 transform: rotateY(25deg);
003 }
19 Finish up
< Above>
sAll done! Now we can see how things look when we
resize the browser window
Mobile first
Even with a small project like
this, you should always think
about making it responsive and
suitable for mobile
like how we made our
buttons larger.
deep as the first button, so we give the rotateX property
a value of just 35 degrees.
001 .btn-3db:hover {
002 transform: rotateX(35deg);
003 }
21 Responsiveness
22 Final thoughts
Understanding
transform-origin
As indicated in this tutorial, the transform-origin
property can take up to two space-separated
keywords or length values for a 2D transform
and up to three values for a 3D transform.
.square {
transform-origin: top left;
transform: rotate(360deg);
}
17 Button C styles
20 Button D animation
001 .btn-3dd:hover {
002 -webkit-transform: rotateY(-15deg);
003 -moz-transform: rotateY(-15deg);
004 -ms-transform: rotateY(-15deg);
005 transform: rotateY(-15deg);
006 }
007
Add angled
page designs
with CSS
and jQuery
Create a striking page design with
CSS3 by using an angled background
and adding images
06 Add a paragraph
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
04 Opposite angle
001 .container{
002 display: block;
003 width: 100%;
004 overflow: hidden;
005 padding-top: 50px;
006 }
08 A wider margin
001 .angle{
002 margin: 0 -50px;
003 -webkit-transform-origin: left center;
004 -moz-transform-origin: left center;
005 -o-transform-origin: left center;
006 -ms-transform-origin: left center;
007 transform-origin: left center;
008 }
09 Odd angles
< Above>
s(JWJOHUIFABOHMFDMBTTBXJEFSNBSHJOUIBOUIFQBHFDBVTFTUIFDPOUFOUUPMPXPGUIF
FEHFTPGUIFQBHF
CVUUIJTXJMMIJEFUIFFEHFTPGUIFBOHMFMBUFSPO
< Above>
s"EEJOHUIFBDUVBMSPUBUJPOUPUIFFMFNFOUTDBVTFTUIFNUPEJTBQQFBSCFDBVTFXFIBWFB
NBSHJOUPQPGQY
TPFBDIBOHMFPWFSMBQT
< Above>
s8FDBOTFFBMMUIFBOHMFDMBTTFTXPSLJOHBUUIFJSEJGFSFOUBOHMFTCVUUIFZIBWFOUCFFO
QSPQFSMZGPSNBUUFEZFU
TPUIFZSFTUJMMPWFSMBQQJOHBOEDBOUCFSFBE
< Bottom right>
s'JOBMMZXFIBWFFBDITFDUJPOUBLJOHVQUIFJSEFTJHOBUFETQBDFXJUIJOUIFEFTJHOnOPXXF
DBODPODFOUSBUFPOTUZMJOHUIFJOOFSUFYUPGFBDITFDUJPO
001
002
003
004
005
006
007
008
009
010
.angle:nth-child(odd){
border-top: 16px solid #091e3d;
background-color: #666;
-webkit-transform: rotate(5deg);
-moz-transform: rotate(5deg);
-o-transform: rotate(5deg);
-ms-transform: rotate(5deg);
transform: rotate(5deg);
margin-top: -200px;
}
10 Going even
001 .angle:nth-child(even){
002 background: #ccc url(../img/shattered.png)
repeat;
003
004
005
006
007
008
009
-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-o-transform: rotate(-5deg);
-ms-transform: rotate(-5deg);
transform: rotate(-5deg);
}
11 Move it down
001 .angle:first-child{
002 margin-top: 0px;
003 }
001
002
003
004
005
.content{
margin: 0 auto;
padding: 130px 100px 250px 100px;
}
<Left>
sThe headings are now in place and the
formatting is starting to come together
on the design with decent space around
the headings
<Below>
Here we see the finished site with the
angles fully working and the background
images all in place without being rotated
<Above>
sThe odd children (one, three and five) of the angle are rotated so
that the text is now straight and is beginning to take shape
14 Concise paragraphs
001 .content p{
002 width: 75%;
003 max-width: 500px;
004 margin: 0 auto;
005 font-size: 18px;
006 line-height: 24px;
007 padding-top: 10px;
008 }
009
<Above>
sBoth the odd and even inner content to the angled sections are
rotated in the opposite direction to the angle so the text is straight
15 Easier to read
001
002
003
004
005
006
007
.angle:nth-child(odd) .content{
-webkit-transform: rotate(-5deg);
-moz-transform: rotate(-5deg);
-o-transform: rotate(-5deg);
-ms-transform: rotate(-5deg);
transform: rotate(-5deg);
color: #fff;
Adding
media queries
Use media queries at
breakpoints in your design for
approximations of when the
design changes by different
devices, reformatting
the content accordingly.
16 Opposites attract
tag back the opposite direction of the angle class. This time
though, we are targeting the even children and the content
is rotated five degrees to compensate. Save this now and
when you view in the browser, youll see we have the basis
for our tutorial covered.
001
002
003
004
005
006
007
.angle:nth-child(even) .content{
-webkit-transform: rotate(5deg);
-moz-transform: rotate(5deg);
-o-transform: rotate(5deg);
-ms-transform: rotate(5deg);
transform: rotate(5deg);
}
001
002
003
004
005
001
002
003
004
005
006
007
008
009
010
003
Any stretch of
the imagination
We are using the Anystretch
plug-in to enhance our design
as we cannot easily get the
same result with CSS alone.
This way we are able to keep
our markup clean
and simple.
few lines below the previous code snippet. This tells the
Anystretch plug-in to stretch the image to fill the
background on the full class which were added in Steps 19
and 20. Save the document now and refresh the browser
to see the finished tutorial in action, complete with
background images and angled design.
js></ script>
004
001 <script>
002 $(.full).anystretch();
003 </script>
004
Make a
responsive
menu for a
retina screen
Make sure your menu is responsive
and ready for retina screens by using
custom fonts instead of images
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
001 @font-face {
002 font-family: 'icomoon';
003 src: url('../fonts/icomoon.eot');
004 src: url('../fonts/icomoon.eot?#iefix')
format('embedded-opentype'),
url('../fonts/icomoon.woff')
format('woff'),
006
url('../fonts/icomoon.ttf')
format('truetype')
007 url('../fonts/icomoon.svg#icomoon')
format('svg');
008 font-weight: normal;
009 font-style: normal;
010 }
011 .icon-happy,.icon-loved,.icon-uniF4F1,.
icon-skull,.icon-uniF539,.icon-rocket,.iconmenu {
005
font-family: 'icomoon';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
.icon-happy:before {content: "\e603";}
.icon-loved:before {content: "\e61c";}
.icon-uniF4F1:before {content: "\e613";}
.icon-skull:before {content: "\e607";}
.icon-uniF539:before {content: "\e612";}
.icon-rocket:before {content: "\e600";}
04 Base CSS
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
.main,
.container > header {
width: 100%;
margin: 0 auto;
padding: 16px 32px;
}
.main {
max-width: 1300px;
min-height: 640px;
}
header {
text-align: center;
font-size: 16px;
background: rgba(255,255,255,0.6);
}
header h1 {
font-family: 'Hammersmith One', sansserif;
018
font-size: 75px;
019
line-height: 0.8;
020
margin: 0;
021
font-weight: 300;
022
color:#3f3782;
023 }
024 .movie {
025
font-size:102px;
026
color:#e63c2b;
027 }
05 Menu HTML
< Above>
sAs more and more screen sizes flood into the market, it pays to keep your responsive elements as simple as possible to avoid meeting a width they
cant deal with. Having three breakpoints, roughly representing PC, tablet and smartphone, is a tried and trusted approach to this problem
Menu love
Navigation menus can be
overlooked as necessary
items, requiring little thought.
This is a shame since they are
often the part of your site that
is engaged with most.
Love them and make
them shine.
span></a></li>
001 body {
002 font-family: 'Hammersmith One', sansserif;
*/
007 }
008
12 Tablet animation
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
15 Background changes
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
.nav li:nth-child(6n+1) {
background: rgb(230, 60, 43);
}
.nav li:nth-child(6n+2) {
background: rgb(63, 55, 130);
}
.nav li:nth-child(6n+3) {
background: rgb(63, 55, 130);
}
.nav li:nth-child(6n+4) {
background: rgb(230, 60, 43);
}
.nav li:nth-child(6n+5) {
background: rgb(230, 60, 43);
}
.nav li:nth-child(6n+6) {
background: rgb(63, 55, 130);
}
Code library
17 Last transition
001
002
003
004
005
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=edge,chrome=1">
006 <meta name="viewport" content="width=device-width,
initial-scale=1.0, user-scalable=no">
007
<title>London Movie Reviews</title>
008
<link rel="stylesheet" type="text/css" href="css/style.
css" />
009
<link href='http://fonts.googleapis.com/
css?family=Hammersmith+One' rel='stylesheet' type='text/css'>
010 </head>
011 <body>
012
<div class="container">
013
<header>
014 <h1>LONDON<br><span class="movie">MOVIE</
span><br>REVIEWS</
015 h1>
016
</header>
017
<div class="main">
018
<nav class="nav">
019
<ul>
020 <li><a href="#"><span class="fon icon-happy"></span><span
class="item">COMEDY</span></a></li>
021
<li><a href="#"><span class="fon icon-loved"></
span><span class="item">ROMANCE</span></a></li>
022 <li><a href="#"><span class="fon icon-uniF4F1"></span><span
class="item">ACTION</span></a></li>
023 <li><a href="#"><span class="fon icon-skull"></span><span
class="item">HORROR</span></a></li>
024 <li><a href="#"><span class="fon icon-uniF539"></span><span
class="item">DRAMA</span></a></li>
025 <li><a href="#"><span class="fon icon-rocket"></span><span
class="item">SCI-FI</span></a></li>
026 $(window).scroll(function(){
027 </ul>
028 </nav>
029 </div>
030 </div>
031 </body>
032 </html>
Create
data-driven
interfaces with
KnockoutJS
Make a modular app that has real-time
UI updates, multiple views, and is easily
maintainable and extendable
002
003
004
04 Observables in VM
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
001 <head>
02 Require dependencies
001 //app.js
002 require([libs/knockout, filmViewModel,
libs/jquery, libs/
domReady!],
function(ko, filmViewModel) {
003 use strict;
004 });
05 Get data
001
002
003
004
005
006
//filmViewModel.js
self.getFilms = function () {
return $.getJSON(api.php);
};
//app.js
$.when(filmViewModel.getFilms(
)).then(function (films) {
007 filmViewModel.films(films);
008 });
<Above>
s5IF,OPDLPVUTJUFBOElearn.knockoutjs.comBSFJOWBMVBCMFSFTPVSDFTGPSMFBSOJOHBCPVUUIF
GSBNFXPSLJOBOFOHBHJOHBOEJOUFSBDUJWFXBZ
006
007
008
009
010 };
$(event.target).parent().siblings().
removeClass(active);
event.target.parentNode.classList.
add(active);
appViewModel.view(event.target.
getAttribute(href).split(#)[1]);
}
07 Apply bindings
<Above>
s3FRVJSFJSMPBETTDSJQUTJOQBSBMMFMSBUIFSUIBOXBJUJOHGPSFBDIJOEJWJEVBMTDSJQU
UPMPBECFGPSFHFUUJOHBOPUIFS
009
</li>
010 </ul>
011 </div>
09 Page structure
001 ko.applyBindings(appViewModel);
003
dashboardViewModel>
005 </section>
08 Our view
11 Update values
002
003
<Above>
s4XJUDIJOHCFUXFFO
WJFXT
ZPVDBO
TVCTDSJCFUPXIFO
BOPCTFSWBCMFT
WBMVFDIBOHFT
NBOVBMMZCZVTJOH
UIFTVCTDSJCF
NFUIPE
bind=foreach:
003 filteredFilms>
004
<a href=# data-bind=text: title,
004
005
click: $parent.getFilmData></a>
005 </div>
006 </div>
14 Update observables
003
004
005
006
api/public/v1.0/movies.json?q= + film.
title + &apikey=YOUR_API_KEY&callback=?
, function (data) {
var movie = $.extend
(film, data.movies[0]);
self.currentFilm( movie );
});
};
006
007
008
16 Attribute bindings
004
17 Virtual elements
18 Computed observables
003
006
19 Custom binding
002 ko.bindingHandlers.liveEditor = {
003 //next step, init and update
004 };
008
return { editing: observable.editing };
009 });
010 }
24 Create Dashboard VM
004
27 Add Dashboard VM
21 Extend observables
005
006
007
).location>
<span class=view>
Location: <a href=# data-bind=
click: currentFilm().location.edit,
text: currentFilm().location()></a>
</span>
</div>
</div>
23 Editing values
libs/jquery], function(ko) {
use strict;
return function () {
var self = this;
/* next step */
}
});
001 ko.bindingHandlers.fadeVisible = {
002 init: function(element, valueAccessor) {
003
var observable = valueAccessor();
004
$(element).toggle(ko.utils.
unwrapObservable(observable));
005
006
007
008
009
010 };
},
update: function(element, valueAccessor) {
var observable = valueAccessor();
ko.utils.unwrapObservable(observable) ?
$(element).fadeIn() : $(element).
fadeOut();
}
dashboardViewModel();
28 Is Knockout a knockout?
26 Use fadeVisible
) === dashboard>
<h2>Dashboard</h2>
<h3>Possession</h3>
Tricks
64
Animate CSS
72
78
82
86
102
104
Produce a 3D direction-aware
hover effect
108
110
112
116
98
82
Create scrolltriggered
animations
94
90
Add excitement
and interactivity to
your web pages
108
Make a
shake effect
with CSS
110
116
Make a
rotating
3D cube
Build an
HTML5
game
102
Scaling
hover
effects
ANIMATE
Animate CSS
EXPERT
INSIGHT
CSS animations are not only
simple to create and adjust
but also take advantage of
the processing power of
todays browsers. Compared
to JavaScript animations, they
transition much faster and
smoother, which enhances
the user experience. Simple
animations can be used now,
falling back to either basic
state changes or JavaScript
animations for those browsers
without the support. As these
browsers become less and
less prevalent with users, it will
make interface animations easy
to code and we will be finding
more complex and creative
ways of using these techniques.
Luke Guppy
Creative director
redweb.com
CSS3 Animation
CSS3 Transitions
MacPro
FiftyThree
Polygon
BROWSER SUPPORT
VERSION
VERSION
VERSION
VERSION
VERSION
10.0
5.0
5.0
4.0
12.0
MOBILE
BROWSERS
Animate CSS
MAKE IT MOVE
Understand animation from the ground up with this step-by-step guide
MAKE A BOX
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
<!DOCTYPE html>
<html>
<head>
<style>
#box
{
width:100px;
height:100px;
background:blue;
-webkit-animation:animOne
5s; /* Chrome, Safari,
Opera */
animation:animOne 5s;
}
</style>
</head>
<body>
<div id = box></div>
</body>
</html>
2 MAKE AN ANIMATION
003
004
005
006
007
008
009
from {width:0px;
height:0px;
background:red;}
to {width:100px;
height:100px;
background:blue;}
}
007
008
009
3 RUN IT
STEP
BY STEP
010
011
012
001 #box
002 {
003 width:100px;
004 height:100px;
005 background:blue;
006 -webkit-animation:animOne
013 }
014
/* For Chrome, Safari and Opera */
007
008
009
010
011
012
013
014 }
015
005
006
007
008
009
5 BREAK IT UP
MORE CONTROL
001 #box
002 {
003 width:100px;
004 height:100px;
005 background:blue;
006 position: relative;
004
/*
CSS vs
JavaScript
Which one is
better? What are the
differences between
them and are they really
in competition?
In official web-lore CSS
animations are always faster
than JavaScript animations. CSS
just works while JavaScript and
jQuery need custom animation
handlers and need to repeat
thirty or even sixty times a
second. So a browser always
works harder running scripted
animation code than running a
plain CSS equivalent.
Its usually a good idea to
use vanilla CSS for simpler
animations. In 2D, you can do
most of what you need with CSS,
and you only need scripting for
complicated timeline-based
effects, or for effects where you
need to manage the position and
movement of a lot of different
elements at the same time.
3D is more complicated. 3D
animations stress the browser
harder but JavaScript has some
useful features like 3D matrix
operations that just arent
possible in CSS. So, a good rule
of thumb is to see if you can
achieve what you want in CSS
first. If you cant, fallback to
JavaScript and custom code.
Either way, test your
animation on low-powered
hardware to check that it works.
You may find it runs fine on
your MacBook Pro i7, but dont
forget most users will have older,
cheaper hardware and you need
to be aware of what they can
realistically deal with.
6 RUN IT AGAIN
FALLBACK
CODE
You dont have to limit
animation support to
newer browsers, but
fallback code does take
some extra effort
If only fallbacks werent needed.
Unfortunately, they usually are,
so you have find different ways to
work around them.
The simplest way to manage
fallbacks is to include the usual
browser-checking code using
something like Modernizr. For a
CSS-only solution you can use
Modernizr to select animationfree code using the usual .no
prefix to create fallbacks when
features arent available. You can
also check if CSS properties are
available by asking the Modernizr
JavaScript object to check and
report back to you.
A simpler but less flexible
option is a hybrid framework
like cssAnimate (cortys.de/
cssAnimate). It runs CSS
animations if a browser supports
them, but falls back to slower
jQuery effects if it doesnt. The
framework runs and selects the
correct effect automatically, so it
(mostly) just works.
The most reliable but slowest
option is to do everything in
jQuery. jQuerys animation effects
are powerful and open-ended
but theyre not very efficient. This
can cause problems with mobile
support. Because the world, its
dog and iPhone are expected to
support mobile sites now, jQuery
can be risky and youll have to
decide whether its worth taking
a chance on the performance of
your target devices. The upside
is that you can write once and
create complex effects that are
challenging with pure CSS.
1 SMOOTH MOVES
001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
font-size: 100px;
007 position: absolute;
008 -webkit-animation:animX 1s;
/* Chrome, Safari, Opera */
-webkit-animation-timingfunction:linear;
010
001
002
003
004
005
006
007
008
009
010
011
012
013
014
<!DOCTYPE html>
<html>
<head>
<link rel=stylesheettype=
text/css media=all href=
//fonts.googleapis.com/
css?family=Lato/>
<style>
#textX
{
left:100px;
top:100px;
font-family: Lato;
font-size: 100px;
position: absolute;
-webkit-animation:animX 1s;
/* Chrome, Safari, Opera */
}
001
002
003
004
005
006
007
008
009
010
011
012
013
2 STRAIGHT LINES
cssAnimate is an interesting
hybrid fallback framework
thats worth a look. Its not
bulletproof, but it can solve
some common problems
STEP
BY STEP
011 }
CRASH STOP
001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
font-size: 100px;
007 position: absolute;
008 -webkit-animation:animX 1s;
009
010 }
011
4 CUSTOM CURVES
001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
007
008
009
font-size: 100px;
position: absolute;
-webkit-animation:animX 1s;
/* Chrome, Safari, Opera */
-webkit-animation-timingfunction:cubic-bezier(0.4, 0
,0.36,0.66);
010 }
011
HORIZONTAL
5CONTROL
AND VERTICAL
How do you know what the numbers
do? You can experiment with them
at random and end up getting utterly
confused. Or, you can visit the handy
cubic-bezier.com site, which has a cool
preview feature with blobs and curvy
lines and handles you can drag. Click
GO! to preview your custom curve.
001 #textX
002 {
003 left:100px;
004 top:100px;
005
font-family: Lato;
006
font-size: 100px;
007 position: absolute;
008 -webkit-animation:animX 1s;
009
010 }
011
6 BOUNCE EFFECT
Animate CSS
3D ANIMATION
Take your animations into the next dimension with 3D transforms
CSS 3D transforms make complicated effects look
easy. The key thing to remember is how to work with
X, Y, and Z co-ordinates. X runs left to right, Y runs up
and down, and Z runs in/out of the screen.
An X rotation flips an element vertically. Because this
is a 3D rotation, it looks as if its spinning in and out of
the screen around its horizontal centre line. A Y rotation
does the same thing around a vertical centre; it looks
like its twirling around. A Z rotation simply spins an
item around in the plane of the screen.
As you might expect, things get a little more
complicated when you combine X, Y and Z. You can
create a combined transform that spins something
in all three axes at once. This makes most users feel
STEP
BY STEP
010
011
012
013
font-family: Lato;
font-size: 100px;
position: absolute;
-webkit-animation:animX
2.2s; /* Chrome, Safari,
Opera */
014
-webkit-animation-timingfunction:linear;
015
-webkit-animationiteration-count:infinite;
016 }
017
3
2
NOW IN 3D
001
002
003
004
005
006
007
008
009
<!DOCTYPE html>
<html>
<head>
<link rel=stylesheet type=
text/css media=all href=
http://fonts.googleapis.com/
css?family=Lato/>
<style>
#textX
{
left:100px;
top:100px;
SPIN ME ROUND
4 ON-CLICK CONTROL
001 <script>
002 $(document).ready(function(){
003 $(#textX).on(click,
004
function() {
$(this).addClass
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
(animateX);
window.setTimeout(
function(){
$(#textX).
removeClass(animateX);
}, 2300);
});
});
</script>
<style>
#textX
{
left:100px;
top:100px;
font-family: Lato;
font-size: 100px;
position: absolute;
}
.animateX
{
-webkit-animation:animX
2.2s; /* Chrome, Safari,
Opera */
-webkit-animation-timingfunction:linear;
}
5 MOUSE ENTER
Add another handler for mouseenter events for the Y <div>. This works
in similar way to the on-click event that
we looked at earlier, but instead spins
the <div> when the mouse enters it.
Note that you cant use a mouse hover
event because it triggers the spin on
mouse entry as well as exit.
001 $(document).ready(function(){
002 $(#textX).on(click,
003
004
005
006
007
008
009
010
011
012
013
014
015
function() {
$(this).
addClass(animateX);
window.setTimeout(
function(){
$(#textX).
removeClass(animateX);
}, 2300);
});
$(#textY).on(mouseenter,
function() {
$(this).
addClass(animateY);
window.setTimeout(
function(){
$(#textY).
removeClass(animateY);
}, 2100);
});
});
6 FULL CIRCLE
NATIVE
HARDWARE
ACCELERATION
Animate.css
URL daneden.github.io/animate.css
A lightweight but powerful collection of ready-to-roll CSS
animations, you can download this framework directly from the
site or from GitHub, drop into a project, and get instant access
to a huge collection of animation effects. The list includes
entrances, exits, fades, flips, hinges, and even a few sliders. The
code is simple so its easy to customise it with your own easings
and other additions but for most projects you wont need to,
because the basic effects are so useful right out of the box. Plus,
the subtle colour fade on the site looks lovely.
Move.js
URL visionmedia.github.io/move.js
Move.js packages a collection of CSS animations and makes
them accessible with a few lines of code. Dont be deceived by
the bare site, this is more of a toolkit than Animate.css, so some
assembly is required. You can use the animations as is, but
things get a lot more interesting with the conditional options.
Use them to chain animations together, select animations
depending on other events, set up callbacks and customise
different easings. The sites design doesnt make it obvious that
each feature has a demo under it but it does, so check it out.
001 transform:
translate3d(0,0,0);
002 font-smoothing:
antialiased;
This works but only
sometimes because the null
transform forces the graphics
system to load the element and
process it in harder. The catch, as
you may have guessed, is that it
can kill sub-pixel font smoothing,
so your fonts may not render how
you expect.
Anima.js
URL lvivski.com/anima
Anima is a combined CSS/JavaScript animation framework with
physics support. It handles the usual chained/delayed animation
options available in other frameworks, but also includes features
that make it easy to squash and bounce items as you animate
them. The framework is only 5k, so its lightweight enough
to add to any project. The only catch is that its more of a full
animation API than a simple drop-in library of canned effects.
You may want to master a less complex framework before
trying to use this one on a production project.
Greensock GSAP.js
URL www.greensock.com
Making a bid as the next Flash, Greensocks GSAP.js framework
is a fast and efficient HTML5 library for professional animation
applications. Its a streamlined alternative to jQuery animation,
optimised for speed and with added timeline management and
optional plug-ins. The good news is that it does a lot. Its much
more powerful than plain CSS animation, which has helped it
find a home in high-end commercial projects. The bad news? It
costs up to $150 per year if you use it in games or subscription
sites. Still, basic use is free, so its definitely worth a look.
Animate CSS
RESOURCES
ANIMATION IN ACTION
Are you ready to take on the best? Get inspired and discover what the
competition is getting up to with these must-see examples of CSS animation
URL dataveyes.com
DataVeyes skirts the dangers
of the retro-Flash swamp to produce
a splash page thats worth loading.
The animation looks simple its
just dots and lines but some clever
coding and physics modelling take it
a couple of steps beyond the basics.
The result is a coherent presentation
that appeals to the eyes and mind
and sells the skills of the design team.
Theres enough visual ingenuity
to make the site stand out, but not
so much that the design falls over
the edge into being self-indulgent
eye-candy glued on for the sake of
making something move.
CSS3 ANIMATION
CHEAT SHEET
URL bit.ly/1lH9GNk
This outstanding animated periodic table throws tiles
around the viewport, shaping them into a flat 2D table, a sphere,
a helix/carousel and a grid format in full 3D, with mouse control
of zoom and rotation. You probably wouldnt use this design in
a typical business project but its a brilliant example of whats
possible with CSS 3D, coded with the three.js framework.
URL http://hakim.se/experiments
Hakim El Hattabs experiment pages have breathtakingly
creative examples of the art in CSS animation. Highlights include
fold-out 3D menus, 12 different table effects, a collection of mini
JavaScript frameworks for zoom effects and web presentations
and even an animated DOM Christmas tree. Most of the code is
on GitHub, so you can download it for use in your own projects.
FUTURE DEVELOPMENTS
www.justinaguilar.com/
animations
As the name says,
this is a handy
cut-out-and-keep
cheat sheet of
canned CSS3
animations. Theres a collection of
buttons, a pile of code and a quirky
demo area so you can see what
each animation does. There are also
some notes about creating more
sophisticated effects by linking the
animations into jQuery scripts.
expert insight
Richard Stevenson
Head of PR, 1&1 Internet Ltd www.1and1.co.uk
While selling online is now a necessity for
retailers, fierce competition and tough
consumer expectations are a constant challenge
to manage. Therefore, it is important that you
have a well-defined eCommerce strategy, set of
objectives and target audience before launching
your online store. With many easy-to-use and
increasingly powerful solutions, such as DIY-style
packages from web hosts, business owners can
now get a shop online in a matter of minutes. But
what should you be looking for in order to create
the best online presence possible?
There are a now number of basic elements to
cover when designing an efficient eShop in order
to boost traffic, sales and profits.
01
Starting an online store can be overwhelming.
:HUHYHDOWKHVHFUHWVWKDWFDQKHOS\RXUUVW
foray into eCommerce be a success
02
03
04
05
SELECTING AN
ECOMMERCE PLATFORM
PRODUCT DESCRIPTION
PAYMENT OPTIONS
SHIPPING
CUSTOMER SUPPORT
STEP
BY
STEP
01
Sign up to Magento Go
Magento Go
05 dashboard
02 personal details
06
Store theme
If you head over to frontend of your store (the URL will be http://<your_
username>.mygostore.co.uk), you will notice that it is currently very plain, with a
simple black and white design. This is because we are yet to upload our own products and
its set to using the default T-Shop theme.
03
Congratulations, your store has now been set up! After signing up, you will be
presented with the URL of your store and login information to the Magento Admin
Panel. You will also receive an email containing your new store URL and login details,
informing you that your store is up and running.
07
Theme editor
Customise
08 store theme
04
Once you have received the confirmation email, head over to the admin panel.
Your admin login URL will be https://<your_username>.mygostore.co.uk/admin.
Input your personal login information, click Login and youll be taken to the Magento Go
Admin Dashboard, where the fun really begins!
Upload
09 your own
logo
13
To upload your product images, under the Images tab, select Browse Files, locate
your images and then simply click on Upload Files. Once uploaded, you can add
an alt text to each of the images in the label field. You will want to assign an image as your
base, small and thumbnail. Finally, click Save.
Upload your
10 own favicon
View your
14 store
Set up
15 payment
gateway
11
Lets start importing products to the new store. If you wish to upload a large sum
of products in one lot, you can import all via a CSV file. Alternatively, to manually
create a new product, head to Catalogue>Manage Products>Add Product.
Create a
12 product
Set up tax
16 rates
17
Delivery rates
21
With your domain name added, you will need to make sure you configure your
DNS to point at the IP address supplied by Magento. Once this is complete, jump
to your Magento Admin Panel and navigate to System>Configuration>Web>Active Domain
and select your custom domain name before clicking Save.
CSV delivery
18 rates
Purchase SSL
22 certificate
19
Royal Mail
20
Make sure you have already pre-purchased a domain name. Log in to your
Manage Your Magento Account, located at: https://go.magento.co.uk/go/index/
stores. Click on the Magento Go link on the left side bar menu, click on the Add link button
next to Custom URL, type in your domain name and click Save.
23
After purchasing an SSL certificate you will be required to change the A record of
your custom URL to point to the new IP address provided by Magento. This will
vary depending on your DNS manager and registrar. Once the A Record has been
updated, click Confirm DNS Change to certify that the A Record has been updated.
24
Go live!
Now all of thats out of the way, youre ready to launch your store for production.
In the Magento Admin Panel, at the top click on Start My Store and select Get
Going>Launch Your Store. This will open a dialog box. Click on the Go button and
congratulations, your new store is now live!
ONLINE MARKETING
ANALYTICS
Keep a close eye on your analytic stats, these wont just
tell you where customers are coming from but also
where they may be dropping out. Consistently improve
the user experience to ensure pages are conversion
optimised to keep customers on site for longer and
ensure they reach the end of the checkout process.
SHOPIFY
www.shopify.com
Launched in 2006, Shopify houses over 90,000 stores
and is a great platform for any start-up merchants that
want to begin selling online.
BIGCOMMERCE
bigcommerce.com
Bigcommerce boasts a wide range of feature-rich tools
available to business owners so they can get their
store going in no time at all.
VOLUSION
www.volusion.co.uk
A fully cloud-based eCommerce solution that has an
outstanding back-office system with all the features
necessary to run a successful online store.
PROS:
PROS:
PROS:
s/PUOFDFTTBSZUPCFBOFYQFSUXFCEFWFMPQFSPSBO
FYUSBPSEJOBSZEFTJHOFS
TJODFUIFSFBSFPWFS
QSPGFTTJPOBMUIFNFTUPDIPPTFGSPN
s /PUIJSEQBSUZQBZNFOUHBUFXBZTFUVQSFRVJSFE
4IPQJGZIBOEMFTBMMQBZNFOUQSPDFTTJOHGPSZPV
s'FBUVSFTBXPOEFSGVMMZFBTZUPVTFJOUFSGBDF
JODMVEJOHNBOZLFZTFMMJOHBOENBSLFUJOHGFBUVSFT
TVDIBTAEFBMPGUIFEBZ
s4FBNMFTTMZTFMMPOPUIFSQPQVMBSNBSLFUQMBDFT
JODMVEJOHF#BZBOE"NB[PO
s"TZPVSTUPSFHSPXT
UIFNPOUIMZDPTUHSPXTXJUIJU
nQMVT4IPQJGZUBLFTCFUXFFOPOFBOEUXPQFSDFOU
POBMMUSBOTBDUJPOT
s&EJUJOHBOEBEEJOHDPOUFOUDBOTPNFUJNFTCF
EJJDVMUBOEMFTTJOUVJUJWF
s5IJTQMBUGPSNMBDLTBOZNVMUJMBOHVBHFTUPSFGSPOU
BOEUSBOTMBUJPOGFBUVSFT
s5IFSFBSFBMBSHFBNPVOUPGUFNQMBUFTUPTFMFDUGSPN
CVUNBOZPGUIFNMPPLBMJUUMFPOUIFPVUEBUFETJEF
BOEBSFOUSFTQPOTJWF
s"EWBODFEBOEIFMQGVMGFBUVSFTBSFPOMZBWBJMBCMF
GPSUIFUPQUJFSQBJEGPSQMBOT
s&YQFOTJWFPWFSDIBSHFTXIFOFYDFFEJOH
CBOEXJEUIMJNJUT
XPSLJOHPVUBUSPVHIMZGPS
FWFSZ(#PWFSZPVSBMMPDBUFEMJNJU
CONS:
CONS:
CONS:
Scroll
horizontally
using
jInvertScroll
To see the bigger picture, wide can be
better than tall, and using horizontal
parallax showcase that
007
<img src="images/cloudsandballoons.png"
alt="" />
008 </div>
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
01 The HTML
001
002
003
004
005
006
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>The Hot Air Balloon</title>
<link href="http://fonts.googleapis.
com/css?family=Open+Sans:400,300,700"rel="s
tyle sheet"type="text/css" />
007 <link rel="stylesheet" href="css/
jInvertScroll.css" />
008 <link rel="stylesheet" href="css/style.
css" />
009 </head>
02 Background
001
002
003
004
<body>
<div class="container">
<div class="horizon scroll">
<img src="images/background.png" alt=""
001
002
003
004
005
006
007
008
009
04 The script
001
001
002
003
004
005
006
007
008
009
{
overflow-x: hidden;
}
.scroll
{
position: fixed;
bottom: 0;
left: 0;
}
/>
005
006
</div>
<div class="middle scroll">
06 Design-specific styling
<Above>
sParallax scrolling is very much in vogue. It provides a great method
for telling stories, delivering timelines and presenting statistics.
<Right>
sWhen choosing colours, remember that its normally much more
effective to use darker shades in background layers and lighter ones
in the foreground
001
002
003
004
005
006
007
008
009
{
padding: 0;
margin: 0;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
font-size: 16px;
color: #555;
background: #9fdefd;
}
001
002
003
004
005
006
007
008
009
010
011
h1,
h2
{
color: #238acb;
}
.horizon
}
line-height: 0;
z-index: 100;
width: 3000px;
}
001
002
003
004
005
006
.middle
{
z-index: 250;
line-height: 0;
width: 4500px;
}
09 Content layer
<Top>
s$POTJEFSIPXUIFFMFNFOUTXJMMJOUFSBDU*UTFBTZJGZPVS
TVCKFDUTBSFMZJOH
CVUDBSTBOEQFPQMFNJHIUOFFEBSPBE
UPNPWFBMPOH
<Left>
s%POUNBLFZPVSGPSFHSPVOEDPOUFOUTPMBSHFUIBUJU
QSFWFOUTQFPQMFGSPNBQQSFDJBUJOHUIFFGPSUZPVQVUJOUP
ZPVSCBDLHSPVOEMBZFST
<Right>
s4USVHHMJOHUPDIPPTFBTVCKFDUUPUSZPVUUIJTUFDIOJRVF +VTU
UIJOLXIBUZPVXPVMEEPJGZPVSESFBNDMJFOUKVTUCSJFGFEZPV
BOEUBLFJUGSPNUIFSFnMFUZPVSJNBHJOBUJPOSVOXJME
Mixing it up
$IFDLPVU/FX:PSLBHFODZ
'MVHFSTTIJOJOHFYBNQMFPG
QBSBMMBY
XIJDIDMFWFSMZ
JOUFHSBUFTIPSJ[POUBMBOEWFSUJDBM
TDSPMMJOHBTUIFZUBLFZPVPOB
MZQBTUUPVSPGUIFJS
TFSWJDFT$IFDLJUPVU
BU fluger.com
008 }
11 Content panels
10 Avoid confusion
001
002
003
004
005
006
.intro
{
position: absolute;
left: 500px;
top: 0px;
padding-right: 50px;
001 {
002 top: 0px;
003 width: 500px;
004
background: white;
005
padding: 10px 30px;
006
border: 1px #eee solid;
007
position: absolute;
008 }
12 Panel positioning
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
.panel1
{
left: 1500px;
}
.panel2
{
left: 2575px;
}
.panel3
{
left: 3800px;
}
.panel4
{
left: 5100px;
}
Code library
The plug-in
The jInvertScroll is a lightweight plug-in, written by Alex Franzelin and sponsored by
Pixxelfactory. Easily configured, it can help you achieve the perfect horizontal scroll effect
Extract all selected
elements from the DOM
and then save them into
an array
13 In context
winHeight)).toFixed(4);
16 Content panels
035
036
037
038
039
040
Create a
scroll-triggered
animation
Give your content beautiful animations
for when the user has scrolled to that
position perfect for responsive sites
when content can be pushed further
down the screen
open the entire folder so that we can use its built-in Node.
js server. Open the start.html file and then add the
following stylesheets and fonts.
003
Source files
available
sIUUQXXX
JMFTJMPDPVL
CLT
a
<Above>
s#ZPSHBOJTJOHUIFJOJUJBMTDSFFOTDPOUFOUXFDBOMBUFS
BOJNBUFUIFMBSHFSMPHPBOEUFYUPOUPUIFTDSFFOGPS
XIFOJUDPNFTJOUPWJFX
<Above>
s"UUIJTTFDUJPOXFXJMMCFBCMFUPBEEBOJNBUJPOUP
FBDIPOFPGUIFDJSDMFJDPOTTPUIBUUIFZBQQFBSPO
TDSFFOPOFBUBUJNF
OJNBUJPOFFDUTBSFBMMXFMMBOE
HPPECVUJUTOPUBMXBZTQPTTJCMF
UPTFFUIFNJGUIFVTFSIBTOU
TDSPMMFEUPUIFJSMPDBUJPOPOUIF
QBHFXIFOUIFZSFCFJOH
USJHHFSFEThe problem is, that
location is getting harder and
harder to predict, given the sheer
multitude of different-sized screens
that users can be looking at your site with. Libraries such as
Scrollr are great but its all based on pixel sizes and whether
the user has scrolled a certain number of pixels down the
page. This isnt possible to predict with responsive devices,
as content gets pushed further down the page and those
pixel sizes go up the spout.
In this tutorial we are going to take a different approach
to animating content on the screen and it will work well
with many responsive frameworks such as Bootstrap and
Foundation. Weve opted to use Foundation but that isnt
the main focus here; instead we are focusing on using the
free animate.css library of animations. To trigger these we
are using the appear.js plug-in for jQuery, which enables us
to detect when certain elements will appear on the screen.
When they do appear, we will then add in the relevant
animation effects so that the user sees the right animation
at the right time. This is perfect for anything that you really
want to draw the users attention to.
001 body{
002
background: url(img/bg.jpg)
003
004
005
006
007
008
001 #hero{
002
margin-top: 500px;
003
background: rgba(256, 154, 9, 0.7);
004
min-height: 500px;
005
}
006
#hero h1{ padding-top: 20px;}
007
#hero img{ padding-top: 90px;}
05 Sign-up colours
<Above>
s*OJUJBMMZUIFTJUFOFFETTPNF$44UPTUZMFUIFFMFNFOUTVQTPUIBUUIFSFJTNPSFPSHBOJTBUJPO
UPUIFQBHFBTXFMMBTTPNFEJTUBODFCFUXFFOFBDIFMFNFOUTPUIBUUIFZDBOCFTDSPMMFEUP
001 #signup {
002
margin-top: 300px;
003
background: #0ec8b0;
004
padding: 90px 0;
005
}
06 Three-column section
001 #three {
002
margin-top: 300px;
003
background: #00add8;
004
padding: 90px 0;
005
}
006
001 #lower {
002
margin-top: 300px;
003
background: #df86ca;
004
padding: 90px 0;
005
} #footer {
006
background: #333;
007
padding: 30px 0;
008
}
10 Use appear.js
<Top left>
sThe last section of the site has an
image that we will be able to animate
into position later, when the user
scrolls this far down the page
<Top right>
sNow as we have added our JavaScript content,
we dynamically add the animation to the
elements as they are in view in our browser. Here
the main logo and text is in mid transition
001
002 <script src=js/jquery.appear.js></script>
003
11 Readable text
001 $(document).ready(function($) {
002
003
$(.animated).appear();
004
$(.animated).on(appear, function() {
005
var elem = $(this);
006 var animation = elem.
data(animation);
<Bottom left>
sThe Free Download text is being bounced into
position in order to draw attention to the call to
action here. You can see the text is just slightly
off centre as it comes to rest
AJAX loading
Many of the effects used in this
tutorial only work when viewed
from a server, so ensure your site
is on a local server, a web
server or being viewed in
the live preview
from Brackets.
001 if ( !elem.hasClass(visible) ) {
002
var animationDelay = elem.
<Bottom right>
sAs the three icons appear on the
screen they are delayed slightly so that
each icon rotates into position with a
3D transform one at a time
001 if ( animationDelay ) {
002
setTimeout(function(){
003
elem.addClass
004
005
( animation + visible );
}, animationDelay);
}
data(animation-delay);
001 else {
002
elem.addClass
( animation + visible );
003
}
004
}
005
});
006 });
007
001
002
003
004
005
006
007
.animated {
visibility: hidden;
}
.visible {
visibility: visible;
}
002
17 Delayed animation
What the final result is for the end user is animations that trigger nice and smoothly, as the elements that
have animation on them appear in their browser window.
002
animated data-animation=fadeInUpBig
data-animation-delay=200>
002
18 Throwing a wobbly
002
002
002
Make an
animated SVG
header with
Snap.svg
Achieve crisp graphics at all resolutions
and add interactivity and animation
with Adobes new Snap.SVG library
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
01 Get started
What is an
SVG then?
The scalable vector
graphic format is an XML
file, its plain text just like
your HTML documents.
Open it in your code
editor and you
will be able to read
it, but therell be a
lot of numbers!
<Above
sUsing Snap.SVG we can easily add animation and interactivity to our SVG graphics. Snap gives us a simple way to traverse the structure of an SVG and
target specific IDs in much the same way as jQuery lets you do with the DOM
07 Typography styling
001 <style>
002 svg{
003 display: block;
004 margin: 0 auto;
005 }
006 #Dojo{ font-family: Lobster,
cursive; }
007 #Designs{ font-family: Lobster,
cursive; }
008 #Strapline{ font-family:
Lobster, cursive; }
009 </style>
001 <script>
002 var dojo, designs, strap, chick,
bear, dog, tie, face, arm;
var timer;
003 window.onload = function () {
004 var s = Snap(960, 400);
005 Snap.load(scene.svg, function(f) {
006 s.append(f);
007 });
008 };
009 </script>
02_____________Anchor point
Hover over the icons in the top bar until the
pop-up for reference point displays. This is
a 3x3 point square. Click on its left-centre
point and it will darken when it is selected.
CSS
keyframes
Keyframes are elements to
be blended together by
changing one set of CSS
styles to another, dictating
what something should look
like at different points along
the animation.
12 Change opacity
001
002
003
004
005
006
007
008
009
010
chick = f.select(#chick);
bear = f.select(#bear);
dog = f.select(#dog);
tie = f.select(#bowtie);
face = f.select(#face);
arm = f.select(#arm);
chick.attr({opacity: 0});
bear.attr({opacity: 0});
dog.attr({opacity: 0});
//arm.attr({class: arm});
14 Interactive bear
15 CSS3 keyframes
001
002
003
004
005
006
007
008
009
010
011
012
@-webkit-keyframes wave{
0% {
-webkit-transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(30deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
16 Apply keyframes
001 .arm {
002 -webkit-transform-origin: 808px
273px;
003 -webkit-transition: -webkittransform .4s;
004 -moz-transform-origin: 808px 273px;
005 -moz-transition: -moz-transform .4s;
006 }
007 .arm.animating {
008 -webkit-animation: wave .4s
infinite;
009 -moz-animation: wave .4s infinite;
010 }
011
17 Final step
Code library
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
<script>
var dojo, designs, strap, chick, bear, dog, tie, face, arm;
var timer;
window.onload = function () {
var s = Snap(960, 400);
Snap.load(scene.svg, function(f) {
dojo = f.select(#Dojo);
designs = f.select(#Designs);
strap = f.select(#Strapline);
dojo.attr({opacity: 0, transform: scale(0.1, 0.1) });
designs.attr({opacity: 0, transform: scale(0.1, 0.1) });
strap.attr({opacity: 0});
dojo.animate({opacity:1, transform: scale(1, 1)},800,
mina.elastic);
timer = setTimeout(designIn, 500);
function designIn() {
clearTimeout(timer);
designs.animate({opacity:1, transform: scale(1,
1)},800, mina.elastic);
strap.animate({opacity:1}, 1500);}
chick = f.select(#chick);
bear = f.select(#bear);
dog = f.select(#dog);
tie = f.select(#bowtie);
face = f.select(#face);
arm = f.select(#arm);
chick.attr({opacity: 0});
bear.attr({opacity: 0});
dog.attr({opacity: 0});
arm.attr({class: arm});
s.append(f);
dog.hover(dogOver, dogOut);
function dogOver() {
tie.animate({ transform:t0,0r360}, 400); }
function dogOut() {
tie.animate({transform:t0,0r0}, 0); }
bear.hover(bearOver, bearOut);
function bearOver() {
face.animate({ transform:t0,0s1.5}, 400, mina.
elastic); }
040 function bearOut() {
041
face.animate({transform:t0,0s1}, 200, mina.backin);
042 }
043 chick.hover(chickOver, chickOut);
044 function chickOver() {
045
arm.attr({class: arm animating});
046 }
047 function chickOut() {
048
arm.attr({class: arm});
049 }
050 });
051 };
052 </script>
Create an
animated
infographic
with SVG
Why just look at an infographic when
you can interact with one? We make it
possible using SVG, CSS and JavaScript
code editor (eg Sublime Text) what you see may not be
as unfamiliar as you expect.
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
<svg>
<g id=background></g>
<g id=logo></g>
<g id=quote>
<g id=quote-left-speech></g>
<g id=quote-right-speech></g>
<g id=quote-text></g>
</g>
<g id=timeline>
<g id=stage-one>
<g id=stage-one-badge>
<g id=stage-one-title></g>
<g id=stage-one-details></g>
</g>
</g>
//repeated for subsequent stages
</g>
</svg>
04 Safety first
05 Tweak away
06 Using fonts
<Above>
sIf you have something interesting or entertaining to share, and can turn it into an attractive infographic, you might find you have a hit on your hands. There always seems to be an infographic going
viral, which can score plenty of kudos for the creator if not actual money!
5.778,0.329l0.271-2.5l-0.823,0.046l1.304,11.747l1.687-0.104l-0.66,6.749
l-11.146,0.729l1.059-6.812l1.746-0.104l1.77311.817l-0.842,0.047l-0.395,2.521l5.704,0.329l1.788-9.413l19.039-0.994
L234.508,85.439z M232.604,83.433l0.444.949l-15.384,0.822l-0.898,5.018l1.8780.104l0.436-2.601l4.591-0.253l-2.249,16.229
l-1.712,0.104l-0.34,2.364l6.484-0.414l0.2582.354l-1.708,0.107l1.988-16.188l4.624-0.255l0.254,2.569L232.604,83.433z/>
Error
loading SVG?
Many browsers wont
enable access to the SVG
DOM locally. For troublefree development, use
Mozilla Firefox when
working on your own
interactive SVG.
Infographic
inspiration
If you are stuck for a subject for
your own infographic, why not
check out the sites dedicated to
promoting them? You could do
worse than visit www.
coolinfographic.com or
dailyinfographic.com.
family=LeagueGothic font-size=27>preceded
by a period of worry and depression.</text>
005 </g>
001
002
003
004
005
006
007
008
009
010
011
012
013
@keyframes fade-in {
0% {
opacity: 0; }
100% {
opacity: 1; } }
@keyframes grow-y {
0% {
transform: scaleY(0); }
100% {
transform: scaleY(1); } }
@keyframes grow-x {
014 0% {
015
transform: scaleX(0); }
016
017 100% {
018
transform: scaleX(1); } }
11 Just grow up
001 @font-face {
002 font-family: LeagueGothic;
003 src: url(../fonts/league-gothic/leaguegothic.eot);
src: url(../fonts/league-gothic/leaguegothic.eot?#iefix) format(embeddedopentype), url(../fonts/league-gothic/leaguegothic.woff) format(woff), url(../fonts/
league-gothic/league-gothic.ttf)
005 format(truetype), url(../fonts/leaguegothic/league-gothic.svg#League_Gothicwebfont) format(svg);
006 font-weight: normal;
007 font-style: normal; }
004
008
001 #stage {
002 background-color: #fff;
003 width: 1024px;
004 height: 800px;
005 margin: auto;
006 -webkit-box-shadow: rgba(0, 0, 0, 0.3)
0px 0px 10px;
14 Lets back it up
001
002
003
004
[id$=badge] {
transform: scale(0.6, 0.6); }
[id$=title] {
transform: scale(1.3) translate(0px, 48px);
Code library
Create a standard
HTML document and
link to your CSS file.
Modernizr will give
you some backward
compatibility
content=IE=edge,chrome=1>
007 <meta name=viewport content=width=device-width,
initial-scale=1.0>
008
009
010
011
005 [id$=details] {
006 transform: scale(0, 0); }
012
013 <script src=js/modernizr.custom.js></script>
014 </head>
015
016 <body>
017
018 <div id=stage></div>
019
020 <script src=http://ajax.googleapis.com/ajax/libs/
g:hover [id$=details] {
transform: scale(1, 1); }
#timeline > g:hover [id$=title] {
transform: scale(1) translate(0px, 0px); }
[id$=badge], [id$=title], [id$=details] {
transition: transform 0.25s ease-in-out; }
001
002
003
004
005
006
007
008
009
#stage-one {
transform-origin: 200px
#stage-one-badge {
transform-origin: 130px
#stage-one-title {
transform-origin: 110px
#stage-one-details {
transform-origin: 110px
200px; }
400px; }
320px; }
320px; }
17 Go Intro sequence
002
003
004
005
006
jquery/1.9.0/jquery.min.js></script>
021 <script src=js/infographic.js></script>
022
023 </body>
024
025 </html>
001
002
003
004
005
006
$(function()
{
$(#stage).load(infographic.svg,function(response){
$(this).addClass(svgLoaded);
if(!response){ // Error loading SVG
$(this).html(Error loading SVG. Be sure you are running
from a the http protocol (not locally));
007
008 }
009 });
010 });
Streamline
your workflow
with Bower
and Grunt
Create your own build process and
simplify your front-end headaches with
these two tools
001 dependencies: {
002
normalize.css: 3.*.*,
003
jquery: 2.1.1,
004
angular: *,
005
angular-animate: *,
006
angular-resource: *
007 }
008 $ bower install
06 List dependencies
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
01 Install Bower
Bower requires Node, npm, and Git to be
installed on your computer. If you dont have them
already then install Node from nodejs.org and Git from
git-scm.com/downloads. Both sites have installation
instructions for OS X, Linux, and Windows. npm is
installed with Node so you dont have to worry about
separately installing it.
03 Install packages
In our fictional project were going to build a
complicated web app with different views, routing and
third-party dependencies. We can go for two approaches,
we could install them individually (as below) but for
long-lived projects it would be good to have a reference
for what our app depends on.
04 Create bower.json
A bower.json file can quite easily be created
interactively through Bower itself via some yes or no and
also some multiple choice questions. If theres already an
existing bower.json it will replace the values within that file
(rather than creating a new one). The file contains
metadata about your project such as name, URL, and
importantly, dependencies.
07 Project resources
A handy feature included with Bower is the
ability to easily go to the projects homepage (and
hopefully documentation as well) with just a single
command. This will then automatically open the site in
your default browser.
It doesnt always have the outcome you may expect
though, the code below takes you to the very specially
managed Bower-compatible version of Angulars
GitHub page.
09 Update packages
If a new version of a package does become
available then you can update it with the following
command. If you decide that you dont want to include a
projects development dependencies, then add a
production flag. Bower will let you know if a new version
conflicts with a package so you shouldnt really be having
any nasty surprises.
<Above>
s5IFTFEBZTJOTUBMMJOH/PEFBOEOQNJTB
DJODIXJUIUIFCJOBSZJOTUBMMFSGPSNPTU04T
<Above>
s:PVDBOFBTJMZDSFBUFBCPXFSKTPOXJUIUIF{JOJU{
DPNNBOECZBOTXFSJOHTJNQMFRVFTUJPOT
10 Uninstall a package
If you find that you no longer require a package
(or if you happen to --have installed one accidentally) then
you can remove it with the `uninstall` command. The
flags S and D stand for save and save dev respectively.
Passing these will then remove the package from the
projects bower.json file as well meaning it stays current.
-SD
11 Install Grunt
Now that we know how to use Bower were going
to introduce another tool to improve our workflow, Grunt.
Despite its macho appearance and name its actually
quite useful. Grunt is a task runner and requires the
command-line interface to be installed globally and Grunt
itself within the project folder.
002
grunt.initConfig({
003
//further steps
004
});
005 };
001 {
002
003
004
005
12 Write Gruntfile
Grunt is configured with a Gruntfile, were going
to write one called Gruntfile.js. This is what Grunt looks
for when being run from the command-line. If you prefer
to write CoffeeScript then you can do that too, it
supports both with no additional configuration.
CoffeeScript does produce a nicer looking syntax so its
down to personal preference.
<Top left>
s8JUIUIF{MJTU{DPNNBOEXFDBOTFFIPXPVS
QSPKFDUTEFQFOEFODJFTSFMBUFUPPOFBOPUIFS
006
007
008 }
name: deps,
version: 0.0.1,
description: An example of
package.json,
author: Tim Stone <you.name@
example.org>,
dependencies: {},
private: true
14 List development
<Above>
s3VOOJOH{JOTUBMM{XJMMJOEBMMPGUIFQSPKFDUTMJTUFE
JOCPXFSKTPOBOEGFUDIUIFNJOUPZPVSQSPKFDU
001 devDependencies: {
002
grunt: ~0.4.5,
003
grunt-contrib-uglify: 0.5.*,
004
grunt-bower-concat: 0.3.*,
005
grunt-wiredep: 1.8.*
006 }
15 Install dependencies
Well then install all of our project dependencies.
The projects that we specified are: Uglify which minimises
files; Bower concat which concatenates files together; and
Wiredep, which will inject files installed with Bower into
our HTML files. Well look at each one in more detail when
we come to configuring.
dependencies
We list our build dependencies as devDependencies.
Imagine a scenario where our app is deployed to a new
production server, we want to install whats needed to run
it but not to build it. This is where the separation between
dependencies and development dependencies is really
17 Configure Concat
Each plugin to be configured is referenced by its
name (as a general rule hyphens are replaced with
<Top left>
s-JLF#PXFS
OQN
XJMMSFBEJUT
NFUBEBUBJMFBOE
JOTUBMMBMMPGUIF
EFQFOEFODJFTUIJT
DBOUBLFUJNF
<Top right>
s"GUFSUIFA6HMJGZ
UBTLIBTSVO
PVS
NFSHFEJMFTXJMM
UIFOCFNJOJNJTFE
GSPN.#UP
,#
<Bottom left>
s#PXFS
DPODBUFOBUFXJMM
NFSHFPVS
EFQFOEFODJFTJOUP
POF
TBWJOHPO
OFUXPSLSFRVFTUT
<Bottom right>
s/PXBMMPGUIF
QJFDFTBSF
UPHFUIFS
SVOOJOH
{HSVOU{XJMMSVOPVS
tasks
creatingBO
PQUJNJTFETJUF
001 bower_concat: {
002
all: {
003
dest: dist/<%= pkg.name
app/views/**/*.html
]
004
005
006
007
008
}
009 },
004
005
006
}
007 },
Substituting
Gulp for Grunt
exclude: [normalize.css],
bowerOptions: {
relative: false
}
18 Configure Wiredep
Wiredep magically gets the correct file from
Bower and inserts a path to it in your HTML files. It also
supports Jade, Sass, and YAML without any additional
plugins. It has many other optional configuration options
at: https://github.com/stephenplusplus/grunt-wiredep
and its parent project:
https://github.com/taptapship/wiredep.
001 uglify: {
002
options: {
003
banner: /*! <%= pkg.name %> <%=
grunt.
004
005
006
007
008
009
010 }
001 grunt.loadNpmTasks(grunt-contrib-uglify);
002 grunt.loadNpmTasks(grunt-bower-concat);
003 grunt.loadNpmTasks(grunt-wiredep);
21 Register tasks
[<%=
bower_concat.all.dest %>]
001 wiredep: {
002
target: {
003
src: [
:PVDBOBMTPVTF(VMQBTB
UBTLSVOOFSCVUUIFSFBSFMFTT
PVUPGUIFCPYQBDLBHFTGPS
(VMQJODPNQBSJTPO
UP(SVOU
}
}
22 Run it all
Finally we can execute it all with `grunt`. Without
any arguments it will run the task called default. To
execute a specific task all you have to do is `grunt build`,
or whatever youve named your task. If there are errors in
your files Grunts explicit error handling should save you.
001 $ grunt
002 $ grunt build
003 $ grunt install
23 Wiredep placeholders
For Wiredep to work we need to include the
following comments in our HTML file (or Jade, or
wherever you want to output them). Your project files will
then come after them. If for some reason you dont like
this text its configurable within the Gruntfile using a
regular expression.
001
002
003
004
005
006
007
008
009
<head>
<!-- bower:css -->
<!-- endbower -->
</head>
<body>
<!-- bower:js -->
<!-- endbower -->
<script src=../app.js></script>
</body>
24 Minify CSS
So far in this tutorial what we have been doing is
concentrating on concatenating and minimising our
JavaScript dependencies. Next we will then apply the
same principles to our CSS files. Although, Uglify only
works on JavaScript files, so you will have to include a
new CSS minimiser (one such as grunt-contrib-cssmin). It
would be very convenient to have one tool which would
do both concatenating and minimising of course but not
everyone wants that kind of overhead for their project.
001 bower_concat: {
002
003
004
005
006
007
008
009
css: {
dest: dist/<%= pkg.name
%>.dependencies
css,
include: [normalize.css],
mainFiles: {
normalize.css: normalize.
css
}
}
}
<Above>
sGrunt has inserted the dependencies between the
placeholders with a relative link to them
001 concat: {
002
dist: {
003
src: [dist/*.css, app/ui/*.
004
005
006 }
007
css],
dest: dist/<%= pkg.name %>.css
}
003
Alternative
workflows
An alternative to using Bower
and Grunt is a package
manager called Duo
(duojs.org). It looks like a
promising evolution and
integrates maintenance
and building.
28 Configure Bower
You can further configure Bower with a .bowerrc
file. This can be stored in multiple locations: your home
folder (~), the project folder, or root folder (/). Were not fans
of the name bower_components folder name and this is
the place that you can change it. Other examples are at
www.bower.io/docs/config. It follows a JSON format.
001 {
002
003 }
004
directory: dependencies
29 In review
Bower aims to help you manage dependencies
over the lifetime of your project and Grunt along with its
plugins enables you to use these packages to create
optimised versions of your project for production.
Theres no doubt that this duo goes a long way to
improve the current process, but the amount of
configuration and learning curve hampers what could
be a really great workflow.
Manipulate
the DOM
with
AngularJS
Create an Angular application, with
custom directives to create lightbox
and accordion UI components
HTML page and you can then display any data defined in
$scope. In a browser window you should now see the
$scope.title value displayed in a H1 tag.
003 <head>
004 <meta charset=utf-8 />
005 <title>Angular UI App</title>
006 <script src=http://ajax.googleapis.com/
007
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
ngularJS is an application
framework that clearly separates
the DOM from any logic, by
means of a view (your HTML)
and a range of controllers (your
JavaScript logic). This is all held
together using directives, and
AngularJS has a huge range of
directives available. These are
used to join the DOM elements
with any data and logic held within your controllers and
are added to the markup as attributes. With jQuery for
example, the DOM elements are referenced from the
JavaScript and not the other way around. This means
that to get these DOM references, the entire (or a
significant portion) of the markup must be looped
through for each element.
As well as utilising the standard directives, custom
directives can be built. This tutorial will cover the creation
of such directives to provide both lightbox and
accordion UI components that can be easily reused.
Following this you will be able to create your own
custom directives for any custom UI interactions you
may need as part of your AngularJS application.
003 <head>
004 <meta charset=utf-8 />
005 <title>Angular Listing App</title>
006 <script src=http://ajax.googleapis.com/
007
008
009
010
001
002
003
004
ajax/libs/
angularjs/1.2.15/angular.min.js></
script>
</head>
<body data-ng-app=uiApp>
</body>
</html>
//modules/ui.js
angular.module(ui.module,[])
//myApp.js
var myApp = angular.module(uiApp, [ui.
module]);
03 Add a controller
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
ajax/libs/
angularjs/1.2.15/angular.min.js></
script>
<script src=scripts/modules/ui.js></Q
script>
<script src=scripts/myApp.js></script>
</head>
<body data-ng-app=uiApp>
<section data-ng-controller=uiCtrl>
<h1>{{title}}</h1>
</section>
</body>
</html>
//modules/ui.js
angular.module(ui.module, [])
.controller(uiCtrl, [$scope, function
($scope) {
use strict;
$scope.title = DOM manipulation with
AngularJS;
$scope.lightboxText = Some text that
should be
displayed in a lightbox;
}]);
007 }
008 };
009 //myApp.js
010 var myApp = angular.module(uiApp, [ui.
directives,ui.module]);
<Above>
s"MMJMFEPXOMPBETBSFBWBJMBCMFGSPNhttps://angularjs.org
PSPO(JU)VCBMPOHXJUIFYUFOTJWFEPDVNFOUBUJPOBOE
UVUPSJBMTPOCBTJDVTBHF
<Above>
s1SPQFSUJFTEFJOFEXJUIJOZPVSDPOUSPMMFSTDPQFBSF
BWBJMBCMFUPSFOEFSXJUIJOZPVS)5.-VTJOHBTUSBJHIU
GPSXBSEAIBOEMFCBSTTZOUBY
006
007
008
009
<div data-my-lightbox></div>
<!-- directive referenced using element
-->
<my-lightbox></my-lightbox>
<!-- directive referenced using class
-->
<div class=my-lightbox></div>
</section>
022
template: <div
class=lightbox><p>{{content.
text}}</p><button data-ngclick=content.testFunc
()>click me</button></div>
015 //myApp.html
016 <div data-my-lightbox data-mycontent=lightboxText>
</div>
017 <div data-my-lightbox data-mycontent=lightboxText2>
</div>
-->
004
005
<Above>
s5IFMJHIUCPYEJSFDUJWFSFOEFSTUIFNBSLVQEFJOFECZJUT
UFNQMBUFQSPQFSUZJOBMMJOTUBODFT
BOEUIJTNBSLVQIBT
BDDFTTUPUIFDPOUSPMMFSTDPQF
07 Passing functions
023 }
024 });
001 $scope.lightboxObject = {
002 text: some text as a separate property
in an
010 }
011 });
012 //modules/ui.js
013 $scope.lightboxText = Some text that
should be
displayed in a lightbox;
014 $scope.lightboxText2 = Some different text
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
object,
001 //directives/uiDirectives.js
002 template: <div class=background data-ngshow=
content.visible></div><div
class=lightbox
datang-show=content.visible>><button data-ngclick=
content.toggleView()>close</
button><p>{{content.
<Above>
sBy isolating the directive scope you can render different
content across multiple instances of a directive
<Above>
sFunctions defined within the controller $scope
can be run from within a directive
<Above>
sCombining the data-ng-show attribute and a Boolean property in
the controller makes it really easy to hide and show the lightbox
class=lightbox data
-ng-show=content.visible><button
data-ng-click=
content.toggleView()>close</
button><div
text}}</p</div>
003 //myApp.html
004 <section data-ng-controller=uiCtrl>
005 <h1>{{title}}</h1>
006 <!-- directive referenced using attribute
data-ng-
-->
007
transclude></div></div>
011 }
012 });
Directive naming
It is best practice to always prefix
your directive names. This will avoid
any conflicts with future changes in
HTML elements. Do not us ng as a
prefix as this would then confuse
custom directives with the standard
set provided as part of AngularJS.
Also note that when referenced in
HTML the directive names are
hyphenated opposed to
being camel case.
004 scope: {
005 content: =myLightbox
006 }
template
001 //directives/templates/lightbox.html
002 <div class=background data-ngshow=content.visible></div>
004
show=content.visible>
<button data-ng-click=content.
toggleView()>close</button>
007 }
008 })
15 Add a controller
012 })
accordion
item</p>
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
parentCtrl){
013
// code here will run when the
directive is called
014
},
015
template: <h2>{{title}}</h2><div
class=accordionContent data-ng-transclude></
div>
016 }
017 });
<ul>
<li>Bullet item 1</li>
<li>Bullet item 2</li>
<li>Another bullet item</li>
</ul>
</div>
<div data-my-item>
<h3>A sub heading</h3>
<p>Some text for the second
accordion</p>
<ol>
<li>Numbered item 1</li>
<li>Numbered item 2</li>
<li>Another numbered item</li>
</ol>
</div>
<div data-my-item>
<p>Some intro text to the last
accordion item</p>
<ul>
<li>Bullet item 1</li>
<li>Bullet item 2</li>
<li>Another bullet item</li>
</ul>
</div>
</div>
18 Add titles
001 parentCtrl.addItem(scope);
You can
define any desired
content within the
accordion items
Web Design Tips, Tricks, & Fixes 101
Create a scaling
hover effect
inspiration www.fancyfeast.com
INSPIRATION
Move me
3
Unique 404 pages
Responsive layout
Visual appeal
Number of pages
Hidden gems
Brand trust
Customer testimonials,
product ratings and
social media are given
prominence within the
site layout, reinforcing
trust in the brand
Sticking to simplicity
<comment>
What our
experts think
of the site
The workshop files have purposely been kept simple in order to focus on the
technique and will work without problems in the current version of Firefox. Out in
the wild, youll need cross-browser support and there are a number of ways of
achieving this. One simple method you might want to check out is prefixr.com.
Jayson Winters
TECHNIQUE
Create a scaling
hover effect
01 Set some styles
001
002
003
004
005
006
007
008
009
010
011
html {
background: url(paw.png) repeat;
}
body {
color: #eee;
font-family: sans-serif;
font-size: 20px;
font-weight: 800;
line-height: 1.75;
text-align: center;
}
02 Centre in browser
Centring content should be a straightforward
task, but the longer you look into the subject, the more
youll end up being reminded of Jack Nicholson in A
Few Good Men You want centred content? You cant
handle centred content!. Anyway, its just about handled
here in the following snippet.
001
002
003
004
005
#container {
margin-top:200px;
float:right;
position:relative;
left:-50%;
006
007
008
009
010
}
#inside {
position:relative;
left:50%;
}
TECHNIQUE
Experiment with
transformations
With about twenty transform property
values, you can scale, skew, translate, etc, any
element in a 2D or 3D plane. But just
because you can, doesnt mean you should.
Dont sacrifice legibility or usability.
01 Up a bit
001
002
003
004
005
006
007
div.scales {
width:400px;
height:272px;
float:left;
transition: 0.3s ease-out;
padding: 0px 10px 50px 10px;
}
02 Round a bit
001
002
003
004
div.scaleOn {
transform: scale(0.9,0.9);
transition: 0.3s ease-out;
}
03 Skew a bit
Produce a 3D
directionaware hover
effect
Present your portfolio using JavaScript
and CSS to create a 3D effect
tools | tech | trends HTML, CSS and JavaScript
01 CSS first
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
001 header {
002 text-align: center;
003 margin: 50px 0 25px;
004}
005 a:link {
006 color: #fff;
007 text-decoration: none;
008 }
009 a:visited {
010 color: #40eaee;
011 text-decoration: none;
012 }
04 Text styling
css?family=Bangers|Sofadi+One);
* {
box-sizing: border-box;
}
html {
background: url(../images/bg.jpg) norepeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
001
002
003
004
005
006
007
008
009
010
011
012
h1 {
margin: 0 auto 5px;
text-align: center;
font-size:70px;
color: #00acae;
text-shadow: 0px -4px #fff;
font-family: Bangers, serif;
}
.container {
width: 840px;
margin: 0 auto;
}
001
002
003
004
005
006
header p {
margin: 0;
font-size: 13px;
color: #00acae;
font-family: Sofadi One, serif;
}
001
002
003
004
005
006
007
008
009
010
011
012
ul {
padding: 0;
margin: 0 0 50px;
}
ul:after {
content: ;
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
The list item (li) is used for each item within the
gallery. The various dimensions can easily be changed
without breaking the technique. You might want to remove
the rounded corners (border-radius) if youre going for the
full Windows Metro look.
<Left>
sBeing direction aware isnt
a super power, so its not on
the list. However, if it
encourages your site visitor
to linger a little bit longer,
stimulates their interest, or
perhaps triggers an enquiry,
you might find that the
technique has a commercial
power for you
001
002
003
004
005
006
007
008
009
010
011
012
013
li {
position: relative;
overflow: hidden;
border-radius: 10px;
list-style: none;
float: left;
width: 200px;
height: 180px;
margin: 5px;
padding: 0;
perspective: 500px;
font-family: Sofadi One, serif;
}
001
002
003
004
li a {
display: inline-block;
vertical-align: top;
text-decoration: none;
005
006
007
008
009
010
011
012
013
014
015
016
border-radius: 10px;
}
li h3 {
margin: 0;
font-size: 18px;
color: rgba(255, 255, 255, 0.9);
}
li p {
font-size: 12px;
line-height: 1.5;
color: rgba(255, 255, 255, 0.8);
}
001
002
003
004
005
li.normal {
width: 100%;
height: 100%;
}
Playground rules
Hats off to Mexican front-end
developer Noel Delgado who
published this technique at
CodePen (codepen.io)
the playground for
the front-end side
of the web.
006
007
008
009
010
li .info {
width: 100%;
height: 100%;
padding: 20px;
position: absolute;
09 Overlay
001 top: 0;
<Left>
sBeing
direction-aware
enables you to
provide novel
methods of
interaction. Okay,
so its not quite the
Minority Report
experience yet but
gesture-based
interaction is
getting closer all
the time
Knowledge is power
Understanding the direction of the mouse
movement makes this an interesting technique
that you can build on. You can trigger additional
animations to provide more functionality, eg
making two icons appear: one to provide a gallery
image zoom option and the other to link to
another page or website. However you could also
use this technique to simulate a gesture-based
(albeit using the mouse) interface. Swiping the
mouse over the hotspot to the left or right might
trigger one response (eg paging backwards or
forwards) and swiping down or up another
response (eg moving deeper or higher in a
hierarchical structure). You could even trigger
different tooltips based on the direction of your
mouseover, for example, mousing from the top
for a brief description or from the bottom for a
more detailed version.
Cross-origin
requests
Youll need to review this in
Firefox unless you want to
run a local server or keep
uploading and reviewing
each change online.
002
003
004
005
006
007
008
left: 0;
overflow: hidden;
border-radius: 10px;
pointer-events: none;
background-color: #00acae;
transform: rotate3d(1, 0, 0, 90deg);
}
004
005
006
007
forwards;
}
.in-left .info {
transform-origin: 0% 0%;
animation: in-left 500ms ease 0ms 1
forwards;
}
forwards;
}
.out-right .info {
transform-origin: 100% 50%;
animation: out-right 500ms ease 0ms 1
forwards;
}
.out-bottom .info {
transform-origin: 50% 100%;
animation: out-bottom 500ms ease 0ms 1
forwards;
}
.out-left .info {
transform-origin: 0% 0%;
animation: out-left 500ms ease 0ms 1
forwards;
}
12 Animation keyframes in
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
@keyframes in-top {
from {
transform: rotate3d(-1, 0, 0, 90deg);
}
to {
transform: rotate3d(0, 0, 0, 0deg);
}
}
@keyframes in-right {
from {
transform: rotate3d(0, -1, 0, 90deg);
}
to {
transform: rotate3d(0, 0, 0, 0deg);
}
}
005
006
007
008
009
010
011
012
013
014
015
016
to {
transform: rotate3d(-1, 0, 0, 102deg);
}
}
@keyframes out-right {
from {
transform: rotate3d(0, 0, 0, 0deg);
}
to {
transform: rotate3d(0, -1, 0, 102deg);
}
}
Code library
Extended JavaScript
Got lost along the way? Dont panic, we delve into some of the intricacies of the code below
Each of the list items are
selected and converted
into an array with the
variable name nodes
007
008
The logic for calculating the
mouse direction is discussed
here: stackoverflow.com/
questions/3627042 but
might not be too helpful
unless you know your atan2
from your modulo
001 <body>
002 <header>
003 <div class=container>
004
<h1>Most wanted super powers</h1>
005
<p>According to <a href=
http://www.ranker.com>Ranker</a> with some
descriptions from <a href=http://
powerlisting.wikia.com/wiki/Superpower_
Wiki>Superpower Wiki</a><br />Creative
Commons images link to originals at
Flickr</p>
006 </div>
007 </header>
An event listener
determines whether the
mouse is inside a list item
element (and adds in to the
class) or if it is outside
(w > h ? (h / w) : 1)),
y = (ev.pageY - obj.offsetTop - (h / 2) *
(h > w ? (w / h) : 1)),
d = Math.round( Math.atan2(y, x) /
1.57079633 + 5 ) % 4;
009
010
return d;
011 };
012 var addClass = function ( ev, obj, state ) {
013
var direction = getDirection( ev, obj ),
014
class_suffix = ;
015
016
obj.className = ;
017
018
switch ( direction ) {
019
case 0 : class_suffix = -top;
break;
020
case 1 : class_suffix = -right; break;
021
case 2 : class_suffix = -bottom; break;
022
case 3 : class_suffix = -left; break;
023
}
024
025
obj.classList.add( state + class_suffix );
026 };
001 _nodes.forEach(function (el) {
002
el.addEventListener(mouseover, function (ev) {
003
addClass( ev, this, in );
004
}, false);
005
el.addEventListener(mouseout, function (ev) {
006
addClass( ev, this, out );
16 Start of list
17 End of list
001 <li>
002
Create a shake
effect using CSS3
animation
inspiration cervezaaustral.cl/viajealorigen
his website for a Chilean beer
makes use of the countrys
scenery to sell the product.
The bottle is shown against a
series of backgrounds that
promote the idea of the product
being produced using natural
ingredients. Clever photography also blends the
bottle into the landscape.
INSPIRATION
Interactivity
1
3
Individual elements Parallax motion
Reactive elements
Realism
Marketing
Navigation
The background is
composed of several
elements which move and
scale independently to
ensure that the bottle
remains the focal point
This site makes good use of the current trend towards images and video that
fill the screen, regardless of how large the browser window is. Movement
between the different slides that make up the site is fluid, and the parallax
effects work to help create a sense of depth.
Sam Hampton-Smith
TECHNIQUE
Shake your bottle
with CSS3
01 Some basic HTML
03 Create an animation
We need to define a preset animation that will be
applied to the bottle when its hovered over. To do this
we use the @-keyframes directive. Were testing in
Chrome, so to save replicating the code for all vendor
prefixes, weve just used the WebKit variant. You should
ensure you cover all vendors in your code.
005
30% { -webkit-transform:
translate(0px, 2px) rotate(0deg); }
006
40% { -webkit-transform:
translate(1px, -1px) rotate(1deg); }
007
50% { -webkit-transform:
translate(-1px, 2px) rotate(-1deg); }
008
60% { -webkit-transform:
translate(-3px, 1px) rotate(0deg); }
009
70% { -webkit-transform:
translate(2px, 1px) rotate(-2deg); }
010
80% { -webkit-transform:
translate(-1px, -1px) rotate(4deg); }
011
90% { -webkit-transform:
translate(2px, 2px) rotate(0deg); }
012
100% { -webkit-transform:
translate(1px, -2px) rotate(-1deg); }
013 }
TECHNIQUE
Cut out the bottle
In order to animate an element that appears
to be non-rectangular, youll need to cut out
your image and save it as a transparent
PNG. Your bottle should be partially
transparent so you can see through the
centre follow our steps to see how to do
this in Photoshop.
01 Grab a bottle
02 Create a selection
001 #bottle:hover {
002
-webkit-animation-name: shake;
003
-webkit-animation-duration:
0.8s;
004
-webkit-animation-iterationcount: infinite;
005
-webkit-animation-timingfunction: linear;
006
-webkit-transform-origin:
50% 100%;
007
008 }
03 Create a mask
Construct 3D
customised cubes
inspiration www.benjandsoto.com
INSPIRATION
The custom
element
3
2
Rotation options
Main focus
Inspiration
Simple uploader
Complete order
<comment>
What our
experts think
of the site
Benj & Soto is a young and creative company, and that requires an innovative
website. Here weve made use of WebGL and the wonderful Three.js library
so that users are able to interactively create their own sitting cubes in 3D. The
social aspect also plays a major role within the websites flow.
David Viaene - Web developer at Weblounge.be
TECHNIQUE
CSS 3D rotating cube
01 Add the <div> structure
001 <style>
002 #holder {
003 -webkit-perspective: 800;
004 -webkit-perspective-origin: 50%
-30%;
005 }
006 #cube {
007 position: relative;
008 margin: 100px auto;
009 height: 200px; width: 200px;
010 -webkit-transform: rotateY(45deg);
011 -webkit-transition: -webkittransform 1s linear;
TECHNIQUE
Create the
background
The background of benjandsoto.com is
reminiscent of a photographers studio and
can easily be recreated in Photoshop just by
applying some subtle gradients.
01 First layers
04 Different angles
05 Make it work
001
002
003
004
<script>
var yAngle = 45;
document.
addEventListener(keydown,
function(e){
005 switch(e.keyCode){
006 case 37:
007
yAngle -= 90;
008
break;
009 case 39:
010
yAngle += 90;
011
break;
012 };
013 document.getElementById(cube).
style.webkitTransform=rotateY(+yAngle
+deg);
014 }, false);
015 </script>
016
03 Add colour
Use overlay
effects on
background
video
HTML5 video is currently supported in
over 80 per cent of browsers so here
we integrate it into designs with a
variety of creative effects
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
< Above>
sAt this stage we have added the
video and set it behind our other
content using CSS to position the
video. Now we need to start styling
the page and visual effects
004
<source src=loop.ogv type=video/ogg>
005 </video>
001 <style>
002 h1, h2, h3, h4, a { color: #636; fontfamily: Amaranth, sans-serif;}
003 body {
004
color: #555;
005
font-family: HelveticaNeue-Light,
Helvetica Neue Light, Helvetica Neue,
Helvetica, Arial, Lucida Grande, sans-serif;
006
background: url(images/bg.jpg) #000 norepeat center center fixed;
007
008
-webkit-background-size: cover;
009 }
010
011 </style>
04 Video background
<Left>
sWe have produced the logo entirely out of CSS
and a background pattern. The pattern adds
visual interest and allows the text of the logo to
stand out and the circle is achieved using the
border radius property
<Above, top to bottom>
sHere we have begun styling up the strapline.
Notice how we have added a transparent
background tile of an x pattern to the screen.
This creates an interesting visual effect and
allows the text to stand out more as well
s.PTUPGUIFDPOUFOUPOUIFTDSFFOXBT
unreadable, so we create a class called white to
add a white background to the main text areas
draw more attention to it over the video
001 video{
002 position:fixed;
003 left:0;top:0;
004 min-width:100%;
005 min-height:100%;
006 width:auto;
007 height:auto;
008 z-index:-100;
009 visibility: visible;
010 }
001 #logo{
002 width: 320px; height: 320px;
003 margin: 80px auto;
004 padding: 20px;
005 text-align: center;
006 border-radius: 50%;
007
Gradients in CSS
background: url(images/thick_stripe.
png);
008 }
06 Vertically centring
001 #vCent{
002 display: table;
003 height: 320px; width: 320px;
004 overflow: hidden;
005 }
006
07 Vertically centred
middle;
font-size:5em;
letter-spacing:.02em;
line-height: .8em;
color: #636;
<Above>
sCreating spaces between content sections help to show the division of content, but it also allows the background video to
show through for the user
<Top right>
sThis transparent section features a quote and also a semi-transparent black background allowing the video to show through
<Bottom right>
sAgain we combine CSS3 gradients with a tiled dot image to add an interesting space. The gradient fades into the footer
section at the bottom of the page
001 .strapline{
002 padding: 20px 0;
003 color: #fff;
004 font-size: 2.5em;
005 font-family: Amaranth, sans-serif;
006 }
007
001 .cntr{
002 margin: 0 auto;
003 width: 95%;
004 max-width: 960px;
005 line-height: 1.6em;
006 }
10 Side view
001 .lines{
002 border-top: 2px solid #fff;
003 border-bottom: 2px solid #fff;
004 padding-bottom: 10px;
005 }
11 Readable text
Disguise the
compression
Adding a transparent tiled
image over video helps to
disguise the compression of
the video, so add these if you
have heavily compressed
video that saves time
downloading the large
file sizes.
001 .white{
002 background: #fff;
003 padding: 40px 0;
004 }
001 a{
002 display:inline-block;
003 color:#fff;
004 text-decoration:none;
005 background: #636;
006 padding:.5rem;
007 transition:.3s background;
008 }
13 Rollover transition
We have added a link for the Creative Commonssourced video background that we have used, so we need
to make that link stand out. Here we add a background
001 a:hover{
002 background:#303;
003 }
14 Horizontal rules
001 hr {
002 height:1px;
003 background-color:#ddd;
004 border:none;
005 }
15 Rule of thirds
001 .third{
002 float: left;
003 width: 30%;
004 padding: 0 1.5%;
005 }
006 .clearfix{ clear: both; }
16 Create spaces
001
002
003
004
005
17 Fold it up
001 .respond {
002 max-width: 100%;
003 }
001 .thin_bg{
002 background: -webkitgradient(linear, left top, left bottom,
color-stop(0%,rgba(55,55,55,0.9)),
color-stop(80%,rgba(55,55,55,0)),colorstop(100%,rgba(55,55,55,0.3))), url(images/
thin_stripe.png);
003 }
You may notice inside the video tag that there are
three different versions of the same video this is
because different browsers support different
video types. This is actually becoming easier to
cater for than in the past. At present Safari,
Chrome, IE (version 8 onwards) and Firefox
(version 21 onwards) all support the MP4 format.
Hot on their heels is Opera, which currently is the
001 .about-img
002 {
003 max-width: 360px;
004 display: block;
005 float: right;
006 }
20 Dark gaps
001 .dark2_bg {
002 background: -webkit-gradient(linear,
left top, left bottom, colorstop(20%,rgba(45,45,45,0)), colorstop(100%,rgba(45,45,45,0.8))), url(images/dot.
png);;
003 }
001 .dark{
002 background: #222;
22 Final step
Build an
HTML5
platform game
Your time has come the Quintus
Game Engine makes it easier than
ever for you to create your own
HTML5 game
tools | tech | trends Tiled map editor (www.mapeditor.org)
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
<Left>
sIts all very pretty but, as a
web designer, you already
know that if it doesnt work
well and look good on
smaller devices youve lost
over half your audience
before youve started.
Fortunately Quintus does
work well and it does look
good right out of the box
001
002
<script src='lib/quintus.js'></script>
<script src='lib/quintus_sprites.js'></
script>
003 <script src='lib/quintus_scenes.js'></
script>
004 <script src='lib/quintus_input.js'></
script>
005 <script src='lib/quintus_anim.js'></
script>
006 <script src='lib/quintus_2d.js'></script>
007 <script src='lib/quintus_touch.js'></
script>
008 <script src='lib/quintus_ui.js'></
script>
011
012
013
014
015
016
</style>
</head>
<body>
</body>
</html>
06 Level design
07 Sprite design
001
002
003
004
005
006
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=0,
minimum-scale=1.0, maximum-scale=1.0"/>
007 <title>Spacewars</title>
008 <script src='spacewars.js'></script>
009 <style>
010
body { padding:0px; margin:0px; }
Make it
your own
Storm the enemy mothership
in your one-man shuttlecraft,
fight off the baddies and
reach the golden container.
Other childhood fantasies are
available. With Quintus its
now a lot more achievable
for everyone.
001 window.addEventListener("load",function() {
002
003
var Q = Quintus()
004
.include("Sprites, Scenes,
Input, 2D, Anim, Touch, UI")
005
.setup({ maximize: true })
006
.controls().touch();
09 The player
001
002
Q.Sprite.extend("Player",{
init: function(p) {
003
this._super(p, { asset:
"player.png", x: 110, y: -1000, jumpSpeed:
-400});
004
this.add("2d,platformerContro
ls");
005
},
006
step: function(dt) {
007
if(Q.inputs["left"] &&
this.p.direction == "right") {
008
this.p.flip = "x";
009
}
Attributions
and licences
Some game tiles are derived from
work by Csaba Felvegi (chabull at
opengameart.org) and the player
sprite is partly derived from work
by MillionthVector, both licensed
under CC3.0. The map and game
code is partly derived from
the tutorial posted by
Pablo Farias Navarro at
gamedevacademy.org.
010
if(Q.inputs["right"] &&
this.p.direction == "left") {
011
this.p.flip = false;
012
}
013
}
014
015
});
10 Baddies
001
002
003
004
Q.component("commonEnemy", {
added: function() {
var entity = this.entity;
entity.on("bump.
left,bump.right,bump.
bottom",function(collision) {
005
if(collision.obj.
isA("Player")) {
006 Q.stageScene("endGame",1, { label: "Game
Over" });
007
collision.obj.destroy();
008
}
009
});
010 entity.on("bump.top",function(collision) {
011
if(collision.obj.isA("Player")) {
012
//make the player jump
013
collision.obj.p.vy = -100;
014
015
016
017
018
019
020
021
//kill enemy
this.destroy();
}
});
},
});
11 Ground baddies
001
002
003
Q.Sprite.extend("GroundEnemy", {
init: function(p) {
this._super(p, {vx:
-100, defaultDirection: "left"});
004
this.add("2d, aiBounce,
commonEnemy");
005
},
006
step: function(dt) {
007
var dirX = this.p.vx/
Math.abs(this.p.vx);
008
var ground = Q.stage().
locate(this.p.x, this.p.y + this.p.h/2 + 1,
Q.SPRITE_DEFAULT);
009
var nextTile =
010
011 //if we are on ground and there is a cliff
012
if(!nextTile && ground) {
013
if(this.p.vx > 0) {
014 body > header.halfsize {
015
if(this.p.defaultDirection
== "right") {
016
017
018
019
020
021
022
023
this.p.flip = "x";
}
else {
this.p.flip = false;
}
}
else {
if(this.p.defaultDirection
== "left") {
024
025
026
027
028
029
030
031
032
033
this.p.flip = "x";
}
else {
this.p.flip = false;
}
}
this.p.vx = -this.p.vx;
}
}
});
12 Flying baddies
001 Q.Sprite.extend("VerticalEnemy", {
002
init: function(p) {
003
this._super(p, {vy: -100,
rangeY: 200, gravity: 0 });
this.add("2d,
commonEnemy");
005
this.p.initialY = this.p.y;
006
},
007
step: function(dt) {
008
if(this.p.y this.p.initialY >= this.p.rangeY && this.p.vy >
0) {
009
}
004
010
011
else if(-this.p.y +
this.p.initialY >= this.p.rangeY && this.p.vy <
0) {
012
this.p.vy = -this.p.vy;
013
}
014
}
015
});
016
13 Play again?
Game graphics
The tone of your game will be determined by the visual style you choose. Take some time to see what has
been done before and then go off and create something amazing and unique
001 Q.scene("endGame",function(stage) {
002 var container = stage.insert(new Q.UI.
Container({
003
x: Q.width/2, y: Q.height/2, fill:
"rgba(99,99,99,0.5)"
004 }));
005
006
016
017
021
001 Q.scene("level1",function(stage) {
002
003
stage.insert(new Q.Repeater({
.png"}],
004
005
stage.collisionLayer(new
Q.TileLayer({ dataAsset: "level1.tmx",
layerIndex:0, sheet: "tiles", tileW: 70,
tileH: 70, type: Q.SPRITE_DEFAULT }));
006
007
Q.Player())
005
["GroundEnemy",
y: 3*70, asset: "ground.png"}],
006
["GroundEnemy",
y: 6*70, asset: "ground.png"}],
007
["GroundEnemy",
y: 0, asset: "ground.png"}],
008
["GroundEnemy",
y: 0, asset: "ground.png"}],
{x: 6*70,
{x: 18*70,
{x: 20*70,
{x: 11*70,
16 Load assets
001 stage.loadAssets(levelAssets);
002 stage.add("viewport").follow(player,{x:
true, y: true});
003 Q.load("tiles_map.png, player.png, ground.
png, fly.png, level1.tmx, background-wall.jpg",
function() {
004
Q.sheet("tiles","tiles_map.png",
{ tilew: 70, tileh: 70});
005
Q.stageScene("level1");
006
});
17 Keep building
Fixes
122
128
134
Modernizr masterclass
138
150
154
158
162
166
128
The theory
of text
and type
146
142
170
146
Build a
Foundation
template
162
170
Discover
the Google
Maps API
Automate
processes
with Grunt
122
Take your
CSS to the
next level
SUPERCHARGE
YOUR CSS
Do you want to spend less time writing CSS and more time
doing fun stuff? A CSS preprocessor could change your life
ts that meeting on Friday. Your team has
worked on the site for the last month. This is the
final client review. Everyone loves it, until the
client leans in and says Fantastic. But I dont like
that font. And my new phone has rounded
buttons, not square ones. So could you add those
too? Otherwise good job everyone. If you put your
site together with plain old CSS, even making basic
changes will take a while.
WHAT IS A PREPROCESSOR?
CSS preprocessors take the CSS code youve always
wanted to write, and turn it into the CSS code youve
always had to use. CSS has always been half a
solution. Its better than manual markup, but its not a
sleek and efficient way to specify styling elements.
A key problem apart from the crafty syntax is that
CSS has no memory or intelligence. In coder-speak, this
makes it WET: Write Everything Twice. So youll often
have to write the same stylings again in many places.
Plus, if you want to change something, you have to find
those places again and hand-edit them.
TWO ALTERNATIVES
If none of the big three are appealing, you
could always give these options a try
QSWITCH
bit.ly/18AbUbB
QLESS
lesscss.org
QSTYLUS
learnboost.github.io/stylus
Switch is a preprocessor in
Embryo. Its big feature is
out-of-the-box Apache
compatibility it runs as an Apache module
under mod_python, which gives Apache support
for the Python programming language. The
code is freely available at code.google.com/p/
switchcss. If youre minded to explore full-cream
code development, Python is a good language
to start with. Its much easier to work with than
heavyweight languages like C++ and its not
impossibly difficult to customise Switch to create
your own mini-preprocessor.
QSPIFFING
spiffingcss.com
Do you need a preprocessor
that plays stirring patriotic
music while draping red, white
and blue bunting around an
old red British phone box?
Probably not. But just in case, take a look at
spiffingcss.com. It swaps spellings like color
and gray into sensible English words like colour
and grey. It even converts the brashly selfabsorbed !important keyword into !please. Tea
and scones not included, unfortunately. But its
smashing for weather apps.
INSTALLATION OPTIONS
COMMAND LINE
LESS is written in JavaScript. You can
include the script in your sources while
developing but not for production,
unless you want to cripple your server.
For a one-time final compile, install
Node.js on a dev machine and run the
.less files through the lessc tool (visit
bit.ly/1bG2N9D).
SASS works with Ruby. See
rubyinstaller.org for Windows, and
www.ruby-lang.org/en/downloads for
Linux and OS X (Mavericks includes a
version of Ruby, but RVM can manage
multiple versions). You can then gem
install sass, and use sass input.scss
output.css in order to compile.
SERVER-SIDE
If you have Node.js on your server, you
can install LESS as an npm package
with npm install g less. You can then
use the lessc tool to compile files
manually, just as you would on a
development machine. But you can
also render CSS live with Nodes less.
render command but this can get
pretty complicated.
In theory, SASS is never run
server-side. In practice you can set up
Ruby on a server and have it either
compile on the fly whenever the user
loads a page (inefficient) or compile
then cache, so only changed files are
rebuilt when they need to be.
You can include the script in your sources while developing but
not for production, unless you want to cripple your server
QLIVERELOAD
livereload.com
LiveReload combines built-in
compilation for SASS, LESS, Stylus and
an alphabet soup of other tools.
LiveReloads big feature is
automated compilation: it monitors the
files in your project and automatically
recompiles CSS when you edit it, so
you dont need to worry about
command line tools or setting up a
preprocessor on your server.
Optionally you can run a script after
QSCOUT
mhs.github.io/
scout-app
Scout takes the effort out of Ruby,
Compass and SASS for Mac users, by
bundling them all into one
development environment. It includes a
project console for file and directory
management, and an embedded
terminal output window.
Its not a full GUI editor like CodeKit,
youll need to do your editing elsewhere
QCRUNCH
crunchapp.net
Crunch is a LESS editor and compiler.
You edit LESS, you save CSS. Its that
simple. You dont need to set up a
command line tool, or install any extra
add-ons, plug-ins, extensions,
daemons, apps, or anything else.
Crunch is Mac-only, and free from
the website. There really isnt all that
much else to know. It works in a simple
GUI-editor kind of a way. You are able
to have multiple files open at the same
PREPROCESSORS IN ACTION
VARIABLES AND ARITHMETIC
All preprocessors support variables with optional
math functions. Even if you never use any other
preprocessor feature, variables can save you hours of
update time by concentrating critical definitions in
one location in one file. This is usually at the start of
the file, although for even simpler maintenance you
can keep all the main colour palette and font
definitions in one file and import it into the others. In
LESS, variables begin with @. In SASS, they start with
$, rather like PHP variables. Stylus is understated, and
you dont need any special symbols.
The following code illustrates a very simple SASS
example, compiled in CodeKit. It defines two
variables: a font list, and a text colour. There are also
a couple of sketched out container definitions, so you
USE MIXINS
001
002
003
004
005
006
//Original scss
$font-list: Helvetica, sans-serif;
$bodytext-color: #111;
.acontainer {
font: 100% $font-list;
color: $bodytext-color;
007 }
008 .another_container {
009 font: 50% $font_list;
010 color: $bodytext-color*0.1;
011 }
012 //Compiled CSS
013 /* line 4, ../sass/new.scss */
014 .acontainer {
015 font: 100% Helvetica, sans-serif;
016 color: #111111; }
017 /* line 9, ../sass/new.scss */
018.another_container {
019 font: 50% Helvetica, sans-serif;
020 color: #010101; }
CREATE LOOPS
CSS is literal; unlike real programming
languages, it has no concept of
repetition or progress. You can fix this
in a preprocessor. Some possible
applications of repetition include
creating grids and tables with optional
shrinking/expanding elements, a set of
font sizes from a base size, a colour
palette from a base colour and a list of
URLs given the keywords they differ by.
LESS has basic looping. You have to
make it behave with a combination of a
001
002
003
004
005
006
007
008
009
010
011
012
//Original scss
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
-ms-border-radius: $radius;
-o-border-radius: $radius;
border-radius: $radius;
}
.rounded_box {
@include border-radius(50px); }
.very_rounded_box {
@include border-radius(500px);
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
}
//Compiled CSS
/* line 9, ../sass/new.scss */
.rounded_box {
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
-ms-border-radius: 50px;
-o-border-radius: 50px;
border-radius: 50px; }
/* line 13, ../sass/new.scss */
.very_rounded_box {
-webkit-border-radius: 500px;
-moz-border-radius: 500px;
-ms-border-radius: 500px;
-o-border-radius: 500px;
border-radius: 500px; }
NESTED RULES
Inheritance can kill a bigger project
where the basic elements have tens of
variations. With nested rules, you can
keep all the related details in a single
location, indented for clarity. Nested
rules make it much easier to keep track
of which sub-elements have which
styles, and even more usefully the
added readability makes it easier to
see where you need to make changes
to update some elements, while
leaving others unchanged.
THE FUTURE OF
PREPROCESSING
Theres even more to come, as CSS gets closer and closer to a real
programming environment
The biggest change in the near future of web design will very likely be the wider
use of preprocessors. In a css-tricks.com survey last year, it was revealed that
nearly half of all users still hadnt tried a preprocessor. Its true theres a certain
learning curve involved especially if youre installing a server-side
implementation or working at the command line but the initial time demands
are tiny compared to the effort you can save yourself if you add a preprocessor to
your workflow.
All the main CSS preprocessors are continuing to be developed, but at the
moment there are no plans to roll any of them into official w3.org CSS
specifications so dont expect to see native browser support for a while yet. A
few features, such as smarter selectors, are working their way into mainstream
CSS. But for the time being, the inefficient official syntax is unlikely to change.
What may change, however, is the way developers think about CSS. The official
aim of CSS was to abstract content from presentation. HTML and CSS includes
TOP TIPS
QPain-free debugging
Swat those bugs by using readily available, smarter code tools
Debugging preCSS can be challenging. The target browser never sees your
native preCSS code, it only sees the compiled CSS, because thats the only code
it can make sense of.
So how do you fix bugs? A diligent web search will find tools you can add to
most environments. Theyre often in an alpha-ish state, so dont expect a
polished performance but theyre better than nothing. For example, try the
FireSass add-on for FireBug (mzl.la/gXg7x2). Other tools include Sass Sleuth for
Safari and OS X Chrome (bit.ly/18jD94x), and Sass Inspector for Chrome (bit.ly/
YiVSGO). Chromes Developer Tools can work with LESS and Stylus files as well,
as long as you compile them with the source maps option.
Text
T he theory of
and
Type
The perfect typeface does not exist yet,
proclaimed legendary typographer Jan
Tschichold in 1925. In this article we delve
into modern web typography and reveal how to
create beautiful web type
128 Web Design Tips, Tricks, & Fixes
completely unreadable by setting it at a tiny size, reducing letter spacing to -4px, and
finishing it off with everything in lowercase in a light grey on a white background.
Font of Knowledge
Tom
Fonts vs Typefaces
An oft misunderstood area (and one that today only really bothers typographic geeks),
its still useful to know the difference and its really rather simple. A typeface relates to
the overall family, whereas a font relates to a specific version of the typeface. For
example, Helvetica is a typeface, Helvetica Bold is a font.
The simplest way to remember it is to consider the typeface as an album and the
fonts are the tracks contained on it.
Legibility vs Readability
Legibility relates to the clarity of the typeface itself. Blackletter typefaces have low
legibility thanks to their decorative nature. Their ancient style featuring heavy serifs or
accents that often contain ligatures (the joining of letters together) reduce clarity and
should be reserved strictly for the design of old English pub signs.
Readability, on the other hand, is about typesetting. It refers to the individual
elements that can be adjusted with the font itself size, line height, letter spacing,
contrast, colour, and more Its possible to make a very legible font (Times, lets say)
The Guardian website uses their own in-house typeface for its masthead. They also
have a sparing approach towards bolding for serif and sans serif typefaces
Wittlin
No codes or protocols
There are no hard and fast rules that must be applied to
selecting headline type, but theres a few guidelines that
can assist in adding that touch of professionalism to your
design. Focus on readability first (see previous page), test
out lots of different typefaces, use a type testing tool like
Typecast app, and ensure they also have the right feel for
the design of the site.
Tabloid headlines
If we look at newspapers for their approach to titles youll
The sans serif for the offer shown above immediately grabs the attention of potential customers
notice tabloids generally favour large sans serif, impact
fonts set in uppercase while more traditional
broadsheets opt for serifs set in lowercase. This comes
back to the content; tabloid headlines tend to be more
sensationalist with attention grabbing phrases, whereas
broadsheets have more subtlety, which is reflected in the
fonts they have chosen.
Helvetica
Sans serif
www.fonts.com
No prizes for originality but it wouldnt
be right to not mention this milestone of
design in an article about type. Helvetica
is to type what black is to fashion it
goes with anything. Coupled with its
vast range of variations from extra-light
through to rounded bold, Helvetica
gives instant gravitas to any design.
Glober
Sans serif
http://bit.ly/1vq61ap
Despite being a new typeface, Glober
has an instantly familiar look with a wide
variety of feels thanks to its 18 available
weights (two of which are free). Based
on simple geometric shapes, Globers
modern design is also optimised for
web, making it an ideal consideration if
youre after something a little different.
Tip
If using all caps on titles, be sure to play with letter
spacing in CSS to ensure the greatest readability. Also,
if your design looks great with a title on one line, how
might it look if titles are longer and run onto two lines,
or more? Line height may also needs adjusting.
Weve selected four top headline fonts that range from the
old faithfuls through to the young upstarts of web type
Baskerville
Serif
http://bit.ly/1tGCmry
For class and tradition you cant go
far wrong with Baskerville. It works as
well in uppercase as it does in
lowercase. While not ideal for smaller
body copy, its unique characteristics,
such as its beautifully distinctive capital
Q and lowercase g, make headlines
stick out a mile.
Get the
best body
body
Here we choose excellent
choices for creating greatlooking body copy
What to consider
The perfect
Arial
Sans serif
Although generally considered to be a poor mans
Helvetica, Arial is still a workhorse of screen
typefaces. It also comes with the advantage of
displaying on screen better at smaller sizes than
its Swiss counterpart, and can again be used in
email design without concern for the user
owning the typeface.
Proxima Nova
Sans serif
To many, this has become the new standard Arial
replacement and its easy to see why. Beautifully
designed, taking inspiration from greats such as
Futura and Akzidenz-Grotesk, Proxima Nova is
perfect for web body copy thanks to its high
readability at smaller sizes.
Roboto
Sans serif
The original system font designed for Android
OS by Google was slammed for its awkward and
overly digital appearance. However, thanks to an
overhaul just this year, Roboto has now been
transformed into a thing of beauty. Designed
uniquely as a UI typeface, its guaranteed to work at
all sizes on all screens; from a television to a watch.
Georgia
Serif
Destined to be a classic yet still only 21-years-old.
Originally designed for Microsoft as a partner for
their Verdana typeface, Georgia works well in upper
and lower case. Out of all the serifs, its highly
readable at most sizes and, usable on webpages
and in emails safely as its a system typeface.
The Roald Dahl site combines hand-written fonts with Baskerville to create a timeless and classic style
Headline: Avenir
Body: Georgia
A nice contrast between the bold rounded nature of Brandon Groteske and the
angular edges of slab serif, Roboto. Easy to read on full desktop view at 20pt but
watch for how well slab serifs translate at smaller sizes as well as on mobile or tablets.
Again, similar to the above, punchy headlines make way for a more subtle readable
typeface. The feel of the site as a whole is very clean and modern. Using the italicised
serif for the kicker works well for the title sequence.
Rare for a duo of serifs to work exceptionally, but this carries it off well. Freight Display
brings clarity to the titles on a text heavy design. The additional white space given
allows it to breathe and the condensed space is filled with the ever-legible Georgia.
A classic look, popular at the moment for that old field notes/journal vibe.
This combination has been used to create a much more classic feel. The serif callouts
give an editorial feel and the size plays a vital role in the visual hierarchy. When it
comes to using a san serif as the title, the punchier Museo at smaller sizes brings
clear and concise subtitles and navigation.
Headline: Gotham
Body: Chronicle
With a very minimal theme and colour palette, Gotham seems the ideal choice to get
that clean polished look easily. The font allows the medium weight to be scaled up to
gigantic proportions without looking overwhelming and can be tracked as to not feel
too cumbersome. The book weight is ideal for body copy with its light appearance
and wide, spacious characters.
Tip
When testing type, dont use lorem ipsum use real
copy and read it. Relax your gaze on the screen to see
how the typeface feels. If you find it difficult or youre
straining in any way, look at something a little less
Remember to test your chosen typeface on multiple platforms. Its imperative when creating a responsive design
MODERNIZR
MASTERCLASS
By avoiding the latest features of CSS3, and sticking with tried-and-tested XHTML
tags, all the problems of testing and providing workarounds can be avoided right?
One of the biggest challenges with adopting new practices and tools is knowing
which browser supports which features. When we only had to contend with a couple
of versions of Internet Explorer, and the first version of Firefox, it was straightforward;
we knew what each browser was capable of. This allowed designers to target the
behaviour and capabilities of the two, optimising a design to suit each different one.
These days, however, there are at least half a dozen perfectly viable and capable
browser options for web users to choose from, and each has several versions in the
wild at any one time. Its become almost impossible to be intimately familiar with the
individual support characteristics of each web browser that might be used to access
your website. As a result, its no longer practical to target individual browser versions.
Thankfully, theres a simple and elegant solution.
Modernizr masterclass
WHAT IS MODERNIZR?
Modernizr is a JavaScript library that allows you to use
feature detection to determine whether the browser
being used to access your website is going to be able
to render specific types of content, or will support
particular features. The library works by allowing you to
check for support within the browser against a series of
tests. For example, if youre using CSS transitions, you
can test for the browsers ability to render these and, if
the browser doesnt handle animations, provide a
fallback or alternative.
Put in simple terms, Modernizr allows you to write
conditional CSS and JavaScript to tailor the experience
of your website according to the capabilities of the
users web browser.
The library is quick to install, and simple to use. When
a page with Modernizr loads, a JavaScript object is
created that contains the results of the tests. CSS
classes are added to the <html> element, allowing you
to check either via script or CSS whether a specific
feature is supported.
You may be wondering what tests can be run, and
which features are supported by Modernizr. What
makes the library so useful is that its almost a one-stop
shop for browser functionality-support testing.
Modernizr allows you test for over 40 next-generation
features including font-face, rgba, CSS animations,
gradients, canvas, HTML5 audio and video, local
storage and WebGL. Youre not tied into running tests
for every single feature, however. A great strength of
Modernizr in particular is its modular nature; you only
need test for the features you need, rather than having
to conduct every individual feature.
Script customisation
Not everything can be handled with CSS alone. In
above example, JavaScript would offer a good solution.
We could provide animation using CSS if supported, but
fall back to a jQuery animation in browsers that dont
support CSS animations. In this case, we could use a
simple jQuery selector to only run the JavaScript
animation on non-supported browsers:
001
001 If (Modernizr.geolocation) {
002 // This code only runs if the browser
supports geolocation
003 }
CSS-only customisation
For CSS-specific customisations, its as simple as
providing an alternative set of rules that uses the class
system to target browsers that dont support the
feature in question separately from those that do. For
example, you might have one set of rules introducing a
CSS transition for browsers that support animation, and
a second set for those that dont.
The CSS selector for those that support animations
would be:
<HEADER>
<NAV>
<ARTICLE>
<ASIDE>
001 <style>
002 .no-csscolumns body {
003 /* this browser doesnt support CSS columns
*/
004 }
005 </style>
006 <script>
007 if (Modernizr.touch) {
008 // the browser supports touch events, so
run the code within this section
009 } else {
010 // the browser doesnt support touch, so
provide an alternative
011 }
Using polyfills
<FOOTER>
Some older browsers do not support the newer HTML5 tags, an
issue that is easily resolved with Modernizr
Modernizr masterclass
001 Modernizr.load([
002 // object notated list of tests and
responses
003 {
004 test : Modernizr.canvas && Modernizr.
cssgradients,
005 // Multiple resources can be loaded for
each condition
006 // This condition is not met, so load
two files
007 nope : [presentational-polyfill.js,
presentational.css]
008 },
009 {
010
// This just has to be truthy
011
test : Modernizr.JSON,
012
nope : functional-polyfills.js,
013
// These resources will be loaded
014 regardless of the result:
015
both : [ app.js, extra.js ],
016
complete : function () {
017
// Run this after everything in this
group has downloaded
// and executed, as well everything in
all previous groups
019
myApp.init();
020
}
021 },
022 // Run your analytics after youve
already kicked off all the rest
023 // of your app.
024 post-analytics.js
025 ]);
018
Using
YepNope with Modernizr
YepNope makes it easy to load JavaScript and CSS resources into your page according to the result of each Modernizr test.
Well show you how to use the library to only load content each browser needs.
3. Load resources
1. Load the library
001 yepnope({
002 test: Modernizr.video,
003 yep: video.css,
004 nope: [video-html5.css,videopolyfill.js],
001 Yepnope({
002 test: /* condition to be tested, with a
boolean result (true / false) */,
yep: /* list of resources to load if
condition is true */,
004 nope: /* list of resources to load if
condition is false */,
005 both: /* list of resources to load
regardless of result */
006 });
003
Create sticky
table headers
using CSS
and jQuery
Make it easier for visitors to process
large amounts of data with sticky table
headers on both the X and Y axis
016
<td>Winter</td>
017
<td>2011-03-17</td>
018
<td>771-581-3017</td>
019
<td>[email protected]</td>
020
<td>89 W Blackjack</td>
021
<td>Apt 16</td>
022
<td>VA</td>
023
<td>21450</td>
024
<td>Iraq</td>
025 </tr>
03 Format table
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
002
003
004
005
006
007
008
<html>
<head>
<title>Sticky table headers</title>
</head>
<body>
</body>
</html>
02 Import data
id=resultTable>
<thead>
<tr>
<th>First Name</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hilario</td>
<td>Iraq</td>
</tr>
</tbody>
002 <tr>
003
<th>First Name</th>
004
<th>Last Name</th>
005
<th>Date</th>
006
<th>Phone Number</th>
007
<th>Email</th>
008
<th>Address 1</th>
009
<th>Address 2</th>
010
<th>State</th>
011
<th>Post Code</th>
012
<th>Country</th>
013 </tr>
014 <tr>
015
<td>Hilario</td>
001 <style>
002
html {font-family: arial, sans-serif}
003
tbody tr:nth-child(odd) {
004
background-color: #cccccc;
005
}
006
tbody tr:nth-child(even) {
007
background-color: #999;
008
}
009 </style>
010
< Above>
s5IFEVNNZEBUBJOJUTSBXFTU
GPSN
HFOFSBUFEVTJOHdummydata.
meXJUIOPTUZMFBQQMJFEUPJU
< Below>
s6TJOHBMUFSOBUJOHTUSJQFE$44CBDLHSPVOE
DPMPVSTJOPVSUBCMFEBUBJNQSPWFTJUTSFBEBCJMJUZ
HSFBUMZ#FDBSFGVMBCPVUDPNQBUJCJMJUZUIPVHI
< Above>
s$PNCJOFFWFSZUIJOHXJUICPMEMFGUIBOEDPMVNOIFBEFSTGPSBUSVFCJBYJBMTUJDLZUBCMFFGFDU
001
002
003
004
005
006
007
008
009
Thead {
position:
position:
position:
position:
position:
top: 0;
}
-webkit-sticky;
-moz-sticky;
-ms-sticky;
-o-sticky;
sticky;
07 Wider support
libs/jquery/1.11.0/jquery.min.js></script>
08 jQuery cloning
004
});
005 </script>
001
002
003
004
005
006
007
008
009
010
.wrapper {
overflow-x: auto;
position: relative;
margin-bottom: 1.5em;
width: 100%;
}
.wrapper .sticky-thead,
.wrapper .sticky-col,
.wrapper .sticky-intersect {
opacity: 0;
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
position: absolute;
top: 0;
left: 0;
transition: all .125s ease-in-out;
z-index: 50;
width: auto;
}
.wrapper .sticky-thead {
z-index: 100;
width: 100%;
}
.wrapper .sticky-intersect {
opacity: 1;
z-index: 150;
}
.wrapper .sticky-intersect th {
background-color: #666;
color: #eee;
}
.wrapper td,
.wrapper th {
box-sizing: border-box;
}
14 Move columns
<Above>
s5IJTJTour appended table data, driven by jQuery. You may notice at this stage that not all the data is present
CSS colours
When creating a striped table, it
is not recommended that the
two colours are vastly different
from a readability perspective.
Keep them to subtle shades
of the same colour.
005
$(this).after(<table
class=sticky-head />)
006
$(this).after(<table
class=sticky-col /><table class=
sticky-intersect />);
007
008
009
010
011
012
013
014
015
11 Append thead
001
002
003
004
005
006
007
$stickyHead. Append($(this).
find(thead).clone());
$stickyCol
.append($(this).find(thead,
tbody).clone())
.find(thead th:gt(0)).remove()
.end()
.find(tbody td).remove();
$stickyInsct.html(<thead><tr><th>
+$(this).find(thead th:first-child).
html()+</th></tr></thead>);
008
12 Helper functions
012
width($(this).width());
})
.end()
.find(tr).each(function (i) {
$stickyCol.find(tr).eq(i).
height($(this).height());
});
$stickyHead.width($t.width());
$stickyCol.find(th).add($stickyInsct.
find(th)).width($t.find(thead th).
width())
},
001
002
003
004
005
006
007
008
009
010
011
012
repositionStickyCol = function () {
if($stickyWrap.scrollLeft() > 0) {
$stickyCol.add($stickyInsct).css({
opacity: 1,
left: $stickyWrap.scrollLeft()
});
} else {
$stickyCol
.css({ opacity: 0 })
.add($stickyInsct).css({ left: 0 });
}
},
15 Calculate allowance
001
002
003
004
005
006
007
008
009
010
011
calcAllowance = function () {
var a = 0;
$t.find(tbody tr:lt(3)).
each(function () {
a += $(this).height();
});
if(a > $w.height()*0.25) {
a = $w.height()*0.25;
}
a += $sticky.height();
return a;
};
17 Bind objects
the user scrolls down or across the page. You may notice
that the below call uses the $w variable, this is a shorthand,
and well set this later on in the tutorial.
Code library
001 $load(setWidths)
001
002
003
004
005
resize($.throttle(250, function () {
setWidths();
repositionStickyHead();
repositionStickyCol();
})
001 .scroll(repositionStickyHead));
20 Implement throttling
repositionStickyHead));
22 Define shorthand
clone();
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
001 .scroll($.throttle(250,
001 var $w
= $(window),
002
$t = $(this),
003
$thead = $t.find(thead).clone(),
004
$col = $t.find(thead, tbody).
041
042
043
044
045
046
047
048
049
$(this).find(th).length > 0) {
var $w = $(window),
$t = $(this),
$thead = $t.find(thead).clone(),
$col = $t.find(thead, tbody).clone();
$t
.addClass(sticky-enabled)
.css({
margin: 0,
width: 100%
}).wrap(<div class=wrapper />);
$tatter(<table class=sticky-thead />);
if($t.find(tbody th).length > 0) {
$t.after(<table class=sticky-col
/><table class=sticky-intersect />);
}
var $stickyHead = $(this).siblings(.sticky-thead),
$stickyCol = $(this).siblings(.sticky-col),
$stickyInsct = $(this).siblings(.sticky-intersect),
$stickyWrap = $(this).parent(.sticky-wrap);
$stickyHead.append($thead);
$stickyCol
.append($col)
.find(thead th:gt(0)).remove()
.end()
.find(tbody td).remove();
$stickyInsct.html(<thead><tr><th>+$t.find(thead
th:first-child).html()+</th></tr></thead>);
var setWidths = function () {
$t
.find(thead th).each(function (i) {
$stickyHead.find(th).eq(i).width($(this).width());
})
.end()
.find(tr).each(function (i) {
$stickyCol.find(tr).eq(i).height($(this).height());
});
$stickyHead.width($t.width());
$stickyCol.find(th).add($stickyInsct.find(th)).
width($t.find(thead th).width())
},
repositionStickyHead = function () {
var allowance = calcAllowance();
if($t.height() > $stickyWrap.height()) {
if($stickyWrap.scrollTop() > 0) {
$stickyHead.add($stickyInsct).css({
opacity: 1,
top: $stickyWrap.scrollTop()
});
Speed up
responsive
sites with
Foundation
Dont hide content from desktop to
mobile devices, use the Interchange
feature to only load the content
required by the device
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
001 <style>
002 #vid {
003 width: 100%;
004 height: 600px;
005
overflow: hidden;
006 }
001 video{
002
min-width:100%;
003
min-height:600px;
004
width:auto;
005
height:auto;
006 }
007 </style>
002
02 Link up Foundation
003
004
005
004
005
webm">
<source src="header.ogv" type="video/
ogg">
006 </video>
007 </div>
07 Medium screens
< Above>
s8FBEEPVS)5.-WJEFPUIBUXJMMPOMZCFWJFXBCMFJOUIFEFTLUPQCSPXTFST5IJTXJMMTBWF
CBOEXJEUIPOUIFTNBMMFSTDSFFOEFWJDFTUIBUNBZCFBDDFTTJOHZPVSTJUFXJUIBEBUBQMBO
< Above>
s'PSBNPCJMFEFWJDFXFDBOOPXMPBEBTNBMMFSJNBHFTPUIBUOPCBOEXJEUIJTXBTUFE
< Above>
s8IFOJUDPNFTUPPUIFSTJ[FTDSFFOT
*OUFSDIBOHFXJMMPOMZMPBEVQUIFSFMFWBOUDPOUFOUGPS
UIBUTDSFFO)FSFPONFEJVNTJ[FEUBCMFUTDSFFOTXFMPBEBOJNBHFJOTUFBEPGUIFWJEFP
< Right>
s"TXFMMBTMPBEJOHTFQBSBUF)5.-DPOUFOUGSPNEJGFSFOUJMFT
XFDBOBMTPDIBOHFUIF
JNBHFUPUIFBQQSPQSJBUFEJTQMBZTJ[F
reason, this will be the image loaded here. Weve added the
smallest image to the page because if theres no JavaScript,
the user will likely want a low rendering of the page.
002
003
11 Readable text
Test the page in the browser now and you will see
the video and image are responsive but rather than just
downsizing, they actually change to a lower bandwidth for
the smaller-screen devices. Now lets add a little space
<Left>
sFoundations Interchange is very good at loading specific content for devices
and we can create separate files that feel a little like includes in PHP
<Above>
sHere we have added a YouTube video for desktop-sized browsing. As you can
see, it fits responsively into the Foundation grid
001 <style>
002
.spacer{ padding-top: 40px;}
13 Responding map
AJAX loading
400 as shown. Also you might want to get rid of the text to
view a larger map, but thats down to your preference.
004
17 Medium map
<Left to right>
sThe mobile-sized image replaces the Google Map on much smaller device
screens. This is very useful for targeting the right content for your user
sOn other devices we can swap out the HTML code for a Google Map and
make it load an image instead
sAs an alternative to the YouTube video, weve added text as a description of
the content that was presented in the video for smaller-screen devices
18 Small map
Going further
Custom media queries can be
defined for changing content
with Interchange and events can
be fired through JavaScript, visit
bit.ly/1fQPF49 to find
out more.
001 data-interchange=[image/path/to/
retina.jpg, (retina)]
Perhaps a larger problem is that retina screens
22 Final step
Build a
custom
Foundation
template
Get started using Zurbs Foundation
framework to build a responsive
template that can be reused
03 HTML head
04 Basic styles
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
01 Download Foundation
001
002
003
004
005
006
007
008
body {
color: #666;
}
h1, h2, h3, h4, h5, h6 {
font-family: Cabin, sans-serif;
font-weight: 500;
color: #666;
}
002
003
004
005
006
007
008
06 Sub menu
< Left>
sUsing the Top Bar
plug-in you can easily
create functional
drop-down menus,
the only real work is
styling it up
< Below>
sIncorporating a
responsive rotating
slider with swipe- and
touch-enabled
functionality is a
breeze using the
Orbit plug-in
< Above>
sThe Top Bar plug-in is fully responsive navigation,
even the drop-down menus are device-friendly
001 .top-bar {
002 -webkit-box-shadow: 0px 3px 7px 0px rgba
003
004
005 }
data-orbit>
<li>
<img src=img/slides/slide-1.jpg
alt=slider 1 />
<div class=orbit-caption>
Text to go here
</div>
</li>
</ul>
</div>
</div>
09 Orbit JavaScript
Foundation
with Sass
Throughout this tutorial we have
focused on pure CSS but you could
use Sass, which allows greater
customisation of the framework
using nested styles,
variables, function and
reusable code.
001 <script>
002
$(document).foundation({
003
orbit: {
004
animation: fade,
005
animation_speed: 500,
006
time_speed: 1000,
007
pause_on_hover: true,
008
bullets: false,
009
}
010
});
011 </script>
10 Basic content
< Left>
sCreating forms
with Foundation
is easy; forms
are versatile
and packed
with powerful
features including
form validation
< Below>
s5IJTJTUIFfinal
finished custom
Foundation
template by just
using a fraction of
what this
framework offers
<Above>
s5IFOrbit plug-in cannot handle variable height
images but the Clearing Lightbox plug-in can and
makes scrolling through images friendly
<Below>
sEach thumbnail is set as a href
wrapped around an image tag which
contains the large high-res image
11 Add a video
007
Follow
documentation
12 Panel component
13 Lightbox gallery
006
007
008
009
010
011
012
013
014
<ul class=clearing-thumbs
data-clearing>
<li>
<a href=img/photo.jpg>
<img src=img/photo.jpg
alt= data-caption=Text to go here />
</a>
</li>
</ul>
</div>
</div>
14 Gallery styles
001
002
003
004
005
006
007
<form data-abide>
<div class=name-field>
<label>Name:
<input type=text placeholder=
James Smith required pattern=
[a-zA-Z]+ />
</label>
</div>
</form>
20 Form styles
001
002
003
004
005
006
007
label {
text-align: left;
color: #666;
}
textarea {
height: 200px;
}
17 Error message
001
001
002
003
004
005
006
007
008
009
010
.gallery {
padding: 20px 0;
background-color: #f2f2f2;
}
.clearing-thumbs li {
margin: 0 20px 20px 0;
}
.clearing-thumbs li:first-child {
margin-left: 10px;
}
15 Common styles
16 Contact form
18 Email input
004
005
19 Message field
here</p>
</div>
<div class=large-6 columns>
<ul class=inline-list right>
<li>
<a href=#>Link 4</a>
</li>
</ul>
</div>
</div>
</footer>
001 footer {
002 color: #fff;
003 background: rgb(43, 43, 43);
004 background: -moz-linear-gradient(90deg,
rgb(43, 43, 43) 30%, rgb(29, 29, 29) 70%);
background: -webkit-linear-gradient
(90deg, rgb(43, 43, 43) 30%, rgb
(29, 29, 29) 70%);
006 background: linear-gradient(180deg, rgb
(43, 43, 43) 30%, rgb(29, 29, 29) 70%);
007 }
005
Get faster,
smarter
code with
RequireJS
By understanding how to code in a
modular fashion youll level up your
JavaScript prowess
005
app.js
006
slides.html
007
jquery.js
008
main.js
009 styles
010
main.css
011 index.html
03 Require configuration
Source files
available
sIUUQXXX
JMFTJMPDPVL
CLT
01 Data-main
007
008
009
010
02 Directory structure
001 .
002 scripts
003
app.build.js
004
components
001
002
003
004
005
006
require.config({
baseUrl: scripts/components,
paths: {
domReady: requirejs/domReady
}
});
04 Shim configuration
001
002
003
004
005
006
007
008
009
010
011
012
013
shim: {
handlebar: {
exports: Handlebars
},
jquery.slideshow: [jquery],
backbone: {
deps: [underscore, jquery],
exports: Backbone
},
underscore: {
exports: _
}
}
05 Define a module
002
<Left>
s5IF3FRVJSFJSTJUFJTBO
JOWBMVBCMFSFTPVSDFUIBOLTUPJUT
FYIBVTUJWFEPDVNFOUBUJPOBOE
MJOLTUPJUTIFMQGVMDPNNVOJUZ
<Below>
s5BEB8IFOBMMUIF
EFQFOEFODJFTBSFNFU
PVSCBTJD
TMJEFSJTEJTQMBZFEBOECSPVHIU
UPMJGF
slideshow],
<Right>
s)BOEMFCBSTIBTVTFGVMIFMQFST
JOUIJTDBTFXFSFEJTQMBZJOHB
NFTTBHFJGOPSFTVMUTXFSFSFUVSOFEVTJOHJUT\\FMTF^^IFMQFS
<Below>
s/PUFUIBUUIFTMJEFTIPXQMVHJOJTOUDBMMFEVOUJMUIFK2VFSZ
EFQFOEFODZIBTCFFOTBUJTJFE
06 Requiring dependencies
07 External dependencies
08 Custom dependencies
title={{title}}></ li>
004 {{else}}
005
<li><p>There were no results!</p></li>
006 {{/each}}
007 </ul>
008
11 setSlides method
002 return {
003 setSlides: setSlides
004 };
How
it works
<Above>
s8FSFHPJOHUPBEEBTJNQMFTFBSDIGVODUJPOBMJUZUPPVS
slideshow to display images that are determined by the user
<Above>
s+VTUMJLFUIBUXFDBOOPXHB[FVQPODVQDBLFTUPPVSIFBSUT
(stomachs?) content instead of moody cityscapes
<Above>
s#FGPSFUIFSKTPQUJNJTBUJPOXFIBWFOJOFTDSJQUDBMMTUPUBMMJOH
87.8kb. Still, at least now theyre not being loaded synchronously
15 Form HTML
001 <form>
002 <input type="search"
placeholder="Search for
something" required>
003 <button>Find</button>
004 </form>
16 Flexibility of asynchronicity
data, app) {
002 console.log(domReady, data, app);
003 app.setSlides(data);
004 });
002 domReady(function() {
003
// next step
004 });
005 });
(e) {
002
003
001 $(.slides).responsiveSlides();
18 Get images
001 $.getJSON(http://api.flickr.
com/services/rest/?method=flickr.
photos.search&tags= + term + &api_
key=API_KEY&format=json&extras=u
rl_l&jsoncallback=?, function (data) {
002 app.setSlides(data);
003 });
20 Minify main.js
Code library
21 Build configuration
001 ({
002
appDir: ../,
003
baseUrl: scripts/components,
004
dir: ../build,
005
paths: {
006
main: ../main
007
},
008
modules: [{
009
name: main
010
}, {
011
name: app
012
}]
013 })
014
Registering as a named
AMD module is safest
as some concatenation
scripts do not know
how to handle
anonymous modules
23 Exclude files
001 //app.build.js
002 baseUrl: scripts/components,
003 optimize: none,
004
001 require.config({
002 baseUrl: scripts/components,
003 paths: {
004
domReady: requirejs/domReady
005 },
006 shim: {
007
handlebar: {
008
exports: Handlebars
009
},
010
jquery.slideshow: [jquery],
011
backbone: {
012
deps: [underscore, jquery],
013
exports: Backbone
014 },
015
underscore: {
016
exports: _
017
}
018 }
019 });
020 define(main, [require, app], function(require) {
021 use strict;
022 require([domReady, http://api.flickr.com/services/
rest/?method=flickr.interestingness.getList&api_key=API_
KE
024
025
026
027
028
Create
responsive
sites with
intention.js
04 Orientation axis
This JavaScript is the heart of intention.js, and its
known as an axis. The ID value is how we call it with in-ID
or in this case in-orientation. Contexts is an array of
objects, the name is the class name that will be applied
and the value attached to it will be used when
measuring it.
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
01 Script dependencies
Intention.js depends on jQuery and Underscore
in order for it to work, so be sure to include these before
intention.js. Intention also comes with an optional
bootstrap file called context.js, which gives four
common measurements: width, orientation, touch
capable, and whether its high DPI. We then include our
own JavaScript file after it. All of these dependencies
weigh in at a hefty 115.5kb pre-gzip.
001 <script
002 <script
script>
003 <script
script>
004 <script
005 <script
src=js/jquery.js></script>
src=js/underscore.js></
src=js/intention.js></
src=js/context.js></script>
src=js/app.js></script>
02 Intent attribute
To signify that Intention should update an
element, we have to use the data-intent attribute as a
keyword. You can just put intent but itd be nice if we
could write with standards. Once intention.js knows to
do something to an element, we then tell it what
specifically we want to update.
03 In orientation
In the case of the body tag, we want to add a
class of portrait or landscape each time it changes.
Context.js gives us some default behaviour, one of which
is detecting orientation so we can simply write
in-orientation: to add the class. Dont panic, we have a
look at the JavaScript behind this in more detail in the
following step.
05 Matcher method
The measure method runs the test and the
matcher method returns a true or false value depending
on if a contexts value passes the test against the
measurement (eg the orientation value). Were doing a
comparison between window.orientation and each of
the contexts: portrait (0) and landscape (90).
06 Respond to change
Following on from the orientation axis, if window.
orientation is 90 then itll add the class of landscape to
all elements that have data-in-orientation on them, and
when its 0 the class will switch landscape out with
portrait. This isnt completely magic though, context.js
still adds an event listener calling respond(), which
re-evaluates the measure and then calls the matcher.
<Above>
s5IFUXPJOTQFDUPSTTIPXUIFDMBTTDIBOHJOHXIFOJOEJGFSFOUPSJFOUBUJPOTEVFUPUIFBYJT
EFUFDUJOHBDIBOHF
<Above>
s8JUIKVTUBTQSJOLMJOHPG$44BOEUIFBEEJUJPOPG'POU"XFTPNFTJDPOT
XFIBWFBTJNQMFJOUFSGBDF
GPSBNVTJDQMBZFS
<Above>
s8IFOUIFQMBZFSSFTQPOETXJUIGBMTF
UIF1MBZCVUUPOJTTIPXOUPJOJUJBUFQMBZJOHCZDBMMJOHB
UPHHMF1MBZJOHGVODUJPO
<Above>
s$POWFSTFMZ
XIFOUIFQMBZFSSFTQPOETXJUIUSVF
UIF1BVTFCVUUPOJTEJTQMBZFEJOPSEFSUPQBVTFUIF
QMBZJOHPGUIFUSBDL
alt=Album
artwork>
004
</div>
005
<div class=right-column column>
006
<p class=song></p>
007
<p class=album></p>
008
<p class=artist></p>
009
</div>
</section>
003
<i class=icon-step-backward
previous control></i>
004
<i class=play icon-play control
data-intent data-inplaying:></i>
005
<i class=icon-step-forward next
control></i>
006
<div class=volume-container></
div>
007 </section>
008 <audio></audio>
09 Custom axis
To make a new axis, we pass intent.responsive()
as an object with an ID, an array of contexts: the name
will be used for the class and the value can be anything
to match against. In this case itll be true or false but it
could be a number or anything else. Calling .respond()
will evaluate it immediately.
002
ID: playing,
003
contexts: [{
004
name: icon-pause,
005
val: true
006
}, {
007
name: icon-play,
008
val: false
009
}],
010
//next two steps
011 }).respond();
012
10 Measure method
Within our custom axis requires a measure
function, some sort of test that our contexts will be
measured against. Were going to write a simple
music player that will have a playing method, so
thatll be our measure for if its playing or not. If you
grasp this concept, then intention.js will be a snap
for you.
15 Volume axis
Different uses
for intention.js
The Intention blog
(bit.ly/19ZznD7) has
a number of examples
and more ways to use the
library, including a
helpful speed test.
12 Public interface
Now that weve dealt with intention.js a fair bit,
next well build up our actual web player through the
imaginatively titled webPlayer. Itll be very simple so we
only have Play, Pause and Volume controls. The demo in
the online resource files (see link above) also has
seeking and a countdown if youd like to see how
those work.
13 Play function
The Play function sets the variable playing to
true and starts playing the <audio> element. We can
access our playing axis out of scope by using intent.
axes, which contains all of the axes that have been
added. Using this, we can force the playing axis to
re-evaluate itself and switch to the Pause class.
14 Pause function
We do the opposite with our Pause method;
set playing to false, invoke Pause on the player (the
<audio> element) and force the playing axis to
respond. This will measure the playing variable so as
its now false itll switch back to the Play icon. Pretty
simple stuff.
16 Volume matcher/measure
Matcher will iterate through each context and
see if its value (.val) is greater than or equal to the
measure (the current volume, as returned through
webPlayer). It will stop iterating when one of the
matchers returns true (which is why the order is
important). The measure function will get the current
value of the volume bar for you.
001
{
002
003
004
005
006
17 Intent events
You can also listen for events within Intention. An
intent is fired whenever a context returns true, context in
an axis returns true, or when a specific axis passes any
context. Below is an example of each note the colon to
differentiate between always returning true and passing
any context.
<Far left>
sWhen in a mobile
context the volume
control is rotated, so it
is now vertical instead
of horizontally based
<Left>
s5IFSFTVMUPGPVSXPSL
and the final product;
intention.js controls the
appearance of our app
in response to player
events and widths
18 Set volume
volumeBar is a range input (<input type=range>)
and we can read its current value with .value. Once this
is set, we get the volume axis to re-evaluate with
respond(). This will cause the matcher to iterate through
the contexts and update the class name depending on
which context returns true first.
20 Volume markup
The HTML for the range input is mostly standard
but the attributes from data-intent onwards dictate how
this snippet of HTML should behave when within a
certain context (the mobile and tablet contexts). When
were in a mobile context, append the volume to volume
container, which will make it vertical and in tablet and up
put it outside (after) the volume container.
22 Intent on simplicity
In this tutorial weve started to explore just how
adaptable intention.js can be by responding to events in
a music player as well as responding to different widths,
simply by adding HTML attributes to describe how it
should act. If youre looking for a simple solution,
especially on retro responsive builds, then this might be
the tool for you.
When were in a
mobile context,
append volume to
volume container
Adding
elements
after load
For apps that add markup
after loading, you can
manually add elements
with intent.add( element ).
This will add the element
to intentions
watch list.
Make an
eCommerce
web element
with CSS3
Using CSS3, create a simple and
appealing shopping cart web
element that would be useful on
an eCommerce website
04 Star ratings
Source files
available
sIUUQXXX
JMFTJMPDPVL
bks-594
01 Set everything up
001 <body>
002
003
<div class=container>
004
005
<div class=block>
006
007
</div><!-- END block -->
008
009 </div><!-- END container -->
010
011 </body>
001
002
003
004
005
006
007
008
009
<div class=product>
<img src=images/placeholder.png>
<div class=buttons>
<a class=buy href=#>Add to cart</a>
<a class=preview href=#>View item</a>
</div>
</div><!-- END product -->
03 Product information
05 The CSS
001 body {
002 font-family: Arial, sans-serif;
003 color: #aaaeb2;
004 background: #f1f1f1 url(../images/
bg.png);
005 }
006
007 .container {
008
009 width: 900px;
010 margin: 0 auto;
011 }
001 .block {
002
margin: 30px 0;
003
display: block;
004
005
006
007
008
< Above>
s"EEJOHUIFQSPEVDUJNBHFIFSFIBTHJWFOVTTPNFUIJOHUPXPSLBSPVOE
< Above>
s5IF$44GPSUIFA"EEUP$BSUCVUUPOJTDPNQMFUF
OPXXFNPWFPOUPUIFOFYUCVUUPO
< Above>
s4PNFPGUIFCBTJDTUZMJOHBEEFEUPUIFNBJOCVUUPOT A"EEUP$BSUBOEA7JFX*UFN
XJMMCF
WJFXBCMFPODFUIFQSPEVDUJNBHFJTNPVTFEPWFS
< Above>
s*OUIJTTUFQ
XFSFKVTUBEEingBTJNQMFBDUJWFTUBUFPOUIFA7JFX*UFNCVUUPO
position: relative;
width: 300px;
border-radius: 5px;
background: #fff;
box-shadow: 0 3px 8px rgba(0, 0, 0,
.2);
009
07 Product image
001
002
003
004
005
006
007
008
009
010
.product {
display: block;
position: relative;
}
.product img {
width: 100%;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
10 Button styles
001
002
003
004
005
006
007
008
009
010
001 .buttons a {
002
display: block;
003
position: absolute;
004
left: 50px;
005
width: 115px;
006
border-radius: 2px;
007
padding: 18px 10px 15px 65px;
008
font-family: Helvetica, sans-serif;
009
font-size: 14px;
010
font-weight: bold;
011
text-transform: uppercase;
012
color: #fff;
013
text-decoration: none;
014
opacity: 0;
015
text-align: center;
016 }
017
.info {
display: block;
position: relative;
padding: 20px;
}
.details {
border-top: 1px solid #e5e5e5;
padding: 18px 20px;
}
<Above left>
sThings are starting to take shape quite nicely now that some styling has been added to the product description
<Above right>
sThings are really starting to take shape now we have added some styles to our product price
<Top right>
sThe Buy Now button is the last step to finish off the product description section
<Bottom right>
sThe final element is the star rating section. It is here that the list elements are transformed into stars
11 Icon styling
009
.17);
010
011
012
013 }
top: 0;
left: 0;
z-index: 1;
001 a.buy {
002
top: 20%;
003
background: #414141;
004
005
006
007
008
009
010
011
012
013
014
015
016
Button icons
}
.buy:hover {
background: #515151;
background: rgba(45, 45, 45, .85);
}
.buy::after {
background: url(../images/cart.png);
background-repeat: no-repeat;
background-position: 16px 18px;
}
001 a.preview {
002
bottom: 20%;
003
text-shadow: 0 -1px 1px rgba(0, 0, 0,
010
011
012
background-repeat: no-repeat;
box-shadow: 0 2px 0 #165181;
transition: background-position .2s
ease-in;
013 }
014 .preview:hover, .buy_now:hover {
015
background-position: 0 0;
016 }
.4);
004
005
006
background: #286398;
background: -webkit-lineargradient(bottom, #1d4970, #639ed3);
007
background: -moz-lineargradient(bottom, #286398, #639ed3);
008
background-position: 0 -15px;
009
background-size: 400px 80px;
008
009
010 }
background-repeat: no-repeat;
background-position: 16px 17px;
15 Information arrow
001 .info::after
{
002
003
004
005
006
007
008
009
010
011
display: block;
position: absolute;
top: -12px;
left: 23px;
content: ;
height: 25px;
background: #fff;
transform: rotate(45deg);
transform: rotate(45deg);
16 Product title
17 Product description
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
.info h4::after {
display: block;
position: absolute;
bottom: 0px;
content: ;
width: 40px;
height: 2px;
background: #3b86c4;
}
.info .description {
display: block;
padding-bottom: 20px;
font-family: Arial, sans-serif;
font-size: 14px;
font-weight: 600;
color: #5f5f5f;
}
18 The price
The Buy Now button is the last step to finish off the
product description section. Were going to float this right
and use relative positioning in order to position it right
where we want it. Were then going to continue to give it
the same styling as our View Item button finishing up
with a nice transition and drop shadow.
001 .buy_now {
002
float: right;
003
position: relative;
004
top: -5px;
005
display: block;
006
padding: 10px 10px;
007
border-radius: 3px;
008
009
font-family: Helvetica Neue,
Helvetica, Arial, sans-serif;
010
color: #fff;
011
font-weight: bold;
012
text-decoration: none;
013
font-size: 15px;
014
text-shadow: 0 -1px 1px rgba(0, 0, 0, .4)
015
016
017
background: #286398;
background: -webkit-lineargradient(bottom, #1d4970, #639ed3);
018
background: -moz-lineargradient(bottom, #286398, #639ed3);
019
background-position: 0 -15px;
020
background-size: 400px 80px;
021
background-repeat: no-repeat;
022
transition: background-position .2s
ease-in;
023
024
025 }
001 .rating {
002
position: relative;
003
top: 2px;
004
float: right;
005
margin: 0;
006
padding: 0;
007 }
transform: translateY(2px);
The translate(x, y) function is similar to relative
positioning, translating, or relocating an element
by x from the left, and y from the top. Its a handy
way to move elements as it gives you full control
of its positioning from using only one line of code.
transform: translate(2px, 10px);
To give us greater control, we can also use
negative values on either the x or y values. The
line of code below, for example, allows us to move
an element horizontally by 20 pixels.
transform: translateX(-20px)
21 Seeing stars
001 .rating li {
002
float: left;
003
display: block;
004
height: 16px;
005
width: 16px;
006
margin-left: 5px;
007
background: url(../images/stars.png)
no-repeat 0 0;
008 }
009
010 .rating li.rated {
011
background-position: 0px -16px;
012 }
013
22 Final thoughts
Customise
a map with
the Google
Maps API
Take Google Maps beyond the simple
embedded maps with the options in
the Google Maps API
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
01 Get started
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
<!DOCTYPE html>
<html>
<head>
<meta name=viewport content=
initial-scale=1.0, user-scalable=no
/> <style>
html {
height:100%
}
body {
height: 100%;
margin:0;
font-family: Open Sans, sans-serif;
}
#ufo-map {
height:100%;
}
</style>
</head>
<body>
<div id=ufo-map></div>
</body>
</html>
05 Begin scripting
<Left>
The Google API is incredibly
adaptable to anyone who is
comfortable with JavaScript.
Not only are there the
various options that Google
has already supplied, but also
an impressive volume of
extra script enhancements
made available by
enterprising developers who
continue to push the API to
greater heights.
001
<script type=text/javascript
src=https://maps.googleapis.com/maps/api/
js?key=YOUR API KEY GOES HERE&sensor=true>
002
</script>
001
002
003
004
<script type=text/javascript>
function initialize() {
var mapOptions = {
center: new google.maps.
LatLng(52.456009,-1.483154),
005
zoom: 8
006
};
007
var map = new google.maps.
Map(document.getElementById(ufo-map),
008
mapOptions);
009
}
010
google.maps.event.
addDomListener(window, load, initialize);
011
</script>
13 Further animations
11 Multiple locations
Googles API
reference
Code library
There is a variety of
options for styling and
arranging the controls,
from simple relocation to
advanced customisation
001
002
003
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.
DROPDOWN_MENU,
004 mapTypeIds: [google.maps.MapTypeId.
TERRAIN, map_style]
005 },
006 zoomControl: true,
007 zoomControlOptions: {
008 style: google.maps.
ZoomControlStyle.SMALL
009 },
010 panControl: true,
011 panControlOptions: {
012 position: google.maps.
ControlPosition.TOP_RIGHT
013 },
014 };
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
17 Finish up
001
002
003
004
005
006
007
008
009
010
011
012
013
035
036
037
038
039
040
041
042
043
044
045
046
var styles = [
{
},{
featureType: landscape,
elementType: all,
stylers: [{ color:#c2c2c1 }]
},{
featureType: water,
elementType: all,
stylers: [{ color:#284489 }]
},{
featureType: road,
stylers: [{ hue:#9bfa68 },{ visibility:
simplified }]
},{
featureType: all,
elementType: labels,
stylers: [{ visibility: off }]
}];
var styledMap = new google.maps.StyledMapType(styles,
{name: Spooky Map});
var mapOptions = {
center: new google.maps.
LatLng(52.456009,-1.483154),
zoom: 8,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.
DROPDOWN_MENU,
mapTypeIds: [google.maps.MapTypeId.TERRAIN,
map
_style]},
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL},
panControl: true,
panControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT},};
var map = new google.maps.Map(document.getElementById
(ufo- map),
mapOptions);
map.mapTypes.set(map_style, styledMap);
map.setMapTypeId(map_style);
setMarkers(map, ufos);}
var ufos = [
[Rendlesham Forest, 1980, 52.091786,1.404618, 1],
[Bonsall, 2000, 53.128234,-1.675415, 2],
[Dudley, 2007-2013, 52.532096,-2.099075, 3],
[Ilkley Moor, 1987, 53.903081,-1.826917, 4],
[RAF Cosford, 1993, 52.640564,-2.295456, 5],
[Broad Haven, 1977, 51.844263,-5.111389, 6]];
function setMarkers(map, locations) {
Automatically
test your
JavaScript
with Jasmine
Discover how easy it is to ensure code
quality by testing your program via the
Jasmine unit testing framework
05 Code is code
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
02 Test runner?
Jasmine tests usually are run via a file called
TestRunner.html. Open it in an HTML editor of choice in
03 Test suites
Unit tests should be grouped up for easier
management. This is done by creating suites via the
describe function. Its structure follows that of natural
language wherever possible; the first parameter explains
what must be tested, whereas the second one contains
a function that carries out the evaluation.
04 The it command
Actual test work is performed in it() functions.
Each it function should be set up to test one specific
06 Matchers compare...
Unit tests work by comparing the results of the
actual computation with the one intended to be
returned. Your expectations are passed into the
program via an expect() clause, which takes the actual
value produced by the routine under test. It can then be
compared to something else using a matcher.
001
it(Tests some numbers,
function()
002
{
003
expect(1234).toBe(return1234());
004
});
005
08 Is it something?
The simplest form of comparison works by
simply comparing the returned result with the intended
value. This can be achieved by using the toBe function,
which we first introduced a few steps ago. It fails
whenever the two values are not considered equal by a
=== comparison.
09 Analyse strings
Regular expressions tend to be very helpful
when dealing with textual data. Straight comparisons
can be done by invoking the toBe function. If the use of
a regular expression is desired, toMatch is better suited
to the task at hand. The syntax of the RegEx follows
JavaScript conventions.
001
<Above>
sClick the Raw button located on the right-hand side of the screen in order to start the
process of downloading
<Above>
sAn alert dialogue placed inside the test code will pop up as the Jasmine framework begins to
process the unit test
<Above>
sEven though the first comparison did not work out, the alert() dialog is still continues to
be displayed on screen
<Above>
sThe official documentation for Jasmine explicitly confirms that the toBe operator compares using
the === construct
002 {
003
var message = Hello to my
readers;
004
expect(message).toMatch(/my/);
005
});
10 Is it true?
When dealing with true and false values, a
simple comparison against true and false often is
not sufficient enough. toBeTruthy and toBeFalsy can be
used to remedy this problem. They work by performing
an internal compare against a value casted to bool,
thereby matching the normal JavaScript behaviour.
11 Undefined stuff
Generator methods might fail in a way that
causes the unit test code to halt with a null reference
error. This can be avoided by first checking whether an
object is defined or undefined. Use toBeDefined to
check for definedness, toBeUndefined checks whether
the element does not exist.
001
it(Tests whether an array
contains an element,
function()
002 {
003
var a = [a, b, c];
004
expect(a).toContain(c);
005
});
006
13 Numbers
Figuring out whether a number is larger or
smaller than another arbitrary value is usually achieved
via an if clause. This tends to enlarge the length of the
unit test. The toBeLessThan and toBeGreaterThan
clauses provided in Jasmine allow you to shorten all
numeric tests.
001
it(Tests Jasmines numeric
functions, function()
002 {
003
expect(2).toBeLessThan(3);
004
expect(2).toBeGreaterThan(1);
005
});
14 Negate matchers
Most matchers can be forced to work in inverted
mode. This means that a matcher will consider its test
successful only if the condition it is intended to analyse
is not met. For example, putting the .not. object in front
of toBeTruthy transforms the comparison into a lookalike
of toBeFalsy.
001
it(Tests whether an array
contains an element, function()
002 {
003
var a = [a, b, c];
004
expect(a).not.toContain(d);
005
});
006
15 Set up code
Some of the time, it is necessary for the engine
code to be reset to a predefined state before the tests
<Above>
s5IFFYFDVUJPOPGBVOJUUFTUUBLFTQMBDFBDDPSEJOHUPUIFTUSVDUVSFPVUMJOFEJOUIFMPXDIBSU
<Above>
sUP#F5SVUIZDPOTJEFSTUIFTUSJOHAUSVFFRVJWBMFOUUPUIFCPPMFBOUSVFWBMVF
<Above>
s*OUIFXPSTUDBTF
BOVOEFJOFEPCKFDUDBOIBMUUIFFYFDVUJPOPGUIFVOJUUFTUT6TFUP#F%FJOFE
UPDSFBUFSFTJMJFOUUFTUT
<Above>
s6TJOHYJUBOEYEFTDSJCFMFBETUPEJTBCMFETQFDTBOEUFTUDBTFT
XIJDIXJMMOPUCFIBOEMFECZUIF
UFTUSVOOFS
17 Global stuff
The body of the describe function is processed
linearly by the JavaScript interpreter. This means that
you can use it to perform any action that needs to be
handled before the actual unit tests can be run. Our
example declares a variable called valueStore before
running the first it() clause.
001
002
003
004
005
18 More It functions
The code snippets for the steps shown tend to
show more than one it() function per block. This is not a
problem. Jasmine permits you to have an almost
unlimited number of test cases nested into one describe
suite. Simply nest them below one another as shown.
001
it(Tests Jasmines numeric
functions, function()
002
{
003
expect(2).toBeLessThan(3);
004
});
005
it(Uses the not
qualifier,function()
006
{
007
008
});
19 It is not
As code matures, some unit tests become
unneeded. Removing them is not particularly smart, as
they might be needed again at some point in the future.
This problem can be addressed by using the nonworking xdescribe and xit functions. Their syntax is an
exact match of describe and it.
001
it(Uses a spy,function()
002
{
003
spyOn(someObject,
functionName);
004
//Use someObject
005
});
21 Chained spying
Adding the andCallThrough command to the
declaration of the spy enables you to chain the
invocations and reduce the amount of impact on the
system. This means that Jasmine will analyse the callings
of the method, but will then proceed with forwarding
them to the actual implementation provided by the
system under test.
001 {
002
it(Uses a spy,function()
003
{
004
spyOn(someObject,
functionName).
andCallThrough();
005
//Use someObject
006
});
<Above>
s4QJFTDBONPEJGZUIFSFUVSOWBMVFPGUIFGVODUJPOBOBMZTFE*O
PVSDBTF
BOFNQUZGVODUJPOJTPWFSXSJUUFO
22 Was it invoked?
The most basic use case for a spy involves
finding out whether the method in question was
invoked during the execution of the test case. In our
case, the test will be successful only if the code masked
by the comment invokes the functionName method at
least once.
001 {
002
it(Uses a spy,function()
003
{
004
spyOn(someObject,
functionName).
andCallThrough();
005
//Use someObject
006
expect(someObject.
functionName). toHaveBeenCalled();
007
});
008
23 Parameters
Advanced testing requires the use of an artificial
spy. These can be generated by invoking the createSpy
function with a string identifying the name of the
function which you want to be shadowed. The
toHaveBeenCalledWith function permits you to
determine whether the parameter set in question was
actually passed in.
001
it(Uses an artificial
spy,function()
002
{
003
var whatAmI = jasmine.
createSpy(whatAmI);
004
whatAmI(Welcome);
005
whatAmI(I am unreal);
006
expect(whatAmI).
toHaveBeenCalledWith(Welcome);
007
});
26 Control time
When attempting to debug time-based code,
compressing the wait cycles can help to reduce the total
execution time of the test battery. Invoking jasmine.
clock().install halts the flow of time in your program.
From then onwards, calling jasmine.clock().tick will allow
you to advance the time in a helpful step-by-step fashion.
27 Custom matcher
Even though Jasmine provides you with a large
selection of matchers, you might sometimes want to
add a new one to the roster. This can be achieved by
creating a so-called custom matcher. These are passed
in to the framework and can then be used like any other
matcher. See the code library (left).
28 Welcome to Node.js
Running your program from the browser can
become a nuisance. Fortunately, a Node.js-ready version
of the Jasmine framework is available via GitHub at
HJUIVCDPNNIFWFSZKBTNJOFOPEF. Once installed,
your tests can be run via the command line of your
system. Jasmine-Node even supports the Growl system
for sending out notifications through a variety of media.
001 return{
002 compare: function(actual,
expected)
003 {
004
var result=new Object();
005
if(actual.
isRocketName===Bisnovat)
006
{
007
result.pass=true;
008
}
009
else
010
{
Jasmine expects your code to return an object
containing a boolean pass value and a string
describing why a test failed.
001
result.pass=false;
002
result.message=Rocket is
not Bisnovat;
003
}
004
return result;
005 }
006 };
007 }
008 };
009
it(Uses a matcher,function()
010
{
Finally, call addMatchers on the generator array in
order to implement the matcher into the framework
001 jasmine.
addMatchers(customMatchers);
002 var aRocket=new Object();
003
aRocket.
isRocketName=Bisnovat;
004
expect(aRocket).
toBeBisnovat();
005
});
006 });
Automate
development
processes
with Grunt.js
Alleviate the stress of repetitive tasks
and make the most of development
time with the Grunt.js task runner
05 Install Grunt
Source files
available
sIUUQXXX
filesilo.co.uk/
bks-594
01 Prerequisites
06 Dependency added
001
002
003
004
005
006
007
{
name: my_grunt_project,
version: 0.0.1,
devDependencies: {
}
}
04 Create a Gruntfile
001 devDependencies: {
002 grunt: ~0.4.1
003 }
07 Uglify plug-in
001 grunt.config.init({
002
003 });
09 Uglify configuration
<Above>
s(SVOUSVOTPO/PEFKT*GZPVIBWFOUHPUUIJTJOTUBMMFE
IFBEPWFSUPOPEFKTPSHEPXOMPBEUPEPXOMPBE
BOEJOTUBMMJU
<Above>
s5IFQBDLBHFKTPOJMFXJMMVQEBUFXJUIJOTUBMMFEQMVHJOTGPSMPDBMVTF
UIBOLTUPUIF
TBWFEFWMBH
<Above>
s*OTUBMMJOHUIFHSVOUDMJQMVHJOJTJODSFEJCMZTJNQMFUIBOLTUPUIFOPEFQBDLBHFNBOBHFS
<Above>
s3VOOJOHUIFVHMJGZUBTLGSPNUIFDPNNBOEMJOF
ZPVXJMMSFDFJWFTPNFJOGPSNBUJPO
BCPVUUIFTVDDFTTGVMCVJME
001
002
003
004
005
006
007
uglify: {
build: {
src: src/js/script.js,
dest: dest/js/script.min.js
}
}
10 Automatic banners
001 grunt.loadNpmTasks(grunt-contrib-uglify);
001 options: {
002 banner: /*! <%= grunt.template.
today(yyyy-mm-dd) %> */\n
003 },
004 build: {
005 src: src/js/script.js,
006 dest: dest/js/script.min.js
007 }
008
001 > grunt uglify
Reference files
and directories
When creating your tasks
to watch or update a
selection of files, you can
specify individual files, or
choose all files within a
directory using a wildcard
(*). Grunt is highly
configurable.
<Above>
sThe minified JavaScript file
has been written, complete
with inserted banner text
002 options: {
003
banner: /*! CSS Build - <%= grunt.
template.today(yyyy-mmdd)
%> */\n
},
build: {
src: src/css/*.css,
dest: dest/css/combined.min.css
}
}
<Above>
sRunning a watch task to keep an eye on any file updates and changes is really useful
<Above>
sFollowing a file change, when saved, the specified tasks will run and Grunt will
continue to watch for you
004
005
006
007
008
009
010
011
<Below>
sRunning the default Grunt task,
two tasks have been processed
in order to save us some
valuable time and typing
16 Combine tasks
001 grunt.registerTask(default,
[uglify,cssmin]);
002
003 > grunt
14 CSS minification
dev
002
001 cssmin: {
17 Watch files
<Left>
s5IF(SVOU
EPDVNFOUBUJPOJT
EFUBJMFEBOE
JOGPSNBUJWF
BOEJUTB
HSFBUQMBDFUPEJH
EFFQFSJOUPUIF
QPXFSGVMUPPM7JTJU
gruntjs.com/
getting-started GPS
NPSFJOGPSNBUJPO
001
002
003
004
005
006
007
008
009
010
watch: {
scripts: {
files: [src/js/*.js],
tasks: [uglify],
options: {
spawn: false,
},
},
}
// Load the task too (after the config
method)
011 grunt.loadNpmTasks(grunt-contrib-watch);
20 Manage variables
Trusted
plug-ins
5IF(SVOUQMVHJO
SFQPTJUPSZJTGVMMPGGBOUBTUJD
QMVHJOTGSPNUIF
DPNNVOJUZ8IJMFZPVDBO
CFTVSFUIBUBMMPGUIFN
XPSL
BQMVHJOQSFJYFE
XJUIAHSVOUDPOUSJCJT
UZQJDBMMZQSPWJEFECZUIF
DPSF(SVOUUFBN
012
19 Start watching
001 grunt.config.init({
002 pkg: grunt.file.readJSON(package.json),
003 // The rest of the gruntfile...
001
002
003
004
build: {
src: <%= pkg.srcDir %>js/script.js,
dest: <%= pkg.destDir %>js/script.min.js
}
tri Spe
al ci
of al
fe
r
Enjoyed
this book?
Try
3 issues
for just
* This offer entitles new UK direct debit subscribers to receive their first three issues for 5. After these issues, subscribers will then pay 25.15 every
six issues. Subscribers can cancel this subscription at any time. New subscriptions will start from the next available issue. Offer code ZGGZIN must be
quoted to receive this special subscriptions price. Direct debit guarantee available on request.
** This is a US subscription offer. The USA issue rate is based on an annual subscription price of 65 for 13 issues which is equivalent to $102 at the time
of writing compared with the newsstand price of $14.99 for 13 issues being $194.87. Your subscription will start from the next available issue.
About
the
mag
In-depth features
Discover the latest hot topics in the industry
subscribers to
www.imaginesubs.co.uk/wed
Quote code ZGGZIN
Or telephone UK 0844 848 8413 overseas 01795 592 878
EVERYTHING
YOU NEED
TO BUILD ON
THE AWESOME
SKILLS IN THIS
BOOKAZINE
Stock images
YOUR BONUS
RESOURCES
ON FILESILO WITH THIS
BOOKAZINE, FREE AND
EXCLUSIVE FOR WEB DESIGN
TIPS, TRICKS & FIXES READERS,
YOULL FIND A WEALTH OF
RESOURCES, INCLUDING
Free fonts
filesilo.co.uk/bks-594
176 Web Design Tips, Tricks, & Fixes
HOW TO USE
EVERYTHING YOU NEED TO KNOW ABOUT
ACCESSING YOUR NEW DIGITAL REPOSITORY
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 Web Design Tips, Tricks, & Fixes
Add excitement
and interactivity to
your web pages
with dynamic
animation effects,
infographics and
3D elements
unlock the
potential of
web design
Enhance all
aspects of your
web design with a
range of solutions
for improving
code quality and
automating
key processes
FREE
ASSETS