After years of speculation and anticipation, Panic is ready to unveil and release version two of their flagship product: Coda.

Though the Nettuts+ team hasn’t yet dug into the editor, based upon the outline on the home page, Panic seems to have come through with the most requested additions by the community, including:
Be sure to bookmark this page; on May 24th, we’ll finally get our hands on the editor, and provide you with the full review!
Expect the editor to sell for $99 on the Mac App Store…or $49, if you purchase it on launch day.
If you haven’t heard, there’s a new kid in town: CanJS. What better way to dive into what this new framework offers than to build a contacts manager application? When you’re done with this three-part series, you’ll have all the tools you need to build your own JavaScript applications!
Building a JavaScript application without the right tools is difficult. While jQuery is great at what it does, a DOM manipulation library doesn’t provide any infrastructure for building applications. This is specifically why you need to use a library, like CanJS.
CanJS is a lightweight MVC library that gives you the tools you need to build JavaScript apps.
CanJS is a lightweight MVC library that gives you the tools you need to build JavaScript apps. It provides all the structure of the MVC (Model-View-Control) pattern, templates with live binding, routing support and is memory safe. It supports jQuery, Zepto, Mootools, YUI, Dojo and has a rich set of extensions and plugins.
In part one, you will:
Excited? You should be! Now let’s get coding.
You’ll need to create a folder for your application. Inside this
folder, you need four sub-folders: css,
js, views and img. Your
folder structure should look like this when you’re done:
Save this as index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CanJS Contacts Manager</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/contacts.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="span12">
<h1>Contacts Manager</h1>
</div>
</div>
<div class="row">
<div class="span3">
<div class="well">
<nav id="filter"></nav>
</div>
</div>
<div class="span9">
<div id="create"></div>
<div id="contacts"></div>
</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script src="js/can.jquery.min.js"></script>
<script src="js/can.fixture.js"></script>
<script src="js/contacts.js"></script>
</body>
</html>
At the bottom of the page, we load jQuery, CanJS, the fixture
plugin and your application code (contacts.js).
The CSS and images for this tutorial are in included in the source files, which can be downloaded above.
Views are client-side templates that are used to render parts of your app. CanJS supports multiple templating languages, but this tutorial will be using EJS (Embedded JavaScript), which is packaged with CanJS and supports live binding.
EJS templates look like HTML but with magic tags where you want dynamic behavior (using JavaScript). There are three types of magic tags in EJS:
<% CODE %> runs JavaScript code,<%= CODE %> runs a JavaScript statement, and
writes the escaped result into the resulting
HTML,<%== CODE %> runs a JavaScript statement and
writes the unescaped result into the resulting
HTML (used for sub-templates).Templates can be loaded from a file or script tag. In this tutorial templates will be loaded from EJS files.
To render contacts, you’ll need an EJS template. Save the
following code as contactsList.ejs within your views
folder:
<ul class="clearfix">
<% list(contacts, function(contact){ %>
<li class="contact span8" <%= (el)-> el.data('contact', contact) %>>
<%== can.view.render('views/contactView.ejs', {
contact: contact, categories: categories
}) %>
</li>
<% }) %>
</ul>
contactLists.ejs will render a list of contacts.
Let’s examine the template code here in more detail:
<% list(contacts, function(contact){ %>
The EJS list() helper invokes a callback function
on each contact in the list. When used with an observable list, the
list() helper will use live binding to re-run anytime
the length of the list changes.
<li class="contact span8" <%= (el)-> el.data('contact', contact) %>>
The code above uses an element callback to add the contact
instance to the data of the <li>. Everything
after the arrow is wrapped in a function that will be executed with
el set to the current element.
<%== can.view.render('views/contactView.ejs', {
contact: contact, categories: categories
}) %>
This code renders the contactView.ejs sub-template
for each contact. can.view.render() takes a template
and data as its parameters and returns HTML.
Sub-templates are an excellent way of organizing your views into
manageable chunks. They also help simplify your templates and
promote DRY (Don’t Repeat Yourself). Later in this tutorial, you’ll
re-use this template to create contacts. Save this code as
contactView.ejs in your views folder:
<a href="javascript://" class="remove"><i class="icon-remove"></i></a>
<form>
<div class="row">
<div class="span2">
<img src="img/contact.png" width="100" height="100">
</div>
<div class="span3">
<input type="text" name="name" placeholder="Add Name"
<%= contact.attr('name') ? "value='" + contact.name + "'" : "class='empty'" %>>
<select name="category">
<% $.each(categories, function(i, category){ %>
<option value="<%= category.data %>" <%= contact.category === category.data ? "selected" : "" %>>
<%= category.name %>
</option>
<% }) %>
</select>
</div>
<div class="span3">
<label>Address</label>
<input type="text" name="address"
<%= contact.attr('address') ? "value='" + contact.address + "'" : "class='empty'" %>>
<label>Phone</label>
<input type="text" name="phone"
<%= contact.attr('phone') ? "value='" + contact.phone + "'" : "class='empty'" %>>
<label>Email</label>
<input type="text" name="email"
<%= contact.attr('email') ? "value='" + contact.email + "'" : "class='empty'" %>>
</div>
</div>
</form>
Each property of a contact is placed in an
<input> tag. These will be used to add and
update a contact’s information.
Any time EJS encounters attr() while processing a
template, it knows that the surrounding code should be turned into
an event handler bound to that property’s changes. When the
property is changed elsewhere in the app, the event handler is
triggered and your UI will be updated. This is referred to as live
binding. EJS Live binding is opt-in. It only turns on if you use
attr() to access properties.
Let’s look at one of the <input> tags from
the contactView.ejs to see how this works:
<input type="text" name="name" placeholder="Add Name"
<%= contact.attr('name') ? "value='" + contact.name + "'" : "class='empty'" %>>
The code in the magic tags will become an event handler bound to the contact’s name property. When we update the name property, the event handler is run and the HTML will be updated.
can.Controlcan.Control creates an organized, memory-leak free,
stateful control that can be used to create widgets or organize
application logic. You create an instance of a Control on a DOM
element and pass it data your control will need. You can define any
number of functions in your Control and bind to events.
When the element your Control is bound to is removed from the DOM, the Control destroys itself, cleaning up any bound event handlers.
To create a new Control, extend can.Control() by
passing it an object containing functions you want to define. In
part two, event handlers will be passed in as well.
There are a few important variables and functions present in every Control instance:
this – A reference to the Control instancethis.element – The DOM element that you created
the instance onthis.options – An object containing any data
passed to the instance when it was createdinit() – Called when an instance is createdAdd the following snippet to your contacts.js file
to create the Control that will manage contacts:
Contacts = can.Control({
init: function(){
this.element.html(can.view('views/contactsList.ejs', {
contacts: this.options.contacts,
categories: this.options.categories
}));
}
})
When an instance of Contacts is created,
init() will do two things:
can.view() to render contacts.
can.view() accepts two parameters: the file or id of
the script tag containing our template code and data. It returns
the rendered result as a documentFragment (a lightweight container
that can hold DOM elements).can.view() into
the Control’s element using jQuery’s .html().A Model abstracts the data layer of an application. Two models
are needed in this application: one for contacts and one for
categories. Add this code to contacts.js:
Contact = can.Model({
findAll: 'GET /contacts',
create : "POST /contacts",
update : "PUT /contacts/{id}",
destroy : "DELETE /contacts/{id}"
},{});
Category = can.Model({
findAll: 'GET /categories'
},{});
A model has five static methods that you can define to create,
retrieve, update and delete data. They are findAll,
findOne, create, update and
destroy. You can overwrite these functions to work
with any back-end, but the easiest way to define a Model is using
REST service, as exemplified in the code above. You can safely omit
any static methods that won’t be used in an application.
It’s important to point out here that the model instances in
CanJS are actually what we call ‘observables’.
can.Observe provides the observable pattern for
objects and can.Observe.List provides the observable
pattern for arrays. This means you can get and set properties using
attr() and bind to changes in those properties.
The findAll() method returns a
Model.list, which is a can.Observe.List
that triggers events when an element is added or removed from the
list.
Fixtures intercept AJAX requests and simulate their response with a file or function. This is fantastic for testing, prototyping or when a back-end isn’t ready yet. Fixtures are needed to simulate the REST service the models in this application are using.
But first, you’ll need some sample data for the fixtures to use.
Add the following code to contacts.js:
var CONTACTS = [
{
id: 1,
name: 'William',
address: '1 CanJS Way',
email: 'william@husker.com',
phone: '0123456789',
category: 'co-workers'
},
{
id: 2,
name: 'Laura',
address: '1 CanJS Way',
email: 'laura@starbuck.com',
phone: '0123456789',
category: 'friends'
},
{
id: 3,
name: 'Lee',
address: '1 CanJS Way',
email: 'lee@apollo.com',
phone: '0123456789',
category: 'family'
}
];
var CATEGORIES = [
{
id: 1,
name: 'Family',
data: 'family'
},
{
id: 2,
name: 'Friends',
data: 'friends'
},
{
id: 3,
name: 'Co-workers',
data: 'co-workers'
}
];
Now that you have some data, you need to wire it up to fixtures
so you can simulate a REST service. can.fixture()
takes two parameters. The first is the URL we want to intercept and
the second is a file or function that is used to generate a
response. Often URLs you want to intercept are dynamic and follow a
pattern. In this case, you should use templated URLs. Simply add
curly braces to the URL where you want to match wildcards.
Add the following to contacts.js:
can.fixture('GET /contacts', function(){
return [CONTACTS];
});
var id= 4;
can.fixture("POST /contacts", function(){
return {id: (id++)}
});
can.fixture("PUT /contacts/{id}", function(){
return {};
});
can.fixture("DELETE /contacts/{id}", function(){
return {};
});
can.fixture('GET /categories', function(){
return [CATEGORIES];
});
The first four fixtures simulate the GET,
POST, PUT and DELETE
responses for the Contact model, and the fifth fixture
simulates the GET response for the
Category model.
Your application has Models for your data, Views to render contacts, and a Control to hook everything up. Now you need to kickstart the application!
Add this to your contacts.js file:
$(document).ready(function(){
$.when(Category.findAll(), Contact.findAll()).then(
function(categoryResponse, contactResponse){
var categories = categoryResponse[0],
contacts = contactResponse[0];
new Contacts('#contacts', {
contacts: contacts,
categories: categories
});
});
});
Let’s take a closer look at what is happening in this code:
$(document).ready(function(){
Wait for the DOM to be ready using jQuery’s document ready function.
$.when(Category.findAll(), Contact.findAll()).then(
function(categoryResponse, contactResponse){
Call findAll() on both models to retrieve all of
the contacts and categories. Since findAll() returns a
Deferred, $.when() is used to make both requests in
parallel and execute a callback when they are finished.
var categories = categoryResponse[0], contacts = contactResponse[0];
Get the list of model instances from the response of the two
findAll() calls. The responses are arrays, with the
first index being the list of model instances retrieved.
new Contacts('#contacts', {
contacts: contacts,
categories: categories
});
Create an instance of the Contact Control on the
#contacts element. The list of contacts and categories
are passed into the Control.
When you run your application in a browser, you should see a list of contacts:

That does it for part one of this series! You’ve been introduced to the core of CanJS:
In the next lesson (to be published May 28th), you’ll create a
Control and View to display categories
and use routing to filter contacts. Hope to see you there!
Questions? Ask away below!
"QUANTUM SHOT" #325(rev)
Link - article by Avi Abrams
One Ordinary Drop of Water: Liquid Art & Droplet
Photography
It certainly takes great skill and very good equipment to create
these frozen-in-time "water sculptures", in every captured frame
revealing the inherent energy and the beautiful dynamics of
flowing, cascading and dripping water:
("Dew-Soaked Dandelions" by Sharon Johnstone, see
more here)
Some artists decide to substitute water with more viscous liquids,
which leads to even more psychedelic, "lava lamp"-like effects. But
more often than not, simply playing with ambient color and light
distribution is enough to produce an outstanding effect. In this
article we will try to cover the full variety of high-speed liquid
photography and the excitement of resulting abstract-modernist
compositions.
Luiz Luxvich makes startlingly clear images of splashing
water
This master of liquid photography lives in Rio de Janeiro, Brazil,
and has the most fantastic gallery online, bursting
with variety of colorful creations:
(images credit: Luiz
Luxvich)
Amazingly, even without any added coloring, pure water looks simply
great... like in these examples from the French photographer:
(images credit:
JPV)
Liquid Sculptures by Martin Waugh
Martin Waugh, of Liquid
Sculpture, is perhaps the most famous artist in liquid
photography sub-genre. His works are justly praised as "full of
fun, whimsy and wonder" (see full gallery here):
Water Kiss!
(images credit: Martin Waugh)
More Surreal Colored Drops
These droplets seem to have acquired a life of their own. The fluid
forms and smoothly flowing into each other colors remind me of the
similarly fluid illustrations by the famous 1950s science fiction
artist Richard
M. Powers.
Photographs by Fotoopa,
liquid art master from Belgium, are one million times better than a
lava lamp, and significantly more mesmerizing:
(images credit: Fotoopa)
Got Milk? Spill it, Drip it, Swirl it! (artistically speaking,
of course)
A Milk Drop:
(image credit: Michele M.
Ferrario)
Drops of food coloring come together to become an
artistically-pleasing set,
by Peter Ovesny:
(images credit:
Peter Ovesny)
A Tentacle! -
(originals unknown)
This is not mercury, not even melting ice - just water... splendid
water! Woke up one morning, saw this thing crawling toward
me across the sink... decided to go back to bed and sleep it off
-
(image credit: Carolina
LaBranche)
Coffee Meets Milk
Look at the gorgeous "liquid art" photography by Irene Muller,
transforming coffee and milk into a mysterious whole, bringing them
to entirely new heights of artistic expression. With her
permission, here are some samples of this highly delicate art:
Welcome your own personal caffeine octopus:
You want eggs with that? -
Blueberry Milkshake:
Suspended...
(images credit: Irene Muller)
For more great high-speed photography of colored water drops we
recommend to visit this Flickr
group.
(images via)
The following is a 3D rendering, but still very impressive:
(image credit: Ratow)
Cold Shower Splendor
Next time you catch someone creeping from behind and overturning a
bucket of cold water over somebody's head, don't get too upset;
perhaps they are just (very selfishly) trying to take a memorable
picture... Like this one, for example:
(image credit: Helene
Desplechin)
This looks like a flowing water cape!
(image
via)
These interesting water shapes happened as a result of blowing up
water-filled balloons. What lengths some photographers would go to,
just to make a cool picture! -
(image credit: Ronnie
Phipps)
(images credit: John Bush at
M.I.T.)
In Your Face!
Liquid photography is often used in promotional images and
advertisements:
(image
via)
Potpourri of Droplets
The Universe seem to be reflected in a single drop, or in a
necklace of droplets:
(image credit: Irene Mueller)
(originals unknown)
(image via)
(image via)
Beautiful drops of water, just sitting there and waiting to be
photographed:
(originals unknown)
(image credit: Winston
Rockwell)
(image credit: Ark)
In this series
we find perhaps the most artistic presentation of droplets and
bubbles ever made:
(image credit: Linda)
Most of the effects seen here are caused by the surface tension of
common water, as formation and flowing forms of giant soap bubbles
clearly demonstrate:
(image via)
CONTINUE TO NEXT PART! ->
ALSO READ OUR "AWESOME PHOTOGRAPHY" CATEGORY
->
|
"QUANTUM SHOT" #772
Link - article by Simon Rose and Avi
Abrams
The World’s Other Leaning Towers (apart from the one in
Pisa)
Many people are familiar with the Leaning Tower of Pisa, one of the
most famous buildings in the world. Construction began on the Tower
in 1173 and took place in three stages over 177 years but the
structure had already begun to sink into the unstable soil by 1178.
Before restoration work took place between 1990 and 2001, the tower
leaned at an angle of 5.5 degrees, but this has now been reduced to
just under 4 degrees:
(image via)
However, there are many other leaning towers around the world, and
we take a look at some of them here on Dark Roasted Blend.
Apart from the one in Pisa, Italy is home to a number of other
leaning towers, many located in Venice. The tower at the
Basilica San Petro di Castello, located on one of the many
islands in the Venetian lagoon, dates from the late fifteenth
century (left). Also in Venice, here’s the somewhat
precarious-looking bell tower at the San Martino Church on
the island of Burano (right):
(images via
1, Luigi Re)
This campanile itself dates from 1544 and is part of Venice’s 14th
century Chiesa di Santo Stefano (below left). The one on the
right belongs to the church of San Giorgio dei Greci, built
in 1573, an Orthodox church and centre of Venice’s Greek community
(right):
(images credit: Olafur
Olafsson, Howard Somerville)
In medieval Bologna, the city’s leading families built many towers,
of which only a few survive today. The two most famous ones are
the Asinelli Tower and the Garisenda Tower, which both lean.
Over thirty feet was removed from the top of the Garisenda Tower in
the fourteenth century to prevent collapse, but it still leans
three degrees:
(images
via)
The Torre delle Milizie in Rome was completed around 1280.
It used to have three stories, but an earthquake in 1348 caused the
upper level to collapse. The main tower still stands, but leans
precariously and is expected to continue to tilt even further in
the future:
(images credit: Aldo Ferretto,
Peter Bardwell, 3)
There are many legends attached to the Church of St. Mary and
All Saints in Chesterfield, Derbyshire, England, regarding why
its spire is so twisted. It is said that when a virgin was married
in the church, the spire twisted around to see if it was true.
Another story states that a local blacksmith put the wrong shoes on
the devil, who in his pain, leapt over the church spire, knocking
it out of shape. The real reason is probably due to the shortage of
skilled workers in the aftermath of the Black Death, which resulted
in untreated wood being used to construct the spire. When fifty
tons of lead shingles were attached, the weight caused the wood to
buckle slowly in the following decades. The spire currently twists
45 degrees and leans 9 feet 6 inches from its true centre:
(images credit: Jill
Coleman, Cherington)
The 92 ft tall Greyfriars Tower in King’s Lynn, Norfolk,
England, is the only part of the Franciscan abbey still standing
after it was demolished in 1538 during the Dissolution of the
Monasteries. The tower was apparently left intact as it served as a
landmark for sailors (left image below). In Wales, Caerphilly
Castle is still one of the most formidable looking fortresses
from the medieval era. Construction on the castle was begun in 1268
and one of the towers was damaged in the English Civil War in the
1640’s (right):
(images credit 1,
John Richards)
Over in Ireland, Kilmacduagh Monastery’s Round Tower in
County Galway was built in the 10th century and leans outward
around 1.5 feet but is apparently in no danger of toppling (left).
The highest point of Germany’s Suurhusen Church’s is reputed
to be the most tilted tower in the world. The building is
only 90 feet high, but leans at 5.1939 degrees. The church tower
dates from 1450, but only began to lean in the 19th century, when
the nearby marshes were drained:
(images credit: Peter Lynch,
Sonth)
Also in Germany, the church of Our Dear Lady at the Mountain
in Bad Frankenhausen was built in 1382. The spire currently leans
at 4.8 degrees and is increasing by around 2.4 inches every year
(left image below). The twelfth-century tower on the right, in St.
Moritz, Switzerland, has a lean of 5.5 degrees. The tower was once
part of the church of St. Mauritius, which was demolished in
1890:
(images credit: Pascal POGGI,
ms.mac)
The leaning church tower of Walfridus in Bedum in the
northern Netherlands now has a greater lean than the Tower of Pisa
(left). Construction on this tower in Leeuwarden in Fryslan,
Netherlands, began in 1529 and it was originally going to be
higher. However, it began to lean as it grew taller and work was
stopped (right):
(images via 1, 2)
The Oude Kerk or Old Church in Delft, also in the
Nertherlands, is just over 245 feet high and leans about 6.5 feet
away from vertical (left). On the right you see painting by Pieter
de Hooch "Washerwoman and a child at a bleach-field near the Old
Church in Delft - 1657-59":
(images via 1,
2)
The Gateway to Europe towers in the Spanish capital are also
referred to as the Leaning Towers of Madrid. They were built in
1996, deliberately made to lean 15 degrees (right):
(image credit: Javade)
This odd tower of leaning cubes is located on Barceloneta
beach, in Barcelona, Spain (left). In Poland, the Tower of
Torun had a similar experience to its counterpart in Pisa,
leaning not long after it was first built as a result of the
unstable ground beneath it (right):
(image credit: Rebecca
Horn, 2)
Nevyansk Tower in the Russian city of Sverdlovsk was built
in the early eighteenth century. The tower is 189 ft tall tower and
leans around 7 ft away from vertical:
(image credit: Konstantin
Grishin)
The 157 ft high, 8-sided Huqiu Tower, also known as the
Yunyan Pagoda, was built in the tenth century in Suzhou, China. The
building was stable until the seventeenth century, when it began to
lean due it being built partly on soil and partly on rock. The top
of the tower leans out by just over 7.5 feet (left image
below):
(image credit: 1, 2)
The leaning tower in Huludao in northeast China (top right
image above) dates from the time of the Liao Dynasty in the tenth
and eleventh centuries. On the bottom right above, is the
Leaning Tower of Shiraz at the Karimkhan Citadel in Shiraz,
Iran.
In Myanmar, the Leaning Tower of Inwa is also known as the
Watch Tower or Nan Myint. An earthquake in 1838 almost totally
destroyed the structure, but the tower remains, looking ready to
collapse at any time:
(images credit: Roger
Price, Geoff deBurca)
In Teluk Intan in Malaysia, this leaning water tower was
built in 1885 and began to lean four years later:
(image credit: Nick
Hisham)
And finally, here’s the Leaning Tower of Wanaka in New Zealand,
balancing at an angle of 53 degrees:
(image credit: Adrian
Hey)
Here is a hand-drawn interesting take on "leaning towers"
theme:
(image credit:
Elton Huan)
CONTINUE TO "MOST ELEGANT PROPOSED SKYSCRAPERS"!
->
ALSO CHECK OUT OUR "AWESOME ARCHITECTURE" SERIES
->
Avi Abrams is the creator, writer, and owner
of Dark Roasted Blend;
Simon
Rose is the author of science fiction and fantasy novels
for children, including
The Alchemist's Portrait,
The Sorcerer's Letterbox,
The Clone Conspiracy,
The Emerald Curse,
The Heretic's Tomb and
The Doomsday Mask and The Time
Camera.
|
Tired of the “techie” trying to explain to you what web hosting is all about from his bedroom-recorded Skype video? Ever get confused with all the funny terms they drop, like “Shared Hosting” and “Dedicated Servers”? We’ve all been there at one point or another! Well, the guys over at InMotion Hosting created a quick, visual guide that will get you up and running with the jargon in no time!
If you’re still new to this world, and have questions about the hosting world, leave a comment below, and one of us will do our best to help!
"PIC OF THE DAY"
Link
Still hanging there in the 1950s, rusted and
abandoned...
We wrote about the Bennie Monorail System in Glasgow, Scotland
before, see our One Track Wonders: Early Monorails article. But
since then, better pictures have been discovered and more
information has come to light, so we have to share these beautiful
images with our readers:
(image
via)
Propeller-driven "The Bennie Railplane" - "The short test track was
built over a railroad line near Glasgow, Scotland. Two
electrically-powered propellers delivered 240 horsepower in a short
burst for acceleration to the cruise speed of 160 kph. There were
plans for a high-speed link between London and Paris, with a
seaplane to carry passengers across the English Channel, but the
grave economic difficulties of the 1930's doomed the Railplane from
the start." (source)
(images via)
See the pictures and descriptions of the Bennie monorail structure
in the 1950s (in the abandoned condition) on this site:
(images via)
And here is the train in the full "sepia" glory of high-quality
retro photography! (click to enlarge) -
(image
via)
CONTINUE TO "WONDERS OF EARLY MONORAILS!" ->
|
Many dismiss copywriting as something that ad agency people do. Truthfully, all of us need to pay close attention to copywriting if we want to achieve our business objectives.
The goal of a “regular” text is to inform or entertain. The goal of Web copy (and ideally your website in general) is to get people to do something—to sign up, make a purchase, or something similar. Hiring a professional copywriter can be very expensive, which is one of the reasons why this is a valuable skill to have yourself.
“I don’t need to learn copywriting, I write based on how it sounds to me.”
Think you don’t need to learn copywriting?
David Ogilvy, the father of modern advertising, addressed this in his book Ogilvy on Advertising. One of his copywriters told him that he had not read any books about advertising; he preferred to rely on his own intuition.
Ogilvy asked him: “Suppose your gallbladder has to be removed this evening. Will you choose a surgeon who has read some books on anatomy and knows where the gallbladder, is or someone who relies on his own intuition?”
What distinguishes top experts from mediocre players is that the best know more. You can write better copy if you know more about it.
Everything is easier with the right process. If your approach to copywriting is “I’ll just try to be convincing”, you’re setting yourself up for failure.
You don’t even need to be a “natural writer” to come up with excellent copy, you just need the right process and some key principles about writing copy that sells.
The best processes are simple, as those are the ones you actually use.
Here are the six steps of effective copywriting process:
And now let’s get to the details:
This is often the most time-intensive part of your copywriting.
“You don’t stand a tinker’s chance of producing successful advertising unless you start doing your homework. I have always found this extremely tedious, but there is no way around it.” — David Ogilvy
David Ogilvy had the task to do copywriting for a Rolls Royce ad. He spent three weeks reading about it before he came up with the headline and the rest of the copy. While he was talking about advertising, it equally applies to your website copy—the goal is to get people to do something.
Ogilvy’s famous Rolls Royce ad.
You need to figure out why people buy the product, how they buy it, what they use it for, and what really matters to them. If you don’t have this figured out, you really cannot write a copy that works. When it’s your own business that you’re writing copy for, things go much faster, of course, as you know the product and the competition.
You need to be aware of your direct competition, how they present their product, and what claims they seem to be making. If you are not selling something unique, you are selling as much for your competition as you are selling for yourself. Being “like” others or choosing to be “one of the leading providers of” is a losing strategy.
Neuromarketing research tells us that differentiating our claims is the key to talking to the old brain, the decision making part of our brain. Our whole business identity should be different from the competition, and the claims we’re making about our product should stand out.
The answers are not in your office and you won’t have eureka-moments at brainstorming meetings (working solo is far more effective anyway). You have to interview people. Don’t waste time interviewing random people, you need to talk to your ideal customers and find out what’s on their minds.
Find out what they think about your kind of product, what language they use when they talk about it, what attributes are important to them, and what promises would most likely convince them to buy it. Pick the last 10 to 20 customers (who still remember their purchasing experiences), and ask them these questions (recording the interviews is a good idea, but ask for permission):
Take note of the exact wording they use. Your copy needs to match the conversation in your customer’s mind. If you talk about “scribing devices” and he needs a pen, there’s a mismatch.
My point is that when customers see the product described in words they have in their mind already, then you’ve got their attention.
Next step: write the outline. Guideposts are the markers that help you write the content.
Writing an outline usually only takes a few minutes and provides a road map for the rest of the project. It allows you to complete the work faster and ensures that you stick to the flow.
The outline structure will depend on the page you’re writing the copy for. The main pages you need a well thought-out copy in place are your home page and product pages.
Here are outline templates I personally use, and you can copy them. I’ve tweaked and tested them over the years, and this model works the best for me.
Your home page copy structure depends a lot on your business. A nail salon would have a different approach from an e-commerce store; a website selling mobile app design courses is different from a hosting company. Hence, it’s basically impossible for me to give you an outline template for your home page.
What IS universal is the value proposition. Every home page needs one (unless you’re a very well-known brand)
A value proposition is a promise of value to be delivered. It’s the primary reason a prospect should buy from you. The value proposition is usually a block of text with a visual.
There is no one right way to go about it, but I suggest you start with the following formula:
Here’s a list of useful value proposition examples you can check out.
Product page is where you sell the value of your product and where the user takes action (adds to cart, sign up, makes a purchase, etc.).
What you now have in place is like a skeleton. Next step would be to start writing the draft version of the copy by filling in the blanks.
Start filling in the blanks in the template above, and keep these points in mind for the style of your writing.
The goal of the copy is to connect with the reader, and guide them towards an action.
“Human relationships are about communicating. Business jargon should be banished in favor of simple English. Simplicity is a sign of truth and a criterion of beauty. Complexity can be a way of hiding the truth.” — Helena Rubinstein
Using complicated, fancy words does not make you seem any smarter or your solution any better—it just turns everybody off. Who wants to read something that doesn’t feel like it’s written for them? Talk to people like a real human. If you wouldn’t use a phrase on your website in a conversation with a customer, then don’t use it.
In addition to fancy words, avoid meaningless phrases. What do “on-demand marketing software”, “integrated solutions” or “flexible platform” really mean anyway?
Or useless phrases like “changing the way X is done”, “paradigm shifting …” or “exceeding customer expectations”—stop the nonsense. These bland phrases have long lost any meaning, and you will just waste precious attention time. You can see a list of the top 100 most overused buzzwords and marketing speak in press releases here.
Another thing to avoid—superlatives and hype. Saying things like “the best”, “world leader”, “once-in-a-lifetime opportunity” will just ruin your integrity. People don’t believe such claims anyway (even if they’re true).
What to do instead? Be specific.
Specificity converts.
“Clearer and more specific subject lines convert better.” — Bob Kemper, Senior Director of Sciences, MECLABS.
While in that specific quote Bob was focused on subject lines, this principle applies equally well to all copywriting. Specific is believable, specific is attractive, specific is convincing. Don’t be vague, be specific.
“We have the best coffee in the world” vs “Our estate earned the ‘world’s best coffee’ title at the Specialty Coffee Association of America’s Roasters Guild for the third year in a row.” Which claim is more believable?
You can use a superlative if you back it up.
Here’s an example. Can you understand what they offer?
Specific headline. Specific call to action with a specific
explanation of what they get when they sign up. Specific benefits
listed. Specific image to show the product in action.
Remember the old brain I mentioned before?
Our brains have three layers, and the oldest part—the old brain—is the decision-making part.
The “Old Brain” is the part that humans and their predecessors have had the longest—like 450 million years or so. So the part of the brain that controls decisions is fairly primitive and mostly concerned with survival.
If your copy is about you (your product, your company) and not the prospect (his problems, his life), you will fail. Make it about them. Too many companies start by stating “our company was founded…”, “we offer …” or something especially useless like “welcome to your website”.
Instead of saying “we specialize in dog training”, say “train your dog in two weeks”—move the focus from you to the benefit they will receive. People care about themselves—not you—and whether your website can be helpful in some way.
Tests have shown that 79% of people don’t read, they just skim. However, 16% read everything.
Those 16% are your main target group, the most interested people. If people are not interested in what you are selling, it doesn’t matter how long or short your sales copy is. If they are interested, you should give them as much information as possible.
Complete information is the best sales copy. A study by IDC showed that 50% of the uncompleted purchases were due to lack of information. They can always skip parts and click the “buy” button once they have the information they need. But if they read through the whole thing and they’re still not convinced, then you have a problem.
This is why you should always strive to say everything that can possibly be said about your product. You cannot be there in person to explain and answer the questions, so your copy needs to do it for you.
Long form copy works just great, but it’s not necessary to provide all the information on a single page. It’s okay to move supplemental information onto a different page (layer, popup, etc.) and just link to it.
For instance, Amazon often hides full technical information of products behind a link—since it’s only interesting to the hardcore tech savvy customers (and most customers are not).
Full technical details available after clicking a
link.
The important thing is that all the information needed to make
the decision is on a single page. Don’t make people work
click to read stuff that you want them to read anyway (like
features, benefits, testimonials, pricing, etc.).
Some people think that the price drives readers away, and they should hide it somehow—or make it hard to get to. While there is truth in that sometimes, it’s mostly false.
Consider this:
You should always make the price easy to find, but for more complex / expensive products communicate the value before the price.
Let’s say you’re selling a copper vase. Price: $990.
Seems expensive. But what if you knew that it was designed by Andy Warhol and previously used by Kurt Cobain? If you know who these people are and respect them, this changes everything, and it might seem like a steal instead.
So communicate value before price.
If your price is cheap, you want people to know it. If it’s expensive, the price qualifies the right people who are convinced to buy your copy. Giving price details also convinces your reader of the image and brand value of your product.
Once you have the content in place, it’s time to give it a conversion boost. The goal of the website copy is to convert the reader into a buyer (or subscriber, lead, etc.). There are certain things we can do to improve the conversion rate (the percentage of readers that take action) of the copy.
We’ll use three guides here to make the copy sell better:
Conversion boost. Image credit
APM Alex.
Conversion frameworks are a structured approach for increasing website conversion rates. The most prominent ones have been fine-tuned over the years and have been proven to boost sales.
While the conversion frameworks apply to a website as a whole, they can also be used as frameworks to improve sales copy.
There are many conversion frameworks around, let’s use one of them as an example:
C = 4m + 3v + 2(i-f) – 2a
This is not a lesson in physics, but a conversion formula developed by Marketing Experiments. Translation:
C = Probability of conversion m = Motivation of user (when) v = Clarity of the value proposition (why) i = Incentive to take action f = Friction elements of process a = Anxiety about entering information
Summary: The probability of conversion depends on the match between the offer and visitor motivation + the clarity of the value proposition + (incentives to take action now—friction)—anxiety. The numbers next to each character signify the importance of them.
How to apply this to your copy:
Persuasion has been researched thoroughly. Mr. Cialdini is undoubtedly the biggest authority on the field. His books are bestsellers and have been on the “must-read” list for marketers and copywriters for years.
In his research, Cialdini came up with six scientific principles of persuasion that will help guide you to become more effective at getting people to do what you want. In case you’re not familiar with those principles, then here’s the summary:
Principle 1: ReciprocityPeople feel obligated to give back to others who have given to them. How to use it: teach your prospect something useful in your copy, give away free stuff, and better yet—add value to your prospects long before you even start to sell them something.
Principle 2: LikingWe prefer to say “yes” to those we know and like. How to use it: talk/write like a human, connect with the reader, share details about yourself. Blog. Be friendly and cool (like Richard Branson, Oprah, Gary V).
Principle 3: Social ProofPeople decide what’s appropriate for them to do in a situation by examining and following what others are doing. How to use it: show how many others are already using your product. Show off your numbers. Use testimonials. Link to 3rd-party articles.
Principle 4: AuthorityPeople rely on those with superior knowledge or perspective for guidance on how to respond AND what decisions to make. How to use it: Demonstrate your expertise. Show off your resume and results. Get celebrity (in your niche) endorsements.
Principle 5: ConsistencyOnce we make a choice/take a stand, we will encounter personal and interpersonal pressure to behave consistently with that commitment. How to use it: Start small and move up from there. Sell something small at first (a no-brainer deal), even if you make no money on it. They now see themselves as your customer, and will most likely return to make a larger purchase.
Principle 6: ScarcityOpportunities appear more valuable when they are less available. How to use it: Use time or quantity limited bonuses. Limit access to your product. Promote exclusivity.
Research in neuromarketing (put together in this book) reveals interesting things about our brains.
Neuromarketing study in action. Image credit:
SMI Eye Tracking.
We’re usually trying to talk to the “new brain”—the sophisticated one—but it’s the brute “old brain” that makes all the decisions, so we need to dumb it down. Here’s the formula for talking to the old brain:
Selling probability = Pain x Claim x Gain x (Old Brain)3
How to apply it to your copy:
Done with conversion boosting? Now enjoy a full night of sleep and come back to the copy in the morning.
A fresh look a day later will help you spot inconsistencies, missing information, and flaws in the general flow of the copy. Use this time to add more information, rearrange the order of different blocks and fix the typos (spelling mistakes can cost you customers).
Before you publish the sales copy, it always pays to get two or three other people to read it and give you feedback. You want feedback from your ideal customers—do they get any questions that were left unanswered? Is there any part that needs to be made clearer? And peers—other marketers or entrepreneurs. What could make the offer better and more credible?
Once the editing is complete, you can make it live on your website. Don’t guess whether the headline or value propositions are as good as they can be, immediately launch two versions of the copy and test them.
There is no good way to predict how well the copy will do. Sometimes the conversion rates can skyrocket overnight. Sometimes the new copy turns out to be a downright dud.
You need to test your copy. Image credit
Horia Varlan.
Maybe it’s because the offer is weak. Perhaps the headline is the bottleneck. It’s impossible to put the finger on the problem as all you have are hypothesis. The only way to know is to test.
Don’t trust a copywriter who says he always writes killer copy on his first try. Nobody does.
Most common problems:
Start with A/B testing value propositions, and go from there.
Writing great copy is a skill you have to learn just like anything else. Use the outline and the tips to get started on the right track. Stephen King, the famous writer, said that if you want to be a writer, you must do two things above all others: read a lot and write a lot. I believe the same goes for writing great copy.
The best Web copy is not the one that uses sophisticated persuasion and mind manipulation techniques. The best copy provides full information about the product, its benefits, and makes it clear whether it’s the right one for the user.
(jvb) (il)
© Peep Laja for Smashing Magazine, 2012.
When I started designing and developing themes and templates for the ThemeForest marketplace five years ago, customer support was easy. I’d get an email or two a day, answer them, and move on.
But as sales picked up, things became complicated. One or two emails turned into five, which turned into ten, which turned into twenty! I’d respond to a question, and get another question in response. Emails were lost. Customers were frustrated. It was all a big mess.
Email was no longer a tenable support solution.
Two years ago, I decided that enough was enough. Email was no longer a tenable support solution. I needed to find a better way.
So I did some digging around for a support solution. And believe me, there are plenty out there. Some are free — mostly poorly designed, buggy DIY scripts to install and run on your own server. Some aren’t — prettier, feature-rich … and expensive. Fifty bucks a month? For a guy like me, forget it.
Simply put, there was nothing out there that appealed to someone doing well — but not getting rich — selling online. So I decided to build one. Something simple. Something with the features I needed, and nothing else. And something that played nice with the Envato API.
Two years later, I finished Ticksy — and I love it. It’s sleek, easy to use and getting some great reviews.
Most importantly, it’s doing a great job handling my support requests — the reason I built it in the first place!
As any developer knows, simple on the outside invariably means complicated on the inside. And, while Ticksy was a labor of love, building it was anything but easy.
Naming it? That’s a different story. Support ticket system. “Tick.” “Sy.” Ticksy. Get it?
I spent roughly three months designing the UI – buttons and form fields on the login screen, tabs and dropdowns in the app and more. Product management had to be spot-on, too. The initial Envato integration made it possible for me to tie every ticket directly into one of my products in the marketplace. Eventually, I worked product verification into the mix — only actual owners (not pirates) of my themes could submit tickets.
They liked it. No more email!
I developed the first, basic version of Ticksy using PHP and MySQL in about five months — continuing to support customers via email in the meantime (yuck). Finally, by the end of 2010, I was able to deploy the system for my own business. Customers started using it. They liked it. No more email! I felt great; a huge load was off my shoulders.
Then, something unexpected — and pleasant — happened. People started asking me about the system. The customers actually enjoyed using it as much as I did and wanted to know how they could use it in their businesses. I had no answer at the time. This was my system. I built it for me. Were there other people like me that would use something so simple?
Turns out there were. People wanted Ticksy. So I was back to the drawing board.
Two partners and I redesigned the UI and backend to allow for multiple systems, added social sign-in buttons (Facebook and Twitter), got feedback from friends and family and added a few other features. I essentially redesigned/developed the entire Ticksy system, and launched a beta build in early 2011.
I had around ten beta users using it full-time, and they loved it. Months went by, bugs were squashed, the UI was refined and I let it get some good use for a long time. If I was going to release this to the public and expect people to pay for it, it had to work well. I let it go for a year before deciding to release it to the public. My product was polished. Ticksy was ready for the limelight.
After many months of testing, developing a marketing site (powered by WordPress), creating a marketing video (with the help of VideoHive’s own Bryan Drake) and planning everything to the last detail, we launched Ticksy to the public in March.
If you’re a designer, you know the feeling of taking a product live. It’s amazing. But it’s also a bit scary. What if people don’t like it? What if it doesn’t sell?
Thankfully, with Ticksy, my fears were quickly assuaged. The initial group of users loved it, talking up its simplicity, its reliability and even its price point. Like me, they were freed from the headaches of email-based support — without having to turn to a cheaply built free solution or an expensive, bloated “do-it-all” app.
As a designer, it was supremely validating. And it was a reminder to keep working.
A developer’s work is never done. And despite the project’s success, that’s certainly been true for Ticksy.
As initially released, Ticksy was an intuitive, bloat-free, web-based customer support solution that could be customized to match any existing brand. After months of work, it’s still that — and more. Now, end users can label their tickets “public” or “private,” bringing an element of the traditional community forum to support. Search functionality for customers is enabled. And enhanced FAQs, notification systems and better Envato integration are on the way soon. (You can check out our roadmap here.)
Ticksy has been a two-year journey of discovery and hard work.
For me, Ticksy has been a two-year journey of discovery and hard work. But it’s been worth it.
What started as a project to simplify my own work has taken on a life of its own. I never expected Ticksy to see the light of day outside my office. But it’s incredibly vindicating to check the growing list of users and read their feedback. Really, it’s every developer’s dream. Ticksy has truly arrived. And, with each user, it’s making web-based customer support just a little bit simpler.
The process of taking an idea from sketch to launch is a significant achievement. If you have any, more specific, questions about the process (such as the tools we used for reporting bugs, version control, etc.), let me know in the comments, and we’ll talk!
Responsive design is the hottest topic in front-end Web development right now. It’s going to transform the Web into an all-singing, all-dancing, all-devices party, where we can access any information located anywhere in the world. But does responsive design translate well from the text-heavy Web design blogosphere to the cold hard reality of commercial systems?
Rumors came through our office grapevine that management was looking to revamp our mobile presence. There was talk of multiple apps being built externally that could be used on some of the major mobile devices. Our team had been getting familiar with responsive design and put forward a proposal of doing away with device-specific apps and developing a single responsive website that could be served to both desktop and mobile users. After a few hasty demos and prototypes, the idea was accepted and we began work.
The brief: make our current website, Airport-Hotels.uk, responsive while retaining the existing layout for users on browsers of 1000 pixels and up.
The following is what we picked up along the way.
The general consensus now seems to be “mobile first.” I agree. Starting with a single(ish)-column mobile website is the easiest way to get your CSS off to a great start. However, we use an external design agency, so the time and cost of a new mobile-first design was not feasible. It was left to the front-end developer to translate the existing design onto screens of smaller dimensions.
The solution was to break up the website into smaller blocks (or nuggets), which could then be positioned differently as the browser’s width increased. This led to our first base media query, which contained the main branding elements, with minimal layout information. Because the nuggets were of a fairly fixed size, we had a foundation for creating a grid for each of our major media queries. Anything that wasn’t deemed to be a “nugget,” such as a larger block of text, would be responsive and fill in the gaps that the nuggets couldn’t.
While this method is not as good a practice as “mobile first,” it does have the advantage of being faster and cheaper than a full redesign. And you pick up great knowledge along the way for when resources do become available for something more substantial.
When getting your feet wet with media queries, you’re tempted to go all out, but do you need to? Theoretically, you could serve a completely different design to each device. While this would be spectacular and self-satisfying, maintaining it would be a nightmare. We ended up using the default media queries in Andy Clarke’s 320 and Up framework, containing four breakpoints (1382 pixels was not in the brief). Looking back now, we could have removed at least one of those queries, possibly two.
We’ve been gathering statistics in the weeks since the website’s release, and by far the majority of our customers are running browsers either of 320 × 480 pixels or on full desktops. We could hit over 85% of our user base by focusing on these resolutions, while cutting down on development time and maintenance.
This was especially evident on our availability page, which easily contains the most information of any of the pages in our booking flow. In the end, rather than try to serve the perfect design to each device width, we moved much of the CSS for the largest media query to the size below: less maintenance, less fuss, and more time to work on the UX (and, importantly to the business, to make bookings).
When I first saw tools like Modernizr, I thought they would change everything. I suppose they have, but don’t rely on them too much. Mobile browsers have more inconsistencies than any desktop I have ever seen. Even WebKit-based browsers can render things completely differently. With debugging tools at a minimum, it’s like we’ve been thrust back into the pre-developer toolbar era of IE bug fixing. Luckily, that’s one of my favorite things.
Exploring this strange new world of bugs became one of the major aspects of the project. A few of my favorites are highlighted below. Hopefully, they won’t trip you up.
I love CSS columns. I had been wanting to use them for a while; but, other than small personal projects, nothing with appropriate content came up. While trying to work out the best layout for our website on a 320-pixel device, I realized that, rather than generating columns using floats or inline blocks, we could reduce the layout CSS to just a few lines by creating CSS columns. With most major mobile Web browsers being based on WebKit and Opera, this seemed to be a fairly reasonable solution and appeared to lay out everything perfectly. Great!
Here is the original code for the 320-pixel media query:
.product {
-moz-column-count: 2;
-moz-column-gap: 5px;
-webkit-column-count: 2;
-webkit-column-gap: 5px;
column-count: 2;
column-gap: 5px;
}
And here is the updated solution (roughly speaking — the actual code was much longer):
.product>div {
width: 49%;
float: left;
margin: 0.5%;
}
Unfortunately, the column specification isn’t quite
ready yet. On BlackBerrys and some HTC Android phones, our form
elements (specifically, the buttons) became unclickable. The layout
was perfect — we checked that the CSS was accepted with Modernizr,
and all the links worked — and yet you couldn’t click the “Book”
button. Back to the drawing board with that one.
We ended up using a more standard float-based column layout.
Gradients were another excellent instance of browser idiosyncrasies. We used a lot of CSS gradients in this redevelopment to replace some images. This should have saved the user’s bandwidth and made redesigns and maintenance faster.
On WebOS (with a WebKit-based browser), though, CSS gradients
would render as completely black unless used on a form input
element. It was baffling. In the end, we figured out that it was a
bug in the implementation of -webkit-linear-gradient.
We’ve learned that the bug has been fixed in the upcoming version,
so this might not be an issue in the future.
Here is the offending CSS:
.ppcHeader {
background: #73bff1; /* Old browsers */
background: -moz-linear-gradient(left, #73bff1 0%, #009ff7 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#73bff1), color-stop(100%,#009ff7)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #73bff1 0%,#009ff7 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #73bff1 0%,#009ff7 100%); /* Opera11.10+ */
background: -ms-linear-gradient(left, #73bff1 0%,#009ff7 100%); /* IE10+ */
background: linear-gradient(left, #73bff1 0%,#009ff7 100%); /* W3C */
margin-bottom: 20px;
}
(Bear in mind that CSS gradients add a heavy load to the browser’s rendering engine, so if you are using a lot of them, switching them off for mobile might be wise.)
Basically, JavaScript does not work on Blackberry 5.0. BlackBerry tries, but it’s so inconsistent and buggy that it’s not worth it. We were reliably advised by Peter-Paul Kochs to just resort to device sniffing and to turn off any JavaScript. This is another reason to make sure your websites are progressively enhanced by falling back to non-JavaScript versions.
Meanwhile, Opera Mini works fine with JavaScript, but each of a
website’s pages is rendered on Opera’s servers and then essentially
compressed into a big image before being sent to the mobile device.
This is great for the user because it can reduce bandwidth to 10%
of the normal browsing experience. On the other hand, if you have
onkeyup validation in your forms, this can be a
problem because each call to the JavaScript would require
refreshing the entire page from the server.
This was and still is one of the major problems with mobile browsing on our e-commerce website. In order to make a purchase on an average website, the user has to fill in a lot of information: names, addresses, credit-card details, the list goes on and on. While typing on mobile has gotten much easier, navigating large forms is a frustrating and laborious process.
Our mockup payment page had 22 form inputs that needed some kind of interaction. These were required either to make a successful booking, to provide information to the product supplier after booking or for our own sales and data purposes.
The question became (as it always seems to be with mobile), what could we remove and what did we have to keep? Well, we tried to take the middle path, which is currently in development or might even be live by the time you read this.
We chose to split our payment process into two stages. Because our users can save more on their purchase by booking early, our first payment stage asks for the very minimum of information required in order to confirm a booking: name, car registration and credit-card details. This gives the user the best price available and chalks up another booking for us. Part two of the payment process is to gather the rest of the information required to “complete” the booking. This second stage can be filled out at the user’s convenience, either immediately or later on using our online booking management system. This eases any frustration caused by having to fill out a large form.
A good user interface means something completely different on mobile devices — and even tablets for that matter. Many of the user-friendly features we have implemented on our desktop website would just be bad ideas on these smaller mouse-less devices.
Lightboxes were all the rage a few years ago. They were a
convenient and pretty way to display a small amount of content or
something that wasn’t worth loading a new page for. In IE 7 and up,
you can position lightboxes using position: fixed,
which is great. On mobile devices, though, browsers do not
implement position: fixed, or they implement it in an
odd way to prevent non-mobile-ready websites from not working at
all. This will ruin any lightboxes.
We recommend just loading a new page for lightbox content: less JavaScript, easier and fast. A new tab would also be fine, but due to the infancy of tabbed browsing on mobile devices, maintaining the flow is probably a better idea for now.
Content that is only visible via hovering obviously doesn’t work on touchscreens. What used to be an easy way to hide content while keeping it accessible has become a bit of a nightmare to deal with. We tried just removing the hover and showing the content, to see what would happen. The iPhone actually handles hovers fairly well, translating them into tap events. On Android, you need to click and hold for a little while to prevent the default action of clicking the link (our links are anchor-tag-based).
In the end, modifying the code that handles the hovers (assuming it’s JavaScript) and adding a tap event seemed to be the best solution. This allowed us to preserve the design’s aesthetic, while keeping as much functionality as possible for mobile users.
if( document.createTouch ) {
this.addEvent(c[j],'tap',this.tipOver,false);
} else {
this.addEvent(c[j],'mouseover',this.tipOver,false);
this.addEvent(c[j],'mouseout',this.tipOut,false);
}
Our date-picker calendar was one of the biggest hurdles to overcome in the UI. We have a text input that allows the user to enter a date. Prior to the date-picker, our solution was a dynamically generated select box, but that caused confusion among many users because they might have remembered the day of the week they were flying on but not the date. So, we added the jQuery UI Datepicker to make filling in the search form one step easier.
However, what was one step forward for convenience on the desktop was one step back on mobile. Focusing the text input would open both the date picker and the phone’s keyboard, thus obscuring the date picker.
Our next option was to use the HTML5 date input. Because this element was released so recently, browsers are still playing catch up, and implementations vary wildly. It’s just as rough on desktop, with Firefox still rendering it as a text input, Chrome adds an up/down selector and forces the date format, while Opera actually renders a calendar just like the jQuery UI Datepicker. This solution still requires the date-picker JavaScript, but it forces the format, which can actually make it less user-friendly. While the concept is great and the solution will be great once the bugs are ironed out, we found that the date type input is not yet ready for commercial use in this fashion.
Our eventual solution (not yet live) was to use a JavaScript “touch event” query to generate a more mobile-friendly date picker than the standard jQuery UI one. This creates an iOS-styled triple drop-down menu for day, month and year and is user-friendly on mobile devices. The no-JavaScript backup can be either a text input or a select drop-down menu. Have a look at the code for yourself.
The final point, which reflects the complexity of mobile development, is how to fit old versions of IE into this new technology. IE 8 and below ignores media queries, which presents a rather sticky problem when your entire website is based on them. There are several solutions to this, which we’ll explore below.
I can think of two great JavaScript polyfill options for media queries. The first is Respond.js, which continually monitors the browser’s width, parses the CSS and then serves the correct styles for that width. This is a great solution if you need the website to respond on IE 8 and below. The main issue is the time between the document loading and the JavaScript kicking in; the website is initially displayed using the base style sheet, usually the mobile view, before it “jumps” to the full desktop version. Obviously, this doesn’t look great on a desktop monitor, and if the user is on an old browser, then their computer and Internet connection will probably be slow, too, which means that the jump time could be even longer.
The other JavaScript option here is the Chrome frame, which achieves the same end and has the same disadvantages. This solution isn’t bad, but just not right for our implementation.
This is one of my favorite options for responsive websites and is also used in the latest version of the 320 and Up boilerplate. Create a separate CSS file for each device width; and for IE, serve them all to the user, with no media queries. With a mobile-first approach and a couple of fixed widths in your IE style sheet, this will serve the full-sized version of the website to users of outdated browsers. This solution is fast, simple and easy to maintain.
Finally, given the right conditions, you could just write a completely separate IE style sheet, full of conditional comments to load the full desktop version of the website. Theoretically, this need only contain small amounts of layout information; but given that many of these styles will be reproduced in your media queries for wider widths, it can cause maintenance issues down the line. Duplicating code is never a good idea, which makes me wary of this solution.
Interestingly, we used this solution in the end, but with a twist. We used a PHP plugin in our template files to combine, compress and cache our CSS files. Due to some issues with the cache in IE, we were already generating a separate cached CSS file for IE users. We added a couple of lines to the PHP file to strip out media queries entirely as it combines and compresses the CSS. This method delivers the results of the “include all media queries” solution, while allowing the option for inline media queries in the style sheet. Because of the way we organized the CSS, this turned out to be the best solution for the project.
After all that, we finally have the first version of our responsive booking flow. I like to think that this epitomizes “mobile-ready.” We aren’t necessarily mobile-optimized, but our feet are on the bottom rung of a tall ladder that climbs to a great system that works perfectly on all devices. This is the starting point, if you will.
Was it worth it? It’s been a long journey, with a lot of head scratching and learning on our feet fast, but that’s what Web development is about, and I wouldn’t have it any other way. You can’t be perfect the first time round, and you don’t have to be. The point is that this technology is ready now, and the sooner you start using it, the better prepared you’ll be for the mobile market as it comes running at you. In the next few years, we’re hoping to see JavaScript network APIs that will allow Web users to add purchases directly to their monthly phone bill. I expect the mobile e-commerce market will explode at that point. Will you be ready?
(al) (da) (il)
© Gavyn McKenzie for Smashing Magazine, 2012.
In this article, we take a break from some of the more advanced ways to customize WordPress, and share some super-easy customization techniques for the WordPress Admin area.
If you’re just getting started with WordPress, or have been running with default functionality for a while and now want to dig in with some useful and easy ways to customize your WordPress site, a great place to start is the WordPress Admin area, or backend. One of the great things about WordPress is that each part of the backend is easily customized using simple PHP functions.
In this article, you’ll learn how to customize the login page with your own logo, add new widgets to the dashboard, add custom content to the admin footer, make it easier to get in and out of the Admin area, and more. When combined, these techniques can improve branding, accessibility, and usability of your WordPress-powered site.
By default, logging in to the WordPress Admin area requires
either /wp-admin or /wp-login.php in
the URL, which isn’t a lot to type. You can, however, make it even
easier by changing the login URL to something more memorable and
better branded.
This technique requires .htaccess file
manipulation. Usually, this is a file hidden in the root of
your WordPress installation. It’s automatically created
by WordPress after setting custom permalinks using URL
rewriting.
First, check your SFTP/FTP client preferences to show hidden
files—most FTP clients manage that. Then, check that the file
.htaccess exists. If that is not the case, create it
by using your favorite notepad. On Windows, use the Notepad++
software to create it. Open it and add this line on top:
RewriteRule ^login$ http://YOUR_SITE.com/wp-login.php [NC,L]
Just replace the login keyword with one of your choice and your website’s URL.
Now, open your favorite browser and go to
http://yoursite.com/login. You’ll be redirected to
the WordPress login page. Remember that your clients are not
supposed to know everything about WordPress usages—a user-friendly
URL is far better to remember
than /wp-login.php.
Easy to remember, easy to teach, easy to learn!
When you log into WordPress, the default logo links to WordPress.org. Let me show you a quick tip for using your own link. Open the functions.php file. Then, add the following lines of code. And be sure to remember the PHP tag enclosure.
// Use your own external URL logo link
function wpc_url_login(){
return "http://wpchannel.com/"; // your URL here
}
add_filter('login_headerurl', 'wpc_url_login');
Don’t forget to save the file. Log out to view the result. Better, no?
Reinforce your brand by changing the default WordPress login logo. The logo is one of the most important elements of your brand! People will memorize it to find you quickly. Showcase it!
This is the default WordPress login screen:
To enhance it, add these lines of code in your functions.php:
// Custom WordPress Login Logo
function login_css() {
wp_enqueue_style( 'login_css', get_template_directory_uri() . '/css/login.css' );
}
add_action('login_head', 'login_css');
The third line points towards a separate stylesheet. Even though it’s possible to use that of your default CSS theme, I advise you to use Firebug—a useful Firefox add-on—or any other Web development tool that allows you to edit your website in real-time. As you can see, just one line of code is needed to change the default logo.
#login h1 a {
background-image: url("http://YOUR-WEBSITE.com/wp-content/themes/YOUR_THEME/images/custom_logo.png") !important;
}
Feel free to change the logo URL if it’s not located in your theme folder. Now have a look at your login page: your custom logo appears!
If that is not the case, make sure that no white lines are
present at the end of your functions.php file.
The default WordPress administration footer thanks you for using their content management system and links to WordPress.org. For professional use and website branding, you’ll want to customize this area.
Open the Appearance menu and click
on Editor. Click
on functions.php on the right side of your
screen. You can also access the footer by using an FTP client to
locate /wp-content/themes/NAME_OF_YOUR_THEME/functions.php.
Now, add the following lines of code, taking care to place them between PHP tags:
// Custom WordPress Footer
function remove_footer_admin () {
echo '© 2012 - WordPress Channel, Aurélien Denis';
}
add_filter('admin_footer_text', 'remove_footer_admin');
To customize the content, just change the second line inside the
echo, between the quotes.
Finally, refresh your browser to see the result.
It can be useful to add your own widget to provide general or commercial information. Adding a widget to the WordPress dashboard can be done very quickly. Again, open the functions.php file, then, add the following lines of code:
// Add a widget in WordPress Dashboard
function wpc_dashboard_widget_function() {
// Entering the text between the quotes
echo "<ul>
<li>Release Date: March 2012</li>
<li>Author: Aurelien Denis.</li>
<li>Hosting provider: my own server</li>
</ul>";
}
function wpc_add_dashboard_widgets() {
wp_add_dashboard_widget('wp_dashboard_widget', 'Technical information', 'wpc_dashboard_widget_function');
}
add_action('wp_dashboard_setup', 'wpc_add_dashboard_widgets' );
In this example, add the desired text between the
echo tag, after the quotes. You could also insert
HTML; an unordered list for example. Name your widget—this will be
the widget title—by replacing “Technical informations” with your
title of choice. This is what it will look like.
If you do not see your custom widget, click on the Options menu screen located in the top right of the window to display it.
The WordPress dashboard displays multiple widgets that you can easily move by dragging and dropping. To mask them definitively, just add the following lines in the functions.php file:
add_action('wp_dashboard_setup', 'wpc_dashboard_widgets');
function wpc_dashboard_widgets() {
global $wp_meta_boxes;
// Today widget
unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now']);
// Last comments
unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_comments']);
// Incoming links
unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_incoming_links']);
// Plugins
unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins']);
}
You can choose what widgets you’d like to hide. In this case, “Right Now”, “Recent comments”, “Incoming links” and “Plugins” have been removed from your WordPress dashboard. To learn more about this feature, have a look at the codex.
If you’re not totally satisfied with the WordPress admin color
scheme, this is how you can customize it. All you need to do is
create a new CSS stylesheet. In this example, we’ll call
it admin.css and place it in a folder
entitled/css. Once again, edit
the functions.php file and add this
snippet:
// Custom WordPress Admin Color Scheme
function admin_css() {
wp_enqueue_style( 'admin_css', get_template_directory_uri() . '/css/admin.css' );
}
add_action('admin_print_styles', 'admin_css' );
Your admin.css file must contain styles that are
compatible with WordPress. Again, I recommend you use Firebug or
Web Inspector to identify the right ones.
That’s all folks! I hope you have learned a few good tips to make WordPress act more like a white label CMS. Remember that customization is not just a branding technique, but also a way to boosting your productivity, by increasing user-friendliness.
If you’re not comfortable with PHP, you can make most of these changes with the White Label CMS WordPress plugin. Do you know any other great tips? Share them with us!
(jc)
© Aurélien Denis for Smashing Magazine, 2012.
Link
Quick Update: Great Dieselpunk Art
Is there such a thing as "blimp-punk"? Well, these airships are
sufficiently dark, industrial and dirty to be called such... Click
to enlarge, this is fantastic and very atmospheric work "Landscapes
L51" by Gutalin! - see it in detail here.
Also, don't miss this wonderfully futuristic vision of the Gears
City by Daniel
Dociu:
(art by Daniel Dociu)
Daniel Dociu is a video game art director and concept artist at
NCsoft North America & ArenaNet. Dociu was born in Cluj,
Romania.
Here is yet another lovely dieselpunk artwork by Stefan Prohaczka:
...and a nameless futuristic city by Benedict Campbell (see more here - some nsfw):
(art by Benedict Campbell)
Don't miss these REAL dieselpunk images from the 1940s US War
Effort (in wonderful Kodachrome, see more at Shorpy):
(images via)
CONTINUE
TO OUR RETRO-FUTURE CATEGORY!
|
This tutorial will cover the basics of CSS regions, which allow us to flow content within various sections of the page. Confused? You probably are; read on!
At the time of this writing, the CSS Regions specification is a working draft and things may change! Techniques mentioned in this tutorial might change in implementation. The aim of this tutorial is to give a basic understanding of CSS Regions and what might be coming to a browser near you.
Check out caniuse.com for a list of browsers which have some support for CSS Regions. This tutorial will only use webkit/non-vendor-prefixed examples for simplicities sake.
If you find the demo is not working for you it may be because CSS Regions needs enabling, here are instructions for Chrome (should work for Chrome, Chrome Canary & Chromium )

Demonstrating CSS Regions in a simple manner actually requires very little code!
To get into the flow of things lets go through a quick example of how to use CSS Regions.
First, we need some dummy text which is contained within the paragraph tag, below that you’ll notice two empty divs each with a class of “regions”. Using CSS Regions we will allow our “example-text” to flow into the region divs.
<p class="example-text">"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."</p> <div class="regions"></div> <div class="regions"></div>
.example-text {
-webkit-flow-into: example-text-flow;
padding: 0;
margin: 0;
}
.regions {
-webkit-flow-from: example-text-flow;
border: 1px solid black;
padding: 2px;
margin: 5px;
width: 200px;
height: 50px;
}
If you try viewing the code above in a Webkit browser that supports CSS Regions, you should see something like:

All styling (apart from -webkit-flow-from) which has been applied on the “regions” class is only there to make it evident where the regions are, the two lines of CSS that we really care about are:
-webkit-flow-into: example-text-flow; -webkit-flow-from: example-text-flow;
These will be discussed in more detail below
flow-into Property and Named FlowsThe flow-into property accepts an identifier as its value, once we apply the flow-into property onto an element and pass it an identifier, that element then becomes part of a “named flow”. As soon as an element becomes part of a named flow it is taken out of its usual flow – this essentially means the element will not be rendered on the page, for example:
<p class="example-text">I will not be rendered on the page</p>
.example-text {
-webkit-flow-into: example-text-flow;
}
There are some exceptions to this however, if the flow-into property is given the value ‘none’ the element will not be part of a named flow and thus be subject to usual rendering on the page. As you might have guessed, another case where an element which is part of named flow will be displayed is when it has a valid region associated with it.
Multiple elements can be put into the same named flow:
#example-1 {
-webkit-flow-into: my-named-flow;
}
#example-2 {
-webkit-flow-into: my-named-flow;
}
If there is an associated region for “my-named-flow”, an attempt
will be made to flow the two elements (#example-1
& #example-2) into their corresponding region
chain.
It’s not just simple bits of text which can be put into a named flow, we can put images too! Having the ability to put all sorts of HTML elements into named flows is a powerful thing. For example, let’s say we had two individual lists but from a presentation point of view we wanted to show them together. One way to go about this is to use CSS selectors to target only the portions we need and put them into a named flow, example (extract of code):
<article id="css3">
<header><h4>CSS3</h4></header>
<ul>
<li>Media Queries</li>
<li>Text Shadows</li>
<li>3D Transforms</li>
</ul>
</article>
<article id="html5">
<header><h4>HTML5</h4></header>
<ul>
<li>Canvas</li>
<li>Drag-and-drop</li>
<li>Web Storage</li>
</ul>
</article>
<div id="buzzwords-region"></div>
/* Only put the list within the article into a named flow */
#css3 > ul {
-webkit-flow-into: buzzwords-flow;
}
#html5 > ul {
-webkit-flow-into: buzzwords-flow;
}
#buzzwords-region {
-webkit-flow-from: buzzwords-flow;
border: 1px solid green;
}

(Demo of the above.) If you look at the source code
you’ll notice that our HTML5 & CSS3 lists have been merged into
a new buzzword list. Take note of how the headers of
those lists were not targeted in the CSS selectors and thus are not
part of any named flow, they are therefore still rendered on the
page and are not contained within a region.
flow-from PropertyThe flow-from property is able to take a container, for example an empty div and turn it into a region. For it to turn into a valid region it must have an associated named flow. As discussed, named flows are created by using the flow-into property and then using an identifier as its value.
<div class="region"></div>
.region {
-webkit-flow-from: my-named-flow;
}
Similar to flow-into property, we can assign the value of ‘none’ to the flow-from property, this makes the corresponding element nothing more than a container e.g. it will not act as a region.
When applying the flow-from property on an element, it will not have a height or width which is why you’ll need to set these in order to view the contents of the region. Regions may only act as region chains for a single named flow, so multiple elements may flow-into a single named flow however a region can only flow-from a single named flow. A region will maintain the styles of its source element; this means if the source element has the colour value of red the text will continue to appear red when rendered as part of a region.
The CSS Region specification has been considering using @region rules for specific region styling.
“An
@regionrule contains style declarations specific to particular regions.”
This could allow for CSS syntax (similar to that of media queries) such as:
/* A regular style on all paragraph tags */
p {
font-weight: normal;
}
@region #my-region {
/* When text from the p element is flowing into #my-region, use the styling below */
p {
font-weight: bold;
}
}
Being able to do this would allow region specific styling to be applied on the source, currently, setting for example “font-weight: bold” on a region will not cause content displayed within it to be bold – the styling must be applied on the source element.
At the time of this writing, there is some support in Webkit-based browsers to access CSS Region information through JavaScript. Using JavaScript, we can pick out a flow according to its identifier and find out what regions are associated with it. We can even find out the status of a particular region, there may be a use case where empty regions need specific handling, using JavaScript we can accomplish this.
A named flow can be accessed in JavaScript using document.getFlowByName(‘identifier’) (You can try these in the developer console in the demo.)
var flow = document.webkitGetFlowByName('example-1-text');

The returned object is something called a WebkitNamedFlow. flow.contentNodes will contain an array of HTML Elements which are being used as the source for the flow being accessed.
The ability to detect which content belongs to which regions can prove useful in various situations.
var flow = document.webkitGetFlowByName('example-4-text');
var main_content = document.querySelector('#example-4 .main_content');
flow.getRegionsByContentNode(main_content);
In the code above, we first find our flow on the page using the flow name, then using the Selectors API we access a piece of content on the page and pass it as an argument to getRegionsByContentNode(), this returns a list of elements which are being used as regions for that particular piece of content.
We can very quickly determine the status of a region in regards to how content inside it fits.
//This is not a very efficient selector, see https://developers.google.com/speed/docs/best-practices/rendering#UseEfficientCSSSelectors
var region7 = document.querySelector('#example-4 .regions > div:nth-child(7) ');
region7.webkitRegionOverflow //"fit"
element.regionOverflow will return different values
depending on how it’s handling the source content. There are four
possible values: ‘overflow’, ‘fit’, ‘empty’ and ‘undefined’
You can try this out using developer tools in Chrome, on the demo page, right click on one of the blue boxes (a region) and select ‘Inspect Element’. You may find the source element is selected rather than the region div. Try to find the nearest div with the class of ‘regions’ and select one of the child divs (they should appear empty). At this point you can hit the Escape key on your keyboard which should bring up the console; now as a handy shortcut you can type $0 into the console to access the selected element. Now try typing:
$0.webkitRegionOverflow //'overflow', 'fit', 'empty' or'undefined'

Hello! Thanks for reading this tutorial, here are some extra bits of information you may be interested in.
E-commerce runs on secrets. Those secrets let you update your blog, shop at Amazon and share code on GitHub. Computer security is all about keeping your secrets known only to you and the people you choose to share them with.
We’ve been sharing secrets for centuries, but the Internet runs on a special kind of secret sharing called public-key cryptography. Most secret messages depend on a shared secret—a key or password that everyone agrees on ahead of time. Public-key cryptography shares secret messages without a shared secret key and makes technologies like SSL possible.
Cryptography is a scary word: it conjures thoughts of complex equations and floating-point arithmetic. Cryptography does have a lot of math, but it’s more about keeping and sharing secrets.
Telling my best friends a secret is easy: I find a private place and whisper it in their ears. As long as no one is listening in, I’m totally secure. But the Internet is full of eavesdroppers, so we need codes.
We’ve all been inventing codes since we were children. I created this simple number code (actually a cipher) when I was 5:
a=1, b=2, c=3, d=4, e=5…
It fooled my friends, but not my parents. Simple substitution ciphers are based on a lack of knowledge. If you know how they work, then you can decode every message. The experts call this “security through obscurity.” Letter and number substitutions don’t work on the Internet, because anyone can look them up on Wikipedia. For computer security, we need codes that are still secure even if the bad guys, or your parents, know how they work.
The most secure code is still easy to use: a “one-time pad.” One-time pads have been used for centuries, so they don’t even need computers. They played a big part in World War II, when each pad of paper with the key numbers was used only once.
Let’s say I wanted to send you this secret message:
I love secrets
First, I’d turn the message into numbers using my simple cipher from when I was 5. (I’ve heard rumors that other people had this idea first, but I don’t believe it.)

Then I’d mash my keyboard to generate a random key string for my one-time pad.

Now I can add the two strings together. If my number is greater
than 26, I would just wrap it around to the beginning. So,
i(9) + e(5) = n(14), and o(15) + t(20) = i(35 -
16 = 9). The result is an encrypted string:

Decrypting the string to get the secret back is easy. We just
subtract the one-time pad: n(14) - e(5) = i(9). Follow
that pattern through the entire message, and you can securely share
a secret. You don’t even need a computer: just work it out with a
pen and paper.
This function is called a symmetric-key algorithm, or a shared-key algorithm, since it uses the same key to encrypt and decrypt the message. Modern systems can safely use the pad more than once, but the basic idea is the same.
The one-time pad is totally secure because the bad guys don’t
know how we got the encoded letter. The n could be
i + e, j + d or any other combination. We
can use our shared secret (the one-time pad) once to share another
secret.
But there’s a fatal flaw. We need to share the one-time pad ahead of time before we can start sharing secrets. That’s a chicken-and-egg problem because we can’t share the pad without worrying that someone will snoop. If the bad guys get the one-time pad, then they would be able to read everything.
One-time pads help me share secrets with my best friends, but I can’t use them with strangers such as Amazon or Facebook. I need a way to share something publicly that doesn’t compromise my one-time pad. I need a public key.
Public-key encryption focuses on a single problem: how do I prove that I know something without saying what it is? An easy concept to help us understand this is a backpack full of weights.

I want to prove that I know which weights are in my pack, but I don’t want to tell you what they are. Instead of showing you all of the weights separately, I’ll just tell you the total. Now you can weigh the pack and see if I’m right without ever opening it.
If the pack weighs 20 kilos, then you wouldn’t know if it has one 20-kilo weight, twenty 1-kilo weights or something in between. With a large number, you can be pretty confident that I know what’s in the pack if I know the total; you don’t have to see inside. The weight of the backpack is the public part, and the individual weights are the private part.
This basic backpack enables us to share a secret without really sharing it. If we each have a backpack, then we can both share secrets.
The backpack works well enough for smaller numbers, but it isn’t useful in the real world. Backpack algorithms were a mere curiosity for decades. Then RSA changed everything.
RSA was the first public-key encryption system that worked in the real world. Invented more than 30 years ago, it coincided with the introduction of the more powerful computers that were needed to run the big numbers. RSA is still the most popular public-key encryption system in the world.
The basic premise of RSA is that factoring large numbers is difficult. Let’s choose two prime numbers: 61 and 53. I’m using the numbers from Wikipedia’s article on “RSA” in case you want more details.
Multiply these two numbers and you get 3233:
61 × 53 = 3233
The security of RSA comes from the difficulty of getting back to 61 and 53 if you only know 3233. There’s no good way to get the factors of 3233 (i.e. the numbers that multiply to make the result) without just looking for all of them. To think of this another way, the weight of our backpack is 3233 kilos, and inside are 61 weights weighing 53 kilos each. If you make the resulting number large enough, then finding the numbers that produced it would be very difficult.
Unlike the one-time pad, RSA uses the public key to encrypt
information and the private key to decrypt it. This works because
of the special relationship between the public and private keys
when they were generated, which allows you to encrypt with one and
decrypt with the other.
You can share the public key with anyone and never reveal the private key. If you want to send me a secret message, just ask for my public key and use it to encrypt the message. You can then send it to anyone you want, and you’ll know that I’m the only one who can decrypt the message and read it.
I could send you a message in the same way. I would ask for your public key, encrypt the message using it and then send it to you to decrypt. The popular program Pretty Good Privacy (PGP) worked like that. We’re secure as long as we both keep our private keys private.
Exchanging keys is made even easier by special key servers that allow you to search for people and find their public keys.
Public-key encryption also works in reverse to provide digital signatures. Let’s say I want to write a message and prove that I wrote it. I just encrypt it with my private key and post it. Then anyone who wants to check can decrypt it with my public key. If the decryption works, then it means I have the private key and I wrote the message.
RSA is relatively simple: take two numbers (the private key), apply some math, and get a third number (the public key). You can write out all of the math in a few lines, and yet RSA changed the world. Business doesn’t work on the Internet without public-key encryption.
We use public-key encryption every day with HTTPS. When you access Facebook, Twitter or Amazon with HTTPS, you’re using a simple encryption mechanism like the one-time pad, but you’re creating the pad with public-key encryption. Without HTTPS, anyone else at Starbucks could read your credit-card number, Facebook password or private email while sipping a latte.
Amazon has a certificate from a company named VeriSign. The certificate certifies that Amazon is Amazon, and it contains its public key. Your browser creates a special key just for that session and encrypts it using Amazon’s public key. Then it sends it over the Internet, knowing that only Amazon can decrypt the session key. Once you’ve exchanged that secret key, you can use it as the one-time pad to protect your password and credit-card number.

You could keep using public-key encryption for the whole session, but because of all the math, it’s much slower than the one-time pad.
Another place many of us use RSA is GitHub. Every time you push a change to GitHub or pull from a master branch, GitHub has to make sure you have permission to make the change. It gets its security through a secure command shell using RSA.
Remember when you set up your GitHub account and followed some commands to generate keys?

You used the SSH-Keygen tool to generate a new RSA private/public key pair. Then you went to your GitHub account page and entered your public key.
Now, when GitHub needs to authenticate you, it asks your computer to sign something with your private key and return the signed data. With your public key, GitHub can confirm that the signature is authentic and could only have been produced by someone who has the corresponding private key—even though GitHub itself doesn’t have that private key.
That’s better than a simple password because nobody can snoop it. And if GitHub ever gets hacked, your private key won’t be in danger because only you have it.
When WordPress.org was “hacked”, it wasn’t really hacked. WordPress plugin developers, like everyone else, have accounts on other websites. They also reuse their passwords. When hackers cracked those other websites, they used the stolen passwords to log into WordPress.org and make malicious changes to plugins.
Most people use the same user name and password on multiple websites. That makes your website only as secure as everyone else’s. Public-key encryption changes that. Because you never have to share your private key, it doesn’t matter if other websites get hacked. If an attacker breaks into GitHub and gets your public key, they can’t use it to impersonate you or log in as you on other websites. Only someone with your private key can do that, which is why your private key remains safe on your computer. Using public-key cryptography makes GitHub much more secure.
GitHub was hacked recently, but not because the encryption failed. Real-world security breaches are caused by problems in implementation, not in math.
In this case, the hacker was able to exploit a hole and add his public key to the Ruby on Rails repository. Once the key was added, GitHub used it to verify the hacker’s identity and granted him access. We’re lucky this hacker was friendly and told GitHub about the issue.
Once the problem was fixed, you could keep using your private key because GitHub never had it to lose; it stayed on your machine. Public keys saved GitHub from serious problems.
The weakest link in GitHub’s security was in the mechanism that allowed clever users to add public keys to other projects without being authorized. The math was perfect, but the implementation wasn’t.
Knowing the fundamentals is essential (you might say the key) to writing secure applications. The math is complex, but the basics are simple:
When it comes time to implement public-key cryptography in your application, don’t. RSA and other algorithms are already implemented in all major languages. These libraries include extra security features such as padding and salts, and they have a lot of testing behind them.
Most security flaws come from poor implementations and misunderstanding about the libraries. You don’t have to write your own cryptography libraries, but you do have to know the fundamentals so that you can use the ones that are out there.
Illustrations in this article were provided by Robb Perry.
(al) (km)
© Zack Grossbart for Smashing Magazine, 2012.
#180 - Week of May
16, 2012
Every Ship Lost by Great Britain in WW2, hi-res -
[super image]
Extreme Climbing in Moscow, pics - [urban]
Spectacular Planet System Found - [wow
space]
Predictions about 2001 from 1901 - [futurism]
Forbidden Colors Can Be Seen! - [fascinating]
StratoCruiser!,
VW MicroBus - [concepts]
Unveiled: Plans to Nuke the Moon - [history]
Tokyo Sumida River Lit Up with 100,000 LEDs - [art]
Our True Humanity Reach - [wow
space]
More of the Scale of the
Universe - [with additional
info]
The
Caterpillar That Makes Its Own Camouflage, more - [pics]
The
First Practical Artificial Leaf- [wow
science]
Biomes of the Earth:
Geography - [cool map]
And the Global Amount of Water on Earth - [infographic]
First James
Bond actor: Barry Nelson - [interesting]
Turn Anything Into a Keyboard, video - [crazy
project]
Aeolipile: 1st
Century B.C. Steam Engine - [info]
The Monument to Electricity that Never Was - [colossal]
Spooky Abandoned Australian Prison - [gross, pics]
Frightening
Mosquitoes Invasion - [pics, scroll
down]
Pulsar Sound: Cosmic Drum Beat - [wow
video]
It's hard
work but somebody's gonna do it - [fun
video]
Truly Weird
Dance from the 1950s - [fun
video]
Narrow Twisting Road: a Truck and a Bus - [wow video]
Mesmerizing
Play: Hit that ball! - [wow
video]
Carmageddon:
Screwed Up Physics - [nsfw,
Michael Bay-like]
Impossible
Plane Surfing, with
Bus - [game videos]
Camaro Axle
Total Failure - [wow video]
London
Futurism from 1924 - [cool
video]
SEE ALL OTHER LINK LATTE ISSUES HERE
There are dozens of JavaScript testing frameworks, but most of them function in, more or less, the same way. However, Douglas Crockford’s JSCheck is considerably different from most. In this tutorial, I’ll show you how it’s different and why you should consider using it!
Crockford describes JSCheck as a “specification-driven testing tool.
Crockford describes JSCheck as a “specification-driven testing tool.” When using the frameworks you’re used to, you would write a test for a given piece of functionality, and, if that test passes, declare that the given functionality is working correctly. However, it’s possible that you might miss some of edge cases or exceptions that your tests don’t cover.
While uncovering edge cases isn’t the express purpose of JSCheck, it is a nice side benefit. The main idea behind JSCheck is this: the specification you write will actually describe how the code you are testing should work. Then, JSCheck will take that specification (called a claim in JSCheck-lingo), and generate random tests to prove the claim. Finally, it will report the results to you.
Sounds interesting? Read on! Sounds familiar? You might have used the Haskell testing tool, QuickCheck, on which JSCheck was based.
Of course, before actually writing our claim, we’ll want to have some code to test. Recently, I wrote a mini-password scorer, similar to the functionality on HowSecureIsMyPassword.net. It really isn’t fancy: you just pass the function a password and get a score back. Here’s the code:
(function () {
var PasswordScorer = {};
PasswordScorer.score = function (password) {
var len = password.length,
lengthScore = 0,
letterScore = 0,
chars = {}
if (len >= 21) { lengthScore = 7; }
else if (len >= 16) { lengthScore = 6; }
else if (len >= 13) { lengthScore = 5; }
else if (len >= 10) { lengthScore = 4; }
else if (len >= 8) { lengthScore = 3; }
else if (len >= 5) { lengthScore = 2; }
var re = [ null, /[a-z]/g, /[A-Z]/g, /d/g, /[!@#$%^&*()=_+-]/g];
for (var i = 1; i < re.length; i++) {
letterScore += (password.match(re[i]) || []).length * i;
}
return letterScore + lengthScore;
};
(typeof window !== 'undefined' ? window : exports).PasswordScorer = PasswordScorer;
}());
It’s pretty simple code, but here’s what’s going on: the score is made up of two sub-scores. There’s a starting score, that’s based on the length of the password, and then an additional score for each character, 1 point for each lowercase letter, 2 points for each uppercase letter, 3 points for each number, and 4 points for each symbol (from a limited set).
So, this is the code we’re going to test: we’ll randomly generate some passwords with JSCheck and make sure they get an appropriate score.
Now we’re ready to write our claims. First, head over the
JSCheck
Github page and download the jscheck.js file. I
like to run my tests in the terminal, via NodeJS, so add this
single line to the very bottom of the file:
(typeof window !== 'undefined' ? window : exports).JSC = JSC;
This won’t affect the way the file behaves in the browser at
all, but it will make it work as a module within Node. Notice that
the jscheck.js file exposes JSC as the
single global variable for the whole library. If we weren’t making
this adjustment, that’s how we’d access it.
Let’s open passwordScorerSpec.js and start
things:
JSC = require("./../vendor/jschec";).JSC;
PasswordScorer = require("./../lib/passwordScore";).PasswordScorer;
Since I’m running these tests in NodeJS, we’ll have to require the modules we want. Of course, you’ll want to make sure that paths match your file locations.
Now, we’re ready to write our first claim. Of course, we use the
JSC.claim method. This method accepts three
parameters, with an optional fourth. The first parameter is just a
string, a name for the claim. The second parameter
is called the predicate: it’s the actual testing
function. Very simply, this function should return
true if the claim is true, and false if
the claim is false. The random values that JSCheck will generate
for the test will be passed as parameters to the predicate.
But how does JSCheck know what type of random values to hand the predicate? That’s where the third parameter, the specifier comes into play. This is an array, with an item for each parameter for predicate. The items in the array specify what types to give the predicate, using JSCheck’s specifier functions. Here are a few of them:
JSC.boolean() returns either true or false.JSC.character() takes a min and max character and
returns a single character from that range. It can also take a
single character code and return that character.JSC.integer() will return a prime number. Or, pass
it a single parameter to get an integer (whole number) between 1
and the parameter, or two parameters for an integer in that
range.You get the idea. There are other specifiers, and we’ll use some now as we write our first claim.
JSC.claim("All Lowercase Password";, function (password, maxScore) {
return PasswordScorer.score(password) <= maxScore;
}, [
JSC.string(JSC.integer(10, 20), JSC.character('a', 'z')),
JSC.literal(26)
]);
Our first parameter is a name. The second is the testing
function: it receives a password and a max score, and returns true
if the score for that password is less than or equal to the max
score. Then, we have our specifier array. Our first parameter (the
password) should be a string, so we use the
JSC.string() method: it can take two parameters, the
number of characters in the string, and value for those characters.
As you can see, we’re asking for a password between 10 and 20
characters. For the value, we’re using the
JSC.characters() method to get random characters
between ‘a’ and ‘z’.
The next value is our maxScore parameter.
Sometimes, we don’t want the randomness that JSCheck offers, and
this is one of those times. That’s why there’s
JSC.literal: to pass a literal value the predicate. In
this case, we’re using 26, which should be the max score for any
all-lowercase password between 10 and 20 characters.
Now we’re ready to run the test.
Before we actually run the claim and get the report, we have to
setup the function that will receive the report. JSCheck passes the
report to a callback function of JSC.on_report.
Hence:
JSC.on_report(function (str) {
console.log(str);
});
Nothing fancy. Now, all that’s left is to call
JSC.check(). Now, we can head to our terminal and run
this:
node path/to/passwordScorerSpec.js
Behind the scenes, JSCheck runs the predicate 100 times, generating different random values each time. You should see your report printed out.
All Lowercase Passwords 100 of 100 pass 100
They all passed, but that’s not much of a report, eh? Well, if
any of our tests had failed, they would have been included in the
report. However, you can adjust the level of output with the
JSC.detail function: pass it a number between 0 and 4
(inclusive) to get anything for no output to all the test cases.
The default value is 3.
Remember how I said that JSC.claim could take a
fourth parameter? It’s called a classifier, and it
receives the same parameters that the predicate receives. Then, it
can returns a string to classify, or group, our test cases. I’ll
admit I wasn’t really sure where this would be useful until I was
creating the above example claim. See, I made a mistake in the
predicate and compared the score to the maxScore with
the <</code> operator instead of the
<= operator, so any passwords that scored 26 points
were failing. I was seeing reports that looked something like
this:
All Lowercase Passwords 96 of 100
FAIL [12] ("vqfqkqqbwkdjrvplkrx";,26)
FAIL [21] ("nhgkznldvoenhqqlfza";,26)
FAIL [62] ("eclloekuqhvnsyyuekj";,26)
FAIL [78] ("rvrkfivwtdphrhjrjis";,26)
pass 96 fail 4
It’s still entirely obvious why some tests are failing. So I added a classifier function that grouped the test cases by score: like I said, the function takes the same parameters as the predicate, and it returns a string. Every test case that gets the same string back from the classifier will be grouped together in the report.
function (password, maxScore) {
return PasswordScorer.score(password) + " points";;
}
This function should be the last parameter of our claim. Now, you’ll get a report that’s something like this:
All Lowercase Passwords 96 of 100
FAIL [4] 26 points:("illqbtiubsmrhxdwjfo";,26)
FAIL [22] 26 points:("gruvmmqjzqlcyaozgfh";,26)
FAIL [34] 26 points:("chhbevwtjvslprqczjg";,26)
FAIL [65] 26 points:("kskqdjhtonybvfewdjm";,26)
14 points: pass 8
15 points: pass 5
16 points: pass 12
18 points: pass 10
19 points: pass 12
20 points: pass 11
22 points: pass 12
23 points: pass 8
24 points: pass 10
25 points: pass 8
26 points: pass 0 fail 4
You can see how the tests are grouped by how many points the passwords are worth. Now, it’s easy to see that the only passwords that fail the tests are the passwords that score 26 points. And while the problem here was with the test, and not the code, it still shows how it can be useful to add a classifier function to your claims.
So, at the end of the day, it JSCheck worth using? Here’s what I think: it’s not something you’re necessarily going to use with every code base, but sometimes you’ll find it useful to be able to create random test cases that will rigorously test a given piece of code. When that’s what you want to do, I haven’t seen a tool better for that than JSCheck.
JSCheck has a few other options and a bunch of specifiers that we haven't reviewed in this tutorial; head over to JSCheck.og to read about those. Otherwise, I’d love to hear your thoughts about JSCheck in the comments!
In my nearly two decades as an information architect, I’ve seen my clients flush away millions upon millions of dollars on worthless, pointless, “fix it once and for all” website redesigns. All types of organizations are guilty: large government agencies, Fortune 500s, not-for-profits and (especially) institutions of higher education.
Worst of all, these offending organizations are prone to repeating the redesign process every few years like spendthrift amnesiacs. Remember what Einstein said about insanity? (It’s this, if you don’t know.) It’s as if they enjoy the sensation of failing spectacularly, publicly and expensively. Sadly, redesigns rarely solve actual problems faced by end users.
I’m frustrated because it really doesn’t have to be this way. Let’s look at why redesigns happen, and some straightforward and inexpensive ways we might avoid them.
Your users complain about your website’s confounding navigation, stale content, poor usability and other user experience failures. You bring up their gripes with the website’s owners. They listen and decide to take action. Their hearts are in the right place. But the wheels quickly come off.

Most website owners don’t know how to diagnose the problems of a large complex website. It’s just not something they were ever taught to do. So, they’re put in the unfortunate, uncomfortable position of operating like country doctors who’ve suddenly been tasked to save their patients from a virulent new pandemic. It is their responsibility, but they’re simply unprepared.

Sadly, many website owners fill this diagnostic void — or, more typically, allow it to be filled — with whatever solution sounds best. Naturally, many less-than-ethical vendors are glad to dress up their offerings as solutions to anyone with a problem — and a budget. The tools themselves (search engines, CMS’, social apps) are wonderful, but they’re still just tools — very expensive ones, at that — and not solutions to the very specific problems that an organization faces. Without proper diagnostics to guide the configuration of tools, any resulting improvements to the user experience will be almost accidental.

Sometimes design agencies are brought in to fill the diagnostic void. And while not all agencies are evil, a great many follow a business model that depends on getting their teams to bill as many hours as they can and as soon as possible. Diagnostics can slow the work down (which is why clients rarely include a diagnostic phase in their RFPs). So, many agencies move to make a quick, tangible impression (and make their clients happy) by delivering redesigns that are mostly cosmetic.
A pretty face can last only a few years, but by then the agency is long gone. Invariably, the new owner wishes to make their mark by freshening or updating the website’s look. And another agency will be more than happy to oblige. Repeat ad nauseam, and then some.
Oh, and sometimes these redesigns can be pricey. Like $18 million pricey.
See why I’m so grouchy?
Whether you’re a designer, researcher or website owner, I’ve got some good news for you: diagnostics aren’t necessarily difficult or expensive. Better yet, you’ll often find that addressing the problems you’ve diagnosed isn’t that hard.
And the best news? Small simple fixes can accomplish far more than expensive redesigns. The reason? People just care about some stuff more than they care about other stuff. A lot more. Check this out and you’ll see:

This hockey-stick-shaped curve is called a Zipf curve. (It comes from linguistics: Zipf was a linguist who liked to count words… but don’t worry about that.) Here it is in dragon form, displaying the frequency of search queries on a website. The most frequently searched queries (starting on the left) are very, very frequent. They make up the “short head.” As you move to the right (to the esoteric one-off queries in the “long tail”), query frequency drops off. A lot. And it’s a really long tail.

This is absolutely the most important thing in the universe. So, to make sure it’s absolutely clear, let’s make the same point using text:
| Query’s rank | Cumulative % | Query’s frequency | Query |
|---|---|---|---|
| 1 | 1.40% | 7,218 | campus map |
| 14 | 10.53% | 2,464 | housing |
| 42 | 20.18% | 1,351 | web enroll |
| 98 | 30.01% | 650 | computer center |
| 221 | 40.05% | 295 | msu union |
| 500 | 50.02% | 124 | hotels |
| 7,877 | 80.00% | 7 | department of surgery |
In this case, tens of thousands of unique queries are being searched for on this university website, but the first one accounts for 1.4% of all search traffic. That’s massive, considering that it’s just one query out of tens of thousands. How many short-head queries would it take to get to 10% of all search traffic? Only 14 — out of tens of thousands. The 42 most frequent queries cover over 20% of the website’s entire search traffic. About a hundred gets us to 30%. And so on.
This is very good news.
Want to improve your website’s search performance? Don’t rip out the search engine and buy a new one! Start by testing and improving the performance of the 100 most frequent queries. Or, if you don’t have the time, just the top 50. Or 10. Or 1 — test out “campus map” by actually searching for it. Does something useful and relevant come up? No? Why not? Is the content missing or mistitled or mistagged or jargony or broken? Is there some other problem? That, folks, is diagnostics. And when you do that with your website’s short head, your diagnostic efforts will go a very long way.
The news gets better: Zipf is a rule. The search queries for all websites follow a Zipf distribution.
And the news gets even jump-up-and-down-and-scream-your-head-off better: Zipf is true not only for your website’s search queries. Your content works the same way! A small subset of your website’s content does the heavy lifting. Much of the rest has little or no practical value at all. (In fact, I’ve heard a rumor that 90% of Microsoft.com’s content has never, ever been accessed. Not once. But it’s a just a rumor. And you didn’t hear it here.) Bottom line: don’t redesign all of your content — focus on the stuff that people actually need.
You’ll also see a short head when it comes to your website’s features. People need just a few of them; the rest are gravy.
And there’s more. Of all the audience types that your website serves, one or two matter far more than the others. What tasks do those audience types wish to accomplish on your website? A few are short-head tasks; the rest just aren’t that important.
As you can see, the Zipf curve is everywhere. And fortunately, the phenomenon is helpful: you can use it to prioritize your efforts to tweak and tune your website’s content, functionality, searchability, navigation and overall performance.

When you examine the short head — of your documents, your users’ tasks, their search behavior and so forth — you’ll know where to find the most important problems to solve. In effect, you can stop boiling the ocean…

… and start prioritizing your efforts to diagnose and truly solve your website’s problems.
Now, let’s put these short-head ideas together. Below is a report card for an academic website that starts with the short head of its audience:
In other words, of all the audience types this university website has, the three most important are people who might pay money to the university (applicants,) people who are paying money now (students) and people who will hopefully pay money for the rest of their lives (alumni). How do we know they’re the most important audiences? We could go by user research; for example, the analytics might suggest that these audiences generate more traffic than anyone else. Or perhaps the university’s stakeholders believe that these are the most important ones in their influence and revenue. Or some combination of both. Whatever the case, these three audiences likely swamp all other segments in importance.
Then, we would want to know the short-head tasks and information needs of each audience type. We might interview stakeholders to see what they think (column 2). And we might perform research — user interviews and search analytics, for example — to find out what users say is most important to them (column 3).
Of course, as the good folks at xkcd demonstrate, stakeholders and users don’t always see things the same way:
That’s why talking to both stakeholders and users is important. And once you’ve figured out the short head for each, you’ll need to earn your salary and, through some careful negotiation, combine your takes on each audience type’s needs. That’s what we’ve done in column 4.
Finally, in column 5, we’ve tested each task or need and evaluated how well it works. (Because it’s a university-related example, letter grades seemed appropriate.) You can do this evaluation in an expensive, statistically significant way; but really, enough research is out there to suggest that you don’t need to spend a lot of time and money on such testing. More importantly, these needs and tasks are often fairly narrow and, therefore, easy to test.
So, after testing, we can see what’s not going well. Finding information on “mentoring” is hard for applicants. And current students have a devil of a time when they “look up grades.”
Now we’re done diagnosing the problems and can begin making fixes. We can change the title of the “Paired Guidance Program” page to “Mentoring.” We can create a better landing page for the transcript application. The hard part, diagnostics, is out of the way, and we can now fix and tune our website’s performance as much as our resources allow.

These fixes are typically and wonderfully small and concrete, but because they live in the short head, they make a huge and lovely impact on the user experience — at a fraction of the cost of a typical redesign.
The tuning process itself is quite simple. It’s what we used to arrive at the report card below:

If you repeat this simple process on a regular basis — say, every month or quarter — then you can head off the entropy that causes fresh designs and fresher content to go rotten. Thus, the redesign that your organization has scheduled for two years from now can officially be canceled.
Your website’s owners ought to be happy about all this. And you should be, too: rather than tackling the project of getting your website “right” — which is impossible — you can now focus on tweaking and tuning it from here on out. So, forget redesigns, and start owning and benefiting from a process of continual improvement.

Eva-Lotta is a UX Designer and Illustrator based in London, UK where she currently works as an interaction designer at Google. Besides her daytime mission of making the web a more understandable, usable and delightful place, she regularly takes sketchnotes at all sorts of talks and conferences and recently self-published her second book. Eva-Lotta also teaches sketching workshops and is interested in (something she calls) visual improvisation. Exploring the parallels between sketching and improvisation, she experiments with the principles from her theater improvisation practice to inspire visual work.
(al)
© Louis Rosenfeld for Smashing Magazine, 2012.
Link
Scroll down for today's pictures & links.
Mobile Home, Flying Edition
Four Pratt & Whitney engines propel this "flying RV boat" to
recreational bliss in the clouds. Even if this is not real,
somebody should definitely step up to the challenge and build this
thing!
Link
Today's pictures & links:
A Rainbow at Mt. Rundle, Banff, Canada
(image credit:
Mark Thomas)
This is just one of many spectacular photos taken by Mark Thomas on the trip from Calgary to Vancouver
(read the travelogue and see photos at Summit Post). Since we are based near Banff
National Park ourselves, we are very aware of the Canadian
Rockies's abundant natural wonders. With Mark Thomas' kind
permission, here are more shots of the area:
Mt. Biddle & Lake McArthur with its vibrant color:
(image credit:
Mark Thomas)
Some nameless, beautiful Alpine ledges:
(image credit:
Mark Thomas)
Climbing even higher, here is a superb view from the Panorama
Ridge:
(image credit:
Mark Thomas)
------------
Messier Deep Sky Object Number 78
Well, climbing even higher... we see a shimmering nebula and dense
clouds of cosmic dust in the Orion constellation. This NGC 2068
nebula near the famous Orion's belt is often called "Reflection
Nebula" because the dense dust clouds (which give birth to new
stars) reflect the starlight around them. This beautiful pale blue
glow is seen in visible light and hides even more deep objects
inside (more info).
(image credit: ESO/APEX
T. Stanke/Igor Chekalin/Digitized Sky Survey 2)
We flipped the original photo on the side to better fit the format
of our page (after all there is no up and down in space). See the
full version here.
------------
Manhattan: Before and After
One picture is worth a million words, especially in this case (part
of the Mannahatta Project, a digital recreation of Manhattan circa
1609):
(images via)
While researching this topic, we also came by other great tracked
vehicles; some of them snowmobiles, perfect for frozen Canadian
landscapes. Here is a B71 snowmobile for "Perfection Ice Cream"
(left), and other snowmobiles by Joseph-Armand Bombardier, whose
dream was "to build a little machine that glides over the snow" -
the dream that resulted in the machine we now call the
snowmobile:
(images via
1, 2)
------------
Cute Little Manta Ray (Wants to Say Something)
(original unknown)
------------
Abandoned Cathedral in Snow
As you remember, we had the article Exploring the Ruins of Gary, Indiana. Today the
photographer David Tribby announces the giveaway of his spectacular
print "City Methodist Church, Gary Indiana after the 2011
blizzard":
(image credit:
David Tribby)
Full details of the giveaway are here, also see the full version.
------------
A rare fisheye Nikkor: the world’s most extreme
wide-angle
This is a rare 1970 fisheye Nikkor 6mm f/2.8 lens (on sale at
Gray’s of Westminster in London, UK) that offers an angle of view
of 220º, and comes with a price tag of $160,000 USD.
(images credit:
Tony Hurst)
The lens uses 12 glass elements in nine groups, and weighs a
staggering 11.46 pounds! - more info.
------------
The following is a short round-up of the best from our Facebook
stream (which we update every day with unique material, not
available on DRB otherwise):
Something unmentionable happened to this Bentley - more info:
(image via)
This cat has a lot to say:
(original unknown)
"Goodness gracious me!" -
(image credit:
Sergey Zhiboedov)
Some grassroots ingenuity regarding washing the dishes... and a
knitter who was bored? -
Owl in Hiding! -
(original unknown)
A tooth monster! (definitely NOT a fairy) -
Some assorted alpacas, looking like a 1980s rock group lineup:
(photo by Kerstin Joensson/AP)
This balancing rock is a tall basalt stack located on the coasts of
Digby County (part of North Mountain and cliffs along St. Mary’s
Bay and the Bay of Fundy in Nova Scotia) -
Nikita Khrushchev in 1959, showing Communist Party members of the
Politburo the benefits of growing corn all over Russia (even in the
cold climate areas):
"After a trip to Iowa in 1959, he became a huge enthusiast of corn
and decided to introduce it to his country", a doomed obsession
that would carry a huge cost to the Soviet Union in the years to
come.
------------
Almost Unexplainable:
(images via 1,
2, 3)
Ngc488 in Pisces resembles an onion cut in half, or some cosmic
"onion rings":
(images via)
------------
Bored at work? Then try assembling these structures:
(image credit: Knormy)
or this -
(sent in by Jay Gairson)
------------
"Welcome to Weirdsville" book by one of the DRB contributing
writers, author M. Christian
Check out this compendium of the bizarre facts and marvelous
(mostly true) stories: order the Kindle edition from Amazon, and the print version will be in the
stores soon.
Many of the chapters of this book were originally published here on
Dark Roasted Blend (with additional material and illustrations), so
much of it will be familiar to our long-time readers - but for
those new to wonderfully tongue-in-cheek erudite style of M.
Christian we recommend to give this book a try.
------------
Did you hear about the Steampunk World's Fair?
It will take place May 18-20 in Piscataway, NJ. Featuring the
extraordinary Steampunk Circus, the Carnival
Obscura, absinthe tasting... plus Dr.
Grimm himself is expected to attend.
Besides the "Lost Treasures of Steampunk" (a program promoting
overlooked works by steampunk artists) to look forward to, this
year’s Steampunk World’s Fair promises to be grand: over 3,000
steampunk enthusiasts come to the World’s Fair each year along with
hundreds of performers, artisans, writers, and creators from across
the country - more info.
------------
Some Reviews: Monkeys and Energy
Not that monkeys need any additional energy, but we do. Here at
Dark Roasted Blend we get some commercial product samples from time
to time, and here is a couple that "hit the sweet spot":
Funky
Monkey Snacks boast great taste and very unique process of
"freeze-drying full slices and pieces of real fruit to lock in
taste, smell and nutrients of freshly picked fruit, while creating
a fun and satisfying crunch". Well, these were lovely to crunch and
snack on.
And then these is a new energy drink concept in town - MIO Liquid Water
Enhancer. These droplets of extremely concentrated energy stuff
- zero calories, zero sugar and six flavours - come in very
cool-looking Mio bottles (one such bottle can turn into energy
drink full twenty four 16oz bottles of water):
------------
A couple of weird t-shirts
------------
Can you spot Keanu Reeves?
Try it at home.
------------
A Perfectionist's Routine:
READ
THE PREVIOUS ISSUE ->
READ ALL BISCOTTI ISSUES HERE ->
Make
sure to check our daily updates on Facebook!
|
This tutorial will help you prepare a Magento install for high traffic, better load times, and simpler ongoing site management. Ready?
You can download the finished code for this tutorial, or launch the “magento-basic” Quickstart from your Pagoda Box account to test a working site.
Fair Warning: This tutorial may change your life. Pagoda Box is not traditional hosting. The teachings in this article will not only help scale Magento, but it alos lays the groundwork for a progressive development-to-production workflow.
Note: If you already use Git, you can skip this section. If not, the guide Setting Up Git provides specific instructions for creating an SSH Key, as well as links for downloading and installing Git (also below).
While it is possible to use just SFTP on Pagoda Box, the officially recommended (and most efficient) workflow integrates Git into your daily development. Git enables features like collaboration, uniform code distribution, deploys, deploy history and rolling back code. While most of these features are available to FTP users, using Git makes integration seamless.
If you want to fully take advantage of Pagoda Box, download Git, and Learn the Basics. Depending on your operating system, set up may vary slightly. Regardless of your OS, the commands are identical once Git is installed.
Using Git to manage collaboration and version control may involve a brief learning curve. However, there are generally only three commands we’ll use on an ongoing basis to commit changes locally, then deploy to Pagoda Box:
git add . – Adds local files to your
repositorygit commit -m "some message about what you've
done" – Commits your changesgit push pagoda --all – Pushes changes to Pagoda
Box Repository (auto-deployed by default)We’ll use these later.
*
/
/
+_/ / / | _+
||*|||*||
|+||*||+|
/
+_/ / / | _+
||*|||*||
|+||*||+|
____ _ ____ ___ ____ _ ____ _____ __
| _ / / ___|/ _ | _ / | __ ) / _ / /
| |_) / _ | | _| | | | | | |/ _ | _ | | | /
| __/ ___ |_| | |_| | |_| / ___ | |_) | |_| /
|_| /_/ _____|___/|____/_/ _____/ ___/_/_
Welcome To Your Pagoda Box Terminal Client.
-----------------------------------------------
-----------------------------------------
---------------------------------
Enjoy.
Pagoda Box provides a Terminal Client that lets you clone, create, deploy, destroy, rename and rollback an application from the command line. Later in this tutorial, we’ll use the client to create a secure tunnel to the live Magento database with Sequel Pro (the process is similar for other database managment tools like HeidiSQL).
The Pagoda Box Terminal Client is a rubygem, so installation is pretty simple. First off, Ruby needs to be installed. Installation is different for each operating system.
Once Ruby is installed, simply run the following command to install the Pagoda RubyGem:
On Mac or Linux:
$ sudo gem install pagoda
On Windows:
$ gem install pagoda
Then, to verify you have the Pagoda Gem installed properly, run:
$ pagoda list
If this is the first time you’ve used the Gem, it will ask for your Pagoda Box Username and Password. After you’ve entered those, expect to see a list of your Pagoda Box applications. If you haven’t created any applications, the list will be blank.
If you get an error, it’s most likely invalid credentials. You
can verify or change which credentials the gem uses by editing the
file located on your local computer at ~/.pagodarc.
Make sure to exactly match the credentials you use in your Pagoda
Box account. (Note: this is a hidden file, so you’ll need to enable
hidden files or open via the terminal. Also note that the file
stores your credentials twice, so edit both if needed.)
Note: Skip this step if you already have a working local Magento install.
If you don’t have it already, ensure you are using local webserver and database management software. There are several options available, depending on your operating system. A common option for Mac is MAMP, or WAMP for Windows. Both are free and easily set up.
Once your local development environment is set up, go ahead and download Magento, then follow the official guide to install Magento locally.
Feel free to use Magento’s auto install script to set up the application in your local environment. However, due to Pagoda Box’s distributed cloud architecture, the script will not install Magento directly in your production environment. The Pagoda Box workflow and architecture requires you to make code modifications locally, commit, then deploy to production. This workflow accommodates collaboration and development > staging > production best practices.

Note: On Pagoda Box, a YAML Boxfile can be included in the root of your code repository. While the Boxfile is optional, it does provide advanced features, like manipulating your hosted environment on each deploy. We’ll use the Boxfile extensively in this Tutorial to simplify tasks, and to make the respository reusable on Pagoda Box.
Create a file named “Boxfile” in the root of your local Magento installation, then copy the following into your Boxfile (explanation below):
web1:
name: mag-app
shared_writable_dirs:
- media
- var
php_version: 5.3.8
php_extensions:
- pdo_mysql
- mysql
- simplexml
- mcrypt
- hash
- gd
- dom
- iconv
- curl
- soap
This Boxfile serves several purposes. First, it creates a
web1 component, then names it
mag-app.
Second, the Boxfile identifies media and
var as shared writable directories. This allows users
to upload images, video, and other media to a distributed Magento
cloud site without instances writing themselves out of sync.
When a directory is marked as writable, the contents are no longer deployed to Pagoda Box from your local repository. Any time local files need to be deployed to these directories, they must be manually copied via SSH or SFTP. You may also use SSH/SFTP to transfer files from Pagoda Box to your local machine as needed.
The Boxfile also declares which PHP version and extensions will be included in your web instances as they deploy. This way, both the environment and the application are versioned together, so rolling back to a previous deploy includes the correct PHP version and extensions. The list of PHP extensions in this Boxfile was taken from Magento’s official system requirements.
Tip: Once Git is installed in your local environment, use the
.gitignorefile to ignore the writable directories specified in your Boxfile. Identifying these directories inside the.gitignorefile helps reduce the size of your repo, and your deploy time. In addition to the writable directories, you can also add thedownloaderdirectory to the.gitignorefile, since it’s used locally, and not on Pagoda Box.
Once you’ve installed Git and the Terminal Client, configured the Boxfile and finalized your local source code, you’re ready to launch on Pagoda Box.
If you don’t already have one, create a free Pagoda Box account. You will not need to enter a credit card to install Magento for testing.

If you have not already done so, follow this guide to Add an SSH Key in your Pagoda Box Admin panel. The guide will provide specific instructions for setting up an SSH Key on either Mac or Windows.
Once you’ve created a Pagoda Box account and set up an SSH Key, go to the Home Page in your new account and click the “New Application” button to create a new application.
Note: This tutorial names our sample application “magento”. The app name is also used for the Pagoda Box repository, the subdomain for the freshly deployed application (magento.pagodabox.com), and the username in SFTP mode. Replace “magento” with “your-app-name-here” where appropriate throughout the remainder of this tutorial.

Next, choose from the 3 options to launch your Magento site. Since you already have a customized version of Magento locally, select ‘Empty Repo’ to deploy using SFTP or Git, name your application, and click “Launch Application”.

You’ll be asked to select your preferred deployment method (Git or SFTP). Click on your preference, and follow the instrutions on-screen.
You can copy and paste the on-screen instructions from the Pagoda Box dashboard to your terminal after using Terminal to change directory (cd) to the root of your project.

The pasted commands do the following:
git init – Initialize your Magento project as a
Git Repositorygit add . – Add all files from the project to the
repogit commit -m 'your commit message' – Commit files
with a message that allows you to quickly scan deploy history in
the future, in case you need to revert or modify changesgit remote add pagoda
git@git.pagodabox.com:magento.git – Add Pagoda Box as a
remote (the specific git url for your application appears on both
this screen, and in your app dashboardgit push pagoda --all – Push your local code to
the Pagoda Box remote repository. As long as you’re on the “master”
branch (which is the default), Pagoda Box will automatically deploy
your code, and carry out the instructions we set in the Boxfile.
Auto-deploy can be turned off in the Admin dashboard, or configured
to deploy automatically from a Git branch other than Master.If you opted for SFTP, Pagoda Box will guide you through
establishing credentials and a password. Connect via SFTP to Pagoda
Box, and upload your Magento source code in the code
directory.

There are two ways to create a database on Pagoda Box. Each has benefits, explained below:
The Boxfile will automatically create a database component on
deploy, as long as that component (db1,
db2, etc.) doesn’t already exist. Declaring the
database in the Boxfile saves a bit of time now, and makes
deploying multiple Magento sites from a standardized code base much
simpler in the future. (Note: Only cloud DBs can be deployed from
the Boxfile. If you need a larger, dedicated or redundant database,
see the Dashboard option later in this Step.) Add the following to
your Boxfile:
db1: name: mag-db type: mysql
Your updated Boxfile should look like this:
web1:
name: mag-app
shared_writable_dirs:
- media
- var
php_version: 5.3.8
php_extensions:
- pdo_mysql
- mysql
- simplexml
- mcrypt
- hash
- gd
- dom
- iconv
- curl
- soap
db1:
name: mag-db
type: mysql
Then commit changes to the updated file and push changes to Pagoda Box:
$ git commit -m "pagoda config" $ git push pagoda --all
You can also create a database from the Pagoda Box Dashboard. This is where you add a larger, dedicated or redundant database.
First, click “Add Database” in the Dashboard.

Pagoda Box will step through a series of screens to configure your database, depending on your choices. If you’ve chosen the Dedicated option, you will be asked to size your database as follows:

Cloud databases usually deploy within minutes. If you chosen Dedicated, don’t get impatient. You may wait for up to 90 minutes for a big server to be provisioned to your specifications.
Your database automatically generates credentials when it’s created on Pagoda Box. We’ll use those credentials to configure Magento in production.
However, since Magento will be used in both local environments and in production, we need to supply different database credentials for each. We’ll use Deploy Hooks in the Boxfile to simplify this process by executing scripts or commands during deploy.
In the case of Magento, we’ll swap the local.xml
file upon deploy. That way, without manually switching credentials,
the app/etc/local.xml file will automatically have
local database credentials in development, but production database
credentials on Pagoda Box.
First, create a directory named pagoda in root,
then copy Magento’s app/etc/local.xml to the new
directory.
Next, edit local.xml to include Pagoda Box database
credentials from your account dashboard. Note that Pagoda Box uses
3 levels of authentication, so that even if your credentials are
compromised, other users cannot access your database.

Add the following into your Boxfile, under the web1
section to create the Deploy Hook.
after_build: "mv pagoda/local.xml app/etc/local.xml"
Your updated Boxfile should look like this:
web1:
name: mag-app
shared_writable_dirs:
- media
- var
php_version: 5.3.8
php_extensions:
- pdo_mysql
- mysql
- simplexml
- mcrypt
- hash
- gd
- dom
- iconv
- curl
- soap
after_build:
- "mv pagoda/local.xml app/etc/local.xml"
db1:
name: mag-db
type: mysql
Then commit changes and push to Pagoda Box:
$ git add . $ git commit -m "pagoda config" $ git push pagoda --all
With the same tools you use to manage a local database, you can securely manage a live database on Pagoda Box. We’ll use Sequel Pro for this example, but the process is similar for tools like HeidiSQL.
When the Magento install script ran locally, it created several tables in the local database. Those tables need to be migrated to production.
First, export your local database using your database manager: File > Export.
Now choose a location, and Save the export.
Now establish a database tunnel. Using the Pagoda Box Terminal Client, specify the app whose database you are trying to access, and the ID of the database component (e.g. db1), as in this example:
$ pagoda -a magento tunnel -c db1 --OR-- $ pagoda --app=magento tunnel --component=db1
Once the tunnel is established, use Sequel Pro (or similar) to connect to the database using the Host and Port provided by the Pagoda Terminal Client…

And the username and password in your Pagoda database credentials. These were automatically created with your database, and may be found in the Pagoda Box Dashboard under the database component (see example in Step 8).
Next, import your database into production using Sequel Pro (or similar): File > Import. Now select the database export file, and Open.
Finally, since we ran the install script locally, it’s necessary
to adjust the base url directly in the database before browsing the
site. While you are still connected to the Pagoda Box database in
Sequel Pro, navigate/filter to the core_config_data
table and edit the value for the following paths:
web/unsecure/base_url web/secure/base_url
The values for each should look something like this:

To protect your IPs from being flagged as spam, Pagoda Box uses the SMTP mail protocol to send email via third party mail provider SMTP credentials. In English, that means you need a company (like Gmail) that provides mail services.
Regardless of which mail provider you choose, enter account credentials from that provider in your Pagoda Box dashboard. It should look something like this:

A few recurring tasks in Magento (e.g. sending newsletters, log
cleaning, customer notifications, etc.) need to happen
periodically. The cron.php file located in Magento’s
root will trigger these tasks. We’ll set up a Cron Job in the
Pagoda Box admin panel to run cron.php every 15
minutes. (Note: To configure Magento specific tasks, see their
Official Guide.)
Cron Jobs can be added or updated via the Boxfile, then deployed
to Pagoda Box. To schedule a task at 15 minute intervals, add the
following to your Boxfile under the web1: component
(change the “magento” to point to your own app name /
subdomain):
cron:
- "*/15 * * * *": "curl -s -o /dev/null http://magento.pagodabox.com/cron.php"
Your updated Boxfile should look like this:
web1:
name: mag-app
shared_writable_dirs:
- media
- var
php_version: 5.3.8
php_extensions:
- pdo_mysql
- mysql
- simplexml
- mcrypt
- hash
- gd
- dom
- iconv
- curl
- soap
after_build:
- "mv pagoda/local.xml app/etc/local.xml"
cron:
- "*/15 * * * *": "curl -s -o /dev/null http://magento.pagodabox.com/cron.php"
db1:
name: mag-db
type: mysql
In the Pagoda Box admin panel under the Cron tab, add the following (change the “magento” to point to your own app name):
Command: curl -s -o /dev/null
http://magento.pagodabox.com/cron.php
Schedule: */15 * * * *
It should look like this:

You’ve already gotten the heavy lifting out of the way. Your
Magento application is scalable, and changes are easily deployed
across all instances with $ git push pagoda --all.
In the follow-up article, we’ll optimize Magento, add a Redis cache, SSL and Domain aliases, then scale the application for benchmarking and production. See you soon!
The idea behind this project was to produce a consistent set of buttons that could be used for the range of social actions frequently taken in Web applications. These actions are often important goals for users, such as connecting third-party accounts or sharing content to third-party platforms, so their appearance has to be attractive and clear.
The standard buttons provided by third parties (such as Facebook, Twitter and SoundCloud) vary in size, style and interactivity. A consistent button set could reduce a lot of that visual noise and inconsistency. Furthermore, having it in CSS format means that changing the text for certain actions would be a breeze for developers, and it also allows administrators of non-English websites to translate labels into their native languages.
The button set was designed from the beginning to require no extra markup, and the elements used are entirely the choice of the (semantically considerate) designer. All buttons are fully scalable and customizable, and they degrade gracefully on older browsers, although the aesthetics in IE 6 and 7 are admittedly inferior to image-based alternatives.
No raster images or sprites were used. Instead, vector icons were inserted using a custom font file, an @font-face rule and pseudo elements. For more information, John Hicks has an informative write-up on this technique.
This button set is free to use and extend, personally or commercially. No attribution is required.
Screenshots of each set are below. Or view a live demo.
The button set was designed with simplicity and semantics in
mind. No unnecessary or extra markup is required, and button types
are called through class names. Call the zocial.css
file on your page (make sure the font files and the
zocial.css file are in the same directory). Buttons
can be displayed with the following markup:
<button class="zocial facebook">Sign in with Facebook</button>
The parent element is agnostic, so you may use
<a>, <div> or
<button>, but it must contain a child
. [Thanks, Lea!]<span> element
To choose buttons from the set, include the appropriate class
name for the service, such as .dropbox,
.linkedin or .twitter.
Icon versions can be displayed by including an extra
.icon class, as follows:
<a class="zocial quora icon">Follow me on Quora</a>
More code samples are available on the Zocial page.
(al)
© Sam Collins for Smashing Magazine, 2012.
SDP hakee verkkoviestinnän
ammattilaista toteuttamaan SDP:n päivittäis- ja kampanjaviestintää.
Keskeisenä osana tässä toimitustyössä on osallistuminen
sisällöntuotantoon myös sosiaalisessa mediassa. Hakijalta
edellytetäänkin kokemusta mm. verkkosisällön tuottajan roolista ja
sosiaalisen median hyödyntämisestä.
“Tehtävän menestyksekäs hoitaminen edellyttää kokemusta toimittajan ja/tai verkkosisällön tuottajan roolista sekä sosiaalisen median hyödyntämisestä. Osaat myös muokata faktat helposti hyödynnettävään sekä jaettavaan muotoon. Sinulla on kokemusta lehden ja verkkojulkaisujen tekemisestä ja/tai markkinointikampanjoista sekä kampanjaviestinnästä.”
Puolueiden viestintäkoneisto lieneekin melko monimuotoinen paikka tällä hetkellä. Kohdeyleisöjen odotukset vaihtelevat laidasta laitaan, joten kanavien monimuotoisuus lienee todellisuutta vielä pitkään.
“Sinulta löytyy myös graafista silmää ja hallitset yleisimmät taitto-, kuvankäsittely- sekä editointiohjelmat. Sosialidemokratian ja järjestöalan tuntemus sekä englannin ja ruotsin kielen taito katsotaan vahvuudeksi. Työehdot määräytyvät Järjestötoimitsijain Liiton JTL ry. työehtosopimuksen mukaisesti ja palkka on n. 3700 e/kk.”
>> Katso ilmoitus: Verkkoviestinnän ammattilainen/toimittaja
Editor’s Note: This post is the first in the new Smashing Daily series on Smashing Magazine, where we highlight items to help you stay on the top of what’s going on in the industry. Vasilis van Gemert will carefully pick the most interesting discussions, tools, techniques and articles that were published recently and present them in a nice compact overview.
Vasilis goes through dozens of RSS feeds and hundreds of tweets so that you don’t have to. Do you find the new series interesting? What would you like to have? And what wouldn’t you like to see? Let us know! We’d love to hear your feedback in the comments!
A couple of words from Vasilis himself:
“Years ago I started collecting links, and once a week I would write an email to my colleagues with a small introduction to every link. Later on I decided that more people than just my colleagues might benefit from this collection, so I decided to publish everything on The Daily Nerd.
“Last November, during the Fronteers conference in Amsterdam, Lea Verou convinced me to start writing in English; up until then, I wrote my comments in Dutch. More and more people started following me, and I think that’s a good thing; I believe more talented people than me should know the things I know. By more talented people, I of course mean you, the reader, so you can understand just how excited I was when Vitaly Friedman asked me if I wanted to start publishing the Daily Nerd on Smashing Magazine. So, here we are, the first episode of the Smashing Daily! I hope you like it!”
Your local mobile device lab Jeremy Keith started an open local mobile device lab in Brighton, and he urges you to do the same in your home town.
Web font performance: Weighing @font-face options and alternatives An important part of design and UX is performance, so when you decide to use a Web font, you should definitely know what the negative impact that choice might have on your users. Here’s an excellent in-depth article about font performance. Yes, you should definitely read it (and the comments, too, because they’re actually quite good).
Miscellany #7,” Shady Characters Here’s a short post by Keith Houston, with news and thoughts about unusual characters. A pleasure to read, like everything else on his blog.
TypeStacks: Instant font stacks based on your font Here’s a nice tool that suggests a font stack based on your chosen font. It knows the fonts served by TypeKit, although it doesn’t seem to know too many Google Fonts. Still, a very handy tool.
Let’s Get Physical (Units) There are a few occasions when we’d love to use physical units (such as cm and in), but unfortunately these units don’t work as expected in CSS. Boris Smus has written an extensive article about these units, how they should work, why we want them and why they work the way they work.
Cutting the Mustard The BBC is working on a responsive news website, and it is sharing everything it finds out, which is extremely useful. In this article Tom Maslen explains how the BBC manages browser support. An absolute must read for anybody who is struggling with the growing complexity of browser support. This solution (or something similar) should be implemented everywhere.
H5BP Here’s an overview of projects related to the HTML5 Boilerplate. Some excellent stuff is in there, but before you start using everything in there, remember the excellent advice of Rachel Andrew: “Stop solving problems you don’t yet have.”
html5shiv and Serving Content From Code Repositories Never just link to scripts hosted on other domains, because you won’t always get the advantages, such as caching and Gzip. This is explained in detail in this excellent article. Yes, you should definitely read it.
Thinking Async Loading an external JavaScript file can block the rest of the page from loading, which of course is a major performance and usability problem. The solution is to load scripts asynchronously, and Chris Coyier shows us ways to do that, extensively as always.
Experience Design Is the Future of Mobile Payments “Holistic” means something like “complete.” So, Perry Chan argues that a “complete” user experience is the future of mobile payments. I actually think that right now, in the short run, whatever the future, the things we have right now are just terrible. Anything would less painful (at least here in the Netherlands). (I also think the future of UX on the Web is bigger fonts — much bigger).
Learn CSS
selectors interactively
CSS selectors can be pretty hard to understand, especially the
difference between nth-child and
nth-of-type. There are many tools to visualize the
difference, and this is another one by Ben
Howdle.
Allen Tan on highlighting and focus,” Readmill Blog My father always scribbles annotations in the margins of his paper books. He’s probably been doing this for more than 50 years now, and if somehow we could assemble these annotations, it would be an incredibly interesting and useful database. But as it is, it’s pretty useless. Allen Tan writes about this and more in this article on modern digital reading.
Browser Support If, for whatever reason, you don’t like any of the tools or websites out there that tell you what browsers support what CSS feature, then this tool might be the one you’re looking for. I still prefer When Can I Use… or Mozilla Developer Network Docs, though.
Stamen Your app needs a map, but you want something other than boring old Google Maps? You could try OpenStreetMap with one of these beautiful map tiles.
Browser Support? Forget It! What does “browser support” mean exactly? Some think it means pixel perfection for a predefined set of browsers. According to David Bushell, it means something else. This is a good read for people (or clients) who struggle with the ever-expanding browser landscape.
The
id Attribute Got More classy in
HTML5
One of the easy ways to get a somewhat unique ID is by using the
UNIX epoch
time, which generates a string like 1336984564.
The problem is that in HTML, an ID had to begin with a letter.
Mathias Bynens tells us if this is still the case
in HTML5.
Autofill City and State From Zip Code With Ziptastic Filling out forms is a pain in the butt, especially on devices without a traditional keyboard. You should be asking users for as little information as possible. If there were a way to make things easier, you should probably do it. For instance, you could prefill parts of an address when the user enters their ZIP code. Chris Coyier shows us what a flow like that could look like.
CSS Layout Gets Smarter With calc()
A thing we needed desperately before being able to use
box-sizing: border-box was the ability to mix
different CSS units. There are still some use cases for this,
though, and luckily more and more browsers are supporting the
calc() property. Here’s how it works.
The Origin
of the <blink> Tag
Here’s the true story behind the blink tag by the guy
who came up with the idea, Louis J. Montulli II. A
nice anecdote on early browser history.
mr. div Of course, you could use a simple Web technology like canvas or WebGL to generate beautiful animations, but why do it the easy way when you could use the ever-amazing animated GIF? Here’s a great Tumblr blog to follow if you’re looking for some random fantastic 4-D inspiration.
Do you like this new series? What would you like to see in it? Please provide some feedback, and let us know what you think!
Do You Think That the New Smashing Daily Series Is a Good Idea?
(al) (vf) (il)
© Smashing Editorial for Smashing Magazine, 2012.
As Tuts+ Premium continues to sky-rocket, our ability to post better, more frequent, content has improved dramatically as well. This week, we have a variety of fun new things available to members!

In this fifteen-episode course, you’ll learn how to take advantage of that scary app you never touch: Terminal! We’ll begin with the obligatory “hello world” command, and work our way up to advanced usage.

Admit it: you say that you test your JavaScript, but, in reality, you…don’t. That’s okay; the idea of testing JavaScript is a relatively new thing. And unfortunately, there aren’t too many “hold your hand” resources for getting up and running. Well, that all changes with this course. We start from scratch, and slowly work our way up the testing chain.
Along the way, we’ll take advantage of the fantastic Jasmine BDD (Behavior-Driven Development) framework to make our tests as readable as possible. Upon completion of the course, you’ll not only have a robust test suite at your fingertips, but your tests will also make for fantastic documentation!

Other than Internet Explorer, what is the most challenging part of your job? Did you answer clients? If so, this eBook, by Paul Boag, is for you. Discover how to keep your clients happy, maintain your own sanity and produce the most effective websites you have ever built, resulting in happier clients, better websites, and improved job satisfaction.

‘Building Websites for Return on Investment’ uncovers the secrets of sites that successfully generate real return on investment. This book will enable you to transform your website from an expense to a measurable source of income.

For those who haven’t yet had the chance to dig into CoffeeScript, this article will get you up and running in no time!
Nothing above pique your interest? That’s okay; we have plenty of amazing new content on the near horizon, including the following courses:
Already a member? What requests do you have? Haven’t signed up yet? Well now’s the perfect time!
"DRB Pic of the Day"
Link
Lovely Steampunk / Art Nouveau Ring
Fantastic, sophisticated ring, designed by Sergey Zhiboedov - it's
inspired by the antique Greek architecture and true classic style,
and includes 14k gold figures of the Atlant (male) and the Caryatid
(female) giants supporting an amazing 9mm freshwater pearl:
(image credit:
Sergey Zhiboedov)
And... we need more info about these images:
Yet another very narrow house in Japan has been found, an addition
to our
Narrow Buildings in Japan article:
(image via)
This image was sent to us with the caption "Landscaping and Garden
Design in Dublin", but we can not find additional info:
|
I had thought terms like “intellectual property” and “intellectual theft” were of fairly recent provenance, so my eye was caught by the latter’s use in a headline of a 1930 edition of the US trade journal The American Printer.
The article it headed proved to be equally intriguing, a response by the president of American Type Founders (ATF) to a June 1929 article in the German journal Gebrauchsgraphik by the designer Rudolf Koch, calling the ATF a “highway robber of German intellectual property.” At issue was a typeface marketed by the ATF earlier in 1929 called Rivoli.
Koch and the German type foundry Klingspor asserted that Rivoli was no more than a copy of Koch’s 1922 design of Koch Antiqua, also later known as Locarno and released in the US as Eve. Klingspor had already taken legal action for piracy against the Viennese foundry Karl Brendler und Sohne for its lookalike Radio Antiqua but with no success.
Part of the sample of Wyss’ script offered by the ATF to back
its claim that Koch Antiqua was not its designer’s intellectual
property. Neither of the two styles of “g” resemble Koch’s,
however, to take just one example.
Koch Antiqua, and uppercase letters of the italic.
Klingspor lost that case, the ATF argued, because far from Koch Antiqua being Koch’s or German intellectual property, both it and the Austrian face were based on the Lombardic penmanship of the Swiss calligrapher Urbanus Wyss, in particular from his 1549 book Libellus Valde Doctus. Klingspor could not claim theft of a design that was not its to begin with.
Whatever the truth of this, the most striking part of the ATF’s broadside was its free admission that the similarity between Rivoli and Koch Antiqua/Eve, far from being accidental, was quite deliberate, Rivoli having been created and released both as a spoiler for the popular Eve and as a “reprisal” face. Klingspor was partially owned by Stempel, whose 1925 catalogue contained what the ATF claimed were “confessedly” fourteen type series of US origin, including what they deemed pirated versions of their own designs.
The ATF’s comparison of the faces that accompanied its article,
but not the truth, says David Pankow. What was purported to be
Wyss’ script was, in fact, Brendler and Sohne’s Radio Antiqua,
printed heavily on soft paper.
The ATF-Koch-Stempel face-off was part of a savage turf war fought by a company to defend its commercial position, with—arguably, only a decade after a World War—some national antagonism thrown in. (For the full story, see David Pankow’s “A Face by Any Other Name Is Still My Face: A Tale of Type Piracy” in Printing History New York, 1998, page 37.) The ATF remained relatively conservative in its designs, whereas on its own doorstep the New York-based Continental Typefounders’ Association was importing type in which was enshrined the latest European stylistic developments. The acerbity of the language on both sides was unrestrained, and it was exacerbated by the ATF’s suspicions that Continental was involved, too, stoking the fires of the argument.
Type design is a business that has long been bedevilled by piracy and plagiarism (conscious or not), licensing issues and scant or no legal protection for intellectual property. Some of the problems stem from the nature of the craft itself. Although, in theory, the number of ways you can position the points of, say, the capital “A” are myriad, the demands of legibility, style and fashion radically reduce the options, and alphabet designs all use the same raw material.
As designer Dave Farey described himself, facetiously but with an undercurrent of truth, “Nothing I have done is original. It’s all based on the 26 letters of the alphabet and the Arabic numerals.” Add to this the revivals and redrawings of classic faces, and the similarities are unavoidable. Type design is an art that is constantly echoing and alluding. Most people who work in the graphic arts are, in a big part of their design psyche, fans. We were probably inspired to get started in the first place by seeing other people’s work that we absolutely love. It’s unavoidable that some of that DNA will crop up or be used consciously in our own work. In the case of type revivals, you can at least credit your source in the type’s name; as designer Nick Shinn says on Typophile, “plagiarism means copying without recognition of the source.”
In today’s digital environment, do any of the attitudes and practices that marked the ATF quarrel persist? I asked Phil Garnham of London’s Fontsmith if he regards other font companies as rivals:
“I think there is definitely a healthy and friendly rivalry between today’s independent digital foundries. Over the past few years, as designers have become more aware of the power of type in branding, particularly the possibilities of bespoke type and with the boom in type design education at Reading University and Type Media at the Hague, fresh competition is popping up on a monthly basis, which is a great thing for type design. It keeps us all on our toes and looking for new possibilities within our beloved alphabets.”
And spoilers? Phil feels the tactic might still be out there, but for his own part, like musicians who consciously don’t listen to other people’s music when writing and recording, he tries not to look too much at other work: “I think that it keeps me detached from other people’s ideas, and allows me to pursue mine, free from any subconscious involvement.”
But even then, you can find that what you’ve done looks like something else. “Arguably, I think there are many designers tripping up in this way, even with the best intentions. I’ve been in this awkward position myself. You have to explore new proportions and alternative letterforms so you can bring something new to the market.”
Square leg: Horatio with its restyled “R” in the Letraset
catalogue, available in three weights.
How close have people steered consciously? Dave Farey recalls from his time working for Letraset that among a selection of faces presented to the committee for inclusion in the dry transfer giant’s range was Harry, a design owned by the Visual Graphics Corporation (VGC). The committee loved it, but unfortunately permission hadn’t yet been obtained, and VGC refused. So Letraset produced Horatio. “I think the only thing we changed was the leg of the uppercase R,” Dave recalls, adding candidly, “Ours was worse.”
Heldustry, from the 1983 Compugraphic Type catalogue.
Clues could even be gleaned from the font names—or not. Customers requesting Helvetica from photosetting companies of the 1980s that used the Compugraphic type library might have been told, “We don’t have Helvetica, but we do have Heldustry,” which looked… well, similar. The catalogue that digital company Bitstream produced at the start of the 1990s was helpful to customers unable to find familiar names: its Staccato 222, for instance, was the “Bitstream version of Mistral”; “Lapidary 333 was the Bitstream version of Perpetua”; Venetian 301 the “Bitstream version of Centaur.”
Staccato, from the Bitstream catalogue, early 1990s.
Memphis, seen here in extra bold weight, and Stymie Bold.
Memphis was designed by Emil Weiss.
1931 saw ATF squaring off with Stempel again, countering its Memphis slab serif with Stymie, the name being golf lingo for blocking your opponent’s line of play. ATF’s prolific Morris Fuller Benton based Stymie on his own Rockwell Antique, which was itself basically a repackaging of Litho Antique, whose owner (the Inland Type Foundry) had been taken over by ATF. According to Patricia Cost in her book The Bentons, Monotype then copied Rockwell Antique and called it, confusingly, Stymie Bold.
Rather than stealing the design, Excoffon exercised squatter’s
rights in the territory… with style (above). The names were nearly
identical—probably no coincidence.
French type legend Roger Excoffon’s employers, Fonderie Olive, was such rivals with Parisian foundry Deberny and Peignot that Excoffon examined with a magnifying glass a picture of its designer Marcel Janco at work on his new self-named type. “Then I rapidly made some sketches for a few letters in a commercial type, not identical, but of the same family… The rest is a success story. Banco was used throughout the world… It’s the most shameful thing I ever did in my career.” (You’ll find this story in Roger Excoffon et la Fonderie Olive, by Sandra Chamaret, Julien Gineste and Sébastien Morlighem, Ypsilon Editeur, Paris, 2010.)
A comparison of Starling Burgess’ design (Lanston no.54) and
Stanley Morison and Victor Lardent’s work on Times, as it appeared
in “Printing History 31/32” (1994).
According to a 1994 article by Mike Parker that appeared in Printing History, Times New Roman was an extremely close reproduction of a typeface designed years earlier by genius boat and car designer and maverick Starling Burgess, which lay unpaid for and abandoned at Lanston Monotype until the design of the new face for The Times newspaper became problematic. Although Morison had a reputation among some for being a slippery operator, the story as presented seems hard to credit: Font Bureau offers a Mike Parker design called Starling.
Close but no cigar: Twentieth Century (above), and Lanston
Monotype’s response to Futura (below).
Buffalo, New York-based foundry P22 has in its Lanston Type Company collection Twentieth Century, “Monotype’s answer to Futura.” It describes Sol Hess’ redrawing as “close”; as an attractive optional extra, it has included digital recreations of some of Paul Renner’s original experimental characters for Futura.
Comic and Chalkboard: both ideal for warning notices.
Apple’s OS X doesn’t supply you with the world’s favorite, Comic Sans, but you do get Chalkboard, which inhabits pretty much the same terrain.
Hard to fully love perhaps, but Arial has certainly been well
used, if only because it is the default setting.
Arial, designed in 1982 by Robin Nicholas and Patricia Saunders, seems to attract its share of ill will in “font hate” blogs these days on the grounds of it being Microsoft’s Helvetica lookalike.
For the user, does any of this matter? If you like a font and it fits your purpose, then its provenance is irrelevant. And if it’s a new or recent design, then it comes with little or no back story. In terms of design rationale, investigating the background of your choice is always useful. Who designed it? When and for whom—for a particular project or for a company? If for a project, would those associations jar with how you’re planning to use it now, and does that matter? If it was originally designed for Monotype, is the font you’re planning to buy from Monotype or from another foundry? What does Monotype offer as its version, and how does it compare? Stempel Garamond versus Simoncini Garamond, or Garamont?
Koch Rivoli: channelling the spirit of Rudolf Koch and Willard
T. Sniffin.
And how has history served those original battling typefaces? Sebastian Carter in Twentieth Century Type Designers describes Koch Antiqua as “one of the most successful advertising faces of the inter-war period, still often used to suggest the vanishing luxury of ocean liners.” Although some of that usage might have been in reality Rivoli, Koch’s reputation as a type designer endures.
As does the name Rivoli, although its creator or draughtsman, the magnificently named Willard T. Sniffin, is less remembered. But UrbanFonts.com for one offers as a free font Koch Rivoli (a pairing of names that would have the German designer spinning in his grave), an uppercase-only design that takes inspiration from the thick-thin double stroke of Koch’s italic uppercase—and Rivoli’s.
Note: A big thank you to our fabulous Typography editor, Alexander Charchar, for preparing this article.
© Simon Loxley for Smashing Magazine, 2012.
"QUICK SHOT"
Link
Some recently found spectacular imagery for your desktop
wallpapers. Click to enlarge all images.
Here is NGC 3031 (also called UGC 5318) galaxy and surroundings
from the Global Sky Survey:
(image via)
Some delicious fractals:
(originals unknown)
A painter's dream, a perfect studio:
(a Photoshop ad, developed by Bates141 Jakarta
creative director Hendra Lesmono, art directors Andreas Junus and
Irawandhani Kamarga, copywriter Darrick Subrata and photographer
Anton Ismael, via
Super Moon over Paris:
(image credit: VegaStar
Carpentier)
"The Secret City": Moscow in a fantasy light... This is work by
Alexey Kondakoff (click to enlarge):
(image credit: Alexey
Kondakoff)
And perhaps the ultimate in condensed living - the Kowloon Walled City in Hong Kong (cross-section):
(image via)
And going back into deep space - the bountiful "stellar nests" all
over NGC 4725 galaxy in Coma Berenices constellation.
(image via)
Click to enlarge all images.
|
"QUANTUM SHOT" #771
Link - article by Avi Abrams
This article appears simultaneously on Dark Roasted Blend and on
"Out of
Order" magazine - a Yale University print and online
publication that curates innovative and bold fashion, art, music
and film for the university set
Visual Caffeine: Exploring Art and Architecture with Avi Abrams,
Issue 2
This is a second issue of our "visual caffeine concoctions" (read
the first one here) - somewhat unpredictable forays into
history of art and architecture, coupled with mythology, culture
and obsolete technology. For those of you, who want an even larger
dose of our visual caffeine, head over to Dark Roasted
Blend site, and get addicted to our endless stream of thrilling
visual information.
Today we are going to look at some cutting-edge contemporary art
coming out of Japan, covering some popular culture, futurism- and
steampunk-influenced Japanese artists largely unknown in the
West.
We asked Tomoo
Yamaji, an artist specializing in three-dimensional sculptures
(who has a good knowledge of similarly-styled work in Japan) to
highlight his favorite artists - veteran and young, famous and
relatively unknown. He came up with a list of eight artists that
cumulatively represent the state of contemporary three-dimensional
art in Japan.
Slick Predatory Formula One Sculptures by Showichi
Kaneda
Showichi Kaneda combines brand-intensive, slick
and somewhat predatory shapes of Formula One cars with sea
predators like sharks and giant squid in his "Human's Own Evo"
series. His work displays at well-known venues like the Tokyo Gallery,
and I can see how visually arresting and irresistible it can become
to our tastes, obsessed with speed, brand exposure and fascination
with deadly animals:
Covering the nature and animals with well-known brand logos is not
the new idea (it's been done by consumer-culture and kitsch critics
before), but Showichi Kaneda does it with such grace and
streamlined intent that it's hard to avert your eyes and even
harder not to imagine these "sea animals" competing in racing games
under the waves somewhere.
Highly efficient sea predator "killing machines" meet their
technological counterpart in F1 high-speed machines:
(art by Showichi
Kaneda)
Art at the Speed of the Sound
"Land Speed Record" vehicles look impossibly sleek and sensuous in
the work of Tetsuya Nakamura. He is an internationally known
artist (Most of his work is on display at the "Gallery
Koyanagi") whose sculptures are favorites with our guide today,
Tomoo Yamajii:
(image via)
Here is the "Wind Blade Prototype", a shape easily at home in an
art studio or a concept vehicle show room:
Here is a "Hot Rod Bath Tub". And why not, we ask you, why not?
-
(image via)
Ancient Japanese History... Put on a Motorcycle
Akira Yamaguchi paints in a traditional Japanese
style, except that his samurai enjoy latest motorcycle
technology:
(art by Akira Yamaguchi )
This could be called Shogun-steampunk, but we leave it to the
reader to classify the unclassifiable.
Baroque Meets Mannerism, Meets Dark Fantasy
These striking, incredibly sophisticated porcelain creations are
the work of Katsuyo Aoki, evoking comparisons with darkly surreal
masters like H. R. Giger and perhaps H. P. Lovecraft... Some of
them would feel right at home inside the decadent spaceships of
Iain M. Banks "Culture" series:
("Maniera I" art by Katsuyo
Aoki)
"Predictive Dream" series is a reflection on our mortality and
triumphant, exuberant spirit of Life:
(images via)
Serenity on Display
Sueharu Fukami works show all the taut grace
and inherent tension of the Japanese samurai sword.
(art by Sueharu Fukami, images via
1, 2, 3)
"Fukami is a perfectionist, a maestro of clay... It's not an easy
task to try to capture the horizon", note the critics, and Fukami
Sueharu agrees: "I first became interested in the horizon when I
was in my early thirties. I was climbing Daiyozaki mountain pass in
Mie Prefecture and the view just made my heart tremble. I was
deeply moved and knew it was the feeling I wanted to capture in my
work, a feeling of majestic awe".
"Porcelain shows any marks left by the potter's hand and I want to
leave the least amount of evidence that my hands ever touched the
clay. Instead of the potter's obvious imprint I want to leave the
subtle mark of my heart or spirituality," Fukami said. These works,
for example, evoke the pure potential and innocent grace of empty
sheets of paper:
(images via)
The "sleek, lucid, jewel-like" bluish white porcelain known as
seihakuji in Japanese is the perfect medium to capture these
serene sentiments; it is largely unknown variation of the 11th-12th
centuries Song dynasty's Jingdezhen ceramic wares, brought to Japan
in the 13th century but then gradually falling out of favor... and
revived again today in pure brilliance of Sueharu Fukami work.
Insect-Plant Hybrid Mimicry
Hiroshi
Shinno creates imaginary insects that perfectly blend into
their surroundings - because there are made from parts of these
surroundings! He collects petals, leaves, grass stems and flower
stamens - and molds them into intricate "herbal" insects, a blend
of real natural pieces and the polyurethane resin copies:
(art by Hiroshi Shinno)
Hiroshi Shinno works with truly miniature flower parts, seeds,
"shells so thin that they are translucent, and dry, holey leaves
that disintegrate under the slightest pressure". So far he has
constructed nineteen fantastical structures of these fanciful
insects - a testimony to delicate and transient side of nature
where sophisticated are born, develop and die all in one day. See
more "herbal insects" here, and also see how these insects are
constructed step by step:
(images via YOD
Gallery)
Evil babies ride streamlined motorcycles. There is some inner
twisted logic in all of this.
Shigeki
Hayashi is a porcelain artist, but this is almost like calling
Rembrandt a paint-mixer. The surreal heights of Shigeki Hayashi
glazed porcelain creations are going to haunt you for days - that
is, if you come unprepared and never seen "AKIRA" movie or manga,
or never read science fiction stories about mutant babies (the good
example of the latter will be Henry Kuttner's "Mimsy Were the
Borogoves" stories in the 1940s American pulp magazines)
Here is what critics say about Shigeki Hayashi haunting baby
figures: "...This QP doll in a space suit suggests a deeper, hidden
narrative within a... variation on the traditional Kewpie Doll from
the West."
(art by Shigeki Hayashi)
Shigeki Hayashi work has won some prestigious medals, like one at
the Faenza International Competition for Contemporary Ceramics in
Italy. See more "mutant babies" and other artwork at Keiko Gallery and artist's site.
(art by Shigeki Hayashi)
You wanted Steampunk? Michihiro Matsuoka channels mechanical
brass animals in his own Asian steampunk way
Michihiro Matsuoka is not the only
steampunk-influenced artist in Japan, but his polymer clay, acrylic
painted figurines are perhaps the most memorable. They are bizarre
to the point being laughable (kinda like a Crazy Rabbit in Wallace
& Grommit series), but also eminently touchable and impossibly
cute (in some cases).
(art by Michihiro Matsuoka)
Look at his version of Postal Delivery rabbits, for example. Would
you entrust your correspondence to these creatures. They seem eager
enough to deliver it come hell or high water:
See more of this steampunk zoo at artist's site. Squids, of course, are present in significant
numbers, as well as deep-sea creatures and even gold fish
transformed into rust-tainted, cyber-infected nightmares:
(art by Michihiro Matsuoka)
Tomoo Yamajii "Fast Mercy" Unique Transformations
Now's the time to show the work of Tomoo Yamaji - the
artist who compiled the list for us. His favorite style is
transforming futuristic and highly symbolic sculptures. Most of
them easily flow into various shapes and invite touch and
transformation by being attractively curved and exquisitely
shaped:
("Fast Mercy" by Tomoo Yamaji)
Called "Fast Mercy", this is a highly dynamic version of Bodhisattva benevolent spiritual entity who helps
people in times of natural disasters and other hardships. Tomoo
Yamaji made it in 2011 to inspire and help people who have been hit
hard by the earthquake and tsunami in March that year.
("Fast Mercy" by Tomoo Yamaji)
Here is a futuristic Bel Geddes-like plane, with a very special
transformation hidden inside - see more here.
(art by Tomoo Yamaji)
And we finish with "Macross". For it is unthinkable to write an
article about Japanese contemporary art without mentioning these
ubiquitous popular culture artifacts
Here are some fictional transforming air vehicles from the TV
animation series MACROSS. The "DX Chogokin VF-25S Messiah Valkyrie Ozma
Custom", for example, transforms into three incarnations (made by
toy company Bandai in 2012):
(image
via)
Transforming vehicles are staples of toy-manufacturing companies,
of course, but also are a favorite subject with popular culture and
anime-oriented artists. Tomoo Yamaji sends us more examples of this
art form:
(art by Tomoo Yamaji)
In our future explorations we are going to touch in more detail
modern Japanese anime-based illustrations (some of them becoming
more familiar in the West with proliferation of anime
publications), but also will highlight little-known surreal and
naive branch of Japanese graphic arts, full of "kawai" (very, very
cute) imagery.
READ
THE REST OF OUR "ART" CATEGORY ->
ALSO CHECK OUT OUR "BEST OF JAPAN" SERIES ->
|
Myths have developed around and researchers have studied how the human brain juggles creativity and organization. Popular theory tells us that the left brain is structured and logical, while the right brain is artistic and imaginative, and that all human beings use predominantly one side of the other.
Working in a creative field means challenging that theory, or else challenging the schedules and deadlines that managers impose on writers, designers and other creatives. As a project manager in a UX design agency, as well as a writer, I believe it is necessary to challenge both the assumptions about schedules and the belief that creativity implies disorganization.
There’s a quick and easy answer to this question. Yes!
You’re shaking your head now. You’re thinking about how much you hate deadlines and how your designs suffer from the 9:00 to 5:00 schedule imposed by your manager. You’re remembering the sketches or creative writing you did in college at 3:00 in the morning. Sathish Manohar expresses it well in his article “Why 9 to 5”:
“Knowledge work solely depends on creativity of the workers. But, still some how, knowledge work-places got modeled around factories. Employees had to work 9-5, be creative between 9-5, and go home… This is a problem, We cannot schedule the brain to be creative at any given time.”
Yet I’ve spent years trying to merge my creative-writing personality with my project-management skill set and day job. Recently I realized that writing by the light of the moon results in over-caffeinated mornings and sloppy grammar, and still I continued—after all, isn’t that what creativity is all about? I’ve always been able to empathize with my designers, who want nothing more than free reign to be creative when the mood hits. But as a project manager, I also strive to create a working environment where designers and content strategists can be productive and efficient—and where we can deliver mockups on a deadline.
The solution turned out to be easier than you might expect. Spontaneous creativity is not the only way. In fact, as a content strategist, designer or even developer, you are paid for your ability to turn on the creative faucet. So, what goes into creating on command?
“Be regular and orderly in your life so that you may be violent and original in your work.”
– Gustave Flaubert, author
Flaubert did not write on a deadline, and yet he found that following an orderly routine improved his ability to be creative. This holds true for most people. Being able to “do your best work” at 3:00 am is no coincidence: you are training your brain to get those creative juices flowing when the moon is high and the workday is long over. This is fantastic if you don’t have anywhere to be in the morning; but for many of us, 3:00 am is not a great time to be inspired.
Instead, develop a routine that trains your creative juices to kick in at more convenient times. This could mean setting the alarm for 8:00 am, making breakfast and then sitting down with a journal to begin sketching as you eat. It could mean emailing yourself a to-do list before bed, with inspirational quotes to greet you the moment you open your email. Maybe you need a lunchtime scrum every day to energize and focus. Within two weeks, these mini-kickoffs will begin to signal to your brain, “Now is when we begin the creative work of the day.”
“A single meeting can blow a whole afternoon, by breaking it into two pieces each too small to do anything.”
– Paul Graham, essayist and programmer
Distractions are a powerful creativity-blocker. Even the best routine can be waylaid by mandatory meetings, important phone calls and constant emails. If you are a freelancer in charge of your own schedule, try to relegate meetings to the very beginning or end of the day. If a manager schedules your client meetings and internal reviews, talk to them about the benefits of opening up large blocks of time for creative work.
At Above the Fold, we make a point of scheduling around the “maker’s schedule.” Paul Graham sums up the maker’s schedule in his essay, “Maker’s Schedule, Manager’s Schedule”:
“When you’re operating on the maker’s schedule, meetings are a disaster. A single meeting can blow a whole afternoon, by breaking it into two pieces each too small to do anything hard in. Plus you have to remember to go to the meeting. That’s no problem for someone on the manager’s schedule. There’s always something coming on the next hour; the only question is what. But when someone on the maker’s schedule has a meeting, they have to think about it…. I find one meeting can sometimes affect a whole day. A meeting commonly blows at least half a day, by breaking up a morning or afternoon.”
Therefore, at Above the Fold, we hold internal reviews at 5:00 pm, check-in meetings at lunchtime, and client calls first thing in the morning. This gives our creative team the time they crave to get engrossed in projects, without interruption.
This doesn’t solve the issue of interruption via email, of course. Try scheduling specific “Check email” times into your day—again, first thing in the morning, just before your lunch break or at the end of the day works well. Make sure your team is aware that you will not be responding to emails immediately, and suggest they call you or come find you if something is urgent and relevant to the current project. Team members can be surprisingly understanding and can quickly grasp the difference between imperative and interesting.
“Separate brainstorming (idea generation) from synthesis (putting it all into a flowing post).”
– Tim Ferriss, author
Having large blocks of time available and scheduling them into your day sounds well and good, but how do you convince your brain that the time has come to get in the zone and ignore distractions?
Taking a page out of the Agile development book, try starting with a variation on pair programming. Pair programming is designed to help developers break down complex tangles of code with the simple rationale that two heads are better than one. The same is true for kicking off any other sort of creative block of time. Instead of working together all day, kick off the day with a 10-minute group brainstorming session. Nothing focuses the creative mind faster than talking through project details, and 10 minutes can lead to a far more productive three hours of synthesis.
Don’t have a team to kick around ideas with? Hit up a few colleagues on Twitter or Skype. We have found that many in the content and design worlds are happy to help, and you can offer to help in return.
“Major league players aren’t the only professionals that regularly practice. We’ve met musicians, firemen, pilots, and surgeons, all of who regularly practice their skills.”
– Jared M. Spool, founding principal of User Interface Engineering
Athletes warm up their muscles before starting their real work, and so should creative thinkers. A good warm-up helps you practice basic skills, focus your mind and improve the work to come. In addition, taking 10 minutes to warm up allows you to separate your ideas from the plethora of ideas surrounding you.
A few hundred years ago, visual stimulation was hard to come by, and artists were influenced primarily by their surroundings. Now, our surroundings contain hundreds of representations of our surroundings and of other people’s interpretations of their surroundings. Finding your own voice can be difficult amid the clutter.
The following quick warm-ups can bring you back to basics and isolate what makes your creative voice unique. Some of these suggestions even include using someone else’s work as a starting point—but making it your own.
None of these warm-ups should take more than 10 minutes, and each offers a different way to reconnect you to your creative spirit. From here, you might find it easier to begin thinking about new and different ideas, and even jumpstarting a project that has felt stale.
“Laziness in a white collar job has nothing to do with avoiding hard physical labor. “Who wants to help me move this box!” Instead, it has to do with avoiding difficult (and apparently risky) intellectual labor.”
– Seth Godin, entrepreneur, author and speaker
Most creative jobs come with a catch, such as having to respond to client emails, send invoices or email writing samples. It’s not uncommon for these boring, “uncreative” tasks to turn into a means of procrastination. You feel as though you can’t set a task aside because it must be done; but because you don’t want to do it, you procrastinate—effectively avoiding both your creative work and your busywork.
Invoices and emails and bills are quick tasks, so we don’t feel as though delaying them by an hour or two costs much. But the hour you spend avoiding a five-minute task eats away at your creative time. What’s more frightening is the possibility that you’re actively using these tasks to avoid your creative work. As Seth Godin explains, this is due to “lizard brain”:
“The [lizard brain, or resistance,] is the voice in the back of our head telling us to back off, be careful, go slow, compromise. The resistance is writer’s block and putting jitters and every project that ever shipped late because people couldn’t stay on the same page long enough to get something out the door.”
We’ve all dealt with lizard brain, and many of the suggestions in this article can help combat it. But how do you remove the procrastinations that are genuine work, the busywork that must be done but just gets in the way?
Try setting aside one morning a week (Monday is a good day) to devote to the boring tasks. Relegate email reminders of the busywork to a “Monday” folder. Keep all physical folders and to-do lists for that work away from your desk. Of course, you don’t want to wake up one day and realize you forgot to pay the bills, but you won’t forget housekeeping chores like that if you assign them to a specific time slot—and not that generic “tomorrow.”
One more tip: don’t sit in your creative spot to do the busywork. The area for busywork will quickly get cluttered with to-do notes that have nothing to do with the creative work that you need to accomplish. Do the necessary evils somewhere else to avoid distracting yourself the next time you begin your “real” work.
Saying that a wild creative mind can’t be tamed sounds romantic, but romanticism will serve you better in your actual products than in your schedule. The advice above will help you schedule your mind, enhance your creativity and use team members, time constraints and even deadlines to your advantage. Give your creative mind the structure and security it needs to run wild.
Here are some more resources on creative productivity:
What other tips and tools help you to be creatively productive?
(al) (il)
© Marli Mesibov for Smashing Magazine, 2012.
This tutorial will cover the process of creating a basic Joomla module from an existing widget. We’re going to take a widget from Mixcloud, learn how to convert it into a Joomla module and, finally, distribute the extension to JED (Joomla Extension Directory).
If you’ve never created a Joomla module before, this article is the best place to start!

For every module created for Joomla, there are two files that
absolutely need to be present. One file is a configuration XML file
that will hold the module details and parameters and a PHP file
that will control our module. For the purpose of this tutorial, we
will create a folder called mod_mixcloud_widget and,
within it, using your favorite code editor, create
mod_mixcloud_widget.php and
mod_mixcloud_widget.xml. Before we move on to the next
step, create a single HTML file named index.html.The
index.html file that was created will be used to hide
the contents of the module folder when viewing via a browser.
Now that you’ve added the core files, it’s time to add the
template files. We do this by creating a folder called
tmpl. Within that folder, we create
default.php and index.html. The file
default.php will be the module template that will take
generated information and output them into clean HTML format on the
page.
Lastly, while inside our root module folder, we create a new
folder called language. This folder will have two
files: en-GB.mod_mixcloud_widget.ini and
en-GB.mod_mixcloud_widget.sys.ini which will be used
to make our module internationable with the option of having
different languages.
After following each step, you should have the following file structure
Each Joomla Extension installed has an XML file, which is referred to as a manifest or Install file. This file contains metadata details, such as author, version, description etc. It is also used as a configuration file for module prameters. For the purpose of this tutorial, we will be creating a manifest file for a Joomla 2.5 module. Add the following snippet to your XML file.
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="2.5" client="site" method="upgrade">
<name>MOD_MIXCLOUD_WIDGET</name>
<author>B4ucode</author>
<creationDate>May 2012</creationDate>
<copyright>Copyright (C) 2011 - 2012. All rights reserved.</copyright>
<license>GNU General Public License version 2 or later;</license>
<authorEmail>info@b4ucode.com</authorEmail>
<authorUrl>www.b4ucode.com</authorUrl>
<version>1.0.0</version>
<description>MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION</description>
The primary tag extension has a few attributes:
module.new and
upgrade. We will be using upgrade, in case of any
future updates to the module, it will simply upgrade what is
currently there.The other set of tags are metadata tags which hold information about the module which will be used during installation and the administration of the module.
As mentioned before, the manifest file holds information about the files used in the module. During installation, Joomla checks the manifest file for all the files that should be added to the system. If any of the files are missing, then Joomla will give an error explaining the files that are missing. Any files found in the module, that aren’t listed in the XML file are not added to the system with the others. Add the following snippet to your manifest file.
<files>
<filename module="mod_mixcloud_widget">mod_mixcloud_widget.php</filename>
<folder>tmpl</folder>
<filename>index.html</filename>
<filename>mod_mixcloud_widget.xml</filename>
</files>
Instead of writing a line for each file in a folder, we simply use the folder element. This element will instruct the installer to install all the files in this folder.
This element holds the language files that are to be installed with the module. For the purpose of this tutorial, only one language will be used. When there are more languages, you can simply change the prefix of the files and the tag attribute to the exact language based on the Joomla framework.
<languages>
<language tag="en-GB">language/en-GB.mod_mixcloud_widget.ini</language>
<language tag="en-GB">language/en-GB.mod_mixcloud_widget.sys.ini</language>
</languages>
Some extensions don’t work right out of the box, but need certain settings added: these settings are called, parameters, and are defined in the manifest file.
The first element is config which holds other
elements that will be displayed in HTML format. The element called
field is the meat of our parameters where you can
define what type of form data you wish to display. This element at
its basic level is made up of some core attributes:
There are different attributes as they vary per form field type like size, filter, exclude, directory and more.
<config>
<fields name="params">
<fieldset name="basic">
<field type="text" name="feed" default="" label="MOD_MIXCLOUD_WIDGET_FEED_TITLE" description="MOD_MIXCLOUD_WIDGET_FEED_DESC" />
<field name="color" type="color" default="" label="MOD_MIXCLOUD_WIDGET_COLOR_TITLE" description="MOD_MIXCLOUD_WIDGET_COLOR_DESC" />
<field name="width" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_WIDTH_TITLE" description="MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION" />
<field name="height" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE" description="MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION" />
</fieldset>
<fieldset
name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
description="JFIELD_ALT_module_LAYOUT_DESC" />
<field
name="moduleclass_sfx"
type="text"
label="COM_moduleS_FIELD_moduleCLASS_SFX_LABEL"
description="COM_moduleS_FIELD_moduleCLASS_SFX_DESC" />
<field
name="owncache"
type="list"
default="1"
label="COM_moduleS_FIELD_CACHING_LABEL"
description="COM_moduleS_FIELD_CACHING_DESC">
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_moduleS_FIELD_VALUE_NOCACHING</option>
</field>
</fieldset>
</fields>
</config>
</extension>
You may notice that we have written labels and description in some uppercase characters like
MOD_MIXCLOUD_WIDGET_FEED_TITLE. These are strings that we will make translatable when creating our language files.
If you’ve followed thus far, you should have a completed XML File like following
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="2.5" client="site" method="upgrade">
<name>MOD_MIXCLOUD_WIDGET</name>
<author>B4ucode</author>
<creationDate>May 2012</creationDate>
<copyright>Copyright (C) 2011 - 2012 Open Source Matters. All rights reserved.</copyright>
<license>GNU General Public License version 2 or later;</license>
<authorEmail>info@b4ucode.com</authorEmail>
<authorUrl>www.b4ucode.com</authorUrl>
<version>1.0.0</version>
<description>MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION</description>
<files>
<filename module="mod_mixcloud_widget">mod_mixcloud_widget.php</filename>
<folder>tmpl</folder>
<filename>index.html</filename>
<filename>mod_mixcloud_widget.xml</filename>
</files>
<languages>
<language tag="en-GB">language/en-GB.mod_mixcloud_widget.ini</language>
<language tag="en-GB">language/en-GB.mod_mixcloud_widget.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field type="text" name="feed" default="" label="MOD_MIXCLOUD_WIDGET_FEED_TITLE" description="MOD_MIXCLOUD_WIDGET_FEED_DESC" />
<field name="color" type="color" default="" label="MOD_MIXCLOUD_WIDGET_COLOR_TITLE" description="MOD_MIXCLOUD_WIDGET_COLOR_DESC" />
<field name="width" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_WIDTH_TITLE" description="MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION" />
<field name="height" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE" description="MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION" />
</fieldset>
<fieldset
name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
description="JFIELD_ALT_module_LAYOUT_DESC" />
<field
name="moduleclass_sfx"
type="text"
label="COM_moduleS_FIELD_moduleCLASS_SFX_LABEL"
description="COM_moduleS_FIELD_moduleCLASS_SFX_DESC" />
<field
name="owncache"
type="list"
default="1"
label="COM_moduleS_FIELD_CACHING_LABEL"
description="COM_moduleS_FIELD_CACHING_DESC">
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_moduleS_FIELD_VALUE_NOCACHING</option>
</field>
</fieldset>
</fields>
</config>
</extension>
mod_mixcloud_widget.phpThe first thing you want to with your module is to add your copyright notice. If you intend to submit your module to JED [Joomla Extension Directory], you should add some GPL license information.
This is one of the checks done before approving a module into
the directory. Directly below this, I use the statement
defined('_JEXEC') or die; which is used in most PHP
files to protect against hackers. This is also another requirement
for approval on JED.
<?php
/**
* @package B4ucode
* @subpackage mod_mixcloud_widget
* @copyright Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
* @license GNU General Public License version 2 or later;
*/
// no direct access
defined('_JEXEC') or die;
Next, we define our paramaters as variables. Developers
sometimes define their paramaters as variables in order to have
cleaner template files. In order to call a paramaters we use the
$params->get() function and get the param
name defined in our manifest file. Finally, we call
the module Helper function, getLayoutPath, which will
render our module template. The first argument of the function
takes the module name that we are trying to call, then the second
argument looks for the template we intend to render for that
module. In this case, we get the parameter layout and
in the second argument we set the default layout to be
default. This layout is the exact name of the file
that we have in our tmpl folder.
$width = $params->get('width',300);
$height = $params->get('height',300);
$feed = $params->get('feed');
$color = $params->get('color');
$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
require JmoduleHelper::getLayoutPath('mod_mixcloud_widget', $params->get('layout', 'default'));
?>
<?php
/**
* @package B4ucode
* @subpackage mod_mixcloud_widget
* @copyright Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
* @license GNU General Public License version 2 or later;
*/
// no direct access
defined('_JEXEC') or die;
$width = $params->get('width',300);
$height = $params->get('height',300);
$feed = $params->get('feed');
$color = $params->get('color');
$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
require JmoduleHelper::getLayoutPath('mod_mixcloud_widget', $params->get('layout', 'default'));
?>
default.phpAt this point, we have created our manifest file with
paramaters, took those same parameters and turned them into
variables. In this step, we are going to use those variables in our
template file. The template file will render all of our HTML for
the module. Edit default.php from your
tmpl folder and add the following snippets:
<?php /** * @package B4ucode * @subpackage mod_mixcloud_widget * @copyright Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved. * @license GNU General Public License version 2 or later; */ // no direct access defined( '_JEXEC' ) or die( 'Restricted access' );
It is recommended that you add the Copyright Notice and Restricted Access line to your PHP files.
For this tutorial, we will need the embed code from Mixcloud.
Here
is an example on getting the code . Our module’s purpose is to make
the code reusable without having to get the embed each time we want
to create or modify a Mixcloud Widget on our site. The default
embed code comes with some extra information about the widget
content which we don’t need. So for this tutorial, I have stripped
it down to just the embed script. Paste this embed code to your
default.php file.
<div><object width="480" height="480"><param name="movie" value="http://www.mixcloud.com/media/swf/player/mixcloudLoader.swf?feed=http%3A%2F%2Fwww.mixcloud.com%2FMaryAnneHobbs%2Fthom-yorke-moneyback-mix-xfm-music-response-150911%2F&embed_uuid=5d6c18a4-a837-409e-8cec-23ab44372842&stylecolor=&embed_type=widget_standard"></param><param name="allowFullScreen" value="true"></param><param name="wmode" value="opaque"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.mixcloud.com/media/swf/player/mixcloudLoader.swf?feed=http%3A%2F%2Fwww.mixcloud.com%2FMaryAnneHobbs%2Fthom-yorke-moneyback-mix-xfm-music-response-150911%2F&embed_uuid=5d6c18a4-a837-409e-8cec-23ab44372842&stylecolor=&embed_type=widget_standard" type="application/x-shockwave-flash" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" width="480" height="480"></embed></object></div>
If we wanted to embed one widget permanently, we could just zip
up the module right now. However we don’t, so we are going to
replace some of the attributes with our module params . We’re going
to change the width, height,
color and feed. Paste the following
snippet over your embed script.
<div><object width="<?php echo $width; ?>" height="<?php echo $height; ?>">
<param name="movie" value="http://www.mixcloud.com/media/swf/player/mixcloudLoader.swf?feed=<?php echo $feed; ?>&embed_uuid=&stylecolor=<?php echo $color; ?>&embed_type=widget_standard"></param><param name="allowFullScreen" value="true"></param><param name="wmode" value="opaque"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.mixcloud.com/media/swf/player/mixcloudLoader.swf?feed=<?php echo $feed; ?>&embed_uuid=&stylecolor=<?php echo $color; ?>&embed_type=widget_standard" type="application/x-shockwave-flash" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" width="<?php echo $width; ?>" height="<?php echo $height; ?>"></embed></object>
</div>
Take note of how we are just calling the variables from our controller file.
In step one, you might have noticed that we created a folder,
called language, with two files. Then, in step two, we added some
translatable text. In this section, we are going to translate that
text to English. Insert the following snippet to the ini files,
en-GB.mod_mixcloud_widget.sys.ini and
en-GB.mod_mixcloud_widget.ini.
; B4ucode ; Copyright (C) 2011 - 2012 B4ucode. All rights reserved. ; License GNU General Public License version 2 or later; ; Note : All ini files need to be saved as UTF-8 - No BOM MOD_MIXCLOUD_WIDGET="Mixcloud Widget" MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION="This module displays the Mixcloud Widget using feed and other paramaters" MOD_MIXCLOUD_WIDGET_ITEMS_LAYOUT_DEFAULT="Default" MOD_MIXCLOUD_WIDGET_FEED_TITLE="Feed Url" MOD_MIXCLOUD_WIDGET_FEED_DESC="Add the link to single/cloudcast" MOD_MIXCLOUD_WIDGET_COLOR_TITLE="Color" MOD_MIXCLOUD_WIDGET_COLOR_DESC="Add Style color" MOD_MIXCLOUD_WIDGET_WIDTH_TITLE="Width" MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION="Width of Widget" MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE="Height" MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION="Height of Widget"
If you look closely, you will notice that the text I used for the parameters now have an English translation. You can add other files and create translations in other languages!
After following all the steps thoroughly, your module is now installable, but we’d like to make a checklist of things to do before installation and distribution.
index.html to FoldersIt is recommended that you add a index.html file to
each folder. This file, as mentioned previously, stops users from
viewing the contents of a module folder directly in a browser. Add
the following snippet to your files:
<html><body bgcolor="#FFFFFF"></body></html>
At this stage, it is recommended that you look at the files and folder defined in your manifest file, and make sure they exist in your module folder. Any file that does not exist can stop the installer from installing files, or, it may throw an error.
After our little checklist, we can package the module into a zip file, and install it.
By navigating to the modules manager, and selecting the module, you can modify the paramaters with your desired width, height, color and song feed.

Enable the module and check to see if it operates the way that it should.

After registering to JED, one of the main things to note is that you cannot add an extension to multiple sections. So, choosing the appropriate section is very important. Find a suitable section by browsing the site then looking at the top left cornder you will see Submit Extension

Once you’ve chosen to submit an extension, there will be a form to fill in all the details about your submission. Review the screenshots below to see the different fields to be filled out, and read the instructions carefully.




Once all the appropriate fields and files have been submitted, you will see a message like the screenshot above; it will explain how many submissions are in the queue to be checked prior to yours.
Now that you’ve learned how to create a Joomla module from a widget, go forth and code. With the basics of this tutorial, the same idea can be applied to Facebook plugins, Twitter widgets, Social bookmarkers, Youtube video embeds, and so much more. Happy Coding!
There’s a new player in town, and he brought new toys: The PHP World welcomes FLOW3, an enterprise application framework written and backed by the community of the TYPO3 CMS. FLOW3 can be used as standalone full-stack framework for your applications. It’s interesting, because it introduces some concepts of software development that haven’t been adapted to PHP before.
Among these new concepts is “Aspect Oriented Programming”. We will have a look on the theory of the pattern, and will set up a basic FLOW3 Application and weave in our own aspect!
If a new framework hits stable, an excellent question to rise might be: What can it do that the tools that I love can’t?
PHP already has an armada of excellent frameworks and most of them claim to be written with separation of concerns in mind. So does FLOW3.
In terms of software development this means, that the classes that are implementing the logic of your application should only care about one thing. For example, a mailer class should send mails. It should not retrieve potential receivers from a database.
All modern frameworks (including FLOW3) push a lot of patterns into the software stack that do a great job at separating the concerns of your business logic; among them the famous MVC that is separating your logic into different layers.
However, an application is not only built on business logic alone. As it grows, you may want to implement additional services, features, plugins or plugins of plugins. You surely don’t want this stuff in your business logic! But what are your options?
Let’s say you want to implement a logging service that writes some stuff to a text file every time a specific set is deleted from the database. Naturally, the logging service is not part of your database layer. But in order to make it work, you have to place some code right there, like this:
/**
* Delete a user
* @param UserModel $user
* @return void
*/
public function deleteUser(UserModel $user) {
$this->loggingService->log('removing user ' . $user->getName());
$this->users->remove($user);
}
Horrible, isn’t it? Let’s face it: The logging service adds dirt to your code. You have to touch the original code in order to implement it and you add an additional dependency, in this case an instance of the LoggingService.
Hence, you’re adding complexity. And you likely will have to add it all over your app (depending on what else you want to log).
You may come up with an pattern like an event dispatcher or a hook system like it’s implemented in Drupal and WordPress and then have your logger listen for events:
/**
* Delete a user
* @param UserModel $user
* @return void
*/
public function deleteUser(UserModel $user) {
$this->eventDispatcher->dispatch(self::USER_DELETED);
$this->users->remove($user);
}
This is better, but it’s still not cool. You’re code is still dependency aware: it has some code with the sole purpose of informing other parties that something happens.
This has some bad side-effects: What if you want to log something, but there’s not an event dispatched at that time? What if you haven’t written that code because you are writing a plugin? You’d have to change the original code – not once, but every time an update is available.
Let’s call the logging service an aspect and see how FLOW3 takes care of the problem.
Our logging service is only interested in one thing regarding the existing code: It wants to intercept it in some classes at various points (e .g. when something is deleted). With the implementation discussed above, the existing code controls the points of execution.
Wouldn’t it be nice if the service could define a set of rules at which point it would want to inject itself into the class?
This is a software development concept named Inversion of control. It decouples classes from another, because there’s no need to change existing code when you’re changing the service. The service takes care of this itself.
Let’s say we simply want to execute logging on every method in
every class that starts with delete, like
deleteUser(), deleteEntry() or whatever.
A convenient way would be to write a rule into the logging service
and let the framework take care of the correct execution of the
code. This is remarkably easy in FLOW3:
/**
* An aspect that is executed on all methods that start with "delete".
*
* @FLOW3Before("method(.*->delete.*())")
*/
public function logginMethod() {
// Do some logging here.
}
FLOW3 performs some really advanced PHP techniques under the hood.
The rule is named pointcut in AOP and there are some easy-to-learn ways to define them. The one above tells FLOW3 to inject the logging code in every class before every method that starts with delete.
It does so by using the method keyword and by adding wildcards (*) for the class and for parts of the method name. If you’re adding this code in an Aspect Class (as we do later), you’re good to go. You will be able to access properties of the class that you are targeting as well. The targeted class itself remains untouched. It may not yet be written – if it’s added to your app in the future, the rule will then match and the code will be injected.
Maybe you have read the above paragraph twice and are asking yourself: Is this magic? What’s the damn trick? – I sure did, when I was first introduced to AOP!
Well, AOP has been around for some time in the Java world. FLOW3 is heavily inspired by the AOP implementation of Spring, a Java Framework. The word was on the street, that the pattern can’t be transferred to interpreted languages, because it requires compilation.
The trick is, that the framework – or some tools like JAspect – intercepts the compilation process (from Java code to bytecode, that can be executed by the Java runtime) and do an analysis of the defined aspects. Whenever a set of rules (aka the pointcut) matches a method, it is weaved directly into the compiled code. Hence, the framework takes care of merging the code parts together:

FLOW3 did adapt that concept to the world of PHP by introducing an advanced cache. While most frameworks offer caching to increase performance, FLOW3 additionally uses the cache to weave aspects into the original classes.
If you are running your app, FLOW3 delivers the cached classes instead the ones you’ve written. Hence, your original code remains untouched.
This sounds complex – and it is: FLOW3 performs some really advanced PHP techniques under the hood, that are well worth to be explored! But: To you as an application developer, it’s not complicated at all. You don’t have to care, if you don’t want to: FLOW3 monitors your files for changes and if you make some, FLOW3 auto-commits them to the cache upon your next request. If an aspect matches to a method, it’s automatically weaved in – no further configuration needed.
It’s a complex pattern conveniently at your service!
Every cool feature comes with a downside – so does FLOW3. At the moment, we just scratched the surface of what FLOW3′s caching-mechanism is capable of, but I want to give you an idea.
Take a look at the following code:
/**
* @FLOW3Inject
* @var YourAppMailerServiceInterface
*/
protected $mailer;
/**
* Sends a mail.
*
* @param YourAppModelUser $user
* @param string $message
*/
protected function sendMail(YourAppModelUser $user, $message) {
// Sends a mail.
}
The consequence is that PHP is to some degree no longer an interpreted language.
This may look like some code that is just well documented. But it’s much more.
The first property annotation (FLOW3Inject) tells FLOW3 to look for some class in your app that implements the MailerServiceInterface and injects it here (and maybe configure it before). This pattern is known as Dependency Injection.
The second class defines some type definitions in its comment’s annotations – and FLOW3 uses them. If you’re giving the method some data that can be used to build a User object of your model (for example an array with pure strings from a HTML form), FLOW3 auto-transforms the data safely to a User object and applies some security and validation rules to the second parameter (in this case a string).
This is (among some other tricks) done by weaving in some code into the cache.
The consequence is that PHP is to some degree no longer an interpreted language. The process of caching is somewhat similar to compiling and it has the same downsides: You can’t just save & refresh your browser, you have to wait for the cache to be warmed up during development. If you are committing code to your production environment, you have to flush the cache in order to see the changes.
On top of that, FLOW3 adds some kind of type-validation at runtime: You can’t pass an integer as second argument in the example above – it’ll throw an error. I really like this, because I have a background in strictly typed languages like Java and ActionScript. It also adds a lot of security to your application. But if you’re a PHP purist, this may be something that you don’t want.
Alright, enough with theory. Let’s get our hands dirty.
Setting up FLOW3 is pretty straightforward, if you already have a PHP-capable server like XAMP or MAMP installed. Just grab a copy of the framework from FLOW3′s download site (or clone from git) and unpack it into your htdocs directory.
You should already be done now on Windows machines. Unix-based systems like MAC or Linux need to grant the required rights for building the cache. FLOW3 ships with a powerful command line tool, that packs this task into a one-liner:
# On linux: ./flow3 core:setfilepermissions chris www-data www-data # On Mac: ./flow3 core:setfilepermissions chris _www _www
Please replace chris with your username! This should be enough. However, I’ve installed FLOW3 on various machines and have run into some problems. The most common ones are:
If you run into problems, that are not listed here, please post them in the comments!
Now fire up your favorite browser and navigate to http://localhost/flow3/Web! FLOW3 should welcome you with an introduction screen:

This is the Welcome Package. Every application in FLOW3 (and FLOW3 itself) is a package and packages can share code with each other. For example, once the new TYPO3 Version is finished, you can add it as a package and your application will then have an enterprise-ready CMS on top!
Let’s start our own package. It’s an easy task, because FLOW3′s command line tool will handle most of the work! Type in the following command:
# On linux / MAC ./flow3 kickstart:package Nettuts.AspectDemo # On Windows flow3 kickstart:package Nettuts.AspectDemo
This will create a ready-to-go package named
Nettuts.AspectDemo in FLOW3′s Packages/Application
folder. If you review the file structure, you will find many
folders that do follow a specific convention.
The important ones are:
Building a full-featured app is beyond the scope of this
tutorial, so we’ll go with the defaults. Please open the following
URL:
http://localhost/flow3/Web/index.php/Nettuts.AspectDemo

This is not much, but it’s a start. We want to write something to a logfile, every time this site is called. We do this by weaving in an aspect into the StandardController!
Take a look at the StandardController in theClasses/Controller
Folder in your Nettuts.AspectDemo Package.
It implements a method, named indexAction(). FLOW3
has automatically configured our app in a way, that this method
inside the StandardController gets called when we enter the URL
above.
For the moment, we see that this method assigns some strings to the view:
/**
* Index action
*
* @return void
*/
public function indexAction() {
$this->view->assign('foos', array(
'bar', 'baz'
));
}
If you open the file index.html of this view in Resources/Private/Templates/Standard inside our package, you’ll see how these strings are processed by the templating engine.
However, our goal is to intercept the code execution before this method gets called.
At first, create an empty file named Access.log in FLOW3′s Log folder at flow3/Data/Logs. You may save this file wherever you want, but this is a nice place for log files.
Next, create a folder named Service in your Nettuts.AspectDemo/Classes Folder and inside of it, create another folder, and name it Logging. Then create a PHP file named LoggingAspect.php inside of it. It should have the following content:
<?php
namespace NettutsAspectDemoServiceLogging;
use TYPO3FLOW3Annotations as FLOW3;
/**
* @FLOW3Aspect
*/
class LoggingAspect {
/**
* Log a message if this site is called.
*
* @param TYPO3FLOW3AOPJoinPointInterface $joinPoint
* @FLOW3Before("method(NettutsAspectDemoControllerStandardController->indexAction())")
* @return void
*/
public function logSiteAccess(TYPO3FLOW3AOPJoinPointInterface $joinPoint) {
$filePath = '/home/chris/www/flow3/Data/Logs/Access.log';
$message = 'The site has been accessed at ' . time() . '.' . PHP_EOL;
file_put_contents($filePath, $message, FILE_APPEND);
}
}
?>
This is a very basic class, and if you’d like to have an advanced logger, you may want to separate the logging from the intercepting aspect.
What’s going on here? At first, we define a namespace, which is your package name and the path to the actual class (without the class folder itself). Next, we import FLOW3′s annotation namespace. Thus, we can use FLOW3′s powerful annotation parser to configure our class.
That’s exactly what we do in the class comments. We define the class as aspect with the following annotation:
/** * @FLOW3Aspect */
From now on, FLOW3 is aware that this class may define rules for the interception of the code flow and watches our codebase for matches.
This is the rule:
@FLOW3Before("method(NettutsAspectDemoControllerStandardController->indexAction())")
We could use regular expressions or
some other techniques to match multiple methods or classes, but
we know exactly where we want to go: Before the
indexAction() Method in the StandardController – and
that’s exactly what we’re telling FLOW3.
Note the $jointInterface Parameter of the
logSiteAccess() Method, that is provided to us by
FLOW3. We don’t use it here, but it contains some useful data about
the actual context. For example, if the intercepted method would
have arguments, that we may want to use, we could access them like
this:
$argument = $joinPoint->getMethodArgument('argumentName');
The code in our logSiteAccess() method, itself, is
fairly simple. Just adjust the path to the Access.log to your
environment and you’re good to go!
Now, again, open
http://localhost/flow3/Web/index.php/Nettuts.AspectDemo
– nothing should have changed. But when you open the Access.log
file, you should see the following entry:
The site has been accessed at 1335715244.
If you can read this, the aspect has been weaved into the cache. Let’s have a look at the magic!
FLOW3 stores the cache at
flow3/Data/Temporary/Development/Cache/Code/FLOW3_Object_Classes.
You will find a class named
Nettuts_AspectDemo_Controller_StandardController_Original.php.
This is the original class from our codebase.
But there is another class:
Nettuts_AspectDemo_Controller_StandardController.php.
This class extends our original class and it is build up purely by
generated code. Among the many lines you’ll find something like
this:
$this->FLOW3_Aop_Proxy_targetMethodsAndGroupedAdvices = array(
'indexAction' => array(
'TYPO3FLOW3AopAdviceBeforeAdvice' => array(
new TYPO3FLOW3AopAdviceBeforeAdvice(
'NettutsAspectDemoServiceLoggingLoggingAspect', 'logSiteAccess'
$objectManager, NULL),
),
),
);
This is were FLOW3 initiates the aspect and it’s weaved in directly into your class. The aspect gets executed right where we want it – without touching the original controller.
The code snippet initiates an instance of the
BeforeAdvice class, with our aspect, the respective
method and the $objectManager as arguments. The object
manager contains the needed information to build the
jointInterface, that is passed to the aspect.
If you’re interested in the details, have a look at the AOP Folder in the FLOW3 package!
The aspect oriented approach has many advantages waiting to be discovered.
The aspect oriented approach has many advantages waiting to be discovered. For example, FLOW3 uses AOP to intercept its own bootstrap to build up a firewall if you choose to use FLOW3′s security framework. Apart from that, we haven’t yet discussed the specific terminology that is commonly used in AOP.
However, FLOW3 ships with some other unique concepts like Domain-Driven-Design. It has a powerful Doctrine integration and a smart Templating Engine. We have only seen the tip of the iceberg!
What’s your opinion? Are you eager to learn more about the philosophy behind FLOW3? What’s your impression of AOP? Are you excited to have a robust port for the PHP world or do you think it’s too much overhead for an interpreted language?
Interaction designers create wireframes in tools such as Adobe Illustrator, OmniGraffle and Microsoft Visio. Originally, these wireframes were primitive shapes drawn to represent various UI elements. Many of us cannot imagine life without them.
There are, however, reasons to consider moving to the cloud to do interaction design. In short, today’s cloud-based tools are:
Emailing your old static designs will feel old fashioned once you see what these tools can do. Going a step further, there are tools for the user review process, too. Just upload your ideas, from simple mockups to final layouts, link them together, and share them for comment.
(Image credit: baldiri)
This article walks you through the current selection of cloud-based tools and provides some recommendations. The number of offerings and amount of functionality are pretty vast. For the sake of brevity, we’ll address two functions: prototyping and wireframing. But if you’re intrigued, you might want to explore cloud-based image editing, mind-mapping tools and other UX activities. These tools are already out there, and surprisingly good.
For our purposes, prototyping involves uploading images (screens) and linking them together via hotspots. Once these are set up, the prototype is published and available to reviewers for usability testing, commenting or both.
Review criteria Here are the fundamentals that a product should support in order to compete in this space:
Some items aren’t available as of this writing:
What it does Create your screens in your favorite tool and upload them to InVision. Then add hotspots; a hotspot links to another page. This is great if you live and die by the comp (Photoshop file). For example:



Observations The application works as advertised. It enables the user to quickly wire up prebuilt comps, wireframes and sketches. The tutorials also explain useful actions, such as creating hotspots that will be the same on multiple pages (these are called “templates” in InVision).
Speaking of templates, they expose both a major advantage and a major disadvantage of this tool: if the uploaded images are not placed perfectly, then the templates will not line up properly. One would want the ability to adjust the x and y coordinates of any image so that they line up perfectly without having to change the source files. On the upside, if you’ve done the prep work right or you’ve made your hotspots large enough, you can fudge this a bit, and the templates really accelerate the build process.
A number of usability issues have made me scratch my head. For example, the first time I tried adding a hotspot to the search input field, the “Link to…” modal dialog was off to the left side of the browser, which made it impossible to save or cancel the dialog. I then tapped the “Update screen” at the bottom of app to refresh the screen. It turns out that in InVision speak, “Update” = “Replace.” I was afraid to refresh the browser because there is no indication of whether the application saves automatically. So, in the end, I switched to “Preview” and then back to “Build.”
Once you’re familiar with the quirks, however, the application is useful. If you’re a designer or want to work offline to generate wireframes, then give this app a hard look.
In spirit, FieldTest (in private beta) serves the same space as InVision. The designer uploads prebuilt comps, wireframes and the like to FieldTest, ties them together, and then publishes them for review. One advantage is that FieldTest leverages device gestures. In short, you can “play” FieldTest prototypes on your iOS, Android or Windows Phone 7 device and have it respond to gestures. Combined with the built-in screen transitions, this is a powerful function for mobile app designers.
As with InVision, screens are grouped into “prototypes” (projects). Including them in a project means that they can be linked to and from other screens. The process is the same, too: create the prototype collateral, link it together via hotspots, and publish it for review. For comparison’s sake, here are the hotspot configurations for the two apps.

This demonstrates the differences in approach. On the top is FieldTest. It allows a user to choose between gestures (the prototype I built was an iPhone app). The gestures are tap, long tap, swipe, swipe left and swipe right. Multiple gestures can be active for the same hotspot, which is particularly cool and gives a realistic experience of various actions. On the bottom is InVision, whose ace is templates. The author can create a template for several controls that appear together, and they can reuse that template on several screens.
Observations If I were to choose between these prototyping tools, FieldTest would be my choice, largely because I build mobile applications. Having listeners for multiple gesture types makes for a more realistic prototype. If the app were Web-based, then InVision is more mature.
FieldTest still has work to do, though. In the beta, gestures such as up and down are missing. Templating as InVision does is really useful. It streamlines the addition of hotspots. Another area for improvement is in comments, and allowing a prototype’s end user to provide feedback.
There are other usability nits. For example, FieldTest includes a status bar at the top of each screen. I have yet to figure out why someone would want this, and it’s not optional. So, if you take a screenshot on an iPhone, you’ll have to edit it to remove this status bar, only for FieldTest to put it back.
Try it out for yourself on the prototype built for this review. Please note, there is no down gesture, so if you want to try that, gesture from right to left (like when advancing through pictures in iPhoto).
ClickDummy is another competitor in this space and has the same process as the others. The user uploads materials and then links them together through hotspots. The link function is a “tool” contained in a drawer (i.e. a UI element that slides in and out from one side of the screen).

Observations This drawer seems innocent enough, but it creates unnecessary hurdles for the user. In an attempt to simplify the problem, it has added confusion and multiple steps to an easy process. How? The user has to toggle between this tool drawer and the page-picker drawer a lot. The page picker also has to be overloaded in order to provide both functions (selecting a page, as in navigation, and selecting a page, as in a hotspot target).
A second issue: the website says that the user can drag and drop images onto the pages drawer. This doesn’t work in my (Chrome) browser. It instead replaces the current page with the image. After a panicked “Backspace,” the user is restored to their project but has lost their location and has to start over.
Another point: this all-important drawer is closed when the app launches. It took about five minutes to determine that the app was working, and this after weeks of looking at apps in this space.
Lastly, unlike both of the apps reviewed above, this one has no compelling feature that makes the additional effort worth the time. In future, hopefully, the addition of some product differentiation, combined with a rework of the primary use case, would make this application worth another look.
You can see the output from this exploration for yourself.
Think of a wireframe as a black and white low-fidelity screen mockup. The mockups I create also include call-outs to give the development team additional context.
In the process, the user will create an account, create a project, and then land on a blank screen. The user then drag and drops UI controls (radio buttons, text input fields and so forth) onto the page.
Once the project is saved, a permalink can be given out for people to see your work. If you change a screen, it will auto-magically show your updates the next time that URL is opened (or refreshed) by a team member. This last point is what the cloud is all about: everyone always has the same (i.e. current) version of your work. Changes are instantaneously available whenever the wireframe is saved.
Compared to most offline tools, the library of available objects is focused on low-fidelity UX. Don’t expect to create gradients or to use a pencil tool.
Review criteria Here are some basics that are fairly universal in my experience:
Here’s what you won’t see right away from the tools out there:
As with the prototyping tools, wireframes — or “mockups” in Balsamiq-speak — are organized into projects. From there, things change. Tools like InVision and FieldTest assume that you have created your pages or screens in another tool. In Balsamiq (and Mockingbird, discussed next), the tool is designed for wireframe creation, with extremely limited functionality for prototyping.



Observations Having worked with some other tools, I’ve become a fan of Balsamiq. A great UI control library and easy object configuration are two areas where this tool excels. There are some areas for improvement, though. First, and I’m sure the development team is tired of hearing it, the sketching style is fine for those who understand low-fidelity mockups, but you probably wouldn’t want to show the mockups to your CEO.
A second gripe is that the editing tool is built in Flash, so work is limited to platforms that support it.
On the upside, a few non-obvious pros:
+ Add and
sub-menu, > translates to:![]()
And here’s the rundown:
Mockingbird is also a wireframing tool, and a good one at that. In some ways, it compares favorably to Balsamiq: Mockingbird’s editor isn’t Flash-based; it uses an unobtrusive font; and adding UI controls is (almost) comparable to Balsamiq.
The process is similar, too. Here’s the outcome:

Observations More professional, right? On the surface, it is more polished, but there are some subtle shortcomings. For example, one cannot left-justify text in an input field. Also, I couldn’t get the icons to all be exactly the same size (36 pixels). And so forth.
There are some logistical hurdles as well. Many of the controls are primitive. To add a call-out, like ones in yellow above, you actually have to add two objects: the yellow circle and the black text. And when a control is added via the quick-add function, the filtering text is not cleared, so after every addition, one has to clear the previous query. Put practically, this mockup took about four times as long to create as the Balsamiq version.
Another entry in the wireframing space is Mockup Builder. Functionally, it lies somewhere between Mockingbird and Balsamiq. It has a fairly good library of controls — in fact, it’s the only cloud-based solution with native Android controls (Ha!). Moreover, I find its aesthetic better than that of competitors.
Like the others, Mockup Builder starts with a blank canvas, and the user drag and drops controls onto the canvas for configuration.
Here’s the mockup created for this review:

Again, the mockup is fairly clean, but there are some issues: the icons use some funny clipping, and they do not scale properly. The user cannot toggle the various defaults for the iPhone, such as the gray bars at the top and bottom of the screen.
Observations This tool is a little too buggy for everyday use. For example, the notes to accompany illustrations are in Lorem Ipsum text. Also, when copying text from the Web and pasting into a multi-line text area, the text does not wrap to the control’s width — meaning that the text shows exactly one line, and the user has to use the control’s handles to wrap it. I also wanted to show two paragraphs of text but could not figure out how to insert a “Return” in the text.
Another grievance: the tool could use more polish. For example, the screen surface on the iPhone control is narrower than the keyboard, so the user has to resize the keyboard by hand. When that’s done, the “e” is missing in the button. I understand that these are minor, but one would expect these t’s to be crossed off before moving away from a beloved tool like OmniGraffle.
Cloud-based tools are now available and well designed for UX work. Many of the features in the offerings above are not available in software running locally on your machine. While this space is still growing, I’ve been working in the cloud for the past two years and cannot imagine going back.
Collaboration is instantaneous, and the tools are optimized for the right activities: wireframing and testing with users. In fact, these apps have several unexpected and delightful features, and you might find yourself walking away from your favorites, too.
Of course, there are valid reasons to avoid working in the cloud. Stay with your old standbys if any of the following apply:
These could be a deal-breaker for some. But these tools are free to try, and some are so simple that you might get hooked in five minutes (as I did a few years ago). Almost all of the research for this article was done with free trials. Given the ease with which you can try these out, you have every reason to go out and see whether one or more is right for you.
If you have another favorite, we’d love to learn about it. The space is ever changing!
(al)
© Erik Perotti for Smashing Magazine, 2012.
We’re planning our next few Tuts+ sites, and would love your opinion and advice on which topics you think we should cover next! We’d be really grateful if you could take a minute to answer our quick poll and share your thoughts…
We’ve been considering lots of different ideas for our next Tuts+ sites over the past few weeks, and wanted to also ask the opinion of our awesome community!
A selection of different concepts are included in the poll to the right, along with the option for you to submit your own ideas as well.
The important thing to note is that these are just ideas. Some of these are close to making our final cut, and others aren’t… We’d love to hear what you think, to help guide our decision.
Thanks for taking the time to offer your suggestion — I can’t wait to see what you have to say!
Our poll will be running for the next couple of weeks, and we’ll be choosing one respondent at random to receive a six-month Tuts+ Premium membership!
To be entered into the giveaway, just leave a comment on this post to go into a bit more detail about your site suggestion. We’ll choose one comment at random to win the Tuts+ Premium membership when the poll ends.
Best of luck!
The Web has become increasingly interactive over the years. This trend is set to continue with the next generation of applications driven by the real-time Web. Adding real-time functionality to an application can result in a more interactive and engaging user experience. However, setting up and maintaining the server-side real-time components can be an unwanted distraction. But don’t worry, there is a solution.
Cloud hosted Web services and APIs have come to the rescue of many a developer over the past few years, and real-time functionality is no different. The focus at Pusher, for example, is to let you concentrate on building your real-time Web applications by offering a hosted API which makes it quick and easy to add scalable real-time functionality to Web and mobile apps. In this tutorial, I’ll show how to convert a basic blog commenting system into a real-time engaging experience where you’ll see a comment made in one browser window "magically" appear in a second window.
Although the Real-Time Web is a relatively recent mainstream phrase, real-time Web technologies have been around for over 10 years. They were mainly used by companies building software targeted at the financial services sector or in Web chat applications. These initial solutions were classed as "hacks". In 2006 these solutions were given an umbrella term called Comet, but even with a defined name the solutions were still considered hacks. So, what’s changed?
In my opinion there are a number of factors that have moved real-time Web technologies to the forefront of Web application development.
Social media, and specifically Twitter, has meant that more and more data is becoming instantly available. Gone are the days where we have to wait an eternity for Google to find our data (blog posts, status updates, images). There are now platforms that not only make our data instantly discoverable but also instantly deliver it to those who have declared an interest. This idea of Publish/Subscribe is core to the real-time Web, especially when building Web applications.
As more users moved to using applications such as Twitter and Facebook, and the user experiences that they deliver, their perception of what can be expected from a Web application changed. Although applications had become more dynamic through the use of JavaScript, the experiences were seldom truly interactive. Facebook, with it’s real-time wall (and later other realtime features) and Twitter with it’s activity stream centric user interface, and focus on conversation, demonstrated how Web applications could be highly engaging.

Earlier on I stated that previous solutions to let servers instantly push data to Web browsers were considered "hacks". But this didn’t remove the fact that there was a requirement to be able to do this in a cross-browser and standardised way. Our prayers have finally been answered with HTML5 WebSockets. WebSockets represent a stardardized API and protocol that allows realtime server and client (web browser) two way communication over a single connection. Older solutions could only achieve two-way communication using two connections so the fact the WebSockets use a single connection is actually a big deal. It can be a massive resource saving to the server and client, with the latter being particularly important for mobile devices where battery power is extremely valuable.
Real-time Web technologies are making it possible to build all sorts of engaging functionality, leading to improved user experiences. Here are a handful of common use cases:
In the rest of this tutorial I’ll cover building a basic blog commenting system, how to progressively enhance it using jQuery and finally I’ll also progressively enhance it using the real-time Web service I work for, Pusher, which will demonstrate not just how easy it can be to use real-time Web technology, but also the value and increased engagement that a real-time factor can introduce.
I want to focus on adding real-time commenting to a blog post so let’s start from a template.
This template re-uses the HTML5 layout defined in the post on Coding An HTML 5 Layout From Scratch and the file structure we’ll start with is as follows (with some additions that we don’t need to worry about at the moment):
The template HTML, found in index.php, has been changed from the HTML5 Layout article to focus on the content being a blog post with comments. You can view the HTML source here.
The main elements to be aware of are:
<section id="content"> – the blog post
content<section id="comments"> – where the comments
are to appear. This is where the majority of our work will be
doneNow that we’ve got the HTML in place for our blog post and for
displaying the comments we also need a way for our readers to
submit comments, so let’s add a <form> element
to collect and submit the comment details to
post_comment.php. We’ll add this at the end of the
<section id="comments"> section wrapped in a
<div id="respond">.
<div id="respond">
<h3>Leave a Comment</h3>
<form action="post_comment.php" method="post" id="commentform">
<label for="comment_author" class="required">Your name</label>
<input type="text" name="comment_author" id="comment_author" value="" tabindex="1" required="required">
<label for="email" class="required">Your email;</label>
<input type="email" name="email" id="email" value="" tabindex="2" required="required">
<label for="comment" class="required">Your message</label>
<textarea name="comment" id="comment" rows="10" tabindex="4" required="required"></textarea>
<-- comment_post_ID value hard-coded as 1 -->
<input type="hidden" name="comment_post_ID" value="1" id="comment_post_ID" />
<input name="submit" type="submit" value="Submit comment" />
</form>
</div>
Let’s apply some CSS to make things look a bit nicer by adding the following to main.css:
#respond {
margin-top: 40px;
}
#respond input[type='text'],
#respond input[type='email'],
#respond textarea {
margin-bottom: 10px;
display: block;
width: 100%;
border: 1px solid rgba(0, 0, 0, 0.1);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-o-border-radius: 5px;
-ms-border-radius: 5px;
-khtml-border-radius: 5px;
border-radius: 5px;
line-height: 1.4em;
}
Once the HTML structure, the comment form and the CSS are in place our blogging system has started to look a bit more presentable.

The next step is to write the PHP form submission handler which accepts the request and stores the comment, post_comment.php. You should create this file in the root of your application.
As I said earlier I’m keen to focus on the real-time functionality so a class exists within the template that you’ve downloaded which encapsulate some of the standard data checking and persistence functionality. This class is defined in Persistence.php (you can view the source here), is in no way production quality, and handles:
$_SESSION.
This means that a comment saved by one user will not be available
to another user.This also means that we don’t need to spend time setting up a database and all that goes with it and makes post_comment.php very simple an clean. If you wanted to use this functionality in a production environment you would need to re-write the contents of Persistence.php. Here’s the code for post_comment.php.
<?php
require('Persistence.php');
$db = new Persistence();
if( $db->add_comment($_POST) ) {
header( 'Location: index.php' );
}
else {
header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
?>
The above code does the following:
Persistence object
and assigns it to the variable $db.$db. If the
comment is successfully added it redirects back to the blog post.
If it fails the redirection also occurs but some error text is
appended to an error query parameter.The final thing we need to do to have our Generic Blog
Commenting System up and running is to update the blog page,
index.php, to fetch and display the comments from the
Persistence object.
$comment_post_ID value to be 1.$comment_post_ID.
<?php
require('Persistence.php');
$comment_post_ID = 1;
$db = new Persistence();
$comments = $db->get_comments($comment_post_ID);
$has_comments = (count($comments) > 0);
?>
Since we now have the $comment_post_ID accessible
via PHP we should update the HTML for the comment form to use this
value.
<input type="hidden" name="comment_post_ID" value="<?php echo($comment_post_ID); ?>" id="comment_post_ID" />
We now have all the comments related to the blog post referenced
by the $comments variable we need to display them on
the page. To do this we need to update the PHP in
index.php to iterate through them and create the required
HTML.
<ol id="posts-list" class="hfeed<?php echo($has_comments?' has-comments':''); ?>">
<li class="no-comments">Be the first to add a comment.</li>
<?php
foreach ($comments as $comment) {
?>
<li><article id="comment_<?php echo($comment['id']); ?>" class="hentry">
<footer class="post-info">
<abbr class="published" title="<?php echo($comment['date']); ?>">
<?php echo( date('d F Y', strtotime($comment['date']) ) ); ?>
</abbr>
<address class="vcard author">
By <a class="url fn" href="#"><?php echo($comment['comment_author']); ?></a>
</address>
</footer>
<div class="entry-content">
<p><?php echo($comment['comment']); ?></p>
</div>
</article></li>
<?php
}
?>
</ol>
You’ll notice that if the value of $has_comments is
true an additional CSS class is applied to the ordered list called
has-comments. This is so we can hide the list item with
the "Be the first to add a comment" message when comments are being
displayed using CSS:
#posts-list.has-comments li.no-comments {
display: none;
}
Now that all this is in place we have a functional blog commenting system. If you would like to start writing your code from this basic functioning blog commenting system you can also download the code completed up to here.

The first step in making our blog commenting system feel less like a Web page and more like an application is to stop page reloads when a user submits a comment. We can do this by submitting the comments to the server using an AJAX request. Since jQuery is probably the defacto standard for cross browser JavaScript functionality we’ll use it here. Although I’m using jQuery here, I’d also like to highlight that it’s a good idea to not always use jQuery. Instead, analyze your scenario and make a considered decision because there are some cases where you are best not to.
In an attempt to try and keep as much scripting (PHP and JavaScript) from the index.php file we’ll create a new folder for our JavaScript and in there a file for our application JavaScript. The path to this fill should be js/app.js. This file should be included after the jQuery include.
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="js/app.js"></script>
When the page is ready bind to the submit event of
the form.
$(function() {
$('#commentform').submit(handleSubmit);
});
When the form is submitted and the handleSubmit
function is called the comment data we want to send to the server
is extracted from the form. There are more elegant ways of fetching
the data from the form but this approach clearly shows where we’re
getting the values from and the data object we are
creating.
function handleSubmit() {
var form = $(this);
var data = {
"comment_author": form.find('#comment_author').val(),
"email": form.find('#email').val(),
"comment": form.find('#comment').val(),
"comment_post_ID": form.find('#comment_post_ID').val()
};
postComment(data);
return false;
}
function postComment(data) {
// send the data to the server
}
Within the postComment function make a
POST request to the server passing the data that we’ve
retrieved from the form. When the request is made an additional
HTTP header will be sent to identify the request as being an AJAX
request. We want to do this so that we can return a JSON response
if it is an AJAX request and maintain our basic functionality if it
isn’t (for more information on this see
Detected AJAX events on the Server). We also define two
handlers; postSuccess for handling the comment being
successfully stored and postError to handle any
failures.
function postComment(data) {
$.ajax({
type: 'POST',
url: 'post_comment.php',
data: data,
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
success: postSuccess,
error: postError
});
}
function postSuccess(data, textStatus, jqXHR) {
// add comment to UI
}
function postError(jqXHR, textStatus, errorThrown) {
// display error
}
At this point the comment data is being sent to the server and saved, but the AJAX response isn’t providing any meaningful response. Also, the comments section isn’t being updated to show the newly submitted comment so the user would have to refresh the page to see it. Let’s start by writing the code to update the UI and test that functionality.
If you are thinking "Hang on a minute! We don’t have all the data we need from the Web server to display the comment" then you are correct. However, this doesn’t stop us writing the code to update the UI and also testing that it works. Here’s how:
function postSuccess(data, textStatus, jqXHR) {
$('#commentform').get(0).reset();
displayComment(data);
}
function displayComment(data) {
var commentHtml = createComment(data);
var commentEl = $(commentHtml);
commentEl.hide();
var postsList = $('#posts-list');
postsList.addClass('has-comments');
postsList.prepend(commentEl);
commentEl.slideDown();
}
function createComment(data) {
var html = '' +
'<li><article id="' + data.id + '" class="hentry">' +
'<footer class="post-info">' +
'<abbr class="published" title="' + data.date + '">' +
parseDisplayDate(data.date) +
'</abbr>' +
'<address class="vcard author">' +
'By <a class="url fn" href="#">' + data.comment_author + '</a>' +
'</address>' +
'</footer>' +
'<div class="entry-content">' +
'<p>' + data.comment + '</p>' +
'</div>' +
'</article></li>';
return html;
}
function parseDisplayDate(date) {
date = (date instanceof Date? date : new Date( Date.parse(date) ) );
var display = date.getDate() + ' ' +
['January', 'February', 'March',
'April', 'May', 'June', 'July',
'August', 'September', 'October',
'November', 'December'][date.getMonth()] + ' ' +
date.getFullYear();
return display;
}
The code above does the following:
postSuccess function we clear the form
values and call displayComment.displayComment first calls the
createComment function to create the list item
(<li>) HTML as a String.$(commentHtml) and hide the element.<ol>). The list also has a class called
has-comments added to it so we can hide the first list
item which contains the "Be the first to comment" statement.commentEl.slideDown() so that the
comment is shown in what is becoming the standard "here’s a new
item" way.The functionality is now implemented but we want to test it out. This can be achieved in two ways:
displayComment is a global function so we can
call it directly using the JavaScript console of the browser.displayComment functionLet’s go with the latter and bind to the "u" key being
released by binding to the keyup event. When it is,
we’ll create a fake data object containing all the
information required to create a new comment and pass it to the
displayComment function. That comment will then be
displayed in the UI.
Hit the "u" key a few times and see the comments appear.
$(function() {
$(document).keyup(function(e) {
e = e || window.event;
if(e.keyCode === 85){
displayComment({
"id": "comment_1",
"comment_post_ID": 1,
"date":"Tue, 21 Feb 2012 18:33:03 +0000",
"comment": "The realtime Web rocks!",
"comment_author": "Phil Leggetter"
});
}
});
});
Great! We now know that our displayComment function
works exactly as we expect it to. Remember to remove the
test function before you go live or you’ll really confuse
your user every time they press "u".

All that’s left to do is update the post_comment.php file to detect the AJAX call and return information about the newly created comment.
Detecting the AJAX request is done by checking for the
X-Requested-With header:
$ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');
Once we know the request is an AJAX request we can update the code to respond with an appropriate status code and the data representing the comment. We also need to ensure that the original functionality is maintained. The post_comment.php code now looks as follows:
<?php
require('Persistence.php');
$ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');
$db = new Persistence();
$added = $db->add_comment($_POST);
if($ajax) {
sendAjaxResponse($added);
}
else {
sendStandardResponse($added);
}
function sendAjaxResponse($added) {
header("Content-Type: application/x-javascript");
if($added) {
header( 'Status: 201' );
echo( json_encode($added) );
}
else {
header( 'Status: 400' );
}
}
function sendStandardResponse($added) {
if($added) {
header( 'Location: index.php' );
}
else {
header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
}
?>
Key points from the above code are:
$db->add_comment($_POST) call returns the
data from the added comment which is assigned to the
$added variable.The blog commenting system now works in a much more dynamic way, instantly showing the user that their comment has been posted without refreshing the page. In addition, the way the we’ve added the JavaScript based functionality to the page means that if JavaScript is disabled or a JavaScript file fails to load that the system will fallback to the standard functionality we first implemented.
As with any "from scratch" tutorial it can take a bit of time to get to the really interesting part, but we’re finally here. However, all the work we’ve up in has been worth it. Because we’ve built our commenting system up in a progressively enhanced way, plugging Pusher into it is going to be really easy
At the start of the tutorial we said that we would use Pusher to add the realtime functionality to the application. But what is Pusher?
Pusher is a hosted service for quickly and easily adding realtime features into Web and mobile applications. It offers a RESTful API that makes it really easy to publish events from any application that can make a HTTP request and a WebSocket API for realtime bi-directional communication. You don’t even need to use the APIs directly as there are server (PHP, Ruby, node.js, ASP.NET, Python and more) and client (JavaScript, iOS, Android, .NET, ActionScript, Arduino and more) libraries available in a host of technologies which means you can add realtime functionality to an app within minutes ‐ I’m confident you’ll be surprised just how easy!
In order to add Pusher-powered real-time functionality to a Web application you first need to sign up for a free Sandbox account. After you have signed up you’ll be taken to the Pusher dashboard where you’ll see that a "Main" application has been created for you. You’ll also see you are in the "API Access" section for that application where you can grab your API credentials.

For ease of access create a pusher_config.php file and
define the credentials in there so we can refer to
them later:
<?php
define('APP_ID', 'YOUR_APP_ID');
define('APP_KEY', 'YOUR_APP_KEY');
define('APP_SECRET', 'YOUR_APP_SECRET');
?>
In your version of pusher_config.php be sure to replace the values which being ‘YOUR_ with your actual credentials.
You should also require this in your
index.php file. We should also make the
APP_KEY available to the JavaScript runtime as we are
going to need it to connect to Pusher.
<?php
require('pusher_config.php);
?>
<script>
var APP_KEY = '<?php echo(APP_KEY); ?>';
</script>
The first thing you need to do when adding Pusher to a Web application is include the Pusher JavaScript library and connect to Pusher. To connect you’ll need to use the key which you grabbed from the Pusher dashboard. Below you can see all that is required to hook up the front-end application to Pusher.
Include the Pusher JavaScript library after the app.js include:
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://js.pusher.com/1.11/pusher.min.js"></script> <script src="js/app.js"></script>
Add the Pusher functionality to app.js:
var pusher = new Pusher(APP_KEY);
var channel = pusher.subscribe('comments-' + $('#comment_post_ID').val());
channel.bind('new_comment', displayComment);
This probably looks too easy to be true, so here are the details about what the above code does:
var pusher = new Pusher(APP_KEY);
Creates a new instance of a Pusher object and in doing
so connects you to Pusher. The application to use is defined by the
APP_KEY value that you pass in and that we set up
earlier.var channel = pusher.subscribe('comments-' +
$('#comment_post_ID').val());
Channels provide a
great way of organizing streams of real-time data. Here we are
subscribing to comments for the current blog post, uniquely
identified by the value of the comment_post_ID hidden
form input element.channel.bind('new_comment', displayComment);
Events
are used to further filter data and are ideal for linking updates
to changes in the UI. In this case we want to bind to an event
which is triggered whenever a new comment is added and display it.
Because we’ve already created the displayComment
function we can just pass in a reference to the call to
bind.We can also test out this functionality without writing any server-side code by using the Event Creator for your app which can also be found in the Pusher dashboard. The Event Creator lets you publish events on a channel through a simple user interface. From the code above we can see that we want to publish an event named "new_comment" on the "comments-1" channel. From the earlier test function we also have an example of the test data we can publish.

Again, we’ve proven that our client-side functionality works without having to write any server-side code. Now lets add the PHP code we need to trigger the new comment event as soon as a comment is posted in our comment system.
Pusher offers a number of server-side libraries which make it easy to publish events in addition to helping with functionality such as private channel authentication and providing user information for presence channels. We just want to use the basic event triggering functionality in the post_comment.php file so we need to download the Pusher PHP library (direct zip file download).
Once you’ve downloaded this zip file, unzip it into the directory along with your other files. Your file structure will now look something like this:
An event can be triggering in just a few lines of code:
<?php
require('squeeks-Pusher-PHP/lib/Pusher.php');
require('pusher_config.php');
$pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
$pusher->trigger('comments-1', 'new_comment', array(
"comment_post_ID" => 1,
"date" => "Tue, 21 Feb 2012 18:33:03 +0000",
"comment" => "The realtime Web rocks!",
"comment_author" => "Phil Leggetter"
));
?>
However, we need to apply a some additional logic before we trigger the event:
$added array.$added data. Note: The library automatically
converts the $added array variable to JSON to be sent
through Pusher.Therefore the full post_comment.php file ends up looking as follows:
<?php
require('Persistence.php');
require('squeeks-Pusher-PHP/lib/Pusher.php');
require('pusher_config.php');
$ajax = ($_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest');
$db = new Persistence();
$added = $db->add_comment($_POST);
if($added) {
$channel_name = 'comments-' . $added['comment_post_ID'];
$event_name = 'new_comment';
$pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID);
$pusher->trigger($channel_name, $event_name, $added);
}
if($ajax) {
sendAjaxResponse($added);
}
else {
sendStandardResponse($added);
}
function sendAjaxResponse($added) {
header("Content-Type: application/json");
if($added) {
header( 'Status: 201' );
echo( json_encode($added) );
}
else {
header( 'Status: 400' );
}
}
function sendStandardResponse($added) {
if($added) {
header( 'Location: index.php' );
}
else {
header( 'Location: index.php?error=Your comment was not posted due to errors in your form submission' );
}
}
?>
If you run the app now in two different browser windows you’ll see that as soon as you submit a comment in one window that comment will instantly ("magically") appear in the second window. We now have a real-time commenting system!
But…, we’re not done quite yet. You’ll also see that the comment is shown twice in the window of the user who submitted it. This is because the comment has been added by the AJAX callback, and by the Pusher event. Because this is a very common scenario, especially if you’ve built an application in a progressively enhanced way as we have, the Pusher server libraries expose a way of excluding a connection/user from receiving the event via Pusher.
In order to do this you need to send a unique connection
identifier called a socket_id from the client to the
server. This identifier can then be used to define who will be
excluded.
function handleSubmit() {
var form = $(this);
var data = {
"comment_author": form.find('#comment_author').val(),
"email": form.find('#email').val(),
"comment": form.find('#comment').val(),
"comment_post_ID": form.find('#comment_post_ID').val()
};
var socketId = getSocketId();
if(socketId !== null) {
data.socket_id = socketId;
}
postComment(data);
return false;
}
function getSocketId() {
if(pusher && pusher.connection.state === 'connected') {
return pusher.connection.socket_id;
}
return null;
}
The changes we’ve made are:
getSocketId has been added
to get the socket_id. It wraps a check to ensure that
the pusher variable has been set and also that the
client is connected to Pusher.handleSubmit has been updated to check to see
if a socket_id is available. If it is, this
information is posted to the server along with the comment
data.On the server we need to use the socket_id
parameter if it is present and therefore exclude the connection and
user who submitted the comment, or pass in null if
it’s not:
$channel_name = 'comments-' . $added['comment_post_ID']; $event_name = 'new_comment'; $socket_id = (isset($_POST['socket_id'])?$_POST['socket_id']:null); $pusher = new Pusher(APP_KEY, APP_SECRET, APP_ID); $pusher->trigger($channel_name, $event_name, $added, $socket_id);
And as simple as that we have a fully realtime enabled blog commenting system and we only send messages to users who really need to see them. As with the AJAX functionality the realtime functionality has been added in a progressively enhancing way, to ensure it doesn’t impact on any other functionality. You can find the a demo running here and the completed solution in the realtime commenting repository in github.
Real-time application development shares common good development practices with general Web development. However, I thought I would share a couple of tips that can come in particularly handy.
When you start doing a lot of JavaScript development the browser developer tools becomes your best friend. It’s the same when adding realtime functionality to your Web app, not only because you are using JavaScript, but also because the JavaScript library you are using is likely to be doing some reasonably complex things internally. So, the best way of understanding what is going on and if your code is using it as expect is to enable logging which usually goes to the developer console. All major browser vendors now offer good developer tools which include a console:
The Pusher JavaScript library provides a way to hook into the
logging functionality. All you need to do is assign a function to
the
Pusher.log static property. This function will
then receive all log messages. You can do what you like within the
function but best practice is to log the messages to the developer
console. You can do this as follow, ensuring the code it executed
after the Pusher JavaScript library include:
Pusher.log = function(msg) {
if(window.console && window.console.log) {
window.console.log(new Date().getTime() + ': ' + msg);
}
};
The code above checks to make sure the console and
log function is available – it’s not in older browsers
– and then logs the messages along with a timestamp to the
JavaScript console. This can be incredibly handy in tracking down
problems.

Any good real-time technology will maintain a persistent connection between the client (web browser) and the Web server or service. Sometimes the client will lose connectivity and when the client isn’t connected to the Internet the real-time functionality won’t work. This can happen a lot with applications running on mobile devices which rely on mobile networks. So, if your application relies on that connectivity and functionality then it’s important to deal with scenarios where the client isn’t connected. This might be by displaying a message to tell the user they are offline or you might want to implement some alternative functionality.
The Pusher JavaScript library exposes
connectivity state via the pusher.connection
object, which we briefly saw earlier when fetching the
socket_id. Binding to state changes and implementing
your required functionality is quite simple as it follows the same
mechanism as binding to events on channels:
var pusher = new Pusher(APP_KEY);
pusher.connection.bind('state_change', function(states) {
Pusher.log('Connection state changed from: ' + states.previous + ' to ' + states.current);
});
We’re seeing real-time functionality appearing in a large number of high profile applications: some have it at the core of what they offer whilst others use it sparingly. No matter how it is used the end goal is generally the same; to enhance the user experience and keep users engaged with an application. By converting a basic blog commenting system into a more engaging communication platform I hope I’ve demonstrated that the functionality and experience can easily be layered on existing application.
The ease of access to this technology is a relatively new thing and we’ve only just touched the potential uses for the technology. Real-time stats, instant news updates, activity streams, social interaction, collaboration and gaming are just a few common uses but as more developers become aware of, and comfortable with, the technology I’m confident that we’re going to see some truly amazing innovation. An "Internet of Real-Time Things?"?
© Phil Leggetter for Smashing Magazine, 2012.
When you define a function within JavaScript, it comes with a few pre-defined properties; one of these is the illusive prototype. In this article, I’ll detail what it is, and why you should use it in your projects.
The prototype property is initially an empty object, and can have members added to it – as you would any other object.
var myObject = function(name){
this.name = name;
return this;
};
console.log(typeof myObject.prototype); // object
myObject.prototype.getName = function(){
return this.name;
};
In the snippet above, we’ve created a function, but if we call
myObject(), it will simply return the
window object, because it was defined within the
global scope. this will therefore return the global
object, as it has not yet been instantiated (more on this
later).
console.log(myObject() === window); // true
Every object within JavaScript has a “secret” property.
Before we continue, I’d like to discuss the “secret” link that makes prototype work the way it does.
Every object within JavaScript has a “secret” property added to
it when it is defined or instantiated, named
__proto__; this is how the prototype chain is
accessed. However, it is not a good idea to access
__proto__ within your application, as it is not
available in all browsers.
The __proto__ property shouldn’t be confused with
an object’s prototype, as they are two separate properties; that
said, they do go hand in hand. It’s important to make this
distinction, as it can be quite confusing at first! What does this
mean exactly? Let me explain. When we created the
myObject function, we were defining an object of type
Function.
console.log(typeof myObject); // function
For those unaware, Function is a predefined object
in JavaScript, and, as a result, has its own properties (e.g.
length and arguments) and methods (e.g.
call and apply). And yes, it, too, has
its own prototype object, as well as the secret
__proto__ link. This means that, somewhere within the
JavaScript engine, there is a bit of code that could be similar to
the following:
Function.prototype = {
arguments: null,
length: 0,
call: function(){
// secret code
},
apply: function(){
// secret code
}
...
}
In truth, it probably wouldn’t be quite so simplistic; this is merely to illustrate how the prototype chain works.
So we have defined myObject as a function and given
it one argument, name; but we never set any
properties, such as length or methods, such as
call. So why does the following work?
console.log(myObject.length); // 1 (being the amount of available arguments)
This is because, when we defined myObject, it
created a __proto__ property and set its value to
Function.prototype (illustrated in the code above).
So, when we access myObject.length, it looks for a
property of myObject called length and
doesn’t find one; it then travels up the chain, via the
__proto__ link, finds the property and returns it.
You might be wondering why length is set to
1 and not 0 – or any other number for
that fact. This is because myObject is in fact an
instance of Function.
console.log(myObject instanceof Function); // true console.log(myObject === Function); // false
When an instance of an object is created, the
__proto__ property is updated to point to the
constructor’s prototype, which, in this case, is
Function.
console.log(myObject.__proto__ === Function.prototype) // true
Additionally, when you create a new Function
object, the native code inside the Function
constructor will count the number of arguments and update
this.length accordingly, which, in this case, is
1.
If, however, we create a new instance of myObject
using the new keyword, __proto__ will
point to myObject.prototype as myObject
is the constructor of our new instance.
var myInstance = new myObject(“foo”); console.log(myInstance.__proto__ === myObject.prototype); // true
In addition to having access to the native methods within the
Function.prototype, such as call and
apply, we now have access to myObject’s
method, getName.
console.log(myInstance.getName()); // foo var mySecondInstance = new myObject(“bar”); console.log(mySecondInstance.getName()); // bar console.log(myInstance.getName()); // foo
As you can imagine, this is quite handy, as it can be used to blueprint an object, and create as many instances as needed – which leads me onto the next topic!
Say, for instance, that we are developing a canvas game and need
several (possibly hundreds of) objects on the screen at once. Each
object requires its own properties, such as x and
y coordinates, width,height,
and many others.
We might do it as follows:
var GameObject1 = {
x: Math.floor((Math.random() * myCanvasWidth) + 1),
y: Math.floor((Math.random() * myCanvasHeight) + 1),
width: 10,
height: 10,
draw: function(){
myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
}
...
};
var GameObject2 = {
x: Math.floor((Math.random() * myCanvasWidth) + 1),
y: Math.floor((Math.random() * myCanvasHeight) + 1),
width: 10,
height: 10,
draw: function(){
myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
}
...
};
… do this 98 more times …
What this will do is create all these objects within memory –
all with separate definitions for methods, such as
draw and whatever other methods may be required. This
is certainly not ideal, as the game will bloat the browsers
allocated JavaScript memory, and make it run very slowly… or even
stop responding.
While this probably wouldn’t happen with only 100 objects, it
still can serve to be quite a performance hit, as it will need to
look up one hundred different objects, rather than just the single
prototype object.
To make the application run faster (and follow best practices),
we can (re)define the prototype property of the
GameObject; every instance of GameObject
will then reference the methods within
GameObject.prototype as if they were their own
methods.
// define the GameObject constructor function
var GameObject = function(width, height) {
this.x = Math.floor((Math.random() * myCanvasWidth) + 1);
this.y = Math.floor((Math.random() * myCanvasHeight) + 1);
this.width = width;
this.height = height;
return this;
};
// (re)define the GameObject prototype object
GameObject.prototype = {
x: 0,
y: 0,
width: 5,
width: 5,
draw: function() {
myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
}
};
We can then instantiate the GameObject 100 times.
var x = 100,
arrayOfGameObjects = [];
do {
arrayOfGameObjects.push(new GameObject(10, 10));
} while(x--);
Now we have an array of 100 GameObjects, which all share the
same prototype and definition of the draw method,
which drastically saves memory within the application.
When we call the draw method, it will reference the
exact same function.
var GameLoop = function() {
for(gameObject in arrayOfGameObjects) {
gameObject.draw();
}
};
An object’s prototype is a live object, so to speak. This simply
means that, if, after we create all our GameObject instances, we
decide that, instead of drawing a rectangle, we want to draw a
circle, we can update our GameObject.prototype.draw
method accordingly.
GameObject.prototype.draw = function() {
myCanvasContext.arc(this.x, this.y, this.width, 0, Math.PI*2, true);
}
And now, all the previous instances of GameObject
and any future instances will draw a circle.
Yes, this is possible. You may be familiar with JavaScript libraries, such as Prototype, which take advantage of this method.
Let’s use a simple example:
String.prototype.trim = function() {
return this.replace(/^s+|s+$/g, ‘’);
};
We can now access this as a method of any string:
“ foo bar “.trim(); // “foo bar”
There is a minor downside to this, however. For example, you may
use this in your application; but a year or two down the road, a
browser may implement an updated version of JavaScript that
includes a native trim method within the
String‘s prototype. This means that your definition of
trim will override the native version! Yikes! To
overcome this, we can add a simple check before defining the
function.
if(!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^s+|s+$/g, ‘’);
};
}
Now, if it exists, it will use the native version of the
trim method.
As a rule of thumb, it’s generally considered a best practice to avoid extending native objects. But, as with anything, rules can be broken, if needed.
Hopefully, this article has shed some light on the backbone of JavaScript that is prototype. You should now be on your way to creating more efficient applications.
If you have any questions regarding prototype, let me know in the comments, and I’ll do my best to answer them.
"QUANTUM SHOT" #770
Link - article by Avi Abrams
Utmost Intimidation: The Power to Terrify - First World War
Tanks
In the first part of this series we saw some
strangely-shaped armored vehicles from the first idea of a tank to
real-world pre-WW1 war machines. The 1900s were perhaps the most
fascinating period in tank history as nothing on the engineering
side was "cast in stone" yet and the resulting shapes were wildly
unpredictable. It was a time of experimentation, shifting ideas and
a constant flow of prototypes. Now we come to the point in history
when all this frightening potential had to become a sinister
reality and a race to the top "number of casualties" from a
particular machine...
(left: the 1904 David Roberts ‘crawler track’ seen
on ‘Hornsby Steam Crawler Track Tractor’. right: “Dreadnought” 3D
art by Matt Wood & Julian Holtom)
"Steam Mastodons" on the Canadian Prairies
The beginnings of enormous steam tanks can be traced to the humble
steam tractors widely manufactured and used by the end of 19th
century. "Humble", that is, if you do not consider the truly
monstrous tractors from British tractor maker Marshall, Sons &
Company. This company was in business since 1848, making its first
tractor in 1907 and now looking for new markets in Western Canada.
Winnipeg, Manitoba, and Saskatoon, Saskatchewan got the first taste
of these grandiose plans:
(image via)
Titled "Dreadnaughts of the Prairies" the company promoted its
"British Colonial Tractors" with the slogan, "Built like a
Battleship, Runs Like a Watch." - more info
Enter the American Steam Powered Tractor, All Dressed Up
Americans were one of the first to think of a steam powered tractor
as a great chassis for a military "land ship", or a "tank". Here we
see The American Steam Tank from 1918:
(images
via)
This was the heaviest ready-for-combat tank of WWI, "The America".
Some specialists cite glaring problems with this tank, for example,
"a stray shell would have ignited the kerosene stores, and exploded
the steam-chambers scalding to death everyone inside". The Steam
Tank, however, was a step above the Tsar Tank in that it did not
completely fail. It was ready to be sent to the battlefields...
equipped with a flamethrower!
This gigantic beast was similar in shape to the classic British
"lozenge-shaped tanks", except it ran on steam and sported a
flamethrower... Er, did we mention it had a flamethrower? Well,
this could be just a rumor: "...the flamethrower was eventually
placed in a small turret on top of the cab - yet there is no
photographic proof this ever took place".
(image credit: State Archives of North
Carolina, click to enlarge)
Named "Steam Tank, Tracklaying" it was built by the Army Corps of
Engineers in conjunction with Stanley Steamer (the makers of the
Stanley Steamer automobile) - and could also act as a battering ram
if needed. "Accounts state that this tank arrived in France in
1918, however, the war ended before any meaningful tests could be
carried out."
Best's Track Machine, Model 75
Built by an American citizen named Best in 1917, this military
machine was looked favorably upon by the U.S. Army command (it
ordered 50 of these vehicles in 1917):
A similar shape was seen on the Holt "75" conversion, built in
1916:
Here is a harrowing encounter on a narrow street (on the left is
the original version of the Holt Steam Tractor):
(images via)
There were a lot of interesting armored vehicles based on the 1905
Holt Steam Tractor chassis (seen above left). On the right are some
bizarre Christie SPGs prototypes. Speaking of Christie, these were
unusual tracked vehicles designed by J. Walter Christie - here is
the M1919:
(image
via)
One of the Holt tractor conversions was the Holt gas-electric
hybrid - see a good model of it here. "It had a crew of six and used a Holt
four-cylinder motor to turn a generator in order to power two
electric track motors". One problem: it looks really ugly (which is
probably not a problem for a tank but rather an asset). Shown below
is the Holt one-man tank prototype:
(left image
via)
Right image above: this is an even more interesting Steam Wheel Tank (from 1916-1917) which is a throwback
to the big-wheel design idea:
(images
via)
It was also referred to as "the three-wheeled steam tank", "the
Holt Steam Tank" and the "Holt 150 Ton Field Monitor". The Steam
Wheel Tank was designed on the basis of the early British "Big
Wheel" Landships from 1915. It also resembled the German
"Treffas-Wagen" of 1917. Speaking of landships, there were designs
proposing linking two or even three such machines together,
essentially building a tracked armored train! -
The British Side of Things
We already mentioned classic British "lozenge-shaped tanks with a
kerosene engine". These were Mark
I tanks: the British Army and the world's first combat tanks.
"The Mark I entered service in August 1916, and was first used in
action on the morning of 15 September 1916 during the Battle of
Flers-Courcelette, of the Somme Offensive... It was the first
vehicle to be named "tank" (partly to maintain secrecy and to
disguise its true purpose). It could definitely cross trenches,
thus fulfilling Winston Churchill's requirements that we mentioned
in the first part of this series.
(images via)
Here is a good crowd shot of the MK-4:
(image via,
courtesy Roger Todd)
The British Mark IV tank, 1916 - truly a landship, rising
over the trenches as though carried by ocean waves! -
(images via 1, 2)
As you can see, tanks were getting heavier and more massive. It was
only a matter of time till British Armed Forces would entertain the
idea of a shell-proof super-heavy Land Dreadnought: The Flying
Elephant!:
(images
via)
Here is an interesting Gun Carrier MK-1 version:
And a unique photograph of "Mk.VIII International", an
Anglo-American effort (more info) with a very compact-looking "Renault M-1917" (or
Renault FT) on top of it! Right image shows bizarre
American Skeleton Tank (also here):
French Heavy Tank Monster
In the meantime, the French military came up with the "char lourd"
(heavy tank) St
Chamond in 1916:
(images via)
This beast (second of the French heavy tanks of the First World
War) had very strange specs: it had no rotating turret and the long
nose was prone to dig into the ground, which despite pretty decent
speed of 12 km/h, made it a rather cumbersome vehicle. No crossing
trenches for it either, due to its short tracks and very long body.
The word in the army was that "Nobody wants to serve on the
Saint-Chamond"... Despite this, production continued with a total
number of around four hundred tanks made.
German Intimidating Offerings
The famous Treffas-Wagen machines (well-known in steampunk
and gaming circles) were essentially armored steamrollers or
tractor engines with a shooting platform on top:
(right : model image
via)
Near the end of World War I Germany introduced the A7V tank
in 1918 (the only tank used by Germany in WW1 operations). British
forces respectfully called it the "Moving Fortress":
(images via
1, 2)
Which brings us to... the German Super Heavy Tank Project!
(I bet you were waiting for this). German K-Wagen was 12
meters long, 6 meters wide and weighed 120 tons! -
(image
via)
Last but not least, strange Italian battle machines. Here is a
Carro Armato interpretation of the wheeled armored vehicle, capable
of crossing trenches of reasonable depth:
All the players set, all tank pieces developed... the First
World War action starts
(on the right is Italian CV-35 tests in 1940,
via)
The Battle of Verdun in 1916 (among other First World War
photographs) from the pages of the LIFE Magazine:
(images via LIFE
magazine)
On the left image below is weird and inappropriately "cheery"
depiction of the tank in action - and on the right is a
significantly more realistic painting by John Hassall, showing pain
and suffering on the Somme battlefield. "By the time the Battle of
the Somme ended, there were over a million casualties on both
sides, with over 300,000 killed or missing".
(right image: The Collection Art Archaeology in
Lincolnshire,
Usher Gallery, left:
via)
Other (Mostly) Imaginary Steel Leviathans
The imagination of the reading public was fired up pretty early:
consider this sketch made in 1906 of the "Lethal Armored Vehicles"
featuring egg-shaped streamlined armor:
(image via)
"Exit the Cavalry, Enter the Tanks!" proclaimed Popular Science
magazine in August 1931:
(images
via)
The readers and editors did not spend much time mourning over the
"impending passing of the United States Army’s most romantic unit,
the mounted cavalry". Horses were definitely too slow for modern
warfare, and cavalrymen of the future were expected to ride their
gasoline steeds (new tanks) into battle.
(Future War Tank, 1939 - image via)
The Electrical Experimenter, July 1917 cover (left) and
Science & Mechanics cover from much later period, 1934
(right):
A more modern approach, this is a tank design for the "Nadia: The
Secret of Bluewater" (1991, Japan), and the tank concept from the
WarHammer game universe: Land Raider Proteus (see more):
(images via 1,
2)
Camouflage! -
Stay tuned for the next part featuring strange and unusual tanks of
the 1920-1930s.
READ THE FIRST PART HERE ->
CONTINUE
TO OUR "MILITARY" CATEGORY ->
|
The new Smashing Book #3 has finally arrived—freshly printed, neatly packed and ready to be shipped to you, our dear reader. We believe this is by far the best book we’ve produced so far. We are very proud and excited, and the initial verdict has been thoroughly positive, yet in the end it’s up to you to decide how valuable and useful they really are. Get your books now!
In recent years, the Web has changed—a lot. The Web designer’s tools are now advanced, and browsers are highly capable. Designers have established clever coding and design techniques, and they face new challenges and are embracing new technologies. These changes are fundamental and require us to reconsider how we approach Web design. It’s time to rethink and reinvent: it is time to redesign the Web. The new Smashing books will change the way you design websites for the better.
But are we all prepared for this? How does responsive design fit into your workflow? What UX and mobile techniques do you follow when designing websites? And if you have a redesign project on the horizon, how do you approach it and work your way through it? The books explain what you need to know in order to create effective websites today, and what you need to know to be prepared for the future. Well-known experts share practical know-how and introduce a whole new mindset for progressive, future-proof Web design.
With over 40 people having worked on the project, a lot of thorough
editing and consideration needed to be done to fine-tune each
chapter’s content and order to make the most sense. In the end, 11
of the most outstanding articles made it into the Smashing Book #3,
covering topics ranging from the business side of design to mobile
approaches and responsive design.
The Smashing Book #3 covers innovative coding, design and UX techniques and discusses the peculiarities of the mobile context and emotional design. It also presents practical HTML5, CSS3 and JavaScript techniques, as well as a bulletproof workflow for responsive Web design. The book challenges you to think differently about your work, your code and your designs.
| AUTHOR | CHAPTER | DETAILS |
| Elliot Jay Stocks | Preface | |
|
|
||
| Paul Boag | The Business Side of Redesign | |
A redesign is the best thing that a Web designer
can experience. Yet before leaping head on into a project, we must
consider the business behind the redesign. By its nature, a
redesign has the potential to make a website successful, but it
also has the power to destroy a perfectly good idea. Important
considerations to keep in mind before engaging in a redesign
project include common dangers, required research, the working
process with the client and testing. Paul Boag leads you through
this process step by step.
Chapter keywords: business model, redesign timing, scope of redesign, redesign considerations, realignment, project pitfalls. |
||
| Rachel Andrew | Selecting a Platform for Redesign | |
Once you have understood the business side of
the redesign project, the next step is to choose the right
platform. Understanding all of the requirements of a project will
save you valuable time in aligning the new functionality with the
technological circumstances. Take stock of existing structures such
as the CMS, e-commerce system and payment gateway. Beware of the
project constraints, including the budget and wishes of the client.
Only then will you be able to concentrate fully on the project,
without encountering unpleasant surprises ahead.
Chapter keywords: technical requirements, CMS, eCommerce, payment gateway, refactoring, platform choice, redesign project constraints. |
||
| Ben Schwarz | Jumping Into HTML5 | |
Ben Schwarz takes away the fear that many Web
developers suffer when confronted with a new technology—by
encouraging experimentation. The chapter guides you through the new
HTML5 elements and discusses the possibilities that come with the
adaptation to these elements. This is a practical, compact guide to
HTML5, with everything you need to know today in order to create
flexible and maintainable websites for the future.
Chapter keywords: HTML5, semantics, semantic outlining, ARIA, client-side storage. |
||
| Lea Verou, David Storey | Restyle, Recode, Reimagine With CSS3 | |
![]() Some CSS workarounds that have hung around from
earlier days prevent us from becoming better, more efficient
designers. Learn how to recode CSS to reduce the number of images,
HTTP requests, presentational JavaScript and wrapper divs on the
page, while making the style more flexible and maintainable. Learn
about the rem unit, Flexible Box Layout, source-order independence
with flex order, multiple backgrounds and gradients, background
clipping, border images, transforms, transitions, box sizing and
new CSS3 selectors. Restyle, recode, reimagine: because CSS3 is
here to stay!
Chapter keywords: CSS3, techniques, Flexbox, multiple backgrounds and gradients, transforms, transitions, box-sizing, selectors, layout. |
||
| Christian Heilmann | JavaScript Rediscovered | |
Even though jQuery is written in
JavaScript, it is not the same; nor is it native to browsers. The
large jQuery library abstracts away a lot of issues that Web
developers face, yet sometimes it’s used without a real purpose.
Christian Heilmann takes us back to its origins and shows us how to
implement simple JavaScript solutions without resorting to jQuery,
achieving the same result in a slimmer and less process-intensive
way.
Chapter keywords: JavaScript, jQuery, CSS selectors, classlist, localStorage, tutorials. |
||
| Dmitry Fadeyev | Techniques for Building Better User Experiences | |
User experience means good design, and the
central aim of design is not to decorate, but to solve problems.
Whether that means getting more sign-ups, inviting users to post
more content or making the interface easier and faster to use, this
is ultimately the sort of design that delivers a great user
experience. This chapter features powerful UX techniques that you
can easily apply to your products and websites. Make sure users
stay on your website for the right reasons, and get an edge over
the competition by improving user-targeted processes. Also, explore
experimental approaches and avoid some misleading design
techniques.
Chapter keywords: UX design, forms, good defaults, customer service, copywriting, storytelling, experimental techniques, design pitfalls. |
||
| Marc Edwards | Designing for The Future, Using Photoshop | |
Because good design and user experience are
almost mandatory for success today, the lines between desktop
software, mobile software and the Web are increasingly blurry. We
have to continually change our tools and techniques to meet new
requirements. Marc Edwards addresses some of the challenges that
Web designers face today and will in the future when using
Photoshop. Realism, scale, screen sizes, resolutions, formats,
techniques—this chapter touches on all of it. There is no reason to
surrender to scaleability and liquid image requirements when using
Photoshop!
Chapter keywords: Photoshop, screen sizes, pixel density, scale, gradients, shapes, color profile, mobile, Retina display. |
||
| Aaron Walter | Redesigning With Personality | |
Any design that does not effectively establish a
connection with its audience has missed its goal. Getting to know
your user is just as important as knowing yourself and the
personality behind the brand; this will set you apart from
competitors. This chapter describes how to develop your own design
persona and define the key characteristics to guide your project’s
path. New technologies and techniques are not what build
connections with users, but rather the empathy evoked by the
personality behind them. Aaron Walter explains how to bring out the
personality at the heart of your work.
Chapter keywords: personality, brand sympathy, engagement methods, design persona, voice and tone. |
||
| Aral Balkan | Mobile Considerations in UX Design: Web or Native? | |
The native vs. Web debate is meaningless and
counterproductive. All products nowadays have high demands for UX
design. Web designers turn into UX designers by gaining specialized
knowledge of the Web and by mastering auxiliary frameworks and
their components. Not only do the aesthetics of an interaction
object count, but also how the object behaves upon contact.
Designing documents and designing applications requires knowledge
of basic responsive design principles and progressive enhancement.
This chapter helps you understand your medium, explains what
exactly it means for an application to be “native,” and goes over
how to choose the right tools and technologies for the job.
Chapter keywords: mobile, user experience, native applications, native as culture, interaction design principles, responsive Web design. |
||
| Stephen Hay | Responsive Workflow: A Future-Friendly Approach | |
Web design changes quickly. In multiplatform
design, where websites and apps are used on many and varied
devices, we are confronted with multiple destinations. How do you
go about integrating as many devices as possible? Is targeting as
many different platforms as possible really important? In this
chapter, Stephen Hay suggest a new design workflow for responsive
Web design. A new way of thinking leads to a new way of design—the
sooner you get the hang of it, the sooner you will be ready to
discover what works best for your projects.
Chapter keywords: responsive Web design, device-agnostic approach, content inventory, future-friendly approach, breakpoint graphing, designing in the browser. |
||
| Andy Clarke | Becoming Fabulously Flexible | |
There are significant upsides
to responsive Web design for designers, especially in workflows
that embrace flexibility. Responsive Web design still asks more
questions than it answers, and it challenges the working
relationships and interactions between everyone involved in every
process. Andy Clarke gives you some insight into the techniques
that helped him become fabulously flexible when developing
responsive designs. Learn his approach to designing atoms and
elements of a design first and see if it works for you. It might
enable you to create many facets of the same experience within a
single workflow.
Chapter keywords: Responsive Web design, design challenges, style tiles, design atmosphere, flexibility, designing components first. |
||
Well-respected professionals have poured their heart and expertise into these contributions. To ensure quality, every chapter of this book has been thoroughly reviewed by experts, including Jon Hicks, Tab Atkins, Paul Irish, Russ Weakley, Josh Clark, Anders M. Andersen, Bryan Rieger, Joshua Porter, Ryan Carson and Elliot Jay Stocks.
Our new books: the Smashing Book 3 and Smashing
Book 3⅓—The Extension. Both are available as a
print bundle, as
eBooks and as a complete
print + eBooks Bundle.
With Web design, we can do much more than inform the audience. The power of storytelling and content strategy is in creating engaging, emotional connections that transcend their platform. In this book, we will review emerging navigation design patterns and understand how to employ a content strategy—which is an important process, often underestimated, and dependent on many factors.
Smashing Book 3⅓, otherwise known as “The Extension,” presents practical applications of storytelling to Web design, reviews emerging navigation design patterns and helps you understand how to meaningfully employ content strategy on your websites. A case study of Smashing Magazine’s responsive redesign illustrates how this approach could look like in practice.
| AUTHOR | CHAPTER | DETAILS |
| Iris Lješnjanin | Preface | |
|
|
||
| Denise Jacobs | The Missing Element of Redesign: Story | |
|
Chapter keywords: storytelling, invisible design, literature, narrative devices. |
||
| Christian Holst and Jamie Appleseed | Rethinking Navigation: Techniques and Design Patterns | |
|
Chapter keywords: navigation, design patterns, filtering, mega menus, checklist. |
||
| Colleen Jones | Rework Your Content So It Works for You | |
|
Chapter keywords: content strategy, content inventory, audit, context, maintenance, results assessment. |
||
| Vitaly Friedman | Responsive Smashing Redesign: A Case Study | |
|
Chapter keywords: redesign trap, responsive Web design, advertising constraints, design persona, typography-out approach, designing in the browser, redesign manifesto. |
||
The Smashing Book series has gotten a rather eye-catching facelift. The well-respected Belgian artist Veerle Pieters has taken on the significant task of putting together an innovative, bold cover design. And the result is bold indeed. Veerle’s styling of Smashing Magazine’s “S” reflects the many aspects that make up a Web designer’s workflow today.
An excerpt of Veerle’s final cover design for the Smashing Book
#3.
Veerle’s final sketches for the cover of the Smashing Book
#3.
If you have the Smashing Book 2, you’ll know that animals play a distinct role—forming almost a tradition for the series. This time, we have asked the talented young illustrator Kate McLelland to illustrate the introductory pages for all of the chapters. Kate has been impressively creative in her designs; the theme of redesign has obviously shaped the tone of her artwork. Each chapter begins with an elaborate drop cap.
A detail of a chapter illustration, designed by Kate
McLelland.
Each illustration employs a different metaphor that relates to the accompanying chapter. See what they all are once you get your hands on the book. Appropriately enough, when strung together, the drop caps spell out “Redesign the Web.” The composite style of the illustrations points to how so many components have to come together for a successful redesign.
We’re looking forward to honest, objective reviews of the brand
new Smashing Books. Please share your photos, opinions and feedback
on Twitter using the hashtag #smbook3. The first
feedback has
been
throughout
positive
and, in fact, we’ve discovered the first reviews of the books as
well:
“The entire book is wonderfully balanced between theoretical and practical, with each author contributing a strong point of view on their area of expertise as well as a thorough explanation of how to execute it in a way that is useful. [...] curating the most cutting edge perspectives on the Web and offering the tools and information that the rest of us need to build upon them. If you’re into that, check out this book.”
— Christopher Butler, Book Review: Smashing Book #3
“This book is worth buying and reading for yourself. It really covers many aspects of modern website production in eleven in-depth chapters. There will likely be a few you don’t care for—we all have our own tastes—but I’d be surprised if any genuinely leave you disappointed given the chance. I was quite prepared to write something less positive, the first Smashing Book didn’t excite me, but this one very much did.”
— David Bushell, Smashing Book #3
“The Smashing Book #3 is an invaluable resource for Web designers, regardless of skill level or experience and we highly recommend it.”
— Cameron Chapman, Review: Smashing Book #3
Please feel free to submit a link to your review in the comments to the post and we’ll add your testimonial into this article. Feel free to provide criticism or praise: we’d love to hear your honest opinions!
A quick peek into the Smashing Book #3. Yes, we do
like animated GIFs.
If you haven’t purchased Smashing Books #1 and #2 yet, we’ve prepared a couple of complete bundles for your convenience. Even though the first two books were published a couple of years ago, they remain relevant and valuable, because they were designed by our editorial team to be timeless. Save 20% off the price and get yourself the Smashing Anthology, a collection of all of our books as of today:
We want to make it as easy as possible for everyone to buy the new Smashing Book. We welcome all suggestions and advice that could improve Smashing Magazine’s user-friendliness. Here are answers to some frequently asked questions about the Smashing Books #3 and #3⅓:
| Questions | |
| What’s the difference between Smashing Books 1, 2 and 3? | |
|
The first two books covered best practices in modern Web design. Although they had similarities, the two books covered different areas of Web design. Smashing Book #3 has a particular theme: redesign. It covers the redesign process per se, as well as cutting-edge approaches to Web design on a broader scale. It focuses on the most recent developments and current demands of today’s rapidly changing environment. Smashing Book #3 gives professional advice on the what, when and how of responsive and bulletproof Web design, according to the requirements of today’s Web. |
|
| What’s this extra Smashing Book #3⅓? | |
|
Our authors have turned out to be much more productive than we anticipated, coming up with more exciting chapters than one book could handle. Adding these chapters to the book would have increased the size and weight—and, hence, shipping cost—substantially. Not wanting to withhold these chapters, we have decided to release them separately. We are proud to present the Smashing Book #3⅓: The Extension, four extra chapters of quick quality reading. Buy it as part of a bundle and save! |
|
| Will the book be available in other languages? | |
|
Maybe in future, but we have not made arrangements for that yet, so don’t hold your breath. |
|
| Are the Smashing Books #3 and #3⅓ available as eBooks? | |
|
Yes, the books are available in PDF, EPUB and Mobipocket formats, and you can order an eBook bundle right now. |
|
| What are the costs for shipping to my country? | |
|
The shipping cost for one book or a bundle is $5—wherever you are in the world. We are paying a share of the shipping costs ourselves to make it possible for anyone to purchase the book. Our prices are transparent: we don’t have any hidden costs, and we won’t confuse you with tricky calculations. What you see is what you pay! |
|
| How long will delivery take to my country? | |
|
All books are shipped via air mail to keep delivery times as short as possible. You can find the anticipated delivery time for your country in the delivery times overview. |
|
| What payment methods are accepted? | |
|
We accept PayPal, VISA, MasterCard and American Express. We use a secure connection, with 256-bit AES encryption and a green GeoTrust Extended Validation SSL CA certificate. |
|
| Is there a money-back guarantee? | |
|
Yes, absolutely! No risk is involved. Our 100-day full money-back guarantee keeps you safe. Don’t hesitate to return your purchase. You’ll get your money back—no ifs, ands or buts about it. |
|
| I have a question that is not covered here. | |
|
Please leave a comment below, or get in touch with us via the contact form or via @SmashingSupport on Twitter. We would love to help you in any way we can! |
|
These new books took seven months of production time, from brainstorming to delivery; 43 people worked on the content, design, layout, editing and proofreading of the book; 623 animals are hidden in various places in the Smashing Book #3; and the production costs for initial circulation, excluding marketing costs, required a six-figure budget. That’s what it took us to ensure that our Berlin warehouses are stocked with these new valuable books, waiting to be shipped right away as soon as you place your order.















The authors of the new Smashing books.
Here at Smashing Magazine, we do our best to support and enrich the design community. Yet we also rely heavily on community opinion—in fact, the magazine would not be what it is today without the constant feedback of the community. That’s where you come in: we now pass the book onto you. Use it, enjoy it, test it, read it, rate it, evaluate it, criticize it or praise it—and share your honest opinion of it with the rest of the world.
Feel free to take as many pictures of it as you like and to use the Smashing Book #3 media kit (.zip, 9 Mb), which is full of interesting facts, figures and images related to the book. Be one of the first to give the community a critical view of the book; stir the discussion, and encourage feedback on your website.
Your criticism helps us further improve future projects, shapes the selection of topics and enables us to stay close to the pulse of the community. We sincerely appreciate your support.
© Smashing Editorial for Smashing Magazine, 2012.
"QUANTUM SHOT" #769
Link - article by Avi Abrams
From Early Tank Ideas to Enormous Pre-WW1 Steam Tanks
Cataloging the machines of destruction may seem like a thankless
job (when you think about how much pain and misery they brought to
mankind), but the sheer ingenuity of military engineering is
certainly fascinating. It's that "anything-goes, testing be damned,
let's quickly put it into production" attitude that leads to
frenzied arm races, as well as technology breakthroughs. This is
how we ended up with laser-tanks, spherical bomb-tanks and
nightmarish land dreadnoughts, in a short period of last hundred
years or so - all conceived and built by super-powers in the name
of winning righteous wars (any war, it may be argued, can be
considered "righteous" by their participants, if they absorb enough
propaganda and ideology).
So we look at some of the weirdest tank examples here at Dark
Roasted Blend, marveling at their uninhibited design coupled with
war-time mythology, brute force and potential for intimidation
(seeing how the race to "build a better tank" quickly turned into
"building a bigger tank", for example).
It all started in the 14th century. We have a record of a
"pre-tank" machine, called "The Fighting Unicorn" (left) - a
fragment of a page from the work of Mariano di Jacopo (aka Mariano
Taccola) from Sienna:
(images via)
The armored body of this weird tank precursor concealed a number of
soldiers (who must've been of a somewhat slight build to fit in
there), all running in step - with the "unicorn horn" either
lowered into a "charge" position, or simply used to pound on the
helmets of astonished enemies.
Right image above shows another early tank concept: a sketch by
Leonardo Da Vinci, one of fifteen found in his notebooks that
contain weapon and defensive systems designs (among them are some
wildly imaginative ideas like "mobile walls", or the sinister
"cluster bombs"... See all Da Vinci's War machines here (well worth the click).
Here is a better graphic representation of this complex weapon:
(image credit: Jacub Batok,
click to enlarge)
Interestingly, the idea of a turtle-like tank shape found its
realization much later, in the 1930s, in this Venezuelan armored
vehicle:
As you can see from the wonderful recreation of Da Vinci's concept
below (courtesy Discover Channel's Doing Da Vinci show), this amazing tank idea
from 1482 features a tortoise-shaped armor which literally bristles
with cannons all around. Some even call this design "shock and awe"
of the 15th-century battlefield, as it certainly would create fear
and havoc among enemy soldiers.
(images via 1, 2,
3)
Seen on the right in the image above is the Da Vinci's Armored
Assault Vessel (more info) and the already mentioned mobile
walls: "as the enemy used ladders in an attempt to breach the
walls, the levers were engaged to move the rails built into the
walls that the ladders were leaning on, causing them to become
unstable and eventually fall".
More Leonardo Da Vinci war machines - a pivoting radial barrage
canon found in the Codex Atlanticus (left) and the multi-barreled
machine gun (right, sketched in 1480):
(image via)
Moving right along to the Victorian Age we have a mention of first
caterpillar tracks (invented in their crudest form in 1770 by
Richard Edgeworth) being used in the Crimean
War, where a "relatively small number of steam powered tractors
with the caterpillar track were seen manoeuvring around the
battlefield’s muddy terrain." (via). The
idea of armored assault vehicle certainly was floating in the air
but needed better engines and more commitment from political
powers.
Here is the armored steam-powered vehicle proposed in 1855 for
British Armed Forces... apparently this design did not advance past
certain Lord Palmerston (who happened to be Prime Minister at
the time) who deemed it "utter nonsense" and not worthy of further
development:
(image via)
Meanwhile in France, the strangest idea of a caterpillar-like
armored train on tracks was proposed by Eduard Boyen in
1874, boasting incredible weight of 120 tons and a crew of two
hundred people! -
In Germany engineers came up with the Mobile Gunpoint 3-ton
unit in 1885 ("Gruson 5.3cm L/24 Fahrpanzer"). It was brought to
the battlefield by horse, or on rails - and then fired 1.75 kg
projectiles from its 53mm gun. it went into mass production in
1890:
In England Frederick Simms in 1902 designed armored vehicle on
wheels (he called it a "motor-war car") which could also be
converted to track version. Its two revolving machine guns were
developed by Hiram Maxim:
In the years leading to First World War British government was not
keen on developing such "pretty mechanical toys" as tanks (or as
they called them "Land ships"), preferring to concentrate on
cavalry and infantry instead. It took backing of some prominent
political figures (Winston Churchill among them) to advance the
situation - and so the "Little Willie", and then the "Big
willie" were born in 1915:
(images via 1,
2)
The "Little Willie" had a huge limitation in that it was unable to
cross trenches. Crossing trenched was one of the requirements put
forward by Winston Churchill when he commissioned the design of a
vehicle "capable of resisting bullets and shrapnel, crossing
trenches, flattening barbed wire, and negotiating the mud of
no-man’s land".
Crossing trenches was a challenge not only for British engineers.
Also from 1915 is this bizarre "Machine Boirault" tested for the
French Army as a trench crossing vehicle:
(image credit: Steve Zaloga)
Meanwhile in Russia...
...another monster was taking shape on the drawing boards: the
Mendeleev's Super Heavy Tank, 1911. It was proposed with the
256 horse power engine and would weigh 86 tons:
The square and brutal shape of this war machine was later repeated
in the Rybinsk Tank, 1916 (lower right corner, above). These were
developed based on the tractor chassis of the Rybinsk Tractor
Factory - and were quite similar to the squarish hull of the French
medium tank St. Chamond, for example. It's interesting that the
word "tank" comes from the strong resemblance of early armored
hulls to various water carriers and liquid tanks, and so the name
stuck for good - even when the shapes of tanks changed.
Mendeleev's Super Heavy Tank also featured revolutionary "elastic"
suspension system, as can be seen from the drawings below:
Also in 1916, the Russians came up with the "Vezdekhod" concept
(All-Terrain Tank). It had a prominent forward slant of the body,
enabling better traction and climbing various obstacles - and also
perhaps influencing rhomboid tank designs of the British from the
same period:
"Vezdekhod" (translated as "Go Anywhere") vehicle was strangely
streamlined in the first prototypes, could be outfitted with both
wheels or tracks, and was slated into production in the final form
shown on the right:
And yet for all its streamlined curves, this was pretty tame and
conventional layout compared to this:
The Tsar Tank!
This lovely mechanism, designed by N. Lebedenko in 1914, could very
well be the Biggest Tank Ever Built. It was certainly one of
the strangest: a monster of a tank, with a distinctive
steampunk-friendly shape, a full 40-ton battle machine with two
very large wheels 9 meters in diameter. It was called "Tsar Tank"
after Tsar Nikolaj, who helped finance it - and it also had another
sinister name "Netopyr" (a vampire bat):
(images
via)
It was hoped that such unusual configuration of wheels will enable
Tsar Tank to cross any obstacle. Unfortunately during the initial
trial run the smaller wheel got stuck in a ditch... and the engines
did not have enough power to get the rear wheels out. So in the end
this magnificent vehicle (looking like some wild modernist
sculpture) stayed in the middle of the forest till 1926, when it
was dismantled for scrap metal.
(3-D model credit: Mikhail
Levin)
Weird "Iron Horse" War Machine from Italy, 1914
This was Italian mobile gun unit, used in the First World War. It
was equipped with a 305mm cannon, with a shooting range of almost
18 kilometers. Allegedly used during the shelling of the Austrian
fortifications in the Alps:
(image via)
The Giant Destroyers of the Future
You've seen some of the outrageous concepts that appeared worldwide
in the years leading to the First World War. Well, imagination of
certain artists of "super-science" publications ran even wilder,
eagerly providing colossal visions (or rather, nightmares) that
were to dominate public minds for decades to come. Here is an
example from Popular Science magazine (December, 1916):
(images credit: Popular Science, December
1916)
Another Mega Tank concept graced the pages of the "War Budget"
publication in 1916:
(image
via)
And we finish today with the German Mega-Tank nightmare vision,
taken from the October 21st, 1916, issue of the German news weekly,
Die Wochenschau. "Fighting machines of the
future: battle between a gigantic trenchdestroyer and a powerful
electrically-driven circlecruiser":
(image
via)
Stay tuned for the next part featuring strange and unusual First
World War tanks, coming out shortly.
CHECK
OUT OUR "MILITARY" CATEGORY ->
|
While certainly not as well known as Photoshop, Adobe Fireworks is a great tool for creating user interfaces, website designs and mock-ups, wireframes, icons and much more. However, most designers who have been using Photoshop for years may find Fireworks a bit awkward at first. Fireworks does have a slightly different workflow and requires a slightly different approach than you may be used to.
In this article, I’ll share some tips that I use in my work in Adobe Fireworks that could help improve the quality of your designs and workflow. Some of these tips are just quick explanations of features that you might not be aware of, while some are techniques and methods to improve the default visual results. Let’s begin!
Fireworks’ stroke feature gives the user quite a lot of options. But one of the most important is missing: the ability to add a gradient to a stroke. Also, the effect from the Stroke tool isn’t always elegant — for example, when using an inset border with rounded corners.
Native stroke rendering in Fireworks. The rounded corners look
a bit too thick.
Fireworks lets you specify the stroke’s position: outside, centered or inside. But the best results are when the stroke is outside.
Stroke can be set to different alignments in the Properties
panel. Outside (example 3) looks better for fine strokes than
centered or inside.
But in such cases, I recommend a composite path instead of a stroke to get better control of the result and to be able to apply a gradient to it.
Start by drawing two rectangles with rounded corners, one of them 2 pixels taller and wider than the other. Put the smaller rectangle above the larger (you can verify that it’s above in the Layers panel), and make its border radius smaller by several pixels, as shown here:
We’ll need two vector shapes to create our custom
stroke.
The purpose of the smaller shape (the one with the yellow-orange background) is to cut out (or “punch”) the interior of the red shape, resulting in a 1-pixel-wide object that can be used in place of a stroke. To achieve this, select the two rectangles and hit the “Punch Paths” tool icon in the Path panel:
Punch Paths will help us get a better-looking stroke.
Alternatively, you could select the two rectangles and go to
Modify → Combine Paths → Punch.
The stroke is now a composite path that you can easily edit and
even apply a gradient fill to.
Bonus tip: Should you later decide that you need to resize this shape (without distorting its perfectly rounded corners), the “9-slice scaling tool” can come to your rescue:
Distortion-free scaling is easily achieved with the 9-slice
scaling tool.
Triangles are everywhere in user interfaces: arrows in buttons, breadcrumbs, pop-over indicators and so on.
While Fireworks provides built-in arrow and polygon vector drawing features, I recommend going the customized route and drawing those vector shapes yourself.
The Arrow vector autoshape in Fireworks. The yellow control
points allow for easy customization of width and height, thickness,
type of head, roundness, arrow size and more.
The Smart Polygon vector autoshape in Fireworks. You can easily
transform it into a triangle!
To illustrate our new workflow, let’s draw a simple arrow like the one in Kickoff’s download button:
Kickoff’s download button
Let’s start by drawing a nice triangle. Most of the time, you’ll want an odd number of pixels for the triangle’s base so that its middle falls on a half-pixel, resulting in a sharp arrow:
On the left, the triangle with an odd width. On the right, the
triangle with an even width.
To create a triangle like the one on the left, we start by drawing a simple 7 × 7-pixel vector square using the Rectangle tool (found in the Tools panel, or simply press U). To delete its bottom-right point, use the Subselection tool (press A, or use the white arrow in the Tools panel), select the bottom-right node, then hit the Delete key; Fireworks will remind you that you are trying to change one point of a rectangle primitive and that it must be ungrouped for the change to occur; so, click “OK” to turn it into a vector, and delete the point. After deleting the corner, you’ll end up with this:
Our square with the bottom-right point deleted.
We now need to place the bottom-left point exactly at the center, which is located at 7 pixels ÷ 2 = 3.5 pixels from its current position. When you use your keyboard’s arrows, Fireworks moves the elements by full pixels only and aligns them perfectly to the pixel grid. This is convenient in most cases but not in this one. Luckily, Fireworks gives us a “Move Points” feature (in the Path panel) that lets us specify numeric values:
Moving horizontally by 3.5 pixels will center our bottom
point.
If the triangle is now a bit too tall for our arrow, use the Subselection tool to select the center point again, and press the up arrow key twice to move the node up a couple of pixels.
We’re almost done! We just need to draw the 3 × 5-pixel
rectangle part of our arrow and then use the “Union Paths” command
(Modify → Combine Paths → Union, or press
Control/Command + Alt/Option + U) to combine our two
paths into one final single vector shape:
The separated shapes are on the left, and the unified shape is
on the right.
For some reason, Fireworks has difficulty drawing elegant circles (especially small ones), and the circles tend to have too straight an edge:
A default circle in Fireworks. Note that the top, right, bottom
and left edges aren’t rounded enough.
We’ll use the “Numeric Transform” window (Control/Command
+ Shift + T, or in the menu Modify → Transform →
Numeric Transform) to make the circle just a tiny bit
smaller:
Decreasing the circle’s size by a bit will make it appear more
rounded.
The original on the left, and our result after the transform on
the right.
You will notice that the right circle is more elegant; that’s because we have fewer “full” pixels at the edges:
The original on the left, and our perfect circle (after the
transform) on the right!
One great feature of Fireworks that few people seem to know of is the Fillet Points path tool. Basically, it rounds any angle you select by a value that you specify. To use it, select any vector shape, and in the Path panel in the “Edit Points” section, choose “Fillet Points”:
Fillet Points rounds all of your angles.
Let’s use the built-in vector Star autoshape as an example. Note that you need to ungroup autoshapes and rectangle primitives before using Fillet Points; then you can either select the entire vector shape to round all corners or use the Subselection tool to select certain points to round.
The original shape on the left, and with Fillet Points applied
on the right.
This can be a huge time-saver when you want to modify complex shapes with many filters and effects. Now you won’t have to redraw shapes over and over again just because the radius is a few pixels off.
Another useful vector tool many designers are unaware of is the Inset/Expand Paths feature.
Inset/Expand Paths is also accessible via Modify → Alter
Path → Inset Path.
As you’ve probably guessed by its name, this tool enables you to alter a vector path and make it either smaller (inset) or larger (expand) without losing its proportions.
Let’s say we want to make our Star autoshape from above 10 pixels smaller:
The Inset/Expand Paths prompt.
This dialog can be confusing if you do not know what all of the options and abbreviations mean. The third parameter (“Corners”) is the least obvious, because the meaning of “BE, RO, MI” is not defined. The letters are actually abbreviations of “Bevel,” “Round” and “Miter.” You can’t use those abbreviations in the text field, so you need to know the terms they represent. “Bevel” creates squared corners, “Round” creates rounded corners, and “Miter” creates pointed corners; the “Miter limit” specifies the maximum length of the pointed corners before Fireworks replaces them with clipped (or square) tips. We’ll use “Miter” in our example because we obviously want to keep our straight lines.
And voilà!
Adding a gradient between two similar colors (i.e. colors close in hue) in a big shape often produces an unsightly banding effect, as shown here:
Banding is visible in this gradient (especially on LCD screens
of the common “twisted nematic” type, which display only 6
bits per pixel, not 8).
To prevent this, Fireworks introduced in CS5 a Gradient Dither option that can be used if the edges of the object are set to “Anti-alias” and if you use the “Radial” or “Linear” type of gradient fill.
“Gradient Dither” (found in the Properties panel) makes
gradients look better.
The result is a smooth, unified linear gradient, similar to what you would get with CSS browser rendering:
With the “Dither” option applied, the gradient becomes much
smoother.
Similarly good results can be achieved by dithering radial gradients.
Fireworks isn’t very good at rendering large shadows (if you use the “Drop Shadow” live filter). If you’re curious about the subtleties involved, a detailed article on WebDesignShock compares shadow and glow effects in Fireworks, Photoshop and Illustrator.
Instead of a beautiful shadow that slowly fades to a transparent value, the edge of the shadow might look like it has been cut off before fading to full transparency. The issue is particularly noticeable on the Mac version of Fireworks:
A shadow effect created with the Drop Shadow live filter.
Notice the edges (in Fireworks CS5 on a Mac)—yikes!
Here are the settings to use to get this drop-shadow effect on Windows and Mac:
The settings for the drop-shadow live effect on a Mac. Again,
notice the “cut” edges of the shadow.
The settings for the drop-shadow live effect on Windows. The
settings are the same, but the edges of the shadow are almost
perfect.
So, instead of using a live filter, I usually duplicate the shape (the white rectangle in this example), set its edge to “Feather” and fill it with black.
Possible settings for the “shadow” vector shape behind the
object.
Putting this shape behind the white rectangle produces a better-looking large shadow than the built-in method:
The original shadow on the left, and the “Feather method” on
the right.
A picture is worth a thousand words.
Talking about gradients, fills, strokes, vector autoshapes, rounded rectangles, pixels and half-pixels is exciting, but a few real examples would be even better. Below are some illustrations, icons and UI designs that I made exclusively with Fireworks. The tips and tricks covered above made the results more elegant and refined.
As you can see, it’s all about pixel-precision, and Fireworks delivers great results!
Adobe Fireworks is a powerful tool, offering both vector- and bitmap-editing capabilities and even hiding some gems. Yes, it imposes different workflows, and some of its default effects are disappointing, but the advantages outweigh the little quirks here and there.
Having to change one’s work habits is always frustrating. Perhaps actions that you once did in a few minutes with your old design tool will now feel incredibly slow. Getting used to a different workflow takes time, and you might not see the benefit of using Fireworks immediately. The best thing you can do is commit to designing an actual project from start to finish using only Fireworks. Choose a small project or a personal side project for this purpose. Get your hands dirty for a few hours (or a few days). It’s the only way to be able to judge whether Fireworks really suits your needs. If you’re into UI design, I’ll bet it does!
If you’re interested in learning more about Fireworks, I highly recommend watching the great screencasts produced by Rogie King. They offer many more tips and tricks for refining designs and achieving more polished results than this article.
Also, the work of others can be a good source of inspiration and knowledge, so have a look at the Fw PNG Week series by Craig Erskine, and download and deconstruct his free source PNG files.
Happy experimenting with Fireworks!
(mb, al)
Note: A big thank you to our fabulous Fireworks editor, Michel Bozgounov, for preparing this article.
© Benjamin De Cock for Smashing Magazine, 2012.
With so many folks developing jQuery plugins, it’s not uncommon to come across one that just plain – for lack of better words – sucks. There’s no examples or documentation, the plugin doesn’t follow best practices, etc. But you’re one of the lucky ones: this article will detail the pitfalls that you must avoid.
jQuery is no stranger to those of you frequent Nettuts+. Jeffrey Way’s awesome 30 Days to Learn jQuery (and various other tutorials here and elsewhere) have led us all down the path to Sizzle-powered awesomesauce. In all the hype (and a lot of leaps in JavaScript adoption by developers and browser vendors), plenty of plugins have come onto the scene. This is partially why jQuery has become the most popular JavaScript library available! The only problem is that many of them aren’t too great.
In this article, we’ll focus less on the JavaScript specifically, and more on best practices for plugin delivery.
There are some patterns that are, more or less, universally accepted as “The Right Way” to create jQuery plugins. If you aren’t following these conventions, your plugin may… suck! Consider one of the most common patterns:
(function($, window, undefined){
$.fn.myPlugin = function(opts) {
var defaults = {
// setting your default values for options
}
// extend the options from defaults with user's options
var options = $.extend(defaults, opts || {});
return this.each(function(){ // jQuery chainability
// do plugin stuff
});
})(jQuery, window);
First, we are creating a self-invoking anonymous function to
shield ourselves from using global variables. We pass in
$, window, and undefined.
The arguments the self invoking function is called with are
jQuery and window; nothing is passed in
for undefined, so that if we decide to use the undefined keyword
within the plugin, “undefined” actually will be undefined.
This shields from other scripts potentially assigning a malicious value to
undefined, such astrue!
$ is passed as jQuery; we do it this way to ensure
that, outside of the anonymous function, $ can still
refer to something else entirely, such as Prototype.
Passing the variable for the globally accessible
window object allows for more compressed code through
the minification processes (which you should be doing, as
well).
Next, we are using the jQuery plugin pattern,
$.fn.PluginName. This is a way of registering your
plugin to be used with the $(selector).method()
format. It simply extends jQuery’s prototype with your new method.
If you want to instead create a plugin that defines a function on
the jQuery object, add it directly, like so:
$.PluginName = function(options){
// extend options, do plugin stuff
}
This type of plugin won’t be chainable, as functions that are defined as properties of the jQuery object typically don’t return the jQuery object. For instance, consider the following code:
$.splitInHalf = function(stringToSplit){
var length = stringToSplit.length;
var stringArray = stringToSplit.split(stringToSplit[Math.floor(length/2)]);
return stringArray;
}
Here, we are returning an array of strings. It makes sense to simply return this as an array, as this is likely what users will want to use (and they can easily wrap it in the jQuery object if they wish). In contrast, consider the following contrived example:
$.getOddEls = function(jQcollection){ //
return jQcollection.filter(function(index){
var i = index+1;
return (index % 2 != 0);
});
}
In this case, the user is probably expecting the jQuery object
to return from $.getOddEls; so, we return the filter method, which returns the
jQuery collection defined by the function that is passed. A good
rule of thumb is to wrap returned elements in the jQuery function,
especially if they can be chained; if you are returning arrays,
strings, numbers, functions, or other data types, leave them
unwrapped.
Arguably, the most important thing you can do when publishing your code is add the necessary documentation. The gap between what you explain to developers and what the code actually does or can do is the time that users don’t want to waste figuring out the ins and outs of your code.
Documentation is a practice that doesn’t have any hard-fast rules; however, it is generally accepted that the more (well organized) documentation you have, the better.
This process should be both an internal practice (within/interspersed throughout your code) as well as an external practice (explaining every public method, option, and multiple use cases thoroughly in a wiki or readme).
The most popular plugins offer full access to variables (what most plugins refer to as “options” objects) that a user may want to control. They also may offer many different configurations of the plugin so that it is reusable in many different contexts. For instance, let’s consider a simple slider plugin. Options that the user might wish to control include the speed, type, and delay of the animation.
It’s good practice to also give the user access to classnames/ID names which are added to the DOM elements inserted or manipulated by the plugin. But beyond this, they may also want to have access to a callback function every time the slide transitions, or perhaps when the slide transitions back to the beginning (one full “cycle”).
It’s your job to think of all possible uses and needs for the plugin.
Let’s consider another example: a plugin that makes a call to an API should provide access to the API’s returned object. Take the following example of a simple plugin concep:.
$.fn.getFlickr = function(opts) {
return this.each(function(){ // jQuery chainability
var defaults = { // setting your default options
cb : function(data){},
flickrUrl : // some default value for an API call
}
// extend the options from defaults with user's options
var options = $.extend(defaults, opts || {});
// call the async function and then call the callback
// passing in the api object that was returned
$.ajax(flickrUrl, function(dataReturned){
options.cb.call(this, dataReturned);
});
});
}
This allows us to do something along the lines of:
$(selector).getFlickr(function(fdata){ // flickr data is in the fdata object });
Another way of publicizing this is to offer “hooks” as options.
As of jQuery 1.7.1 and up, we can use .on(eventName,
function(){}) after our plugin call to separate the
behaviors into their own functions. For instance, with the plugin
above, we could change the code to look like this:
$.fn.getFlickr = function(opts) {
return this.each(function(i,el){
var $this = el;
var defaults = { // setting your default options
flickrUrl : "http://someurl.com" // some default value for an API call
}
var options = $.extend(defaults, opts || {});
// call the async function and then call the callback
// passing in the api object that was returned
$.ajax(flickrUrl, function(dataReturned){
// do some stuff
$this.trigger("callback", dataReturned);
}).error(function(){
$this.trigger("error", dataReturned);
});
});
}
This allows us to call the getFlickr plugin and
chain other behavior handlers.
$(selector).getFlickr(opts).on("callback", function(data){ // do stuff }).on("error", function(){ // handle an error });
You can see that offering this kind of flexibility is absolutely important; the more complex actions your plugins have, the more complex the control that should be available.
Ok, so tip number three suggested that the more complex actions your plugins have, the more complex control that should be available. A big mistake, however, is making too many options required for plugin functionality. For instance, it is ideal for UI based plugins to have a no-arguments default behavior.
$(selector).myPlugin();
Certainly, sometimes this isn’t realistic (as users may be fetching a specific feed, for instance). In this case, you should do some of the heavy lifting for them. Have multiple ways of passing options to the plugin. For instance, let’s say we have a simple Tweet fetcher plugin. There should be a default behavior of that Tweet fetcher with a single required option (the username you want to fetch from).
$(selector).fetchTweets("jcutrell");
The default may, for instance, grab a single tweet, wrap it in a paragraph tag, and fill the selector element with that html. This is the kind of behavior that most developers expect and appreciate. The granular options should be just that: options.
It’s inevitable, depending upon the type of plugin, of course, that you will have to include a CSS file if it is highly based on UI manipulations. This is an acceptable solution to the problem, generally speaking; most plugins come bundled with images and CSS. But don’t forget tip number two – documentation should also include how to use/reference the stylesheet(s) and images. Developers won’t want to waste time looking through your source code to figure these things out.
Things should just…work.
With that said, it is definitely a best practice to use either injected styles (that are highly accessible via plugin options) or class/ID based styling. These IDs and classes should also be accessible, via options as previously mentioned. Inline styles override external CSS rules, however; the mixing of the two is discouraged, as it may take a developer a long time to figure out why their CSS rules aren’t being respected by elements created by your plugin. Use your best judgment in these cases.
As a rule of thumb, inline CSS is bad – unless it’s so minimal to the point that it doesn’t warrant its own external stylesheet.
The proof is in the pudding: if you can’t provide a practical example of what your plugin does with accompanying code, people will quickly be turned off to using your plugin. Simple as that. Don’t be lazy.
A good template for examples:
jQuery, like any good code library, grows with every release.
Most methods are kept even after support is deprecated. However,
new methods are added on; a perfect example of this is the
.on() method, which is jQuery’s new all-in-one
solution for event delegation. If you write a plugin that uses
.on(), people using jQuery 1.6 or earlier will be out
of luck. Now I’m not suggesting that you code for the lowest common
denominator, but, in your documentation, be sure to explain which
version of jQuery your plugin supports. If you introduce a plugin
with support for jQuery 1.7, you should strongly consider
maintaining support for 1.7 even once 1.8 comes out. You should
also consider taking advantage of new/better/faster features in
jQuery as they come out.
Encourage developers to upgrade, but don’t break your plugin too often! One option is to offer a “legacy” deprecated, non-supported versions of your plugin.
It’s time to bite the bullet if you haven’t learned how to use version control yet.
Along with keeping your jQuery version support/compatibility a part of your documentation, you should also be working in version control. Version control (specifically, via GitHub) is largely the home of social coding. If you are developing a plugin for jQuery that you want to eventually publish in the official repository, it must be stored in a GitHub repository anyway; it’s time to bite the bullet if you haven’t learned how to use version control. There are countless benefits to version control, all of which are beyond the scope of this article. But one of the core benefits is that it allows people to view the changes, improvements, and compatibility fixes you make, and when you make them. This also opens the floor for contribution and customization/extension of the plugins you write.
The world doesn’t need another slider plugin.
Ok, we’ve ignored it long enough here: some “plugins” are useless or too shallow to warrant being called a plugin. The world doesn’t need another slider plugin! It should be noted, however, that internal teams may develop their own plugins for their own uses, which is perfectly fine. However, if you’re hoping to push your plugin into the social coding sphere, find a reason to write more code. As the saying goes, there’s no reason to reinvent the wheel. Instead, take someone else’s wheel, and build a racecar. Of course, sometimes there are new and better ways of doing the same things that have already been done. For instance, you very well might write a new slider plugin if you are using faster or new technology.
This one is fairly simple: offer a minified version of your code. This makes it smaller and faster. It also ensures that your Javascript is error free when compiled. When you minify your code, don’t forget to offer the uncompressed version as well, so that your peers can review the underlying code. Free and cheap tools exist for front-end developers of all levels of experience.
Refer to tip number thirteen for an automated solution.
When you write a plugin, it is meant to be used by others, right? For this reason, the most effective source code is highly readable. If you’re writing countless clever one-liner lambda style functions, or your variable names aren’t semantic, it will be difficult to debug errors when they inevitably occur. Instead of writing short variable names to save space, follow the advice in tip number nine (minify!). This is another part of good documentation; decent developers should be able to review your code and understand what it does without having to expend too much energy.
If you find yourself calling variables “
a” or “x“, you’re doing it wrong.
Additionally, if you find yourself consulting documentation to remember what your own strange looking code is doing, you also likely need to be less concise and more explanatory. Restrict the number of lines in each function to as few as possible; if they stretch for thirty or more lines, there might be a code smell.
As much as we all love using jQuery, it is important to understand that it is a library, and that comes with a small cost. In general, you don’t need to worry too much about things like jQuery selector performance. Don’t be obnoxious, and you’ll be just fine. jQuery is highly optimized. That said, if the sole reason why you need jQuery (or a plugin) is to perform a few queries on the DOM, you might consider removing the abstraction entirely, and, instead, sticking with vanilla JavaScript, or Zepto.
Note: if you decide to stick with vanilla JavaScript, ensure that you’re using methods that are cross-browser. You might potentially need a small polyfill for the newer APIs.
Use Grunt. Period.
Grunt is a “task-based command line build tool for JavaScript projects”, which was covered in detail recently here on Nettuts+. It allows you to do things like this:
grunt init:jquery
This line (executed in the command line) will prompt you with a set of questions, such as the title, description, version, git repository, licenses, etcetera. These pieces of information help to automate the process of setting up your documentation, licensing, etc.
Grunt does far more than just make some customized boilerplate code for you; it also offers built in tools, like the code linter JSHint, and it can automate QUnit tests for you as long as you have PhantomJS installed (which Grunt takes care of). This way, you can streamline your workflow, as tests run instantly in the terminal on save.
Oh, by the way – you do test your code, right? If not, how can you ensure/declare that your code works as expected? Manual testing has its place, but, if you find yourself refreshing the browser countless times every hour, you’re doing it wrong. Consider using tools, such as QUnit, Jasmine, or even Mocha.
Testing is particularly useful when merging in pull requests on GitHub. You can require that all requests provide tests to ensure that the new/modified code does not break your existing plugin.
If the concept of testing jQuery plugins is brand new to you, consider watching our Premium-exclusive screencast, Techniques For Test-Driving jQuery Plugins. Additionally, we’re launching a new “JavaScript Testing With Jasmine” course later this week on the site!
We wouldn’t be doing you any favors by just telling you what you’re doing wrong. Here are some links that will help get you back on the right path!
If you are writing a jQuery plugin, it is vital that you stray away from the pitfalls listed above. Did I miss any key signs of a poorly executed plugin?
Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you’d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!
This month we’ve been attending an Envato company meet-up in Malaysia. We’ve had a fun time working together as a team, made lots of exciting plans for the future of Tuts+, and also had the chance to meet up with lots of our readers! Thanks to everyone who took the time to attend our community meet-up and, if you’re interested, you can find out a bit more about our trip here (and see a few photos!)


Photoshop CS6 is packed with new features and effects that you can use in your work. In this tutorial we will utilize Photoshop’s new 3D capabilities as well as its new content aware features to create a Micro Machines inspired composition. Let’s get started!

Photoshop is a great tool because it allows us to be creative and produce imagery that would be impossible to create otherwise. In this Tuts+ Premium tutorial, author Tony Aubé will create a snowy landscape from desert photography and photos of sand. This tutorial is available exclusively to Tuts+ Premium Members. If you are looking to take your photo manipulation skills to the next level then Log in or Join Now to get started!

Layer styles are a powerful and time saving feature that can help you apply amazing effects to your designs. In this tutorial we will use layer styles to create a light bulb inspired text effect in Photoshop. Let’s get started!

If you’re working on a large project, you’ll no doubt have a build script or a bunch of task scripts to help with some of the repetitive parts of the process. You might use Ant or Rake, depending on the language the project is written in.

Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

I’m frequently asked about how I’m able to create new directory structures and files so quickly in Sublime Text 2. Well the answer is that this functionality is not offered natively; instead, I use a helpful plugin. I’ll demonstrate it in this video.

The line of action is a key ingredient to making your character’s poses look more dynamic. In this guide, we will explore what the line of action is and how it can be used to make your character poses come alive.

If you’re looking for free vector grunge graphics, such as distressed backgrounds, worn textures, dirty paint splatter, and more, then you’ve found a compilation worth downloading. We’ve collected an assortment of vector grunge illustrations, free vector grunge textures, and wickedly worn graphics available for free download. Jump in and grab these free grunge vectors now and start making grunge vector art for your next project.

This tutorial will cover the process of creating a vintage inspired retro flyer design. There are four main areas of concentration to achieve this look and feel: color, type, character and texture. We’ll review a complete vintage vector design workflow to create this retro flyer design. Let’s get started.

Avoiding repetitive tasks is always going to speed up your workflow. In today’s Quick Tip we’ll do just that, by utilizing Photoshop’s actions panel and combining it with hotkeys. Watch this quick screencast and I guarantee you’ll save tons of time next time you’re designing!

During previous screencasts in this series we’ve covered a lot of ground, building our responsive (or adaptive) layout with the Skeleton boilerplate. It’s now time to finish all the final details; arguably the most time-consuming part of any website build!

Photoshop CS6 has been hailed as a huge improvement for web and UI designers. Im going to share with you some of the features that Photoshop CS6 Beta has to offer and demonstrate how they can help you in your web or UI design workflow.

Real estate is one of the world’s most competitive industries. Dominated by ambitious agents looking for the next big sale, selling real estate is all about setting yourself apart from the competition. What better way to catch a buyer’s eye than the perfect photo of the perfect home? In today’s article, we’re taking a look at the exciting world of real estate photography.

An 18% gray card is a handy accessory that every serious photographer should keep in their bag. It doesn’t cost much and it barely takes up any space. If you encounter a situation where you have mixed lights, this unassuming piece of plastic helps you determine the white balance. It can also be used to determine the correct exposure.

The final printed image is the culmination of my journey in creating a piece of artwork that represents my view of the world around me. As photographers in the digital age we spend far too much time staring at our photographs on our computer screens and very little time holding them in our hands. I still take great pride in every print I produce. There are a myriad of options for printing your work today, from canvas wraps to Metal prints, however for me there is something timeless and classic about a finely Matted and Framed print.
In this tutorial you’ll learn how to create a complete character rig for a voodoo doll character in Maya using the Setup Machine and Face Machine plugins from Anzovin studios. You’ll learn how these plugins can save you valuable time during rigging by allowing you to utilize pre-built body and face rigs which can then be customized to fit you and your character’s specific needs.
In this tutorial we’re going to create a smooth, stylish countdown animation. You can use words, letters, logos or whatever you want to make this type of animation. As you can see it’s easy to set up and looks very stylish and attractive.
This week, Cgtuts+ has teamed up with our sister site Psdtuts+ to bring you this amazing two part, in-depth tutorial from Nacho Riesco. In this tutorial we are going to sculpt a Micro Bionic Insect with chemical war purposes using simple hard-surface modelling techniques with the Clipping Brush, Masking and much more. Head over to Psdtuts+ for the conclusion of this project where we’ll composite our render passes from Zbrush, and create the final image in Photoshop!
In today’s tutorial we’re going to take you step by step through everything you need to know to build your own rugged light dimmers. We use these exact dimmers on all our studio and on location shoots. Besides being extremely durable, these little devices provide a wider range of lighting options and are surprisingly valuable when you have to light a scene in a tight location.

We always tend to go to Photoshop for working with still images, but today I’d like to bring up a few thoughts about why working in After Effects might be a better solution for your next project.

In this tutorial we will track freeze frames into a hand-held
scene utilizing The Foundry’s CameraTracker to achieve an effect
that is often referred to as “StroMotion”. We’ll be talking about
different methods of how to remove the subject from the background
and how to line everything up. Enjoy! ![]()

Loops can form the foundation of a track, and are useful for quickly putting some ideas together when sketching out an arrangement. Samples provide us with sounds and colors to create our music with. But where can you download great loops and samples? Here are 30+ great places to start. Every music producer worth his salt is in the process of building up a useful collection of useable sounds.

We’ve all seen how you can morph one face into another in the graphical world. In this screencast Rishabh Rajan shows us how to achieve the same thing with audio using Pro Tools.

Although this is a series on mixing, it feels incomplete not to get into at least a brief discussion on master bus options and to discuss what exactly goes on when you print all your hard work to a single and final stereo file. Due to the depth of this topic, I am splitting it into two parts.

In this tutorial, I’ll introduce you to Google’s new web programming language, Dart, and explain why you should like it and what you need to know about it. Learn about this new language and form some opinions about it – will it really replace JavaScript?

In this tutorial I will show you how to access the same saved data in separate Flash and JavaScript apps, by storing it in HTML5 LocalStorage and using ExternalInterface to reach it with AS3. We will create the same app in both JavaScript and Flash to demonstrate that it is platform agnostic.

Impact is an incredibly powerful HTML5 game framework which takes advantage of modern browser’s canvas element and can also run on mobile or be compile into a native iOS app. In this video I will go over the framework, how to set up a project, some background into how to create classes in it and finally go over the core classes that make up the framework. This is a high level overview which will give you a general sense for how things work.

Usually a website needs a contact form to communicate with the site owner. One of our favorites is Contact Form 7. Let’s see what it can do!
For a lot of WordPress projects these days we use custom post types. The WordPress development team created some handy methods to integrate them into your projects. But when you use custom post types, taxonomies and meta boxes frequently, it’s quite probable that you’re going to repeat yourself. That’s why we are going to use the power of these WordPress functions to build a more powerful class, which we can use to quickly register post types, taxonomies and meta boxes.

When we talk about WordPress we usually associate it with either being a blogging platform or just another content management system, but what about as an Intranet? This tutorial will show you how you can turn your basic installation of WordPress into a robust Intranet for your business.

Engage your users with stunning carousels! We’ll look at how easy and clean it can be to implement scrollable, interactive carousels in your iOS applications. With high configurability, you can have 3D, flat, rotating, and endless scrolling arrays for data, images, and buttons.

In this tutorial series, you will learn how to create a minimalistic Alphabet Soup game. The goal of this game is to allow the player to pick words out from a jumbled set of letters. Read on!

At some point in your iOS development career, you will have the need to interact with a web service from within your app. You may need to access remote data, parse a social network feed, or even download some assets into your application. This quick tip will teach you to do so without using third party libraries!
Vierityspalkin avoimien työpaikkojen palsta on koko kevään porskuttanut tasaisesti. Erityisesti frontend-osaajat ovat olleet kysyttyjä, mutta myös ohjelmoijia ja mobiilipuolen osaajia haetaan tasaisesti. Asiakaspuolelle myös tuottajia ja verkkoviestinnän suunnittelijoita on haettu säännöllisesti. Kaupungeista Helsingin lisäksi osaajia on haettu aktiivisesti erityisesti Tampereelle tänä vuonna.

Tässä joukko poimintoja tällä hetkellä avoimista työpaikoista:
>> Kaikki avoimet työpaikat web-alalla
Over the course of these last two weeks, I had the pleasure of attending an Envato meetup/conference in Malaysia. As you might expect, Envato is composed of ridiculously smart and talented folks…folks so smart that it quickly becomes intimidating!
But I’m not here to talk about the conference specifically; instead, I’d prefer to ramble a bit on one of my largest takeaways from the event.

One day during the conference, I had a chat with Envato’s current (temporary) lead development manager, Pete, about the traditional concept of advancement in a company. In many ways, we’re designed/brainwashed from an early age to follow a very specific path:
That’s a good thing, right? Well, in our industry, specifically, maybe not.
Management can be a bit of a scary word. It indicates Excel, not code. It indicates… management, not development.
Our life-long training tells us that this is what’s supposed to happen.
But, nonetheless, it’s still a higher level (hopefully higher paying) job. Our life-long training tells us that this is what’s supposed to happen, if we desire to be successful. You’ve worked hard; now you get to manage others (and maybe drink scotch). This is the path.
For creatives, though, does this sort of role make us happy?
Sure, we may have a bit more input into the direction of the business, but does it make us happier? For the last year or so, I’ve struggled with this very thing. I adore my current job: I’m able to help shape the future of education in the creative fields (more on that later this year), and spend all of my spare/free time learning how to be a more efficient developer. What could be better than that?
Still, though, that lingering feeling always rested in the back of my mind: I’m only “advancing” in the world if my job title/rank increases sporadically. I had (and have) no desire to change my current involvement/role in the company (Envato), but, nevertheless, felt that I should reach for these more traditional managerial roles.
This old-fashioned notion of advancement is a silly metric for success.
Pete taught me that this old-fashioned notion of advancement is a silly metric for success. Instead, we have to reshape our perception of what both success and fulfillment are. Remember when I noted that Pete was the development manager at Envato? Well, technically, at his own choosing, he’s the temporary manager, while we search for a new development manager. Despite the fact that he’s certainly qualified for the job, he doesn’t want it – which I find incredibly admirable. Instead, his skills/desires rest firmly in things like software architecture. In his own words, that is where he is able to contribute most effectively to the company. So, a bit oddly, perhaps, he is currently in the position of finding and hiring his future manager.
It’s interesting how the older I get, the more and more I come back to this one word: “contentment.” It’s not about job titles, or vanity, or even money (to some extent); it’s simply about contentment. Do what you love, and forget those old-fashioned job titles and notions of success. Or…
Figure out where you’re most effective in your company, and do…that. Period.
What if someone came to you and said, “I’ve designed this great website, but people don’t stay on it. Why?” How would you respond? Would you ask them whether they have done extensive A/B testing? Would you recommend testing the usability of the website?
People like to test a number of metrics to see why people are not staying on a website. I think sometimes we spend so much time focusing on analytics that we throw common sense out the window. Don’t get me wrong—analytics are a powerful tool for improving a website. But often the problem is right in front of your face.
What if you simply told them that the reason people are leaving is because of the way they designed the website? How mind-blowing an idea is that? Doesn’t that change your entire perspective on the design? It could be the greatest thing in the world, but what if you really designed something to chase people away or looking at it another way: What if you have designed it so there is no incentive to stay?
I love getting feedback on the stuff that I write; yet my website has no comments section. Is it reasonable for me to wonder why people don’t leave feedback? I could tell people that there is a forum on the website where they can leave feedback, but that means they would have to register, get approved and then remember what they wanted to write. The website isn’t designed for instant feedback.
When I didn’t have any social media widgets at the end of a post, sharing of articles dropped over 80%. It wasn’t fair for me to assume that people would remember to share something they liked or that if they were on the fence they would make an effort to do so. If I really wanted people to retweet what I write, I would have to guide them to doing so by putting a retweet widget at the end of everything. Maybe I could even add some text asking them to retweet if they like what they read.
The point is that, if I expect a person to take an action, I would have to design the process for taking that action right into the website itself. I should never assume that a person who is interacting with my website will automatically take that action. Would a driver stop at an intersection that had no stop sign?
As designers we have to understand that the interface we create dictates the action of the people using it.
If you run a website and hope to get a lot of comments, then the best way to go about that is to make posting a comment as easy as possible. Of course, doing so could lead to people leaving all types of comments, both useful and not. A great example of designing how you want users to interact with a product is Pinterest.
Most comment blocks on Pinterest are filled with simple comments. The content doesn’t lend itself to much discussion, but Pinterest obviously wants users to engage in other social interactions, and it has designed the product to make that easy to do. You can easily like, comment, repin and share any image that you come across, and all of this makes the content spread quickly throughout the network. This network effect is one of the main reasons for Pinterest’s explosive growth over the past couple of months.

Pinterest made an interesting decision in requiring all users to connect to the website through either Facebook or Twitter. This mean that real names (usually) are tied to users; because of this, the quality of stuff that people share is generally high. Allowing everyone to hide behind fake identities would have resulted in a much different experience.
But the system wasn’t designed that way; it was designed so that people who post quality content (or at least content that others in their circle like) would become popular. Thus, rather than turning into a website full of animated GIFs and Web comics, the website has become a valuable resource to its community—mainly because it was designed to function that way.
I realize that simply saying that a product was designed to do what it is meant to do makes fixing problems seem like the easiest thing in the world. Of course, as you dig deeper into how to improve a design, you will have more variables to keep in mind; but always be aware of the simple fact that people will do what the design of a website lets them do.
Why did Twitter evolve beyond being a place where people just leave status updates? Part of it has to do with the tiny microcopy that was above the status update field. Originally it said “What are you doing?” and this of course led to people talking about their breakfast. After some time they changed it to “What’s happening?” which helped guide the people using the service to post about what is happening around them.
Why was Digg being gamed for so long? Because the design encouraged it. Simple. Executives at Yahoo might sit around a table asking why users aren’t using its search engine? Does the design of the website look like it is meant for search or even encourage it? Do you think Google execs sit around a table asking why people don’t use its search engine when they hit its main page? The design of Pinterest encourages users to continually scroll down the page looking at more and more pins; it is designed to keep you on the website.
Do you want your users to do something specific? Then design your website so that they do it.
It could be the greatest thing in the world, but what if you really designed something to chase people away or looking at it another way: What if you have designed it so there is no incentive to stay?
© Paul Scrivens for Smashing Magazine, 2012.
DigitalBooker on verkkopalvelu, jonka avulla yrittäjät voivat tarjota asiakkailleen ajanvaraussovelluksen verkkosivuillaan. DigitalBooker soveltuu esimerkiksi kampaamoyrittäjille, tai kenelle tahansa jonka liiketoiminta perustuu ajanvarauksiin. Vierityspalkki jututti Fredrik Rönnlundia siitä kuinka he ovat palvelun tehneet, ja kuinka paljon aikaa ja rahaa toteutukseen on mennyt.
1) Teitte tuotteenne uudistuksen hiljattain – miksi päätitte uudistaa tuotteenne alusta saakka uusiksi?
“Päätimme kirjoittaa kaiken uusiksi alusta. Erityisesti tietämys asiakkaiden tarpeista lisääntyy meidänkaltaisen verkkosovelluksen alkuaskelien aikana. Lisäksi myös oma liiketoimintamalli hakee suuntaansa. Meidän tapauksessamme olimme tehneet järjestelmän jolla pystyi varaamaan aikoja resursseilta, mutta kun palvelun kysyntä lisääntyi, niin totesimme esimerkiksi parturi- ja palvelupuolella koko alan logiikan olevan erilaista kuin mihin olimme alunperin varautuneet. Jouduimme jumppaamaan erityisesti ohjelmiston tietomallia. Lisäksi jouduimme miettimään käyttötavat ja käytettävyyden uudestaan, niin että se palvelisi asiakaskuntaa josta meillä ennestään oli kovin vähän substanssiosaamista. Palvelun uudelleenkirjoitus kesti yli vuoden, mutta nyt meillä on sovellus joka taipuu ilman liimaa ja purkkaa niihin tarkoituksiin joissa tänään näemme kasvumme olevan. Tällä hetkellä tärkein palvelumme on nimittäin palvelu- ja ryhmävarausten myymisessä sekä PK-yrittäjien markkinointivälineenä. Alunperin olimme tekemässä tennisratavarausjärjestelmää, joka oli täysin eri maailmansa.”
2) Millä teknologioilla ja millaisin voimin palvelun uudistettu versio nousi pystyyn?
“Uudistettu versio päätettiin tehdä samalla teknologiapaletilla kuin aikaisempikin versio, joka oli hyväksi havaittu, ja jolla pääsimme nopeasti vauhtiin. Ajanvarausjärjestelmämme on Linux+Apache+MySQL+PHP-pohjainen sovellus, jossa käytämme JQuerya käyttöliittymän sokeroimisessa. Palvelu uudistettiin yhden hengen voimin ja uudistuksen kesto oli yli vuoden pituinen työurakka.”
3) Kuinka paljon käytitte työaikaa ja millaisiin asioihin meni eniten aikaa?
“Uudelleenkirjoitus oli erittäin tekninen prosessi jossa suurin osa ajasta (50%+) meni käytettävyyden määrittelemiseen ja suunnitteluun. Työaikaa kului yhteensä noin 350 henkilötyöpäivää kahdelta henkilöltä. Tästä työmäärästä koodaus vei noin puolet ajasta.”
4) Kuinka paljon teillä menee palvelun ylläpitoon, asiakaspalveluun ja jatkuvaan kehittämiseen nykyisin aikaa?
“Ylläpito ja asiakaspalvelu itsessään vie 1-5 tuntia viikossa aikaa. Kaikki keskeiset, toistuvat toiminnot laskutuksesta alkaen on automatisoitua. Jatkuva kehitys saa osakseen kaiken jäljelle jäävän ajan. Välillä on tasaisempia aikoja jolloin nykyistä palvelua parannetaan, ja välillä taas jokin osa-alue räjäytetään osiin, ja aloitetaan joltain osin uudestaan. Teemme noin yhden täyden henkilön edestä töitä järjestelmään tällä hetkellä, joten huomattavasti vähemmän kuin uudistuksen yhteydessä. Toisaalta täysin uudistettu palvelu mahdollistaa muutokset paljon tehokkaammin, joten aikaa jää enemmän asiakaspalveluun.”
5) Mistä asioista muiden kannattaisi ottaa oppia teidän kohdallanne? Mitkä asiat sujuivat mielestäsi hyvin uudistuksessa? Mitä tekisitte kenties toisin?
“Se, että jos haluaa tehdä loistavia verkkosovelluksia on tunnettava sekä teknologiaa että ihmisiä. Yksin “liiketoimintaosaamisella” ei voi tuoda ratkaisuja jotka palvelevat ihmisiä tarpeeksi hyvin, ja yksin teknologiaa osaamalla ei voi tehdä mitään. Suomessa hyvä esimerkki onnistuneesta liiketoimintaosaamisen ja teknisen osaamisen yhdistämisestä on mielestäni esimerkiksi Eat.fi.
Jos voisin aloittaa alusta nyt, niin keskittyisimme myyntiin enemmän heti alussa emmekä odottaisi “ensimmäistä valmista versiota heti nurkan takana”. Muuten olen erittäin tyytyväinen kaikkeen mitä olemme saaneet aikaiseksi. Mutta oppina muille, ymmärtäkää teknologiaa ja asiakkaita, niin onnistutte siinä mitä yritätte tehdä – liian usein painotetaan vain business plania, mutta unohdetaan että jos halutaan tehdä jotain mullistavaa, se ei riipu vain siitä liiketoimintasuunnitelmasta.”
Kommentit (Perttu Tolvanen): DigitalBooker on esimerkki verkkosovelluksesta, jonka ensimmäinen versio ei vastannut toiminnallisesti sitä mitä markkinat kaipasivat. Palvelun kehityksessä jouduttiin tunnustamaan, että pelkästään muokkaamalla hieman perusteita ei jatkokehitys olisi järkevää. Täten päädyttiin uudistamaan koko sovellus alusta alkaen.
Tämä on hyvä esimerkki ohjelmistoalan realiteeteista, jotka koskettavat etenkin tiettyyn erikoistarkoitukseen tehtäviä sovelluksia. Joskus vain täytyy laittaa palvelun perustus kokonaan uusiksi.
Rönnlund myös korostaa kokemuksissaan sitä, että pelkästään liiketoimintaosaaminen ei riitä menestyvän kaupallisen verkkosovelluksen pyörittämiseen. Tekniikan hallitsemisella on merkittävä rooli, ja tekniikan kanssa tulee olla valmis myös työskentelemään ensimmäisen toteutusvaiheen jälkeen.
|
|
Intricate Japanese Movable Type Sets Visual Caffeine: Exploring Art and Architecture, Issue 1 |
![]() |
Impossible Plant-Animal Hybrid This creature should not exist... but it does. |
![]() |
Heavy Bombers: Fearsome Angels of the Cold War A game of fear, played with monstrous planes |
![]() |
The Jewish Engineer Behind Hitler’s Volkswagen Finally, the full story behind emergence of Volkswagen |
![]() |
Fluid Dynamics & Liquid Photography It's a Splash! - High-Speed Photography at its Finest |
![]() |
Hanging Monasteries of the World Truly the way is narrow and the path is steep... |
![]() |
Steam Buses & Trucks Ugly, smoke-belching beasties... |
![]() |
Historic & Elaborate Water Pumps Most flamboyant styles for pumping water |
![]() |
April 29, 2012 - Biscotti Bits Mixed Links & Images Incl. "Epic Launch Video" |
![]() |
April 15, 2012 - Biscotti Bits Mixed Links & Images Incl. "Push to Add Drama!" |
Link Latte #178 - Click Here
Link Latte #179 - Click Here
Check out previous Link Latte issues! - Click Here
CONTINUE READING! -
NEXT PAGE ->
Continue on to other monthly archives:
March
2012
February 2012
Dec-Jan 2012
November 2011
October 2011
September 2011
August
2011
July
2011
June
2011
May
2011
April
2011
March
2011
February 2011
January 2011
December 2010
November 2010
October 2010
September 2010
August
2010
July
2010
June
2010
May
2010
April
2010
March
2010
Winter 2009-2010
Oct-Nov 2009
September 2009
August
2009
June-July 2009
May
2009
April
2009
March
2009
February 2009
January 2009
December 2008
November 2008
October 2008
September 2008
August
2008
July
2008
June
2008
May
2008
April
2008
March
2008
February 2008
January 2008
December 2007
November 2007
October 2007
September 2007
August
2007
July
2007
June
2007
May
2007
April
2007
March
2007
February 2007
January 2007
December 2006
November 2006
October 2006
Link
Lattes
A few weeks ago, I was quite surprised when I saw the pavement quickly approaching while I was out for a walk. Laying there stunned, I soon realized what had happened: I fell. Ouch. B-minus. I normally try to be as attentive as possible, but this time a big crack in the pavement caught my shoe and threw me completely off balance.
After reporting my clumsy accident to friends and family, I instantly received comments like: “be more careful” or “better watch out next time”. In the end, I started to defend myself—if that crack would not have been there, I most likely would not have been face-planted.

When it comes to filling out forms on a mobile phone, I have observed many users running into a similar experience, merely less painful in its physical aspect. Many elements within a mobile form affect how smoothly users will get to a service or product hiding behind a form of any kind.
There are several factors that can be considered to be stumbling blocks throughout the journey of filling out a form. Specifically on a portable device, this journey is complicated by the fact that we have to consider contextual parameters such as time, location, or limited input options, in comparison to a firm desktop experience. In this post we will look at the most common stumbling blocks for mobile devices. Moreover, I will discuss design strategies to avoid stumbling blocks and to facilitate a safe and quick stroll through forms for mobile users.
Some might say that elegantly designed forms can be compared to the likes of an efficient traffic system—as soon as you enter the road, you also enter a world of permanent and dynamic guidance that helps navigate you safely to your final destination. For example, the crosswalk signals tell you when it is okay to cross the street, just as the street signs signal the names of the streets that you are on.
Street lights are also provided to help you navigate through difficult terrain in the dark. Keeping in mind your ultimate destination, you ultimately decide where to go, step by step. Road signs present your options and point out limitations. You can follow the traffic, take a short cut, or obey the navigation system on your phone.
In this situation, comprehensible and timely feedback is vital. The same applies to mobile form design. Signposts and immediate feedback encourage users to complete a form. Although inputting data on a mobile device can be very cumbersome, many people happily key in vast amounts of information when using services such as Twitter, Facebook, or text messaging on their mobile devices. Such services are good examples of how seemingly poor interfaces will not stop people from using a much wanted service, as long as the return of their effort is evident. People who understand and trust the outcome of their journey are less likely to hesitate about wandering even down a difficult path.
However evident the effort of typing on a mobile device might be, inputting data can take some time and can also become frustrating very quickly. Letting your users know almost instantly that they provide data in the wrong format, or that their username is already taken, is important. In the same way, a form can tell them where they are within the form, to make sure they don’t type the right data into the wrong field.
Furthermore, portable devices are more likely to suffer from connection errors and slow connections than desktop devices. Client-side validation techniques, such as HTML5/CSS based or optimized JavaScript approaches, have proven to be advantageous in this case, as they reduce the amount of data transfer to easily allow UI enhancements while coping with less stable connections. But keep in mind when using JavaScript for form validation, that some mobile browsers (such as the Blackberry OS browsers—except of the most recent one), are not JavaScript enabled per default. Therefore, users who are unable or uninformed about how to change their settings will benefit from implementations following the concept of progressive enhancement. The less time users spend on retyping data or waiting for data to be validated the quicker and happier they will get through a form.
One of the biggest take-aways from the Keystroke-level model in form design is that navigating along interactive elements requires both physical as well as mental activity. This can have a severe impact, especially on a mobile phone, based on the natural way of interacting with a portable device. Every input field within a form requires users to scroll through it, understand its meaning, focus on it, and then provide the correct information.
Due to the fact that people use their devices in a lot of different ways and these devices vary “greatly”, form elements that are spread over several input fields are prone to be rendered on a mobile device in a way unintended by the designers. As an example, during user testing sessions, I sometimes see users getting stuck on providing their phone numbers when having zoomed in on the form. The typical behavior is to enter their entire number into the first box provided for the area-code, completely missing the second input field. After submitting the form, they are puzzled about why there are two fields and the corresponding error message.
Separated telephone number fields (left) in comparison to a
unified field (right) with optmized input type and a label within
the field to remind users about the area code.
To allow users to get through a form quickly, there are a variety of compression techniques to reduce the amount of fields needed to provide certain data. Many of them require more post-processing on the back-end. If you can’t dissect numbers on the back-end, smart defaults or clever instructions work just as good. Some of them simply require a thought about the way of keying information into a field. For example, using a predefined drop down to provide the date of birth, rather than a loose input field or htlm5 optimized input fields for numbers, mail addresses, or other types of data, when appropriate. Dynamic input masks can help users to provide even quite complicated types of data with ease. Moreover, it will just take you a minimal effort of scripting.
At other times, forms might benefit from rather unconventional approaches such as text input fields for a quick and easy country selection. Furthermore, there are a variety of libaries such as jQuery mobile to optimize input fields and to ease validation, even for complex data.
Overall, our goal is to allow people to navigate through the form, achieving the quickest possible success with the least necessary effort. At all times we want them to feel that they are doing the right thing, and that their time is well spent. Brevity is crucial. Some people get stressed when spending too much time on trying to find hidden checkboxes, switching between keyboard layouts, or attempting to understand skewed marketing questions. Some people get physically tired answering redundant questions, filling unnecessary blanks, or scrolling up and down to find a required field that they just missed. To reduce cognitive load as well as physical effort it is important to remove optional steps from a user’s radar of attention, simplify the way of inputting information wherever possible, and to create a comprehensible flow throughout the form. If the process is too complicated (or the effort too high) a dropout is quite likely.
In the end, fine-tuned and streamlined forms will save your company phone calls from frustrated users and lead to more and more happy ones as it requires them to spend less time navigating through input fields and figuring out their meanings.
Another great design concept to exploit for form designs are the Gestalt laws of grouping to help support the orientation of users. Applying grouping principles to a multiple questions form allows us to structure content, to create a visual flow, and to group related form elements.
In many projects I have seen design teams arguing about whether to break down a rather long form for mobile devices into several short pages or rather for one long page. Either way, there are endless possibilities for both design approaches to elegantly confirm users about their progress. This helps them recover from their errors, and to make them feel confident that the data being saved will not have to be reentered (in case they loose the connection, or accidentily close the application).
Both design approaches have their individual benefits, the only spanning factor here is the breakdown of the long form into meaningful and manageable chunks. For single-page designs, this means that it should even be possible to visually distinguish the single steps from one another. Especially with portable devices, the longer a form page is, the faster users will be able to scroll through, in case they have to jump between fields. Poor visual guidance in this way will result in users missing to fill out fields, losing sight of fields, and/or getting frustrated by searching for them after being presented error messages. White space and general grouping techniques are therefore vital to create visual guidance throughout a form.
Using color coding to highlight the active input field from
other input fields (left) or to visually differentiate sections
from one another in a long form (right).
Distinct grouping in interface design is a basic exercise because of its power for reducing processing speed and cognitive load. A while back, Matteo Penzo investigated the effect of different visual grouping techniques for a typical sign-up process. In his eye-tracking study, he analyzed the importance of label alignment for input fields and highlighted the superiority of top-aligned labels in many cases. Easy to distinguish input fields with top-aligned labels in close distance to one another allowed users to look at the label and the field in one go.
Other techniques required higher processing efforts, thus increasing the coginitve load and the time it takes to process the entire form. Less effort is good, and despite the granular example, we have to keep in mind that all these factors add up through input elements, the different sections, and the form as a whole within the website. The more complex the form, the bigger the effects of distinct grouping. Reducing the need for visual fixations allows a reduction in cognitive load, helping users to focus on their task and allowing your form to function almost like a navigation system—helping users to find their way to the goal.
By considering the effects of distinct groupings, we support our human capability to naturally perceive objects as organized patterns and take away the need for users to create an understanding about the form by reading the questions in depth, relating to the elements mentally. Naturally we want users to read through the questions. But similar to a vis-à-vis conversation, we can use facial expressions in combination with the words we say to underline our message and to get it across more easily.
One of the major reasons that users get stuck on forms when filling them out on portable devices is limited visibility. Users, who are entering key information into a form’s field, usually have more than half of their screens covered with the keyboard, input suggestions, and other status information. To navigate between fields, and for general orientation, I see in many testing sessions where participants frequently try to disengage the onscreen keyboard, when looking for certain fields, or scrolling through the form to increase visibility.
However, many people will use the “return” button on the bottom right of the keyboard to disengage it after keying information into the field, or even to confirm their input for the single field. Although this approach helps many users to get rid of the keyboard (and to see the form on their whole screen), pressing the button also means, in many cases, that the form will be sent to the server straight away. Therefore, many users will be confused by a loading screen and the need to wait for a server response after pressing the “return” button.
The return button on Android (left) and iOS (right) is very
salient within Web forms, and pressed by many users without the
intent to send off the form.
Using the keyboard to send off a form is very handy, when using a single field form such as a search box. However, for multiple question forms on portable devices, it is important to check the form on the client side before sending it off, when users press the “return” button (by accident) to avoid confusing loading times. To ensure that your form is not submitted by accident, there are plenty of client-side validation tools; jQuery plugins, for example, provide everything we need.
In short, be a tour guide. After all, designing a good form is like planning a hike with friends or family. Not only do we need to find out who will be on the trek, we need to plan for breaks, points of interest, and unguided side-treks in order to make sure everybody gets the most of their hike. However, as most of you will know, most hikes are not free of problems, and difficulties are inevitable; people can wander off, some might need help or more time to get through challenging passages, weather conditions are bound to change, and general mistakes happen. It is seldom that all of these inevitable difficulties will evolve into a real problem as long as we are prepared. Similarly to a hike, difficult situations are all about awarness, clear communication, and guidance. All it takes is a good approach to inform users what their problem is and what they can do to fix it.
There are plenty of techniques to help strayed users find their way back to the right path. Putting messages under input fields, for example, has proven to be quite a solid approach for telling users what has gone wrong. In combination with noticeable color coding (i.e. red for errors, or green for confirmation) you can be sure to get the necessary attention.
Two designs showing prominent error messages for misspelling
hints (left) and general processing errors (right).
Another important aspect that is often neglected when it comes to messages within forms is the choice of words. On the one hand this refers to what we say, and on the other, it is about how we say it. Your error messages or instructions will most likely be read by a nontechnical human being. Let’s create messages as we would be talking directly to your user: avoid jargon, be tactful and brief. There are many useful recommendations on how to design effective error messages. Most importantly, we want our users to understand what happened and why it happened in a clear fashion.
On top of that, most users will not only appreciate clear notification, but also advice on how to fix the problem right away. Dyson, for example, managed to reduce support calls and increase the confidence in their products with a simple change in the way they display error messages. Rather then showing the problem (e.g. “Low Voltage Error”), they switched to displaying possible solutions (e.g. “Check Power Cable”). In this way, they are not only making their users aware of problems, they are also giving them guidance on how to fix them. On your form, many different users will possibly make similar mistakes. If possible, it is a good idea to analyze inputs to include a solution for the problem that helps users to recover them quickly. Ideally it even relates to the data they wrongly provided.
Wherever error messages pop up troughout the day, try to record them. At the end of the day, those records can tell us where stumbling blocks are still hiding, and what we need to improve to smooth out the path.
Mistakes happen—c’est la vie. Ideally though, we should aim to avoid most of the tripping hazards that delay so many users from filling out forms on a portable device. Similar to an uneventful stroll on the pavement, the smoother the path is to the destination, the more likely users will complete the journey. Easy orientation, no detours, clarity, and a little bit of guidance are a traveler’s best friends. And experience shows that the further users get before stumbling upon an error, the more likely they will put extra effort into completing the task.
Ultimately, other stumbling blocks may exist apart from the ones I discussed. So try to connect your analytics to the activity on the pages to find out where people drop out of the process. This will show where stumbling blocks may exist and help to remove one block after the other to ensure the user the smoothest journey.
(jvb)
© Robert Brauer for Smashing Magazine, 2012.
Kotimainen frontend-kehittäjäpiiri on organisoinut päivän seminaarin Helsinkiin. Wanhassa Satamassa nähdään ulkomaisia puhujia, ja kuullaan miten front-end-kehittämisen kenttä makaa nyt keväällä 2012.
Webshaped-seminaarin ajankohta on osuva, koska juuri tänä keväänä on frontend-kehittäminen ollut kuumana puheenaiheena, ja samalla esimerkiksi aihepiirin rekryilmoituksien määrä on lähes räjähtänyt.
Puhujina tapahtumassa nähdään sekä kotimaisia että ulkomaisia ammattilaisia. Mielenkiintoisiin puhujiin lukeutuu mm. designer-supertähti Simon Collison, Github -palvelun pääsuunnittelija Kyle Neath sekä palkitun Tinkercad-palvelun WebGL-asiantuntija Mikko Mononen.
Tapahtuman järjestäjiin kuuluu suomalaisia verkkoammattilaisia, joilla on aiempaakin historiaa tapahtumien järjestämistä (esim. Agile Finland ja Frozen Rails). Organisaattorit ovat myös olleet pystyttämässä kotimaista frontend-yhteisöä (www.frontend.fi).
Tapahtuman hinta on 230 euroa, ja päivän laadukkaasta seminaarista tätä ei voi pitää pahana hintana.
Harvoin Suomessa järjestetään näin kapeaan kenttään erikoistunutta ammattilaisseminaaria juuri webin tekijöille. Sponsoreina tapahtumalla on myös tunnettuja web-alan toteuttajafirmoja, kuten Futurice ja Reaktor.
Kannattaa siis tarttua tilaisuuteen, jos tilaa kalenterista löytyy.
>> Tarkempi ohjelma ja lisätietoja löytyy osoitteesta http://webshaped.fi
PS. Vierityspalkin yleisöön kuuluville frontend-asiantuntijoille on kaksi ilmaislippua tarjolla. Lipun saa kaksi ensimmäistä kommentoijaa, jotka osaavat kertoa kuka puhujista kertoo tarinaa responsiivisen designin toteutuksen workflowsta käytännön tasolla. Jätä kommenttiisi nimi ja sähköpostiosoite, niin pääset seminaariin ilmaiseksi. Lippu on henkilökohtainen.
#179 - Week of May
1, 2012
Hubble
Telescope Needs You (to Find Treasures) - [yes!]
The
Lost Egyptian Labyrinth: Surpassing the Pyramids - [wow history]
Roger Ebert: The Greatest Films of All Time - [awesome list]
Fire Whirl (or
Fire Tornado) - [disasters,
info]
Real-life Inspirations for Simpsons Characters - [fascinating]
Birth
of the Microphone - [vintage pics &
info]
Don't miss a SuperMoon Event this Saturday - [wow space]
Rare Photos: James Bond Auditions - [what
if?]
Urban Oil Wells in Los Angeles - [disguised]
Wind Power Without the Blades - [wow
tech]
Amazingly
Unique Bicycle Concept, similar - [invention]
These Cars
Are Truly Bizarre- [scroll
down]
"The Course
of Empire" by Thomas Cole - [awesome
art]
What would you find if
you remove all the hype? - [search
site]
The Last Artwork of Great
Artists (an online exhibition) - [art]
Great NYC Vintage Photos - [incl. fire
engine]
Titanic to be Rebuilt in 2016 - [hopefully?]
The Worst Things for
Sale - [cool site]
World's
Cutest Squids - [nature, pics]
Most Expensive One-Bedroom Apartment - [architecture]
More-
Cat- Antics! - [fun
videos]
How to Completely Erase Data on a CD - [fun video]
The Smallest
Radial Engine in the World, jump - [wow video]
Another
Fantastic Engine, Even Better - [wow
video]
Birth to 12
years in 2 min. 45 sec. - [cool
video]
Not a
Good Idea to Cross... Too Late! - [wow
video]
Most
Incredible Stunt with a Forklift - [wow
video]
Creative & Luxurious Bathtubs -
[compilation]
Totally Failed Perspective - [funny
pic]
Quality-Schnallity to the Rescue! - [promotion]
SEE ALL OTHER LINK LATTE ISSUES HERE
Any application of typography can be divided into two arenas: micro and macro. Understanding the difference between the two is especially useful when crafting a reading experience, because it allows the designer to know when to focus on legibility and when to focus on readability.
This article focuses mostly on a few simple macrotypographic techniques—with a dash of micro—and on how to combine them all to build a more harmonious, adaptable and, most importantly, readable Web page.
First, some definitions. Microtypography has to do with the details; setting the right glyph, getting the appropriate kerning and tracking, and making stylistic choices such as when to use small-caps. Micro techniques have received a lot of attention recently, as browser makers adopt new CSS attributes that allow for finer control over Web type. Microtypography deals mainly with legibility and can be thought of as the design of letters and words.
Macrotypography focuses on how type is arranged on the page. Most macro techniques have been achievable through CSS for quite some time, but because our understanding of the Web page is changing, the way we use these techniques must adapt. Macrotypography deals mainly with readability and can be thought of as the design of paragraphs and the page.
For the designer’s purpose, readability refers to the ease with which a body of text can be consumed, and it correlates closely to the reader’s eye strain. This should not be confused with legibility, which refers to the degree to which individual glyphs in text can be discerned. The techniques for creating a great reading experience are complementary to those for creating a great user experience (UX), and vice versa. They also both share the same symptoms of failure. Poor readability on a website can lead to confusion, frustration and ultimately abandonment, while a great reading experience is invisible, supportive and engaging.
As with UX design, every website design would benefit from some measure of concern for readability. For example, text-heavy websites—such as blogs, newspapers and magazines—should uphold readability as a priority, while websites for events and e-commerce might just need to tweak line heights and font sizes. Whatever level of importance you place on readability, you should undertake a continual process of refinement towards an effortless reading experience.
The foundation of great reading experiences on the Web lies in the study of book design. After all, books are where readable typography was honed. Personally, I hold The Form of the Book by Jan Tschichold as the ultimate resource for good taste in book design, and I am certainly not alone.
Many of the techniques we’ll cover here have been adapted for the Web page from lessons introduced in this book. Sadly, the book has been out of print for about 20 years (at least in the US), and a copy can cost around $150 on Amazon’s marketplace. I have created a digest of it, but if you want to read the full text, you could always try your local library or university (which is how I finally got my hands on it).
Now, let’s look at the various macro techniques—and a few micro techniques—to make your website’s content more readable. I have chosen an article that is typical of the kinds of reading experiences users encounter. I have removed the header and some branding elements, but it remains mostly as I found it.
In our example, important content (navigation, advertising, related links) lies on either side of the reading area. For optimum readability, a less obtrusive placement of these elements would be best, but this is not always possible. We will, therefore, not rearrange the layout, but work within it. Here is what we are starting with:
As we learn about each technique, we will apply it to our example. But keep in mind that this exercise is to improve only the reading experience, not the overall design.
Margins give the eye room to maneuver. They provide a buffer between the main content and ancillary elements—such as related links and ads—allowing the reader to focus on the text. Beyond this purely functional purpose, margins can also bring deeper harmony to the layout.
Margins comprise negative space; they afford the designer an opportunity to build a relationship between a body of text (the figure) and its surroundings (the ground). As Tschichold tells us, “Harmony between page size and the type area is achieved when both have the same proportions.” Now, the proportions of a page in a book are much different than those of most digital displays (especially ones in landscape orientation), so to adapt this concept to the Web, we can work towards a harmony between our text and its immediate visual container.
On our example page, the margins are not very generous. Also, the main content is crammed in between two very loud columns. First, we can add more space to the right of the text, giving the reader room to go from the end of one line to the beginning of the next without being distracted by the secondary content on the right. And adding more margin to the left of the text allows the reader to easily find the start of the next line and to scan the article for topics they are interested in.
Margins can be set intuitively by increasing the amount on each
side until the content feels comfortable. Applying this to our
article element is easily achieved by adding
padding in our CSS (rather than margin,
in this case). For now, we will just double the
padding on the left and right:
article {
padding-left: 20px;
padding-right: 40px;
}
In our adjustment of the margins, we can create still greater harmony between the copy and its surroundings, but first we must visualize an invisible container around the content. This will be our “page” with which to build harmony in the reading area:
The way to create harmonious proportion between text and its container is to give them the same shape. The content should have the same proportions—only smaller—as its containing element. Tschichold surveyed a mountain of book proportions and concluded that the most harmonious proportions for margins are roughly 2:3:4:6 (top:right:bottom:left) for the left-facing page (recto) of a book. Given that we do not have facing pages on the Web, we can make the margins symmetrical and adjust the ratio to 2:3:4:3 by shaving off a bit of the left margin. Web text does not need as much side margins as book text because Web pages do not need to accommodate the reader’s thumbs.
Though they may seem the obvious unit of measure, percentages
for padding will only measure in relation to the
width of our article element’s container,
skewing our top, bottom and side proportions to an inappropriate
degree. Therefore it’s best work with padding in ems
or pixels until the reading area has the same proportions as its
container. To keep things simple, let’s start with 2em for the top
padding in our example. After applying our adjusted ratio from
above, our article’s padding can be
written as 2em 3em 4em 3em or 2em 3em 4em
in CSS shorthand. Given the fluid nature of content on the Web,
this is just an approximation of Tschichold’s proportions. For a
typical body of text on the web—which is taller than it is wide—the
margin should be generally less on top, even on the sides, and most
at the bottom:
article {
padding: 2em 3em 4em;
}
We can also move the lead image to the right. This allows the body copy to hold its shape better and allows for even easier scanning of the article. We can break this principle to draw attention to images and figures, of course, but for our example the image is too distracting on the left when placed early in the article.
If we want, we can bring the text forward on the z axis, putting even more focus on our copy and de-emphasizing the ancillary content by creating a visible container for our text. This is a tactic we can easily use in Web design that books do not need:
body {
background: #fcfcfc;
}
article {
background: #fff;
border: 1px solid #eee;
padding: 2em 3em 4em;
}
Our page already feels more balanced and less intimidating, but we can use more techniques in the body of the text to further enhance readability.
Font selection is a micro concern, but it has a tremendous impact on the macro appearance. In Detail in Typography, Jost Hochuli best outlines this interdependence: “In typography, details can never be considered in isolation.”
The font for the body copy should be chosen for its on-screen readability, before any concern for style. The headings and pull quotes are perfect opportunities to flex your typographic creativity, but leave the long runs of copy to dependably readable workhorses such as Georgia, Arial and Myriad, which were all designed for optimal reading on a back-lit screen.
Fonts that are more readable on digital screens typically exhibit the following attributes:
All of these rules have exceptions, but they should be your guiding principles when choosing a font for the body copy. Here are some font stacks that I find give some flavor of style, provide appropriate fallbacks and are all highly readable:
"Proxima Nova Regular",
"Helvetica Neue", Arial, Helvetica, sans-serif;
(As used right here on Smashing Magazine)"Myriad Pro", Arial,
Helvetica, sans-serif;
(As used on my
website)"Fanwood
Text"", Georgia, Times, "Times New Roman", serif;"PT Sans",
"Trebuchet MS", Arial, sans-serif;Let’s apply Myriad Pro to the body text on our page:
article {
background: #fff;
border: 1px solid #eee;
font-family: "Myriad Pro", Arial, Helvetica, sans-serif;
padding: 2em 3em 4em;
}
In setting any block of text, we must consider its measure.
Measure is defined by either the number of characters per line or
the number of words. I use words because they are easier to count,
and I try to follow Tshichold’s suggestion of 8 to 12 words per
line. If you base your measure on characters, then 45 to 85
characters per line is ideal. Once the margins and widths have been
set, proper measure can be achieved through two attributes in the
CSS, font-size and word-spacing.
When deciding on a size, strike a balance between making the font small enough that the reader is not too distracted when jumping to the next line, but big enough that they do not have to lean in to read the text on the screen. For most fonts, 16 pixels works well. Other factors might lead you to making it larger or smaller, but 16 pixels is a great place to begin. As for word spacing, most browsers do a decent job of setting this for you, but if you are having trouble getting an appropriate measure, cheating this attribute slightly either way can be handy.
On our page, let’s add a 16-pixel font size, and cheat the word
spacing in just a tiny bit to achieve a proper measure
(word-spacing is supported in all major
browsers). You might instead want to use ems or rems
here so that the layout remains flexible whatever the font size set
by the user as their default.
Until we set a new line height, our page will look like a jumbled mess, so let’s just look at the code at this point:
article {
background: #fff;
border: 1px solid #eee;
font-family: "Myriad Pro", Arial, Helvetica, sans-serif;
font-size: 16px;
padding: 2em 3em 4em;
word-spacing: -0.05em;
}
Once the font size is set, you can determine the appropriate line height. On the Web, we work in terms of line height, which by default is an equal amount of space above and below text on a line. Not to be confused with leading in print design, which generally refers to the amount of space below a line of text. The governing rule for line height (and leading) is, the longer the line length, the taller the line height should be. And vice versa: the shorter the line length, the shorter the line height.
Find an appropriate line height by first determining the point
at which the ascenders and descenders of the lines of text do not
touch, yet the lines are close enough that the reader requires no
effort to find the next line. Then adjust until the height feels
balanced with the line length. Some may leave the
line-height attribute to the browser’s default, while
some may set a global line-height on the
body element. Both approaches make sense because the
line height would then stay proportional to the element’s font
size; but both also assume that the line width of the content will
stay consistent, which could lead to situations that violate our
governing rule.
Let’s add a line height of 1.3 ems to our example, using ems so that our line height stays proportional to the font size, and see how the font size and line height work together:
article {
background: #fff;
border: 1px solid #eee;
font-family: "Myriad Pro", Arial, Helvetica, sans-serif;
font-size: 16px;
line-height: 1.3em;
padding: 2em 3em 4em;
word-spacing: -0.05em;
}
It is important to note that readable line heights can be
especially tricky to keep consistent in responsive layouts, as line
lengths will vary based on device widths. To solve this issue, Tim
Brown has proposed an idea he calls “Molten
Leading,” which would allow line heights to increase
proportionally based on the screen width. His post links through to
a couple of Javascript implementations of this idea. In lieu of
Javascript intervention, you can also manually find the screen
widths at which the line heights become uncomfortable, use a media
query to target that width, and set a more readable
line-height in the CSS.
We need to figure out which paragraph style best fits the content. Jon Tan has done a fantastic job of outlining various styles and how to craft them with CSS. The appropriate style for a piece of content varies based on the flavor of the content and the rhythm of the paragraphs. I have written about my preference for using indents, rather than line breaks, when setting long-form text. This helps to keep the flow between ideas, but it can be distracting when the paragraphs are short or the line length is long. Deciding what constitutes the perfect paragraph for your content is up to you.
Our page is a news article, where the flow between paragraphs is dictated more by chronology than by ideas, so line breaks are still appropriate. We could easily apply indents, if appropriate, to the paragraphs with one simple CSS rule:
article p + p {
text-indent: 2em;
}
We specify p + p rather than just applying the rule
to all p tags because we want to indent only those
paragraphs that follow other paragraphs. Ones that follow headings,
images and so on should not be indented.
Instead of indenting, though, we just want to shrink the line breaks a bit so that each paragraph is not so disconnected from the last. For our page, let’s use half of the line height:
article p {
margin-bottom: 0.5em;
}
One final consideration for content is text color. Contrast is a
major contributing factor in eye strain and
so greatly impacts readability. Low contrast between text and
background causes more squinting
and blinking among readers, a sure sign of strain. Black on
yellow has the highest contrast, but we have been conditioned to
view this as a sign of warning or alarm, thus increasing anxiety
among readers. Black on white is high in contrast, too, but too
harsh for extended reading on back-lit screens. For long-form text,
I have found dark-gray text (around #333) on a white
or light-gray background (no darker than #EEE) to be
optimal. This is a gross simplification of color theory to suit the
purposes of this article. To learn more about color, Mark Boulton
has written a great primer on color
theory for the Web; you can also find many great examples in
Smashing Magazine’s
series on color.
Our article already has a white background (serving as a
boundary for the margins), set against a wider light-gray
background. We should probably keep the white, and lessen the
darkness of the text to #444. We can then use
#000 on the headings to give them slightly more
emphasis:
article p {
margin-bottom: 0.5em;
color: #444;
}
article h1 {
color: #000;
}
We now have a much more readable page that invites users into the content. We could employ many more techniques across the entire website, but we have focused here on the main content block. Harry Roberts has written a great overview of these techniques and more for Smashing Magazine, which will give you a deeper understanding of everything covered here.
With a clean reading experience, people will better absorb the ideas being presented and will undoubtedly come back for more—that is, if your content is worth reading… but I can’t help you there.
Readability is not a new concept, of course. If you are just discovering what makes for a good reading experience, then congratulations, and welcome to all the discomforts of recognizing cramped and neglected type on the Web. It’s not all pain, though. Plenty of well-considered blocks of content are to be found. Let’s look at a few great ones and a couple that could be great with slight tweaks.
Please note: In the interest of showcasing only the reading experience, we have cropped each page to a scrolled view of the main content.
24 Ways The reading experience on 24 Ways is quite nice. The text contrast is well balanced, the measure is not too long, and the font size is generous. At all responsive breakpoints, the design is a perfect example of a page with sufficient and balanced margins around the main reading area.
Desktop view
CNN Long-form articles on CNN are good examples of how readability can work well on news websites. The layout does not show a visible container for the article—which in this case might have been distracting on a page already laden with so much content—but the margins are generous. Also, the line breaks for the paragraph styles are completely appropriate, because most online news stories are collated and updated from many sources and are not linear ideas. The font size (currently 14 pixels for the body copy) could stand to be a bit bigger, though.
Contents The tablet view of Contents magazine is a wonderful experience all around. The measure is perfect, the line height and font size play together nicely, and the paragraph styles are perfectly suited to the content. The measure does get too long at desktop sizes, but with all of the other factors working so well, the effect on overall readability is negligible.
Tablet view
Desktop view
Elliot Jay Stocks Elliot does quite a few things well on his website. The measure is right, the font (Skolar) is very readable and set at a comfortable size (16 pixels), and the line height is just tall enough to accommodate the link style. Generous margins create harmony between the main content and its container, while the side margins are uneven, making the page look like the recto of a book and giving the layout a unique character.
Esquire Most articles on Esquire are great, but the reading experience is merely good. The margins are ample, the font is readable, and the contrast is high. All of these go a long way towards establishing good readability, but a few simple tweaks would make it great. Increasing the right padding would shorten the measure, which is a bit too long as it is. The font size could also be increased by a couple of pixels. And given that most Esquire articles are a linear progression of ideas, I would suggest paragraph indents rather than line breaks.
The Guardian The design team over at The Guardian pays attention to crafting great all-around experiences. Readability is no exception. Measure, contrast and paragraph styles all work together to create a focused and comfortable reading experience in the midst of what could be an overwhelming amount of content.
A Working Library A Working Library is one of the best reading experiences on the Web. Every aspect of readability discussed in this article has been well considered and executed. The harmony between text and its container is pitch perfect.
With the examples above, we have tried to show how readability can excel in a few different digital environments: blogs, news websites and online magazines. Some of these website do not have many of the constraints (such as ads and related content) of more commercial websites, so it could be argued that these designs exist in a vacuum, without pragmatic application or real-world pressures. We need these shining examples, though, to help us find the ideal reading experience for each project; and once we know that ideal, we should do our best to reach it.
In a recent talk on “What Is Reading For?” the famous typographer and poet Robert Bringhurst stated, “Books are and have to be utilitarian objects. They have to be used.” The same could be said of Web pages. Ideal reading experiences create better user experiences. Our job as designers is to refine the aesthetic qualities of the Web’s content in order to speed the process of consumption, thereby facilitating deeper understanding. Tired eyes all over the Web are counting on us.
(al)
© Nathan Ford for Smashing Magazine, 2012.
Ready for a revelation? A concept that you’ve never considered before? Well here it is: never ever, ever pour a glass of wine into your Macbook keyboard. Or, more practically put, be extremely careful when there’s a drink of any kind near your laptop. If a spill occurs, and you don’t act quickly enough, you’ll find yourself staring at a massive bill for a new logic board, hard-drive, battery, and anything in between.
Accidents do happen — so plan on it. What’s more important is that you learn exactly what to do when these spills inevitably occur.
July, 2010
Ahhhh! The wife (meaning, you) accidentally spilled wine all over your keyboard. From personal experience, I can assure you that, for some odd reason, your first instinct with a massive computer spill is to freeze for five seconds or so, in shock. Don’t do this! Luckily Apple laptops are pretty helpful about automatically shutting down to prevent as many issues as possible before they happen. The more recent laptops even have liquid detection…though I’m certain that Apple is more interested in voiding your warranty than protecting you. For those uninformed, most laptop warranties do not cover spills.
Nonetheless, don’t waste a single second. Quickly unplug the computer, and shut it down.
The walls and carpet may have liquid on them as well, but ignore that. The computer is far more important right now.

The next step, which should occur within seconds of beginning Step 1, is to flip the laptop upside down, into an L-shape. Gravity will then force as much liquid to drain out of the keyboard as possible. Make sure that you lay it on a towel so that it can soak up the liquid.
Let gravity do its job. Immediately flip the laptop into an L-shape.

Using a tiny screw driver, unscrew the back-side of your laptop. This will, of course, vary, depending upon which model you’re using. I’m sure you can figure it out.
Particularly on Macs, not all of the screws are the same size. Make a note of which screw goes where.

Before progressing, ensure your livelihood and touch some metal objects nearby to remove any potential static electricity from your body.
Needless to say, batteries and liquids — especially sugary, acidic liquids — don’t play nice together. Wherever yours is located on your laptop, remove it as quickly as possible. Next, get the hard drive out as well. We don’t want to risk any liquid seeping in, and corrupting your file system!
And now that you know how easy it is to remove a hard drive, don’t ever again pay a person to upgrade your hard drive. It only takes a moment to do yourself. ;)

With a paper towel of some sort, begin cleaning the insides of your computer. Depending upon how much liquid was spilled, this may either be a quick or lengthy process. For yours truly, it took around ten minutes to clean everything.
Some people prefer to use a hair dryer to clean the insides. This one is up to you; however, I’d encourage you to not do so. Play it safe and use a towel. We don’t want to risk frying the insides.

Next, we need to continue removing as much sugar and acid as possible from the logic board. Otherwise, over time, it can begin to corrode the wiring. Yeah, this isn’t good!
Using rubbing alcohol and a cotton swab, begin dabbing any stained areas — but be gentle. If you have access to the backside of your keyboard, clean that area as well. Unfortunately, on the newer Macbook Pro models, it’s extremely difficult to access this section. With past models, it was quite easy to remove the keyboard entirely, for cleaning purposes. Unfortunately, that’s no longer the case.
Rubbing alcohol will help dissolve any remaining acid or sugar on the logic board.

Anxiety is a dangerous thing. Resist the urge to determine whether or not you’ve destroyed your laptop, and keep it off for a minimum of 72-120 hours (3-5 days). This will allow any remaining liquid to dry/evaporate first. Make sure that, while its drying, you keep the battery outside of the computer. This is mostly a precaution.
Keep the computer off for 3-5 days — no questions asked. Do not turn it on during this window.

After 72-120 hours, reconnect the battery, screw everything back in, cross your fingers, say a prayer, and turn on the computer. Particularly if you’re using a newer Macbook Pro (2010+ models), you’ve done everything you can do. With hope, and more often than not, it’ll chime, and start-up like a charm. However, if the battery is dead, or the hard drive is corrupted, you’re next best option is to take it in for official repair. Of course, this will somewhat depend upon how skilled you are, when working under the hood.
Jeffrey Way — me…yes, I’m speaking in third person — once committed a Cardinal Sin, and caused a massive wine spill into his Macbook Pro. Had he not followed these exact steps, he’d be forking over another life savings for a new Mac. Luckily, that was not the case.
Thanks for reading. Should the same ever happen to you, I hope this guide will help a bit!
Web development is an industry that’s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.
In this series, published monthly, we’ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump!
All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.

Ahh, JavaScript. I think it has caused more conflict than thatHelen. This time around there’s been a flurry of activity around a single, missing comma. I don’t want to take you away from the drama so check out the Github discussion below, after grabbing some popcorn.
Personally, if you’re not CoffeeScript-ing, just add that darn semi-colon and call it a day.

Most Pythonistas know Django. For those of you who don’t, Django is a high level Python framework that helps you out with web development. While Django has had a repo on Github for a long time now, it was in a state of desolation. You’d often see that the repo only held versions that were a lot behind the curve.
Well, no more of that. Django has finally moved to Github and the repo seems to be active. If you’re interested, Subversion was what was used to manage Django earlier, since 2005.

Tired of the current frameworks and technologies, a group of devs has created a full stack, JavaScript only framework.
Meteor is a set of new technologies for building top-quality web apps in a fraction of the time, whether you’re an expert developer or just getting started. I’m sure people are already tired of reading about JavaScript and the sheer number of frameworks sprouting out each day but this is really worth a look.

SPDY, developed by Google, is a networking protocol aimed at improving web page load times as well as web security.
As with anything web related, it takes eons to get anything standardized and browsers have already started implementing experimental versions of the technology. The latest Firefox beta adds support for the protocol, switching it on by default. It’s not the only browser to do — Chrome already includes support for SPDY while Opera does the same with its preview of version 12.

Microsoft, in order to increase awareness of its spectacularly clean Metro interface, has open sourced a Metro themed design for jQuery mobile. The theme includes a large number of Metro themed widgets and interactions and seems to work really well.

Another month, another Firefox update. To be fair, the updates are now rather substantial this time around though.
This version introduces a ton of developer tools and improvements along with a far more streamlined update process. The list of developer related updates, the ones we really care about, makes for a rather interesting read so make sure to hit the link below.

Developers either love or hate CoffeeScript. I personally love it which is why you’re seeing this here. The latest version enforces the strict more at compile time helping you weed out those annoying, niggling issues.
Version 1.3 also brings you improvements to the REPL as well as a bunch of tweaks and improvements.

With the havoc caused by the mass assignment issue last month,
the Rails team has reconsidered their stance on this issue and has
pushed out version 3.2.3 which changes the value of
config.active_record.whitelist_attributes . There are
also various, assorted fixes and improvements bundled into this
version.
As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention — everything from new books to scripts and frameworks.
Smooth.js takes an array of numbers or vectors and returns a parametric function that continuously interpolates that array. Smooth.js supports several interpolation methods, and flexible options for boundary behavior.
jQuery Scroll Path is a plugin that lets you define your own custom scroll path. What this means exactly is best understood by checking out the demo. The plugin uses canvas flavored syntax for drawing paths, using the methods moveTo, lineTo and arc. To help with getting the path right, a canvas overlay with the path can be enabled when initializing the plugin.
Keymaster is a simple (100 LoC or so) micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.
PHP Microframework for use with whatever you like. Basically just a fast router with nice syntax, and a cache singleton. Will add more things as I go, like perhaps an extension system, autoloader and some other stuff to make developing in PHP less irritating than it currently is.
The jQuery plugin that suggests a right domain when your users misspell it in an email address.
Hammer.js is a javascript library that can be used to control gestures on touch devices.
Monorail.js will never force you, and uses only what you need. Monorail.js will never force you to install anything not needed for your project. The goal is to use what you need. Anything other than creating a project will always be optional.
Rainbow is a code syntax highlighting library written in Javascript. It was designed to be lightweight (1.4kb), easy to use, and extendable.
There are lots of timeline tools on the web but they are almost all either hard on the eyes or hard to use. Create timelines that are at the same time beautiful and intuitive for users. Timeline is great for pulling in media from different sources. Just throw in a link from Twitter, YouTube, Flickr, Vimeo, Google Maps or SoundCloud and Timeline will format it to fit perfectly. More media types will be supported in the future.
FakeS3 is a lightweight server that responds to the same calls Amazon S3 responds to. It is extremely useful for testing of S3 in a sandbox environment without actually making calls to Amazon, which not only require network, but also cost you precious dollars.
retina.js makes it easy to serve high-resolution images to devices with retina displays. When your users load a page, retina.js checks each image on the page to see if there is a high-resolution version of that image on your server. If a high-resolution variant exists, the script will swap in that image in-place.
Rucksack is a jquery plugin to arrange elements that can fit in the given width. It relies on the knapsack algorithm.
jQuery PopBox is a simple balloon UI element inspired by 37Signals Highrise CRM.
This script allows you to take “screenshots” of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
Often, you’re not really looking for a tutorial as much as you’re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those — interesting and cool stuff from the developer community.

A detailed look at why most people, when given a gun with two bullets and asked to shoot Hitler or PHP, want to shoot PHP twice. As much of a PHP lover I am, I can’t help but agree with a lot of this article.

A really well written counter point to the earlier article, backed by a lot of reasoned thinking.

Brendan Eich chimes in with his stance on the entire JavaScript semi-colon issue.

A wonderfully detailed answer on StackOverflow that outlines how to be a kickass programmer without an expensive CS degree.

A very informative presentation that outlines how you should go on about running and upgrading your Rails apps.

A nice little read about the software industry and the rat race around titles.
Well, that’s about all the major changes that happened in our industry lately.
Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading!
We always try our best to challenge your artistic abilities and produce some interesting, beautiful and creative artwork. And as designers we usually turn to different sources of inspiration. As a matter of fact, we’ve discovered the best one—desktop wallpapers that are a little more distinctive than the usual crowd. This creativity mission has been going on for over four years now, and we are very thankful to all designers who have contributed and are still diligently contributing each month.
We continue to nourish you with a monthly spoon of inspiration. This post features free desktop wallpapers created by artists across the globe for May 2012. Both versions with a calendar and without a calendar can be downloaded for free. It’s time to freshen up your wallpaper!
Please note that:
Designed by Ioana Bitin (aka Yoot) from Romania.
Designed by Katerina Bobkova from Ukraine.
Designed by Lotum from Germany.
"Charts of May weeks. Designed for working environment that helps classify desktop files into categories." Designed by Sherif Saleh from France.
Designed by Alex Dovksha from Belarus.
"Love needs food too! And what can be better than music! The two most prescious gifts of life, love and music is expressed beautifullyin this quote by William Shakespeare." Designed by Adrija Mukhopadhyay from India.
Designed by Christine Bradway from USA.
"Japan is the land of the rising sun." Designed by Cheloveche.ru from Russia.
"Negative space lizard on a bed of doodles." Designed by James N Osborne from United Kingdom.
Designed by Pietje Precies from the Netherlands.
"Limundograd (Limundocity) is an illustration for an e-commerce auction site called limundo.com, designed to show users what the site consists of, and much more!" Designed by Mrki from Serbia.
"Keep an eye out for those shooting stars during the clear summer nights. If you see one, make a wish and maybe it’ll come true…" Designed by Eddie Wong from Ireland.
"Inspired by a verse in the Bible." Designed by Lex Valishvili from Russia/USA.
"The photo was taken at Thingvellir national park, Iceland." Designed by Naioo from Germany.
"It’s spring time, and we at JustLanded.com are celebrating with a BBQ!" Designed by Adelacreative from UK.
Designed by Ingrid Cruz from USA.
"In India, May is mostly known for summer holidays and the season of Mango- the best amongst all the fruits. Its the best in terms of flavour, richness and sweetness.As the scorching heat increases in this month, its the delicious mango which keeps us going and makes us look forward to summers. This wallpaper is dedicated to the King of Fruits-Mango." Designed by Charuta Puranik from India.
"May’s fairy is grungy and dark." Designed by Bobbie Killip from UK.
"Wonderful Island is the annual meeting point for a unique community of various fairy creatures from different parts of the world. They come here every single year on the exact same day – May, 1 to talk with the old friends and have fun. The merriest guys are, certainly, Furst, the middle-aged Yeti from the North of Iceland and his best friend Charles Dooon, aka DJ Chuck-Chuck, who can’t imagine their lives without music." Designed by Maria S. from USA.
Designed by Mohammed Aaqib Ansari from India.
Designed by Julie Lapointe from Canada.
Designed by Melissa Infantino from USA.
Please note that we respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us, but rather designed from scratch by the artists themselves.
A big thank you to all designers for their participation. Join in next month!
What’s your favorite theme or wallpaper for this month? Please let us know in the comment section below.
Stay creative and keep on smashing!
(il) (vf)
© Smashing Editorial for Smashing Magazine, 2012.
Link
Scroll down for today's pictures & links.
Epic Launch Video
Feel the raw power of "riding a controlled explosion into space" -
watch this Space Shuttle Discovery launch in high-res and with loud
audio. And if you want more, then watch this too.
Link
Now for those who want to savor all the details of launch from all
possible camera angles, this long video is the ultimate treat.
Today's pictures & links:
Another Kind of Launch
(image credit: Expositions)
Multitude of balloons grace the sky above the Fifth Paris
International Exposition of 1900... Here is the main entry
"Monument Gate" from the same Exposition, designed in the great
Victorian style - click here for large version:
(image via)
------------
The Fibonacci Sequence and the "Golden Ratio"
This perfectly-proportioned spiral was spotted in Kewgardens in
London:
(image credit: James
Newbery)
------------
The road is narrow
(we'd like more information about this road):
(original unknown)
------------
Mixed fresh links for today:
Maybe Black Holes Don't Really Exist - [what?!]
Extreme Graphic Design Plagiarism - [gallery]
Hydrophobic, Nano-textured Glass - [wow
science]
Soviets Built a
Laser Tank!, pics - [why I'm not
surprised]
Literary
Inquisition Facts - [thought-provoking]
Another incredible way to fly - [wow
tech]
Eye-Opening
Info about Texas Drought - [infographic]
Surreal Art by Travis
Louie - [scroll down, art]
Great Counterattack from Goalkeeper - [fun video]
Interesting
Portable Track System - [wow
video]
Riding the Abandoned Road in Japan - [cool video]
Dramatic
Rescue Gone Wrong - [fun
video]
Another Hilarious Roundup of Photoshop
Disasters - [pics]
Bats, Bats, Bats! - [Neatoshop
product]
------------
Is this the Tower of Babel? Hardly. But still a very tall
ancient mosque.
This impressive spiral minaret of the Great Mosque of Samarra was built in 848 A.D. and for
a long time been a highest mosque structure in the world:
(images credit: Reuters,
via)
See another incredible tower in Afghanistan - The Mysterious Minaret of Jam.
------------
This Poor Little Cat Loves You
The apopheosis of cute.
------------
The Kitchenware Sellers
Seen in Naples in 1903 (Vintage photographic postcard, published by
A. de Simone, Naples, Italy):
(image credit: Casas-Rodríguez
Collection)
------------
The following is a short round-up of the best from our Facebook
stream (which we update every day with unique material, not
available on DRB otherwise):
This makes me dizzy... The Library, D’Espresso’s Coffee Bar in New
York:
The REAL movie monsters! "Weird Tales of the Future" cover
art, 1952 -
Spilling grass and water:
Taming a wild truck in Pakistan:
(image credit: "Kashmir Motor News" via)
Great fresh idea for a shower! - the AMETIS collection from
Graff Faucets:
(image via)
------------
Nature Wins. Always.
The most amazing (and tenacious) tree grows in the "urban jungle"
of Hong Kong:
(image credit: Kahscho)
------------
Medieval Reading Gadget: their version of a browser, tabs and
bookmarks
(image
via the Smithsonian Institution Libraries & the Washington
Project for the Arts, click to enlarge)
This is an illustration from the book "Le diverse et artificiose
machine" by Agostino Ramelli (1588). "Back in the 16th century,
books were big and heavy, and therefore some people devised new
technologies for making the reading experience more enjoyable" -
more info:
Zoom... Enhance! -
(image via)
Another book-reading device from 1935:
And a modern version:
------------
Your personal pet wizard
(image via)
"Go on... make a wish!"
------------
Intentional (and unintentional) word play
(images via)
I think the creators of this WW2 Victory Day poster in Russia got a
little confused:
------------
Cake Art. Be Afraid.
(original unknown)
------------
Don't come close to this monster:
(a pug upside down, (image credit:
Nancy
Walsh))
READ
THE PREVIOUS ISSUE ->
READ ALL BISCOTTI ISSUES HERE ->
Make
sure to check our daily updates on Facebook!
|
Modern JavaScript libraries are quite the behemoths — just take a look at jQuery. When you’re creating a mobile app, or even just targeting modern browsers, a library that’s much more svelte and nimble becomes a tastier proposition.
Today, we’re going to look at one such library, named Zepto.
One thing that has snuck past most radars has been the rise of mobile devices.
See, the internet, and the technology that powers it, has grown in leaps and bounds over the past years. We moved from static sites to web applications to dynamic web applications and then to real time, hyper responsive, thingamabob apps of today. One thing that has snuck past most radars has been the rise of mobile devices.
Think about it: a lot of us use smart phones and use it for browsing on a constant basis. Even at home, a non-trivial portion of my circle has adopted a tablet device for casual surfing and email. While this influx of devices is good from an exposure point of view, it isn’t without its caveats.
Instead of thinking of these devices as display constrained like consumers do, we, as developers, need to think of them in terms of resources and bandwidth. Not all them sport a hyper quad gajillion Ghz CPU or come with oodles of memory. And let’s not even get started with the bandwidth. A big portion of the browsing population is still stuck on these infernal excuses for a mobile internet connection.
I think you see where I’m going with this. Big, monolithic libraries like jQuery or Prototype definitely have their place but for this mobile era, I think there’s a place for something that’s a lot more nimble. And a lot of developers seem to agree with me.
Another big issue that I failed to mention is that contemporary libraries do a lot of cross browser stuff. In fact, a big draw of jQuery, initially, was how it abstracted away a lot of the cross browser quirkiness that front end developers had to work around. Even now, jQuery does a lot of heavy lifting under the hood to make sure nothing breaks in different browsers.
But if you’re a developer looking to cater to only contemporary devices, do you really need all this, dare I say, cruft? The short answer is no. By cutting out unnecessary code, you both:
Think that this issue is overblown? Here’s a random blob of code from jQuery’s source:
isPlainObject: function( obj ) {
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
....
Or something a little more esoteric:
// Perform a simple check to determine if the browser is capable of
// converting a NodeList to an array using builtin methods.
// Also verifies that the returned array holds DOM nodes
// (which is not the case in the Blackberry browser)
try {
Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
// Provide a fallback method if it does not work
} catch( e ) {
// The intended fallback
}
....
This may look fairly trivial but keep in mind this tends to adds up. If you’re only going to target modern browsers, either on desktops or mobiles, then there is no real need for all these additional checks and hacks. By cutting down your intended browsers, you win on both bandwidth and performance!
I hear you guys saying “Enough buildup! Tell us about the darn library already!”. So let’s get to it.
Zepto, as the title spoiled it for you, is a mobile
JavaScript framework that rectifies both of the issues mentioned
above. It has a very small code base and is feather weight at
around 8kb.
It manages to be so svelte by mostly cutting out the cross browser stuff. When it was created, the main focus was to support Webkit only. The mobile version of Webkit to be exact. Now, it’s been expanded to work with desktop browsers too — but only modern ones. No more klutzing around to make things work this IE6!
Zepto’s API is jQuery compatible. If you use jQuery, you already know how to use Zepto.
Another area where Zepto manages to be small is how it manages to avoid feature bloat. The core library doesn’t seem to include any extraneous functionality. Even the AJAX and animation functionality are available as separate modules, should the need arise. For users that primarily use libraries for DOM traversal and manipulation, this is an utter god send.
And, oh, did I mention Zepto’s main party piece? Zepto’s API is jQuery compatible. If you use jQuery, you already know how to use Zepto.
Yes and no. Depends is a more apt answer.
Yes because Zepto’s core API mimics jQuery to a large extent. In order to make it easy to use and dramatically reduce the learning curve, Zepto emulates jQuery’s API. Most of the oft used methods, like DOM manipulation, are named pretty much the same and have the same parameters in the same order. The method signatures are the same, for the engineers out there.
Let’s look at a small example:
$('#element').html("Hey! Are you on the GW2 beta?");
Looks familiar? It should. This is the exact same code you’d use with jQuery to change the HTML of an element. As I mentioned, this isn’t limited to just this method. Most DOM operations are built the same way along with your utilities, like AJAX.
On the flip side, the API isn’t a 100% match. Zepto forgoes some
methods present in jQuery that’s liable to break your code. And
just as importantly, since Zepto is a subset of jQuery, you’ll
probably miss out on specific functionalities that are built in —
Deferred is a fine example. You simply can’t swap out
jQuery with Zepto and expect everything to work.
And for me, the biggest hurdle are the methods that have been copied from jQuery but have a different signature and feature set. It becomes a little frustrating when you think you’re using a method right but you aren’t. The clone method’s ability to copy event handlers is a good example. Without looking at the source, I really wouldn’t have found this out.
If you’ve worked with jQuery before, everything below should be a snooze fest.
Enough chit chat, let’s dive into some code now. As with a lot of modern libraries, DOM traversal and manipulation is a core feature that everyone wants to perfect. Since the API and overall functionality is very similar to jQuery, I think you can safely assume everything is top notch.
Let’s take a look at some common DOM related functionality.
This is the bread and butter of DOM operations: reading or
changing the HTML contents of an element. With Zepto, it’s as
simple as calling the html method on the container,
and passing in the new HTML, if needed.
For example, this obtains the HTML of an element and stores it in a variable.
var containerText = $('#element').html();
Or if you want to change it to something else:
$('#element').html("Hola there!");
Pretty simple, right?
As with jQuery, Zepto makes use of the append and
prepend methods. And the invokation remains the same
as well.
$('#element').append("<p>This is the appended element.</p>");
// or
$('#element').prepend("<p>This is the appended element.</p>");
Events are the backbone of any modern application and Zepto
provides you with a bunch of easy to use methods to get your job
done. The bulk of the work is done through the on
method.
$('#element').on('click', function(e){
// Your code here
});
Easy to read and easy to parse. If you’re feeling old school and
feel like using bind, delegate or live
methods, don’t. Just like with jQuery, they’re deprecated
here.
Any modern low level library needs to provide an easy to use wrapper around AJAX and Zepto doesn’t let you down here. Here is an example of a super simple AJAX request.
$.ajax({
type: 'POST',
url: '/project',
data: { name: 'Super Volcano Lair' },
dataType: 'json',
success: function(data){
// Do some nice stuff here
},
error: function(xhr, type){
alert('Y U NO WORK?')
}
});
Things might look a little complicated but what we’re doing can be boiled down to:
As with jQuery, there are separate method for a GET or POST request or ones to merely load up some web content.
What will the world come to without a few animations? Zepto
exposes the almighty animate method that should handle
most of your animating needs.
$('#element').animate({
opacity: 0.50, top: '30px', color: '#656565'
}, 0.5)
We’re basically selecting the element to be animated, invoking
the animate method and specify the properties to be
animated as well as the time it should take to finish animating.
Zepto does the rest.
Or if you just need to show and hide an element, the toggle should work just fine.
I think you get the point here — Zepto’s DOM, animation and events API emulates that of jQuery to a large extent. And as we all know, jQuery is darn good with those things. If you’ve worked with jQuery before, you shouldn’t face too much trouble here.
Zepto does provide you with a few touch specific events that you can leverage in your apps. These include:
Here’s a quick example, delightfully swiped from Zepto’s documentation.
<ul id=items>
<li>List item 1 <span class=delete>DELETE</span></li>
<li>List item 2 <span class=delete>DELETE</span></li>
</ul>
<script>
// show delete buttons on swipe
$('#items li').swipe(function(){
$('.delete').hide()
$('.delete', this).show()
})
// delete row on tapping delete button
$('.delete').tap(function(){
$(this).parent('li').remove()
})
</script>
When a list item is swept, every other list element’s delete button is hidden and only the current’s is displayed. Tapping a delete button removes that button’s parent li item to be removed from the DOM.
This should be fairly similar to how you generally handle events, except you’ve binding your handlers to different events, that’s all.
Considering what and whom I develop for, this is perfect for me; but as it always is, your mileage may vary.
Well, that’s about almost all there is to Zepto. At it’s core, it was meant to be a lean, cruft free version of jQuery that could be used on mobile devices. Over time, it has morphed into a lean library that does away with supporting archaic browsers.
Considering what and whom I develop for, this is perfect for me; but as it always is, your mileage may vary. You may be locked into using jQuery plugins that require non-trivial modifications to make it work under Zepto or just have more faith in jQuery.
Either way, you really need to give Zepto a try to see how it fits in with your workflow before writing it off. I did and I love it!
Well, that’s all from me today. Let me know what you think in the comments below and thank you so much for reading!
Welcome to the first in a new series of interviews called “How I Work”. These interviews revolve around how thinkers and creators in the Web world design, code, and create. The goal is not to get into the specific nuances of their craft (as that information already exists online), but rather step back and learn a bit about their habits, philosophies, and workflow for producing great work.
First up is Douglas Crockford who believes JavaScript might just be the most elegant language ever. Learn why he thinks you should study the history of computer science, the value of reading your code in front of other people, and that jQuery really is a good thing.
Douglas Crockford is known as The JavaScript Guy. He’s famous not only for his O’Reilly book JavaScript: The Good Parts but even more so as the visionary behind the JSON data format as well as the JSLint tool. He was featured in the book Coders at Work for his contributions and philosophies on what JavaScript got right, and what it didn’t.
As a native of Southern California, Doug has the build of a surfer; lean and tall with white hair and a beard. A veteran of Silicon Valley, he’s worked at Atari Labs, founded and worked at numerous software start-ups, was head of technology at Lucas Films and now has the enviable job of being a JavaScript evangelist at Yahoo!.
Image credits go to Eric
Miraglia.
Self-taught (as many of the greats are), he says his goal is simply to get more people coding in JavaScript, or any language for that matter. While his day job may be as a JavaScript evangelist, speaking with Doug you get the sense he really is an evangelist for programming in general.
Below is a conversation that took place in Bozeman, Montana prior to a talk at Montana State University. Doug freely shared his thoughts on great programmers, user empathy, and how JSON restored his faith in humanity.
Well, first semester of physics is a history class. You study Galileo and Newton and all their contributions to the field and that gives us the overall view of physics. It’s a really nice place to start.
I wish CS would do that. It doesn’t seem to have enough value in its history and it’s a really amazing history that’s completely neglected. It’s rarely that the best idea won. So, we’ve taken different paths over the years and maybe haven’t realized why.
Ironically, despite the rate of change in technology, we see in the story of software that it takes a generation to retire or die off before we have a critical mass of bright young minds to embrace new ideas.
I think if people were more aware of their history, they could see these patterns more easily.
That’s an easy one—lack of curiosity. They were so satisfied with the work that they were doing was good enough (without an understanding of what ‘good’ was) that they didn’t push themselves.
I’m much more impressed with people that are always learning. The brilliant programmers I’ve been around are always learning.
You see so many people get into one language and spend their entire career in that language, and as a result aren’t that great as programmers.
My advice to programmers to avoid this trap is to learn lots of different languages. We’re in sort of a language renaissance right now and there are a ton of brilliant languages to learn from.
To learn new languages takes nights and weekends outside of work, and that’s a commitment. The great programmers are the people that are constantly picking a project and diving into it, learning a language that way.
Well, over the years I noticed that there are some terrific programmers out there that are completely content to sit in their cave all day long writing brilliant code. But they don’t interact much with their team, which means it’s a lost opportunity for mentoring other members.
As you know, a lot of coders aren’t the most socially adept animals either.
So, my idea with code reading sessions is to provide a forum where people can come together and read for each other to get them out of their caves. The masters read for the beginners, and vice versa, as a team-building exercise.
The trick for success is to set up rules ahead of time so that nobody is going to get spanked and everyone is respectful in their feedback. It has to be a good learning experience for everyone. You have to be careful with a dysfunctional team, because it can quickly tear apart the group. But I always call the game before it gets that far.
The rules are that it’s about improving the quality of the code that we’re all responsible for, improving the quality of our team, and improving our individual capabilities.
Some people see this as a terrible time sink. Yet, I’ve found by doing this exercise, bugs are caught way ahead of time and you can prevent a team member from going off the tracks. But again, that’s not the goal, it’s about team building.
Over time the masters help pull up the beginners and the overall output from the team gets better.
The best experience I had with empathy was working in marketing support. There were times I would go out into the field and hold hands with the customers and see the consequences firsthand of some of the crap we were delivering to them.
I was shocked when I moved into systems programming and how the programmers actually held the customer in contempt.
I think every programmer should work in customer support for the product they’re delivering.
It’s another case of over-specialization. “I just write the code,” is the response you get and the programmers don’t see it as a chance to improve peoples’ lives.
Virtually every programming language is too big. Language standards have difficulty removing unnecessary features but as users we can choose not to use it.
I would say you can do 100% with knowing 50% of the language.
The language that taught me that lesson the most was JavaScript, because it has more bad parts than good parts. It gave me a very strong motivation for figuring out what are the good parts and what are the bad parts, and what the criteria is for deciding what’s in or out.
And the good parts are just so good. Be sure to watch Doug’s Google Tech talk titled “JavaScript: The Good Parts.”
When I was a journeyman, I was a maximilist. I tried to use the whole language. While I don’t know if I would call myself a master now, I’m certainly a minimalist. I’ve tried to get good at using as little of the language as possible.
I place a lot of value in simplicity and minimalism.
There is some really clever stuff in jQuery and I think John Resig did some very good work there.
I do have a problem with anybody doing anything without understanding what they’re doing. I’m not going to fault jQuery for attracting those sorts of people.
But I do think there are some other AJAX libraries that maybe doing a better job that aren’t quite as accessible. However, I think there is a place for all of these things.
My design criteria were three things: minimal, contextual, and a subset of JavaScript.
The last constraint was to keep us from going off the rails and inventing new stuff. We had to only use stuff that was in JavaScript, which meant that our unicode handling wasn’t quite right because JS isn’t quite right, which was disappointing. We don’t have proper support for dates because JS didn’t have it. But we can work around both of these.
But it also meant that when somebody proposed, “Hey we should do this crazy thing” we could be like “Nope”. So, we had a really easy criteria for stopping extra features from being added.
One interesting story about leaving things out: as we got closer to releasing JSON I decided to take out the ability to do comments. When translating JSON into other languages, often times the commenting piece was the most complicated part. By taking the commenting out we reduced the complexity of the parsers by half—everything else was just too simple.
One of the best features of JSON is that it’s stable. If your program works now, it will work forever, and that is an attractive thing.
I still get notes from people saying they’ve got great ideas for the next version. But there isn’t going to be a next version. I always say you’re free to invent a new standard and promote it as much as you like.
You know, the adoption of JSON sort of restored my faith in humanity because it was a good idea that won out, only because it was a good idea.
It was a case where there were no slick marketing campaigns. In 2001, I started working on it as a way to tie the browsers to the server. At the time, everyone thought XML had to be used or they’d say “that’s a great idea but JSON isn’t a standard”. So, I bought json.org, made a logo, threw up a Web page and it sat out on the Web for three years.
In the meantime, AJAX happened and when it became the way for writing applications JSON was there. There was counter promotion from the XML community, of course.
But when I arrived at Yahoo! some kids at the company started thinking it was okay to start shipping JSON API’s through Web services. And developers found the apps got faster and were easier to write.
It sort of took off from there—no slick campaigns. So a good idea based on simplicity won out for once.
In this presentation from Google Tech Talks, Doug goes over the ideas behind his landmark book, JavaScript: The Good Parts, and dives into the areas of what JavaScript got right and what it didn’t. Learn about the history and common roadblocks programmers run into when developing with this language.
In this video, Doug tells the interesting tale of how JSON was discovered, and sheds some light on how it became a major standard for describing data in an interesting turn of events.
(jvb) (il)
© Jacob Cook for Smashing Magazine, 2012.
Closures are often viewed as an arcane art in the land of JavaScript. Once mastered, they allow you to write some truly amazing JavaScript. This article will get you up to speed on the magic of JavaScript closures.
One of the key truths of JavaScript is that everything is an object. This, of course, includes functions.
A closure is nothing more than a function object with a related scope in which the function’s variables are resolved.
Closures get their name because of the way they close over their contents. Consider the following bit of JavaScript:
topping = "anchovi";
function pizzaParty(numSlices) {
var topping = "pepperoni",
innerFunction = function() {
var topping = "ham";
console.log(" .....But put " + topping + " on " + numSlices + " slices");
};
console.log("This pizza is all about the " + topping);
innerFunction();
}
pizzaParty(3);
If you open up your favorite console and run that bad boy, you will be greeted with a delicious message to the effect of “This pizza is all about the pepperoni ….. But put ham on 3 slices.” This example illustrates some key concepts of JavaScript that are crucial to getting a hold on closures.
How many function objects are in the above code? Well… we have
our pizzaParty function, and nested in that function
is innerFunction. Math hasn’t always been my strong
suit, but 1 + 1 = 2 in my book. Each function object
has its own set of variables, which are resolved in each function’s
scope.
Closures can’t be fully understood without a firm grounding in
scope. JavaScript’s scope mechanism is what allows each function to
have its own topping variable, and without it we might
have too much pepperoni, too little ham, or *gasp* … some anchovies
at our pizza party. Let’s use a quick illustration to better
illustrate this idea.

Functions are executed using the scope that was in effect when the function was defined. It has nothing to do with the scope in effect when the function is called.
The green arrows show that accessibility works from the outside in. Variables defined in the scope outside of a function are accessibile from within it.
If we were to omit the topping variable from inside
the pizzaParty function, then we would get a message
like “This pizza is all about the anchovi”, but since
pizzaParty has a topping variable within
its own scope; those salty suckers will never get near our pizza
party.
Likewise, the numSlices parameter can be accessed
from within innerFunction because it is defined in the
scope above – in this case the scope of
pizzaParty.
The red arrows show that variables in scope for a function are never accessible outside of that function. This is the case only when a variable meets one of the following conditions:
var keyword is being used.Omitting the var keyword when setting a variable
will cause JavaScript to set the closest named variable in outer
functions all the way up to the global scope. So, using our
example, the ham topping in innerFunction
cannot be accessed from pizzaParty, and the pepperoni
topping in pizzaParty cannot be accessed
out in the global scope where the anchovi dwells.
Lexical scope means functions are executed using the variable scope in effect when the function was defined. It has nothing to do with the scope in effect when the function is called. This fact is crucial to unlocking the power of closures.
Now that we understand what a closure is, and what scope means for closures, let’s dive into some classic use cases.
Closures are the way to conceal your code from the public eye. With closures, you can easily have private members that are shielded from the outside world:
(function(exports){
function myPrivateMultiplyFunction(num,num2) {
return num * num2;
}
//equivalent to window.multiply = function(num1,num2) { ...
exports.multiply = function(num1,num2) {
console.log(myPrivateMultiplyFunction(num1,num2));
}
})(window);
With closures, you can easily have private members that are shielded from the outside world.
Let’s break it down. Our top level function object is an anonymous function:
(function(exports){
})(window);
We invoke this anonymous function right away. We pass it the
global context (window in this case) so we can
“export” one public function, but hide everything else. Because the
function myPrivateMultiplyFunction is a nested
function, it exists only within the scope of our closure; so we can
use it anywhere inside this scope, and only in this scope.
JavaScript will hold a reference to our private function for use
inside the multiply function, but
myPrivateMultiplyFunction cannot be accessed outside
of the closure. Let’s try this out:
multiply(2,6) // => 12 myPrivateMultiplyFunction(2,6) // => ReferenceError: myPrivateMultiplyFunction is not defined
The closure has allowed us to define a function for private use, while still allowing us to control what the rest of the world sees. What else can closures do?
Closures are quite handy when it comes to generating code. Tired of remembering all those pesky key codes for keyboard events? A common technique is to use a key map:
var KeyMap = {
"Enter":13,
"Shift":16,
"Tab":9,
"LeftArrow":37
};
Then, in our keyboard event, we want to check if a certain key was pressed:
var txtInput = document.getElementById('myTextInput');
txtInput.onkeypress = function(e) {
var code = e.keyCode || e.which //usual fare for getting the pressed key
if (code === KeyMap.Enter) {
console.log(txtInput.value);
}
}
The above example isn’t the worst, but we can use
meta-programming and closures to make an even better solution.
Using our existing KeyMap object, we can generate some
useful functions:
for (var key in KeyMap) {
//access object with array accessor to set "dyanamic" function name
KeyMap["is" + key] = (function(compare) {
return function(ev) {
var code = ev.keyCode || ev.which;
return code === compare;
}
})(KeyMap[key]);
}
Closures are so powerful because they can capture the local variable and parameter bindings of the function in which they are defined.
This loop generates an is function for every key in
KeyMap, and our txtInput.onkeypress
function becomes a bit more readable:
var txtInput = document.getElementById('myTextInput');
txtInput.onkeypress = function(e) {
if(KeyMap.isEnter(e)) {
console.log(txtInput.value);
}
}
The magic starts here:
KeyMap["is" + key] = (function(compare){
})(KeyMap[key]); //invoke immediately and pass the current value at KeyMap[key]
As we loop over the keys in KeyMap, we pass the
value referenced by that key to the anonymous outer function and
invoke it immediately. This binds that value to the
compare parameter of this function.
The closure we are interested in is the one we are returning from inside the anonymous function:
return function(ev) {
var code = ev.keyCode || ev.which;
return code === compare;
}
Remember, functions are executed with the scope that was in
place when they were defined. The compare parameter is
bound to the KeyMap value that was in place during a
loop iteration, and so our nested closure is able to capture it. We
take a snapshot in time of the scope that was in a effect at that
moment.
The functions we created allow us to skip setting up the
code variable everytime we want to check the key code,
and we now have convenient, readable functions to use.
At this point, it should be relatively easy to see that closures
are vital to writing top notch JavaScript. Let’s apply what we know
about closures to augmenting one of JavaScript’s native types
(gasp!). With our focus on function objects, let’s augment the
native Function type:
Function.prototype.cached = function() {
var self = this, //"this" refers to the original function
cache = {}; //our local, lexically scoped cache storage
return function(args) {
if(args in cache) return cache[args];
return cache[args] = self(args);
};
};
This little gem allows any and every function to create a cached version of itself. You can see the function returns a function itself, so this enhancement can be applied and used like so:
Math.sin = Math.sin.cached(); Math.sin(1) // => 0.8414709848078965 Math.sin(1) // => 0.8414709848078965 this time pulled from cache
Notice the closure skills that come into play. We have a local
cache variable that is kept private and shielded from
the outside world. This will prevent any tampering that might
invalidate our cache.
The closure being returned has access to the outer function’s bindings, and that means we are able to return a function with full access to the cache inside, as well as the original function! This small function can do wonders for performance. This particular extension is set up to handle one argument, but I would love to see your stab at a multiple argument cache function.
As an added bonus, let’s take a look at a couple uses of closures in the wild.
Sometimes, the famous jQuery $ factory is not
available (think WordPress), and we want to use it in the way we
typically do. Rather than reach for jQuery.noConflict,
we can use a closure to allow functions inside to have access to
our $ parameter binding.
(function($){
$(document).ready(function(){
//business as usual....
});
})(jQuery);
On large Backbone.js projects, it might be favorable to have your application models private, and then expose one public API on your main application view. Using a closure, you can easily acheive this privacy.
(function(exports){
var Product = Backbone.Model.extend({
urlRoot: '/products',
});
var ProductList = Backbone.Collection.extend({
url: '/products',
model: Product
});
var Products = new ProductList;
var ShoppingCartView = Backbone.View.extend({
addProduct: function (product, opts) {
return CartItems.create(product, opts);
},
removeProduct: function (product, opts) {
Products.remove(product, opts);
},
getProduct: function (productId) {
return Products.get(productId);
},
getProducts: function () {
return Products.models;
}
});
//export the main application view only
export.ShoppingCart = new ShoppingCartView;
})(window);
A quick recap of what we learned:
Thanks so much for reading! Feel free to ask any questions. Now let’s enjoy the pizza party!
"QUANTUM SHOT" #768
Link - article by Avi Abrams
This article appears simultaneously on Dark Roasted Blend and on
"Out of
Order" magazine - a Yale University print and online
publication that curates innovative and bold fashion, art, music
and film for the university set.
Visual Caffeine: Exploring Art and Architecture with Avi Abrams,
Issue 1
Welcome to new series of showcasing highlights in history of arts
and architecture! Wait a moment, this does not sound exciting
enough. How about -
Welcome to exploring the..."aesthetic-precepts-smashing,
eyeball-massaging,
brain-searing-with-its-heartbreaking-and-fragile-beauty,
visually-apocalyptic" side of Art, Style and Architecture? While
you may think that we exaggerate here (well, only a little), you
are welcome to assume that you will be assaulted with purple prose,
strange "red-shifted-into-impossible" facts, and images... well,
images lurid enough to shimmer through your eyelids and trigger an
iridescent neural zeitgasm! - all for the sake of breaking from
boring and mundane and promoting "weird and wonderful" side of
things.
Seriously though, this column is not going to be earth-shaking in
the way we described it, but don't say we did not warn you... you
may still find yourself lost for some time in ensuing cataract of
pictures and information, unable to complete your study and work
commitments. For those of you, who want even larger dose of our
visual caffeine, head over to Dark Roasted
Blend site, and get addicted to our endless stream of thrilling
visual information.
Might I add, that our "visual caffeine concoctions" are bound to be
somewhat unpredictable as we explore history of art and
architecture in tandem with mythology, culture and obsolete
technology, seeking to find overall "look and feel" of certain time
periods. The goal here is to connect as many points of reference in
art history as possible, highlighting little-known gems, visual
styles and trends - and making them relevant in our
caffeine-infused culture.
Today we're going to see highly-sophisticated sets of Japanese
letterpress movable type:
(images credit: Tomoyuki
Ishida)
Craft letterpress companies are experiencing revival in recent
times, and nowhere it is more evident than in Japan. Most of you
will be familiar with the ancient Chinese and Japanese art of
woodblock printing, but masterpieces created
with the wooden and metal movable type are somewhat less known,
though they show craftsmanship and attention to detail similar to
fine woodblock prints.
(image credit: Tomoyuki
Ishida)
First movable type and printing presses were invented in Asia,
not Europe.
...but their development stalled because of extreme complexity and
sheer number of Chinese and Korean characters (same problem that
Asian cultures faced with transition to typewriters, or internet).
We can thank the simplicity of Western alphabets for the rapid
development and adoption of printed word in Europe, which quickly
lead to the Renaissance and further advances in culture and
education.
It seems to be a widespread misconception that Johannes Gutenberg
created the first movable type system and the printing press,
around 1450 A.D. It's true, Gutenberg was the first to make his
movable type from a certain alloy of lead, tin, and antimony (which
was more efficient than iron used in Asia) - but the movable type
itself was originally invented in China around 1040 A.D. by Bi Seng
(during the Song Dynasty). Th new system was badly needed to
replace the labor-intensive woodblock printing technique, where a
single wooden block was carved to represent a single page. The
first movable type sets was made from wood or ceramic materials,
with clay eventually replacing wood "due to the presence of wood
grains and the unevenness of the wooden type after being soaked in
ink".
(images credit: Tomoyuki
Ishida)
The world's oldest (and still existing) movable metal print book is
considered to be Jikji, which was published in 1377,
seventy-eight years prior to Johannes Gutenberg's printed Bible
(left image below). On the right is another ancient book printed
with the wooden movable type - "The Auspicious Tantra of All
Reaching Union" from 1139–1193, the earliest existing example of
such kind:
(images via
1, 2)
As you can see, just reading this sort of printed material (not to
mention assembling movable type and actually printing it) requires
intense concentration for our Western minds: it's hard to simply
glance on this page and "speed-read" it. We need certain
serendipity and discipline of mind to read long Asian texts -
consider, for example, how you would feel reading the massive 1000
volume encyclopedia "Imperial Readings of the Taiping Era" printed
in 1574?
(letterpress machines seen at Tokyo Printing Museum, via)
Here is an interesting tidbit of history that speaks of extreme
cultural inertia and reluctance to adopt new forms of
communication:
"A potential solution to the linguistic and cultural bottleneck
that held back movable type in Korea for two hundred years appeared
in the early 15th century — a generation before Gutenberg would
begin working on his own movable-type invention in Europe — when
King Sejong the Great devised a simplified alphabet of 24
characters for use by the common people, which could have made the
typecasting and compositing process more feasible.
But Sejong's brilliant creation did not receive the attention it
deserved. Adoption of the new alphabet was stifled by the inertia
of Korea's cultural elite, who were appalled at the idea of losing
Chinese, the badge of their elitism." (via)
Cutting to modern times, today we see some truly gorgeous work
being produced by Japanese craft printing firms, and it seems the
arcane and esoteric skills of movable type setting are much in
demand - see for example here and here. Note the imposing press dominating the room:
(image credit: Takuma
Nakagawa, AllRightKoubou)
Try typesetting in Japanese and learn attention to
detail!
So how did Bi Seng, the movable type inventor himself, used to
group his type and find the proper pieces? He organized them by
"rhyme groups"... turning the printing process into a sort of
poetry. Interesting alternative to organizing information by
alphabet, but not as quick and efficient, perhaps?
(images credit: AllRightKoubou)
Learning the system of storing and retrieving all these characters
can be a daunting task. Here is how Takuma Nakagawa, a master
custom printer, describes the process:
"You have to remember each place for each word - it's about 400,000
characters, can you imagine!.. Too many. Some of them are set in
alphabetical order, and then kanji characters are categorized for
each kind. It's hard to remember it."
(images credit: Takuma
Nakagawa)
ALSO READ: "UNUSUAL TYPEWRITERS"! ->
CONTINUE
TO OUR "ARTS" CATEGORY ->
This article appears simultaneously on Dark Roasted Blend and on
"Out of
Order" magazine - a Yale University print and online
publication that curates innovative and bold fashion, art, music
and film for the university set.
|
The gaming industry is huge, and it can keep its audience consumed for hours, days and even weeks. Some play the same game over and over again — and occasionally, they even get out their 15-year-old Nintendo 64 to play some Zelda.
Now, I am not a game designer. I actually don’t even play games that often. I am, though, very interested in finding out why a game can keep people occupied for a long period of time, often without their even noticing that they’ve been sitting in front of the screen for hours. I want my apps and products to affect my visitors in the same way.
(Image credit: Axel Pfaender
So, what do games have that we miss in UX and Web design? Games have stunning graphics, missions, high scores, etc.. But adding any of those to our designs does not necessarily provide a better user experience — in many cases they’re frippery. What we are really looking for is what those elements bring to the games.
Using game theories in areas not otherwise associated with games is often referred to as gamification. This term, however, has gotten a rather negative air recently, because people tend to use it for the wrong purposes. A common issue with gamification is that it is used in marketing with no other goal than to sell products. I don’t think gamification should be used this way — in the long run, it does nothing good for the company trying to sell. Instead, gamification should be used to improve the experience of buying and using a product.
In this article, we’ll explore how and when to use gamification to improve the user experience of websites and apps, and also when not to use it.
Sid Meier, creator of the Civilization series, once said that a game is “a series of interesting choices.” I believe there’s more to a game than that. For me, the interesting part of a game is what happens in between the choices: exploring new areas, learning how to control your character, pulling people out cars for fun, etc.
In their book Andrew Rollings and Ernest Adams on Game Design, Rollings and Adams speak of four actions related to games: play, pretending, rules and goals.
Playing is usually a recreational activity, and your actions are often nonessential to the game. A game is more of a participatory form of entertainment, whereas books and movies, for example, are mainly presentational. In a game, you decide the storyline.
In Danish and many other languages, the word “play” can be translated as two words, “lege” and “spille.” Lege is like when children are playing. Spille is like when you’re playing a game. The difference is small but present. When children are playing, there are usually no initial goals or rules — they are playing simply because they want to play.
Originally introduced in the Amsterdam International Airport, the urinal fly is a great example of a usable yet fun product. Its intent is to keep the bathroom floor clean; when you aim for the fly, you’re less likely to spill. You can urinate without trying to hit the fly, but for a lot of people trying to hit it is a better and more fun experience.
The urinal fly is proven to reduce spillage. (Image: Sustainable Sanitation
Alliance)
Another example is Danish gas station F24. In December 2011, it introduced new multimedia pumps at its stations. Customers can play games while filling gas, with a 10% chance of winning a prize. They don’t have to play the game while filling their cars, but the chance of being able to drive away without having to pay for the gas is enticing. It’s a great idea because people talk about the game with their friends, and the next time their friends need to fill up, they will go to F24 to try it for themselves.
The iPhone app Clear was extremely popular when it launched recently. The app has a simple concept: keeping lists of tasks. But the way you interact with the tasks is different from what we’ve seen before. Some people even said they made up tasks just to be able to mark them as complete. Very few products are able to make their users do that, but we should try to accomplish it with everything we create.
With websites, a recent trend is parallax scrolling. Nike showed what single-page designs could be with its Better World and We Run Mexico websites. A lot of people scrolled up and down those websites just to watch the effects over and over again. We were intrigued because they were different from other single-page websites.
Games often allow a player to be another person. They give the player a different reality. People tend to behave differently if no one knows who they are.
This could very well be the reason why people love social networks, forums and chat rooms. You get to create your own identity, or at least choose which parts of you others get to see.
Any game has rules — rules that define what players can and cannot do. Adams and Rollings refer to six functions defined by game rules: semiotics, gameplay, sequence of play, goal(s) of the game, termination condition and meta rules.
Everyone loves completing a task. Achieving a goal is one of my favorite things — whether it’s to deliver a website to a client, running a certain distance or learning something new.
Even a small goal can bring great satisfaction. A while back, Ryan Carson of Carsonified posted a screenshot of one of the steps in Twitter’s incredibly clever sign-up process. It has changed a bit since, but the concept is the same: while teaching you how to use the service, Twitter makes you feel like you’re accomplishing a goal by reaching the end of the progress bar.
Twitter’s
sign-up process uses gamification to teach users how to use the
service.
When I (very occasionally) pull myself together to go for a run, and I’m almost at my goal, the lady on the Nike+ app on my iPhone says, “You’re almost at your goal. Keep it up!” This always pushes me a little harder. In its app, Nike takes advantage of our desire to compete — be it against friends or ourselves. Most importantly, Nike motivates and encourages its users.
When you encourage users to complete a task, they are more likely to try to do it. On websites, such a task could be registering, filling out a profile, signing up for a newsletter or simply buying a product. Give the user a sense of success; again, the good experience will satisfy customers and, thus, make them return.
Not all games have a quantifiable outcome or an achievable goal, though. Take Sin City, Space Invaders and flOw. If you haven’t tried flOw, I encourage you to do so. In the game, “players with differing skill levels can intuitively customize their experiences in the zone and enjoy the game at their own pace.”
The process is often a goal in itself. A goal on a website is often to find information or to buy a product, and so the user has to be able to actually find this information — and enjoy doing it.
These are, according to Adams and Rollings, the four main components of a game. Let’s try to expand on them.
Games are more fun when you have someone to play them with. You can fight against an opponent or collaborate on completing a task. Remember when you could connect two Game Boys to trade Pokémons?
In these days of social networking, we have the ideal conditions for cooperating with friends. Social networking is probably way more about marketing than we realize. Companies know that if they show us products that our friends are buying, we’re more likely to buy them, too. Take Spotify; your Facebook stream is filled with music being listened to by your friends. You can listen to it yourself, comment, like and so on. Spotify engages you in its product — even if you don’t even use Spotify.
Services such as FourSquare and Facebook Places rely heavily on social relationships. When your friend ousts you as mayor of Starbucks, you of course have to go to Starbucks to reclaim the title. The process is simple, but it actually involves three of the four actions mentioned above. You’re playing a game with your friend with the goal of being the mayor of Starbucks, and the game is more or less defined by rules, a set of steps you have to go through to complete your turn.
Why should we make our websites usable? Why even spend time on UX? It’s rather simple, actually. Usability expert Jakob Nielsen explains it well:
On the Web, usability is a necessary condition for survival. If a website is difficult to use, people leave. If the homepage fails to clearly state what a company offers and what users can do on the site, people leave. If users get lost on a website, they leave. If a website’s information is hard to read or doesn’t answer users’ key questions, they leave. Note a pattern here? There’s no such thing as a user reading a website manual or otherwise spending much time trying to figure out an interface. There are plenty of other websites available; leaving is the first line of defense when users encounter a difficulty.
This is why we spend so much time on usability and UX design. If we scare off our visitors before they have even had a chance to look at what we’re selling, then we won’t sell anything.
We are not looking to transform our products into games. Instead, we are trying to learn from an industry with an extremely engaged audience. We shouldn’t blindly use these theories; rather, we should adapt them to our needs and to the platforms on which we deliver our products, without compromising with the quality of our products.
Gamification shouldn’t be something you apply after designing and building your product. Gamification is a part of the design process itself. But how do we put this into practice? While the process will be shaped by your product and audience, here are some areas to consider when applying game theories to your product or website, along with some good resources on implementing them.
Since the birth of the personal computer, we’ve been accustomed to using a mouse and keyboard. However, in the world of games, the physical controls change with the platform. On a PlayStation, you have the geometric buttons and a couple of jogs. On an iPhone, you have a touchscreen and an accelerometer. You might have a tennis racket for the Wii. One game can be controlled differently on two platforms; for example, you might steer a car with the keyboard arrows on a PC but tilt on an iPhone.
With the mobile market ever expanding, we need to make sure that our users have a good experience, whatever platform they use to visit our websites. We need to adapt our products to the platform they are being served on.
If you own an iPhone, try visiting Google Images, and compare the mobile to the desktop version. Swiping through the result pages is a great experience because you’re used to that gesture on the iOS platform. Visit YouTube from a PlayStation 3, and you will be greeted by a design suited to a media center.
When I got my first iPhone, I spent a lot of time playing with the interface. But the interface was still limited to a set of predefined gestures. With the iPhone 4S came Siri, which enabled us to interact with the device in a completely new way, and it took mobile devices to the next level in accessibility.
When you visit YouTube from a PlayStation 3, you are redirected
to YouTube
XL.
Resources:
Popular games are often location-based — i.e. the location of the player affects the game. Can we benefit from this in Web and UX design? Heck, yeah!
I live in Denmark. I recently visited Amazon’s US website and was greeted with this message:
Amazon uses
location to direct you to the store for your area.
Amazon detects where I live and points me to Amazon UK. Checking my location may be a simple technical task, but it makes it feel almost as if they know me.
Social networks are taking advantage of our urge to play and the fact that we almost always have a GPS-enabled gadget with us. To get a discount, someone can check in at H&M, and at the same time tell the entire world that they’re shopping at H&M. That is extremely cheap advertising.
Resources:
In games, we often see direct feedback to our actions. For instance, your guide might interrupt a game that’s not going so well to help you remember how to use some skills that you learned earlier in the game.
Providing feedback to your users, especially when something goes wrong, is crucial. Be honest with your users, and help them move on.
There are many ways to give users direct visual feedback in a design: show them what page they are on, use consistent colors for links, create a helpful 404 page, give useful information when a field isn’t filled in correctly in a contact form.
One of my favorite features of Google is its “Did you mean?” suggestions. Many people are poor spellers, but that shouldn’t prevent them from buying your product. Adding a “Did you mean?” feature to your Web store’s search engine can help these users find the product they’re looking for.
Feedback is not only about responding to the visitor’s actions, but also about foreseeing their actions. Olark is a great example. Olark is a customer-support service that puts chat functionality on your website. When you visit Olark’s website and you’ve been there for 10 seconds doing nothing but scrolling, the chat window appears with the message, “Thanks for stopping by! May I help you?” Even though the message is automated for all users, it gives them the impression that they’re chatting with a real person. When a visitor replies to the automated message, they’re connected to an Olark employee, who then answers their questions.
Be careful not to annoy visitors, though. Remember Clippy? Respect your users — if they close the chat window, don’t reopen it when they visit another page on your website.
Resources:
I won’t get into this argument — I’m simply stating that I believe that content is still the most important part of any product. Your candy might be wrapped in pretty paper, but people won’t buy it twice if it tastes like junk. This, of course, doesn’t mean that we shouldn’t wrap it nicely; pretty paper certainly has its advantages.
As Katie Salen and Eric Zimmerman assert in Rules of Play, “Context shapes interpretation” (pages 44–46). Visiting a business website for which the designer chose Comic Sans as the font really takes the focus off of the content. Make sure that your design represents the content — use the design to substantiate your message.
In “Gamification Is Not Game Design,” Adam Loving has this to say:
You cannot increase the intrinsic value of something by adding game mechanics. You CAN make the value more visible. You CAN change the paradigm and context of your site visitor from user to player — increasing their engagement.
Gamification is just a tool to serve content more digestibly. Don’t overuse it; your website or app will not improve from the application of game theories. The product needs to be great, otherwise it won’t matter. Gamification can improve the user experience, but by no means can it create it alone — the user experience is also created by logical structure, good writing, motivation, flow, etc.
In his much debated blog post “Design Is Horseshit”, yongfook tells us: “Focus on value creation. Design enhances value, it does not create it.” And as Joshua Porter mentions in his response post, this statement is entirely true “when you believe that design is just making things look good.”
The same could be said of gamification. A point system and badges are not what make a product good, but rather the experience they provide combined with the product itself. Gamification really can create value — it depends entirely on the user. School teachers know this; to be effective, they have to look at the student, not the class. Not everyone learns the same way. Two times two might equal four, but there are a million ways to learn that. For instance, Treehouse has a great product not because you can earn badges; that’s fun and all, but the value lies in the high quality of the teaching material.
On Treehouse, you can unlock badges by taking quizzes
and completing code challenges.
Vitaly Friedman, editor in chief of this very magazine, said at the Frontend conference (video) in Oslo in 2011 that we should be better at storytelling in Web design. The Web is not a static medium — why don’t we embrace that? The possibilities for creating beautiful, useful and helpful interfaces and products are endless, but we rarely take advantage of them. We need to experiment in order to create better interfaces. As Vitaly said, we need to tailor our designs to the particular needs of the client. We need to stop focusing on selling products; we don’t have to trick people into buying. No one will buy a product that they don’t know something about; tell the user what your product does and why it does it the best before even attempting to sell it.
In October 2011, ZURB posted an article advocating for hiding the sign-up button in order to get more sign-ups. On the home page of a client’s website, ZURB replaced the sign-up button with a “Let’s go” button, inviting the visitor to learn more about the product, before even mentioning anything about signing up or buying a product. Sign-ups actually increased by — wait for it — 350%!
In Angry Birds you can earn badges for completing various tasks throughout the game. I don’t know about you, but I’ve played the same levels over and over again until I got three stars. We want to be best.
Other than getting badges for ranking high, you also get badges for playing longer, hitting a certain number of pigs, etc.
When I visit one of my local bakeries to buy bread, I get a stamp on a card. The next time I visit the bakery, I get another stamp. When I have 10 stamps, I get free bread. Simple but effective. I would never visit another bakery. Research by Joseph Nunes and Xavier Drèze shows that prestamping such cards is effective. It makes customers feel as if they have begun collecting stamps; as a result, they feel more motivated to complete the card than those whose cards are not prestamped. In a Web store, you could give customers double the value on their first purchase or increase the discount they get according to how often they buy from you.
There are many ways to engage users. Ask them for feedback — and listen. Create a Facebook page or Twitter profile, and be active. If you can afford it, giving away free stuff also helps to spread the word about your company. Competitions are often a great way to engage users. This Easter, WOW HD held a competition in which users had to browse its Web store to find Easter eggs. For each egg found, the visitor got a coupon code. In the process, the visitor would come upon a lot of products on which they could spend their coupons. Create fun competitions instead of asking basic questions.
My wife and I visited Las Vegas a couple of years ago. I handed a waitress my credit card to pay for our dinner, and she handed it back to me and said, “Thank you, Peter.” I thought to myself, “How does she know my name?!” only to realize that she’d seen my name on the credit card. But it felt like she knew me. It felt like she cared.
Flickr
greets you in different languages.
This is easy to do when the user has registered an account on your website. Whenever they’re logged in, address them by name to make them feel like you’re speaking directly to them. When you log into Flickr, you’re greeted with the word “Hi” in one of many languages, followed by your name. On Amazon, you get personalized recommendations when you’re logged in, based on items recently bought and viewed.
Ever since I got my first computer, I’ve loved Easter eggs — hidden details like the “Here’s to the crazy ones” speech in the TextEdit icon on Mac OS X, and even hidden games like Snake in Terminal. Many websites also have Easter eggs. Most of the time, they’re just developers having fun, but why not let your users have some fun, too.
There are several ways to include Easter eggs in your
application or website. One of my favorites is the Konami Code. The
Konami Code appeared by mistake in the 1985 arcade game
Gradius. It is entered by pressing certain buttons in a certain
order: up, up, down, down, left, right, left, right, B, A,
Start, and it is probably relevant only to websites related
to games and technology.
Several websites, including Geek & Hype and the website of Paul Irish (which you just have to try) use the Konami Code. You could use it to give users a discount or just to show them something fun.
Another way to use Easter eggs is by placing them on your 404 page. Of course, you don’t want visitors to end up there, but having something fun there might lighten the mood. Check out Fab404 for great 404 inspiration.
Nosh’s
404 page features a video in which a team of ex-special forces
hunts down the missing page.
Resources:
Don’t rush out to add badges and point systems to your designs, though. Gamification certainly has its limits.
Of course, we all know that we’re selling a product. When you visit a physical store, you get an experience. Music comes out of the speakers, and pictures are hung with beautiful people wearing clothes that you’re going to buy because you want to look like them. The store assistant offers your girlfriend or boyfriend a cup of coffee, telling them that they look gorgeous in that sweater. And you leave the store with a good experience.
We want to give our visitors a good experience. But our product is still the website, with all its content, be it a Web store, a restaurant menu or our own portfolio. A great experience doesn’t give visitors much if that’s all there is. Focus on creating a great product before making it look pretty.
As mentioned earlier, gamification doesn’t sell the product. It can make the experience more fun, which will hopefully bring the customer back. But to be honest, if you don’t have a great product, you should probably be spending your time on that instead.
Games always have to have difficulty levels; completing a game without at least failing a couple of times is no fun. On a website, however, users should find what they’re looking for as quickly as possible; if they get annoyed, they will hit the “Back” button and you won’t sell anything. This doesn’t mean you can’t experiment with navigation and effects. But, to quote Steve Krug, just don’t make your users think — at least not too much.
So, you want to promote this shiny new product of yours. What do you do? Perhaps you think to offer a discount if customers tell at least 150 of their friends on Facebook about it. The problem is that everyone hates spam, and the saying “Bad publicity is better than no publicity” is not really true.
Your Twitter followers probably don’t care that you’ve checked into McDonald’s for the fourth time this week on Foursquare — and if they do, they’ll follow you on Foursquare. The main reason I don’t use location-based social networks such as Facebook Places and Foursquare is that they were introduced to me as spam in my Twitter stream. Even though users can opt out of sharing their location, consider whether you should give them the option at all. Doing so could come back to haunt you.
Don’t make it a requirement to play your game. Not everyone wants to collect badges, and you should respect that. Giving discounts to those who want to play is one thing, but don’t exclude anyone from buying.
Before even thinking about using gamification, consider how it might affect your reputation. For instance, websites for law firms and banks probably shouldn’t be “fun” to use. Some aspects of gamification just aren’t suitable for companies that want to be taken seriously. Imagine getting a 10% discount from your lawyer for liking them on Facebook. I would have a hard time taking that lawyer seriously.
The iPhone app of Jyske Bank (a Danish bank) finds your closest
branch by using GPS.
By contrast, helping visitors find the closest branch when visiting your bank website on a mobile device will show them that you care. Figure out how you want your company to be seen before using gamification.
Gamification is here to stay, and unfortunately many people will continue to use it the wrong way. We’ve covered a few ways to use gamification wisely. The goal is to enhance the experience of using your product, without punishing users who just want to buy the product and move on.
People love having unique experiences. Experiences are what brings people back. But don’t let the experience get in their way of buying your product.
To learn more about gamification, have a look at these articles and books:
In addition to the above, be sure to check out these articles and books.
(al)
© Peter Steen Høgenhaug for Smashing Magazine, 2012.
If you’re working on a large project, you’ll no doubt have a build script or a bunch of task scripts to help with some of the repetitive parts of the process. You might use Ant or Rake, depending on the language the project is written in.
But what do you use if the project is primarily JavaScript? That’s the problem Ben Alman set out to solve when he created Grunt.
What exactly is Grunt? Well, the README on Github says
Grunt is a task-based command line build tool for JavaScript projects.
Here’s the idea: when working on a JavaScript project, there are
a bunch of things you’ll want to do regularly. Like what, you ask?
Well, like concatenating given files, running JSHint on your code, running tests, or
minifying your scripts. If you’re pasting your JavaScript into
JSHint online, you probably realize that there’s a better way to do
it; even if you’re using cat to concatenate files or a
command line minifier, it would be nice to have a single, unified
set of commands for all those extra tasks, that worked for every
single JavaScript project, right?
That’s what Grunt aims to be. It has a bunch of built-in tasks that will get you pretty far, with the ability to build your own plugins and scripts that extend the basic functionality.
For more Grunt intro goodness, see Ben’s post on his personal blog and the Bocoup blog.
Grunt is built on Node.js, and it’s available as a package via the Node package manager (npm). You’ll want to install it globally, so use this command:
npm install -g grunt
You’ll notice it installs quite a few dependencies; there are other npm packages that Grunt uses. Once that’s done, you’re all set to go!
As you know, Grunt is a command line tool; therefore, I’ll assume you have a terminal window open for the rest of this tutorial.
Let’s start by creating a sample project directory; we’re not
actually going to be building a project here, but we’ll be seeing
how Grunt works in this directory. Once you’re within that
directory, run the grunt command (according to the
documentation, if you’re on Windows, you might have to run
grunt.cmd). You’ll probably see something like
this:
<FATAL> Unable to find 'grunt.js' config file. Do you need any --help? </FATAL>
Before you can really leverage Grunt to its fullest potential,
you’re going to need a grunt.js file in the project
directory. Thankfully, Grunt can auto-generate a
grunt.js file—and some other project skeleton
material—with the init task, which can run without a
grunt.js file in place. But grunt init
still isn’t enough to get your project started, as you’ll see if
you run it. You need to choose a type of project to generate.
Running grunt init will give you a list of project
types to choose from:
jquery: A jQuery pluginnode: A Node modulecommonjs: A CommonJS modulegruntplugin: A Grunt plugingruntfile: A Gruntfile
(grunt.js)If your project doesn’t really match any of the first four
project types, you can use the final one: gruntfile:
it just creates a basic grunt.js that you can fill in.
So, let’s give this a try, with the jQuery plugin template. Run
grunt init:jquery in your terminal.
You’ll notice a lot of initial output. If you take the time to read the template notes, you’ll see that we’re going to have to fill in a few values, like project name and project title. In fact, after that note, you’ll see something like this:
Please answer the following: [?] Project name (jquery.demo)
Whenever you initialize a project, Grunt will ask you a series of questions, so it can fill in a few options. That value in the parentheses? That’s the default suggestion, based on the project type and the name of the project directory. If you want to change it, write your own project name at the end of the line and hit ‘enter’; otherwise, just hit ‘enter’ to use the default name.
Keep going and fill in the rest of the fields. For a jQuery plugin project, here’s what else you’ll need to give it:
A lot of these have default values; if you want to use the default value, just hit enter for that line; to leave the field blank, you can just type “none.” Once you’ve gone through all the options, you’ll see that Grunt is creating some basic project files. Like what? Like this:
LICENSE-GPL
LICENSE-MIT
README.md
grunt.js
libs
|-- jquery
| |-- jquery.js
|-- qunit
|-- qunit.css
|-- qunit.js
package.json
src
|-- jquery.demo.js
test
|-- jquery.demo.html
|-- jquery.demo_test.js
As you can see, this gives us a good start: not only do we have
our plugin file (src/jquery.demo.js), we also have
Qunit tests (test/jquery.demo_test.js). And these
aren’t empty files, either. They’ve got some initial content, with
a so-super-basic jQuery plugin and unit tests. Go ahead and check
out the contents of these files, you’ll see what I mean.
Grunt does more than set up the project for you.
Of course, Grunt does more than set up the project for you.
Notably, our project now has grunt.js: a
project-specific configuration file; because of the options it
sets, we’re now able to use Grunt’s other built-in tasks. Soon
we’ll crack it open and make some adjustments, but for now let’s
run some tasks.
If you run grunt with no options now, we’ll run the
default task, if one has been set. In the case of a jQuery plugin
project, that’s equivalent to running these four commands:
grunt lint: checks your JavaScript against
JSHintgrunt qunit: runs your Qunit testsgrunt concat: concatenates your project files
together and puts the new file in a dist foldergrunt min: minifies the file concat
put out.I should note something about the Qunit tests here: Qunit tests
are meant to run in the browser by default; just open
tests/jquery.demo.html (or your equivalent) in the
browser. However, the grunt qunit test wants to run
them on the terminal, which means you need to have PhantomJS
installed. It’s not difficult: just head over to phantomjs.org and download and install
the latest version. If Grunt can find that in your path, it will be
able to run the Qunit tests from the terminal.
So, running grunt should give you output to similar
to this:

As you can see, each of our four tasks have run. If any of them
were to fail, the rest of the tasks would be cancelled (unless you
call Grunt with the --force flag).
Already, we’ve gotten a lot of great functionality out of Grunt,
using it just as it comes. However, let’s crack open that
grunt.js file and do some configuring.
Inside grunt.js, you’ll see that all configuring is
done by passing an object literal to
grunt.initConfig(). Let’s look at a few of the
properties of our config object.
pkgThis property points to the package.json file that
Grunt created in our project directory. Having a
package.json file is part of the CommonJS Packages
spec; it’s a single place where most of the metadata about the
project (name, version, homepage, repository link … many of the
values you set when initializing the project) can be stored.
However, this pkg property does more than point to the
package file: notice the syntax:
'<json:package.json>'. That’s one of Grunt’s
built-in directives: it actually loads the JSON file, so Grunt (or
you) can access all the properties in the package.json file from
the pkg property.
metaThe meta property is an object with only a single
property: a banner. This banner is the comment that goes at the top
of concatenated or minified project files. As you can see, it’s a
string with some template tags (<%= %>); in most
cases, the tags surround a call to a property on the
pkg property, such as pkg.title. However,
you can also execute functions from inside those tags: the use of
grunt.template.today() and _.pluck()
shows us that.
concat / min / qunit /
lint / watchI’ve grouped the next five properties together because they’re
very similar. They all set options for specific tasks, the tasks
they’re named after. When configuring these tasks, it’s important
to note that Grunt distinguished between two types of tasks:
regular tasks, and multitasks. Basically, the difference is that
regular tasks have only a single set of configuration options,
whereas multitasks can have multiple sets of instructions (called
targets). Of the five tasks I listed in the header of this
section, the only one that isn’t a multitask is
watch.
Notice that in our config object, the qunit and
lint properties are both objects with the
files property. files is a single target
for this task. In both cases, they’re an array of files to be used
when executing this task. Let’s say I want to be able to lint only
the files in src sub-directory. I could add another
target so that the lint property would look like
this:
lint: {
files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'],
src: ['src/**/*.js']
},
Now, to lint only the files in src, I run
grunt lint:src: I pass the target name after a colon.
If I run only grunt lint, both targets will be
run.
In the case of the concat and min
tasks, the targets are more complicated: they are objects with
source (src) and destination (dest)
properties. Of course, this tells Grunt where to get the files and
where to put them when it is done processing them, respectively. If
you add other files to your project, you’ll want to add them in the
right place to make sure they are concatenated and minified
correctly. So, if I added a src/utils.js file that my
jQuery plugin depended on, I’d change concat.dist.src
to this:
src: ['<banner:meta.banner>', 'src/utils.js', '<file_strip_banner:src/<%= pkg.name %>.js>'], </pre>
<p>Looking at some of these tasks more closely, you’ll notice a few other directives: the most important is probably the <code><config:SOMETHING></code> directive. This allows you to access the properties of other tasks for reuse. You’ll notice that the configuration for the <code>watch</code> task uses <code><config:lint.files></code>, so that it operates on the same list of files that we gave to the <code>lint</code> task. You can learn more about the other directives <a href='https://github.com/cowboy/grunt/blob/master/docs/helpers_directives.md'>in the Grunt docs</a>.</p>
<p>Speaking of the watch task, what exactly does it do? Very simple: it runs the tasks in the <code>tasks</code> property when a file in that list of files is changed. By default, the <code>lint</code> and <code>qunit</code> tasks are run.</p>
<h3><code>jshint</code></h3>
<p>This property simply configures what “bad parts” JSHint looks for in your JavaScript. The complete list of options can be found <a href='http://www.jshint.com/options/'>on the JSHint website’s options pages</a>.</p>
<hr />
<p>At the very bottom of our <code>grunt.js</code> file, you’ll see this line:</p>
1grunt.registerTask('default', 'lint qunit concat min');</pre>
<p>This is what creates our default task; you know, the one that runs when we run just <code>grunt</code>. It’s actually creating an alias task, and you can create as many alias tasks as you want:</p>
1grunt.registerTask('src', 'lint:src qunit:src concat:src min:src');
Assuming you created src targets for each of those
tasks, you can now call grunt src and do exactly what
you want.
While the tasks that come with Grunt will get your pretty far,
you can probably think of other things that you’d love to be able
to automate. Not to worry: Grunt comes with an API that allows
anyone to create Grunt tasks and plugins. While we won’t be
creating any Grunt tasks in this tutorial, if you’re interested in
doing so, you should start with the Grunt plugin template (run
grunt init:gruntplugin), and then read through the
API
docs. Once you’ve written your task, you can load it into a
project by adding this line inside your project’s
grunt.js file:
grunt.loadTasks(PATH_TO_TASKS_FOLDER);
Note that the parameter isn’t the path to the task file itself, it’s the path to the folder the task file is in.
However, other Grunt plugins are starting to appear, and some
are available on NPM. After you install them via npm
install, you’ll load them into your project with this
line:
grunt.loadNpmTasks(PLUGIN_NAME);
Of course, you’ll want to check the plugin documentation to see what you should add to your configuration object.
What Grunt plugins are available? Well, since Grunt is so new (less than an month old as I write this), there aren’t too many yet. I’ve found two:
grunt-css:
for linting and minifying CSSgrunt-jasmine-task:
for running Jasmine specsIf you’ve found others, I’d love to hear about them; post ‘em in the comments!
While Grunt is a very new project, it’s hardly incomplete; as we’ve seen, it comes with pretty much everything you’ll need to use it on a large project, and can be extended as much as you want.
I’m hoping Grunt will become a community standard, and that we’ll see lots of tasks, plugins, and init templates popping up in the near future. How do you feel about it?
Thanks to CSS3, we can create effects and animations without using JavaScript, which will facilitate the work of many designers.
But we must be careful to avoid abusing CSS3, not only because old browsers do not support all of its properties. In any case, we all see the potential of CSS3, and in this article we’ll discuss how to create an infinitely looping slider of images using only CSS3 animation.
To get a solid sense of the process from beginning to end, below is an outline of the article. Please note that this effect will only work properly in modern browsers that support the CSS3 properties being used.
Screenshot of the pure CSS3
cycling slideshow.
To follow this tutorial, having a basic understanding of CSS, especially CSS3 transitions and keyframe animation, is important. Using this simple concept, we will see how to make a functional image slider.
Normally when you change a CSS value, the change is instant. Now, thanks to the transition property, we can easily animate from the old to new state.
We can use four transition properties:
transition-property
Defines the name(s) of the CSS properties to which the transitions
should be applied.transition-duration
Defines the duration over which the transitions should occur.transition-timing-function
Determines how intermediate values of the transition are
calculated. The effects from the timing function are commonly
called easing functions.transition-delay
Defines when the transition starts.At the moment, CSS3 transitions are supported in Safari 3.2+, Chrome, Firefox 4+, Opera 10.5+ and IE 10. Because the technology is still relatively new, prefixes for browsers are required. So far, the syntax is exactly the same for each browser, with only a prefix change required. We will omit them in the snippets in this article, but please remember to include the prefixes in your code.
Let’s see how to apply a simple transition to a link:
a {
color: #000;
transition-property: color;
transition-duration: 0.7s;
transition-timing-function: ease-in;
transition-delay: 0.3s;
}
a:hover {
color: #fff;
}
When assigning an animation to an element, you can also use the shorthand:
a {
color: #000;
transition: color 0.7s ease-in 0.3s;
}
a:hover {
color: #fff;
}
The W3C has a list of all “Animatable Properties.”
CSS animation enables us to create animations without JavaScript by using a set of keyframes.
Unlike CSS transitions, keyframe animations are currently supported only in Webkit browsers and Firefox and soon in IE 10. Unsupported browsers will simply ignore your animation code.
The animation property has eight subproperties:
animation-delay
Defines when the animation starts.animation-direction
Sets the animation to play in reverse on alternate cycles.animation-duration
Defines the length of time an animation takes to complete one
cycle.animation-iteration-count
Defines the number of times an animation cycle should play before
stopping.animation-name
Specifies the name of the @keyframes rule.animation-play-state
Determines whether an animation is running or paused.animation-timing-function
Describes how an animation progresses over one cycle.animation-fill-mode
Specifies how a CSS animation should apply styles to its target
before and after executing.Let’s see how to apply a simple animation to a div.
/* This is the element we are applying the animation to. */
div {
animation-name: move;
animation-duration: 1s;
animation-timing-function: ease-in-out;
animation-delay: 0.5s;
animation-iteration-count: 2;
animation-direction: alternate;
-moz-animation-name: move;
-moz-animation-duration: 1s;
-moz-animation-timing-function: ease-in-out;
-moz-animation-delay: 0.5s;
-moz-animation-iteration-count: 2;
-moz-animation-direction: alternate;
-webkit-animation-name: move;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-delay: 0.5s;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
}
/* This is the animation code. */
@keyframes move {
from {
transform: translateX(0);
}
to {
transform: translateX(100px);
}
}
@-moz-keyframes move {
from {
-moz-transform: translateX(0);
}
to {
-moz-transform: translateX(100px);
}
}
@-webkit-keyframes move {
from {
-webkit-transform: translateX(0);
}
to {
-webkit-transform: translateX(100px);
}
}
But we can use the shorthand property to conveniently set all of the animation properties at once.
div {
animation: move 1s ease-in-out 0.5s 2 alternate;
-moz-animation: move 1s ease-in-out 0.5s 2 alternate;
-webkit-animation: move 1s ease-in-out 0.5s 2 alternate;
}
Each keyframe describes how an animated element should render at
a given point in the animation sequence. The
keyframes take a percentage value to specify time:
0% is the start of the animation, while
100% is the end. You can optionally add keyframes for
intermediate animations.
/* Animation from 0% to 100% */
@keyframes move {
0% { transform: translateX(0); }
100% { transform: translateX(100px); }
}
/* Animation with intermediate keyframes */
@keyframes move {
0% { transform: translateX(0); }
50% { transform: translateX(20px); }
100% { transform: translateX(100px); }
}
The W3C has a lot of useful and detailed information on “CSS3 Animations.”
Now that we know how transitions and animation work, let’s see how to create our slider using only CSS3. This sketch shows how the animation should work:
How the animation slider functions
As you can see, the slider will be a container inside of which the images will be displayed.
The animation is very simple: the image follow a predefined
path, animating the top property and changing the
z-index and opacity properties when the
image returns to its initial position.
Let’s dive right into the HTML markup to create the slider.
The HTML markup is very simple; it’s all organized and SEO-friendly. Let’s see the full code first and then figure out in detail how everything works.
<div class="container">
<div id="content-slider">
<div id="slider"> <!-- Slider container -->
<div id="mask"> <!-- Mask -->
<ul>
<li id="first" class="firstanimation"> <!-- ID for tooltip and class for animation -->
<a href="#"> <img src="images/img_1.jpg" alt="Cougar"/> </a>
<div class="tooltip"> <h1>Cougar</h1> </div>
</li>
<li id="second" class="secondanimation">
<a href="#"> <img src="images/img_2.jpg" alt="Lions"/> </a>
<div class="tooltip"> <h1>Lions</h1> </div>
</li>
<li id="third" class="thirdanimation">
<a href="#"> <img src="images/img_3.jpg" alt="Snowalker"/> </a>
<div class="tooltip"> <h1>Snowalker</h1> </div>
</li>
<li id="fourth" class="fourthanimation">
<a href="#"> <img src="images/img_4.jpg" alt="Howling"/> </a>
<div class="tooltip"> <h1>Howling</h1> </div>
</li>
<li id="fifth" class="fifthanimation">
<a href="#"> <img src="images/img_5.jpg" alt="Sunbathing"/> </a>
<div class="tooltip"> <h1>Sunbathing</h1> </div>
</li>
</ul>
</div> <!-- End Mask -->
<div class="progress-bar"></div> <!-- Progress Bar -->
</div> <!-- End Slider Container -->
</div>
</div>
div id="slider"
This is the main container of the slider. It does not have a
particular function, but we will need it to pause the
animation.div id="mask"
We will use this to hide everything that happens outside of the
slider. In addition to hiding the content, the mask allows us to
display the contents of the slider.li id="first" class="firstanimation"
Every list item has an ID and a class. The ID displays the tooltip,
and the class is tied to the animation that has to occur.div class="tooltip"
This simply displays the title of the image. You can modify it to
your needs; for example, by making it clickable and adding a short
description.div class="progress-bar"
This contains the function that shows the progress of the
animation.Now it’s time for the CSS file.
Let’s create the basic structure of the slider. It will have the same image size. The border property will be useful to create a frame around the image.
/* SLIDER STRUCTURE */
#slider {
background: #000;
border: 5px solid #eaeaea;
box-shadow: 1px 1px 5px rgba(0,0,0,0.7);
height: 320px;
width: 680px;
margin: 40px auto 0;
overflow: visible;
position: relative;
}
The mask class will hide all of the elements that
lie outside of the slider; its height must be equal to the height
of the slider.
/* HIDE ALL OUTSIDE OF THE SLIDER */
#mask {
overflow: hidden;
height: 320px;
}
Finally, to sort the list of images, we’ll have position:
absolute and top: -325px so that all of the
images are positioned outside of the slider.
/* IMAGE LIST */
#slider ul {
margin: 0;
padding: 0;
position: relative;
}
#slider li {
width: 680px; /* Width Image */
height: 320px; /* Height Image */
position: absolute;
top: -325px; /* Original Position - Outside of the Slider */
list-style: none;
}
With these few lines of code, we have created our slider. Now we just need to add the animation.
Image animation for the slider
Before we begin with the animation, we have to specify some parameters in order to get the right view of the animation.
As we know, the total duration of the animation will be 25 seconds, but we have to know how many keyframes equals 1 second.
So, let’s work out a series of operations that gives us the exact number of keyframes based on the images we have and the total duration of the animation. Here are the calculations:
With all of this math, we can now apply the CSS animation to the slider. We will be able to put the animation on infinite loop because each image will follow its own animation that activates once it comes up in the slider.
#slider li.firstanimation {
animation: cycle 25s linear infinite;
}
#slider li.secondanimation {
animation: cycletwo 25s linear infinite;
}
#slider li.thirdanimation {
animation: cyclethree 25s linear infinite;
}
#slider li.fourthanimation {
animation: cyclefour 25s linear infinite;
}
#slider li.fifthanimation {
animation: cyclefive 25s linear infinite;
}
Once the properties of the animation have been assigned, we need to use keyframes to set the animation in motion.
Following this principle, we can connect the animations to each other even though they are separate, which will give us an infinite loop.
I’ve added the opacity and z-index
properties to make the transition from one image to the next more
attractive.
As you can see in the code, the first animation has more keyframes than the rest. The reason for this is that when the gallery is started, the first image is positioned to make way for the second image; but when the last image has finished its animation, the first image has to have additional keyframes in order for the user not to see a break between animation cycles.
Here is all of the code for the animations:
/* ANIMATION */
@keyframes cycle {
0% { top: 0px; } /* When you start the slide, the first image is already visible */
4% { top: 0px; } /* Original Position */
16% { top: 0px; opacity:1; z-index:0; } /* From 4% to 16 % = for 3 seconds the image is visible */
20% { top: 325px; opacity: 0; z-index: 0; } /* From 16% to 20% = for 1 second exit image */
21% { top: -325px; opacity: 0; z-index: -1; } /* Return to Original Position */
92% { top: -325px; opacity: 0; z-index: 0; }
96% { top: -325px; opacity: 0; } /* From 96% to 100% = for 1 second enter image*/
100%{ top: 0px; opacity: 1; }
}
@keyframes cycletwo {
0% { top: -325px; opacity: 0; } /* Original Position */
16% { top: -325px; opacity: 0; }/* Starts moving after 16% to this position */
20% { top: 0px; opacity: 1; }
24% { top: 0px; opacity: 1; } /* From 20% to 24% = for 1 second enter image*/
36% { top: 0px; opacity: 1; z-index: 0; } /* From 24% to 36 % = for 3 seconds the image is visible */
40% { top: 325px; opacity: 0; z-index: 0; } /* From 36% to 40% = for 1 second exit image */
41% { top: -325px; opacity: 0; z-index: -1; } /* Return to Original Position */
100%{ top: -325px; opacity: 0; z-index: -1; }
}
@keyframes cyclethree {
0% { top: -325px; opacity: 0; }
36% { top: -325px; opacity: 0; }
40% { top: 0px; opacity: 1; }
44% { top: 0px; opacity: 1; }
56% { top: 0px; opacity: 1; }
60% { top: 325px; opacity: 0; z-index: 0; }
61% { top: -325px; opacity: 0; z-index: -1; }
100%{ top: -325px; opacity: 0; z-index: -1; }
}
@keyframes cyclefour {
0% { top: -325px; opacity: 0; }
56% { top: -325px; opacity: 0; }
60% { top: 0px; opacity: 1; }
64% { top: 0px; opacity: 1; }
76% { top: 0px; opacity: 1; z-index: 0; }
80% { top: 325px; opacity: 0; z-index: 0; }
81% { top: -325px; opacity: 0; z-index: -1; }
100%{ top: -325px; opacity: 0; z-index: -1; }
}
@keyframes cyclefive {
0% { top: -325px; opacity: 0; }
76% { top: -325px; opacity: 0; }
80% { top: 0px; opacity: 1; }
84% { top: 0px; opacity: 1; }
96% { top: 0px; opacity: 1; z-index: 0; }
100%{ top: 325px; opacity: 0; z-index: 0; }
}
Having created the animations, we have to add a progress bar to display the duration of each animation.
The progress bar for each animation
The process of animating the progress bar is the same as it was for the slider. First, we create the progress bar itself:
/* PROGRESS BAR */
.progress-bar {
position: relative;
top: -5px;
width: 680px;
height: 5px;
background: #000;
animation: fullexpand 25s ease-out infinite;
}
Don’t be afraid of the syntax here. It has the same function as
from to; you can see that the keyframes set the
appearance and disappearance of each image.
/* ANIMATION BAR */
@keyframes fullexpand {
/* In these keyframes, the progress-bar is stationary */
0%, 20%, 40%, 60%, 80%, 100% { width: 0%; opacity: 0; }
/* In these keyframes, the progress-bar starts to come alive */
4%, 24%, 44%, 64%, 84% { width: 0%; opacity: 0.3; }
/* In these keyframes, the progress-bar moves forward for 3 seconds */
16%, 36%, 56%, 76%, 96% { width: 100%; opacity: 0.7; }
/* In these keyframes, the progress-bar has finished his path */
17%, 37%, 57%, 77%, 97% { width: 100%; opacity: 0.3; }
/* In these keyframes, the progress-bar will disappear and then resume the cycle */
18%, 38%, 58%, 78%, 98% { width: 100%; opacity: 0; }
}
The slider is more or less complete, but let’s add a few details to make it more functional. We’ll insert tooltips for the image titles that will be visible on hover.
Simple tooltip
Here is the CSS for the tooltips:
#slider .tooltip {
background: rgba(0,0,0,0.7);
width: 300px;
height: 60px;
position: relative;
bottom: 75px;
left: -320px;
}
#slider .tooltip h1 {
color: #fff;
font-size: 24px;
font-weight: 300;
line-height: 60px;
padding: 0 0 0 10px;
}
Here we’ve made only the image titles visible, but you can do the same to custom text, links or whatever you like.
Animate the tooltip on hover
We have seen how to apply CSS3 transitions to elements; now let’s do it to the tooltips.
If you remember, we added an ID to each list
(first, second, etc.) to have only the
tooltip associated with an image appear on hover, rather than all
of the tooltips appear together.
#slider .tooltip {
…
transition: all 0.3s ease-in-out;
}
#slider li#first: hover .tooltip,
#slider li#second: hover .tooltip,
#slider li#third: hover .tooltip,
#slider li#fourth: hover .tooltip,
#slider li#fifth: hover .tooltip {
left: 0px;
}
Stop slider on mouse hover
To allow users to pause to read content or look at an image, we should stop the animation when they hover over an image. (We’ll also have to stop the animation of the progress bar.)
#slider: hover li,
#slider: hover .progress-bar {
animation-play-state: paused;
}
Finally, we’ve reached the end of the tutorial. The slider is now 100% complete!
Check out the demo. It works in Firefox 5+, Safari 4+ and Google Chrome, as well as the iPhone and iPad. You can also download the ZIP file.
Thanks to Massimo Righi for his images.
The effect is impressive, but admittedly, this slider is not very versatile. For instance, to add more images, you have to edit all of keyframes. CSS3 has great potential, but it does have limits, and sometimes JavaScript is preferable, depending on your target users.
This slider has some interesting features, such as pausing on hover and uniques link for the images, which allow users to interact with the slider. If you want full support among browsers, this is not possible, so JavaScript is recommended. Unfortunately, CSS3 animation has many limitations; its lack of flexibility in particular will prevent its widespread use for now. Hopefully this will spur you on to further study of CSS3.
Feel free to share your thoughts in the comments section below!
(al) (il)
© Alessio Atzeni for Smashing Magazine, 2012.
"QUANTUM SHOT" #767
Link - article by Avi Abrams
Wildly bizarre half-plant/half-animal creature - with a lovely
name "Eastern Emerald Elysia"
This beautiful leaf-shaped sea slug Elysia chlorotica lives in shallow pools along
Atlantic coast of North America, eats its favorite weeds with gusto
- one meal is enough for its lifetime! - and presents the ultimate
mystery: it blurs one of the most basic definitions between the
"animal" and the "plant" kingdoms:
Granted, it looks like a floating tree leaf in water, but closer
inspection reveals that it is obviously a snail, or rather a sea
slug... and yet it eats algae and is able to convert this
chloroplast meal to life energy by utilizing photosynthesis, just
like any other plant!
(images credit: PNAS,
via, Nicholas E. Curtis and Ray Martinez, via)
"It's not easy being green", but for this slug it turned out to be
highly efficient:
The ONLY natural example of genes flowing between living
kingdoms of "plants" and "animals"
Totally green? Check. Though the young slugs are still brown until
they eat their first "green" meal... after that, these slugs are
ready to make the pigment chlorophyll a all by themselves.
Shaped like a leaf? Check.
One thing about Elysia chlorotica, "a sea slug that has
stolen enough genes to become the first animal shown to make
chlorophyll like a plant" (via)... They don't just use chloroplasts from the
algae they eat - this phenomenon, though rare, is known as
kleptoplasty. What's more, they obviously sport particular
DNA genes that make them able to process and use these chloroplasts
in a consistent and sustainable way:
(images credit: Patrick Krug Cataloging
Diversity in the Sacoglossa LifeDesk)
"These slugs can be spotted in the east coast of the United States,
including the states of Massachusetts, Connecticut, New York, New
Jersey, Maryland, Florida (east Florida and west Florida) and Texas
- and as far north as Nova Scotia, Canada. This species is most
commonly found in salt marshes, tidal marshes, pools and shallow
creeks, at depths of 0 m to 0.5 m. Elysia chlorotica can grow up to
60mm in length".
What sorts of surprises can be found in a humble shallow pool?
Turns out, quite a lot! All this should serve as a good
encouragement to look closer into swamps and marshes (provided they
are not haunted by any mad scientist apparitions, or the feral
Hounds of the Baskervilles). Microscopic biodiversity all around
your footsteps can prove to be positively astonishing!
(images credit: Patrick Krug,
Discover Magazine)
Talk about true "slacker" of the animal kingdom!
Consider Elysia chlorotica: when it comes to consuming
chloroplasts, one slurping is enough! "It's the ultimate form of
solar power: eat a plant ONCE, become photosynthetic for the rest
of your life":
Watch the video here of its feeding off the algae (very
appetizing!).
"When it munches on its favorite food - intertidal algae Vaucheria
litorea - it holds the algal strand firmly in its mouth and, as
though it were a straw, sucks out the contents.
Once a young slug has slurped its first chloroplast algae meal, the
slug does not have to eat again for the rest of its life. All it
has to do is sunbathe" (source).
Elysia crispata also stores and converts chloroplasts inside
its tissues - here is a rare close up peek under the hood of this
"green machine":
(image credit: Patrick J.
Krug)
The more scientific description of this creature sounds impressive
enough - "a marine opisthobranch gastropod mollusc" - but its
"Elysium" monicker is more intriguing: could there be a connection
with Elysium Fields as a mythological concept of afterlife
in use in Ancient Greece, and maybe even Eleusinian Mysteries - highly psychedelic in nature
rites of briefly experiencing the state of "higher consciousness",
or rather just herbal drug-induced "high"... Certainly, the gene
magic that this slug demonstrates can seem as mysterious and
esoteric as Elysian Mysteries!
It's all in a family: one colorful character after
another!
Elysia chlorotica may be the only real fusion of a plant and an
animal out there, but it also belongs to fittingly flamboyant
family: it's a member of the clade
Sacoglossa in the family Placobranchidae, the so-called
"sap-sucking sea slugs", as they live by "sucking the sap" from
their favorite algae. The members of this clade may superficially
resemble nudibranch kind - but they are every bit as
bizarre-looking as their more well-known "nudi" cousins!
Here is a sample of astonishing sacoglossan's diversity:
(image credit: Patrick J.
Krug)
Elysia chlorotica is related to Elysia ornata, which
is truly "ornate" just as the name implies:
(image via)
Elysia crispata does not have a shell and, because of its
fanciful appearance, is also called "The Lettuce Sea Slug":
(image via)
(Elysia crispata, image credit: Jim
Chambers)
(image credit: Pol
Bosch)
(images credit: Ellen
Bulger, Jan Hartmann)
The inside of this slug is quite impressive: it looks as an
avant-garde painting and will not seem out of place inside any NYC
modern art gallery:
(image credit: Terence Zahner)
Here it is, tinged blue and all the more beautiful for it... (left
image). On the right is yet another related cutie - Cadinella
ornatissima, classified somewhere between nudibranch and
sacoglossa kinds:
(images credit: Guillem
Mas, 2)
Thuridilla lineolata from Bunaken Marine Park, Sulawesi
(shown left):
(image credit: Marli Wakeling,
Kathe R. Jensen)
More diversity: Cyerce shown left, and Olea
hansineensis from Friday Harbor Laboratories, San Juan Island,
Washington:
(images credit: Greg Rowse, Moorea
BioCode, Patrick Krug)
So... should humans also learn the trick and start
"vegetating"?
By now, after hearing about very "stressful" life this creature
lives - think about turning green, sunbathing, swimming in energy -
you may wonder if one day humans might not develop technology that
would turn us into extremely efficient photosynthesis machines?
According to Proceedings of the National Academy of Sciences
(via):
"Chloroplasts only contain enough DNA to encode about 10% of the
proteins needed to keep themselves running. The other necessary
genes are found in the algae's nuclear DNA. So the question has
always been, how do they continue to function in an animal cell
missing all of these proteins? It seems that the algal gene in E.
chlorotica's sex cells could be passed to the next generation.
Other animals are able to harness sunlight after eating plants, but
this is only because they acquire entire plant cells, which is very
different to transforming an animal cell into a solar-powered
plant-animal hybrid."
"It is unlikely humans could become photosynthetic in this way...
Our digestive tract just chews all that stuff up - the chloroplasts
and the DNA"
(original unknown)
CONTINUE TO "CARNIVOROUS PLANTS"! ->
ALSO
READ OUR "NATURE" CATEGORY ->
|
We’re in need of a kick-ass, talented author to help out on Nettuts+ on a regular basis, a Bieber fan preferably.
We’re not sticklers but we’d optimally like to see weekly and bi-weekly submissions from you. Do you have what it takes? This is a paid gig, so read on!
So, assuming you submit an article a week, and one Premium tut/screencast per month, you can expect to make between $1100 – $1400 each month.
We’ll need the following information from you:
Please email this information to net[at]tutsplus.com.
We get a ton of single line emails. Don’t be that person. Emails without the requisite information will be discarded.
If you can’t manage a weekly/bi-weekly schedule, get in touch either way. I’m sure we can work something out!
Get cracking, ladies and gents! Looking forward to hearing from all of you.
The Web font revolution that started around two years ago has brought up a topic that many of us had merrily ignored for many years: font rendering. The newfound freedom Web fonts are giving us brings along new challenges. Choosing and using a font is not merely a stylistic issue, and it’s worth having a look at how the technology comes into play.
While we cannot change which browser and OS our website visitors use, understanding why fonts look the way they do helps us make websites that are successful and comfortable to read in every scenario. Until recently, there were only a small handful of “Web safe” fonts we could use. While offering little variety (or means of expression), these fonts were very well-crafted and specifically adjusted—or even developed—for the screen, so there was little to worry about in terms of display quality.
Now that we have a great choice of fonts that can be used on websites, it becomes clear that the translation of a design into pixels is not something that happens naturally or consistently. OS makers apply different strategies to render how typefaces are displayed, and these have evolved greatly over time (and still continue to do so). As we now look closer at fonts on screen more than ever before, we realize that the rendering of these glyphs can differ significantly between systems and font formats. What’s more, it has become clear that even well-designed fonts may not look right on Windows if they are missing one crucial added ingredient: hinting.
This article presents the mechanisms of type rendering, how they were developed, and how and why they are applied by the various operating systems and browsers—so that when it comes time to choose a font for your next project, you know what to look out for to ensure the quality of the typography is consistently high.
Ideal shape, black-and-white and grayscale rendering
In digital type, characters are designed as abstract drawings. When a text is displayed on screen, this very precise, ideal shape needs to be expressed with a more or less coarse grid of pixels. As screens turned from mere preview devices for printing output into the actual medium we read in, more and more sophisticated rendering methods were developed in order to make type on the screen easy and pleasant to read.
The earliest method of expressing letter shapes was using black and white pixels, sometimes referred to as bi-level rendering. Printers are still based on this principle, and thanks to their high-resolution, the result is a very good representation of the design. On screen, however, the small number of available pixels does not transport the subtleties of the drawn shapes very well. And although we might not be able to see the individual pixels, the steps found in round contours are noticeable.
In the mid-1990′s, operating systems started employing a very smart idea. Although screens have a rather low resolution, they can control the brightness of each pixel. This allows more information to be brought into the rasterized image.
In grayscale rendering, a pixel that is on the border of the original shape becomes gray, its brightness depending on how much it is covered by the ideal black shape. As a result, the contour appears much smoother, and design details are represented. The type on screen is no longer merely about being legible—it has its own character and style.
This principle—also called antialiasing—is the same that is used when photos are resampled to a lower resolution. Our eyes and brain interpret the information contained within the gray pixels and translate it back into sharp contours, so what we perceive is fairly close to the original shape. A similar effect is at work when a relatively coarse newspaper image that can appear nicely shaded if we hold it far enough away (or similarly, in the art of Chuck Close). Recently, Gary Andrew Clarke took this to the extremes with his “Art Remixed” Series.
Apparently colored pixels increase the resolution.
The third generation of rendering technology is characterized by apparently colored pixels. If we take a screenshot and the edges appear red and blue when enlarged, then we know that we are looking at subpixel rendering.
On LCD screens, the red, green and blue subpixels that control the color and brightness of the pixel are located side-by-side. Since they are so small, we don’t perceive them as individual colored dots. Having a closer look at the “red” pixel marked by the white dot reveals the strategy: all subpixels are switched on or off individually, and if the rightmost subpixel of the “whitespace” happens to be a red one, then the corresponding full pixel is technically red.
Subpixel rendering on an LCD screen.
The benefits of this technique become clear if we desaturate the image. Compared to plain grayscale rendering, the resolution has tripled in horizontal direction. The position and the weight of vertical stems can be reflected even more precisely, and the text becomes crisper.
For the display of text, almost all browsers rely on system rasterizers. When looking at Web font rendering, the key distinction we have to make is the operating system. However, there are differences between the browsers in terms of the support given to kerning and ligatures, as well as the application of underline position and thickness, so we cannot expect perfectly identical rendering in all browsers (even on one platform). What’s more, on Windows, the browser can have the font rendered by either of the system technologies—GDI or DirectWrite.
Before we look at these in detail, lets first get an overview of where each one is to be used:
Rendering modes used by Windows browsers.
On Windows, the font format has a significant impact on the rendering. The crucial difference is between PostScript-based and TrueType-based fonts, and not the way these are brought into the browser—JavaScript vs. pure CSS, raw fonts vs. “real” Web fonts, etc. We will see identical rendering as long as the underlying font is the same.
File formats can give us a clue as to what underlying rendering technology is being used, although it’s best that one doesn’t completely rely on the naming conventions. For example, EOT and .ttf files will always contain TrueType, whereas .otf fonts are typically PostScript-based. But then there’s the wrapped format WOFF, which can contain either “flavor” of font format. So we don’t know which one it contains (and therefore, what kind of rendering may be used), just by looking at the file name. Unless you’re using EOT or .ttf files, and can be sure it’s a TrueType, more investigation when purchasing fonts is always recommended.
TrueType and PostScript fonts differ in the mathematics used to describe curves—something that rasterizers don’t care about too much—it only makes a difference for the type designer when editing the glyph shapes. What is more relevant is the different approach to hinting. PostScript fonts only contain abstract information on the location of various elements of each letter (and rely on a smart rasterizer to make sense of this), whereas TrueType fonts include very specific low-level instructions that directly control the rendering process. Curiously, however, the effective differences in rendering are not due to these differences in concept, but rather stem from Microsoft initially deciding to apply their new rendering engine only to TrueType fonts.
TrueType font rendering with Windows grayscale.
On Windows XP, text is rendered as grayscale by many browsers. Although not as crisp as the subpixel rendering used by Mac OS, the letters are nicely smoothed and look great in large sizes.
TrueType font rendering with Windows GDI ClearType.
ClearType is Microsoft’s take on subpixel rendering. It was first made available for GDI, the classic Windows API. Although available in Windows XP, it is not used by all browsers. In Windows 7 and Vista, ClearType is the default, which makes it the most widely used rendering technology (if we were to consider all internet users). However, it is important to note that this applies only to TrueType-based Web fonts—GDI-ClearType is not applied to PostScript-based fonts.
One curious property of this rendering technology is that along with adopting the advantages of subpixel rendering in horizontal direction, Microsoft gave up smoothing in vertical direction entirely. So ClearType is effectively a hybrid of subpixel and black-and-white rendering. This results in steps within the contour, which is particularly noticeable in large sizes. These jaggies at the top and bottom of the curves are unpleasant, but unavoidable—even the best hinting cannot make them disappear.
For type in large sizes, ClearType is a step backwards in rendering quality. The gains in horizontal precision are not significant, while the rough contours spoil the overall result.
TrueType font rendering with DirectWrite.
The future is bright, at least in terms of Windows font rendering. In DirectWrite (the successor of GDI), Microsoft added vertical smoothing to ClearType. This new rendering mode (so far used by Internet Explorer 9), gives us smooth and precise rendering in all sizes. The main difference to Mac OS that remains is that it still tries to align contours to full pixel heights, which leads to even better rendering given that the font is well-hinted. What’s more, DirectWrite allows for subpixel positioning, which gives the characters exactly the spacing that they have been designed with, improving the overall rhythm and evenness of the texture.
PostScript font rendering with GDI grayscale.
In GDI-based browsers, PostScript-based Web fonts are displayed in grayscale. Unlike the prevalent GDI-ClearType, this gives smooth contours. And unlike TrueType hints, PostScript hinting is easier to create, even automatically.
PostScript font rendering with DirectWrite.
DirectWrite not only gives smoother outlines, it also applies subpixel rendering to PostScript fonts. Unlike TrueType rendering, however, it allows for more gray pixels in order to reflect stroke weights more realistically. That makes it well-balanced, and similar to Mac OS rendering.
At some point in the future—browser makers and users will not switch as quickly as we wish—DirectWrite will succeed the older Windows rendering methods, and we will indeed be spoilt for choice between TrueType- and PostScript-based Web fonts.
Unhinted font rendered with grayscale.
In the old Windows grayscale mode, completely unhinted fonts look surprisingly good. Since the font does not “align itself” to full pixels via hinting, and the rasterizer does not enforce this either, we have a rendering that is similar to that of iOS. Unfortunately, unhinted fonts are currently not an option, as the next example shows:
Unhinted TrueType font in GDI-ClearType rendering.
As noted in many discussions on Web font rendering quality, GDI-ClearType is extremely dependent on good hinting. Horizontal strokes have to be precisely defined by means of hinting, otherwise they might be rendered in an inappropriate thickness. Even in larger sizes, hinting is crucial. Unhinted fonts will show “warts” sticking out where contours are not correctly aligned to the pixel grid, like in the example above.
Unhinted font rendered with DirectWrite.
In DirectWrite, unhinted PostScript and TrueType-based Web fonts show virtually the same rendering. Text fonts of either flavor will still need good hinting in order to keep the strokes crisp and consistent. Display fonts may even get away with sloppy or no hinting, since this does not show much in large sizes.
Font rendering in Mac OS X.
On Mac OS, all browsers use the Quartz rendering engine. TrueType and PostScript fonts are rendered in exactly the same way, since hinting—the biggest conceptual difference between the two formats—is ignored. The subpixel rendering on Mac OS is very robust, so this platform is typically the one we need to worry about the least. The rasterizer doesn’t try to understand the strokes and features that make up a font, as everything is represented by more or less dark pixels. Since the letter shapes are not interpreted, they cannot be misinterpreted. Quartz rendering is reliable because it doesn’t try to be smart. As a side note, Apple does seem to apply some subtle automagic to enhance the rendering, but this is entirely undocumented and beyond our control.
In some cases, however, this leads to less-than-ideal results. In the above example, the large size “T” has a fuzzy gray row of pixels on top because the theoretical height is not a full pixel value, and Mac OS does not force its alignment. Unfortunately this cannot be controlled by the font maker. However, the blurriness occurs only in certain type sizes. So typically, choosing a slightly different font size fixes the problem. With a bit of trial-and-error, one can find a type size that looks comfortable and crisp.
Another difficult-to-control phenomenon is that on the Mac, type tends to be rendered too heavy. This difference is most noticeable in text sizes, where the same font can look a bit “sticky” on Mac OS while appearing almost underweight on Windows.
Font rendering in iOS.
The rendering on iOS follows the same principles as on Mac OS—the main difference is that it currently does not employ subpixel rendering. The reason might be that when the device is rotated, the system would have to re-think and update the rendering because the subpixels are physically oriented in a different way, and the makers wanted to minimize CPU use.
Website visitors use a great variety of systems and browsers. Some are not up-to-date, and sometimes it’s not even the user’s fault, but rather a company’s policy to stick with a certain setup. My personal opinion is that we should try and give them the best rendering we can, instead of blaming OS makers, or demanding users to switch to better systems.
On Mac OS and iOS, we hardly have any control over the rendering, which is acceptable (since it’s generally very reliable). One problem is that fonts generally render too heavy. Maybe some day, Web font services can improve the consistency by serving slightly heavier or lighter fonts depending on the platform.
On Windows, hinting matters—especially for TrueType-based fonts (the only Web fonts Internet Explorer 6–8 will accept). Apart from that, one significant control we have over the rendering is the choice between TrueType and PostScript. Except for very well-hinted fonts in smaller sizes, the latter is equal or superior in rendering, and easier to produce. Even though DirectWrite is making Windows rendering more pleasant, it will not remove the necessity to provide well-hinted fonts.
Some Web font providers (such as Typekit or Just Another Foundry), have started serving display fonts in PostScript-based formats.
JAF Domus Titling in different rendering environments.
While the GDI ClearType jaggies are unavoidable for IE 6–8, all other scenarios produce nice, smooth results. This also means that we will still need fonts that have decent TT-hinting—the browser share of IE6–8 is still too big to deliver fonts that don’t at least render in a clean fashion.
Bello—by Underware on Typekit—served as PostScript-based Web
fonts (right), which gives smoother rendering than TrueType
(left).
Typekit has also started to implement a hybrid strategy by serving display fonts as PostScript in order to trigger smoother rendering in Windows GDI. This requires some decisions to be made on the basis of visual judgement.
“How do you define a display font?”, you may ask, and it is indeed difficult to draw the line. Some of the foundries offer high-quality, manually hinted TrueType fonts that look great in text sizes (and it would be a pity to lose this sophistication by converting them to PostScript). Some text fonts may well be used in very large sizes. So ideally, we would have to offer them in two different formats. However, increased complexity of the UI (as well as back-end handling) have so far kept us from doing this.
More and more type designers are becoming aware of the technical issues that arise when fonts are used on the Web, particularly TrueType hinting. As the Web font business grows, they are willing to put some effort into screen-optimizing their fonts. In the near future, we will hopefully see a number of well-crafted new releases (or at least updates to existing fonts).
With increasing display resolutions— and more importantly, improving rasterizers—we will slowly have to worry less about the technical aspects of font rendering. GDI-based browsers will certainly be the boat anchor in this respect, so we won’t be able to use TrueType fonts that aren’t carefully hinted for yet another few years. Once this portion of Web users has become small enough, the process of TrueType hinting (which is time-consuming and requires considerable technical skills), becomes less crucial. While most Web fonts currently on the market are TrueType-flavored, I am expecting that the industry will largely switch to PostScript, which is the native format nearly all type designers work in (the fonts that are easier to produce).
(jvb) (ac) (il)
Note: A big thank you to our fabulous Typography editor, Alexander Charchar, for preparing this article.
© Tim Ahrens for Smashing Magazine, 2012.
Vierityspalkki-blogi laajentaa historiallisesti toimintaansa myös verkkomaailman ulkopuolelle, ja järjestää lukijoilleen ilmaisen ajankohtaisseminaarin.
Otsikkona on “Mobiilisivustot vai responsiivinen design?“. Seminaari järjestetään reilun kahden tunnin mittaisena aamupalatilaisuutena perjantaina 4.5.2012 digitoimisto Deasignin tiloissa Helsingissä. Seminaari alkaa klo 8.30 aamupalalla. Ohjelma alkaa klo 9.00 ja päättyy klo 11.00.

Seminaarissa on neljä lyhyttä puheenvuoroa asiantuntijoilta, jotka ovat olleet eri puolilla mobiilisivustojen rakentamisprojekteja. Seminaarissa mobiilisivustojen toteutuksen haasteisiin ja ratkaisuihin otetaan neljä erilaista näkökulmaa.
Ensimmäistä näkökulmaa edustaa SC5-yrityksen Pyry Lehdonvirta. Pyry Lehdonvirran tausta on etenkin eri päätelaitteet tavoittavissa HTML5-ratkaisuissa. Pyry avaa seminaarissa responsiivisen suunnittelun käsitettä, ja kertoo myös miksi hänen mielestään julkaisujärjestelmien aikakausi on mobiilipalveluiden ja uusien web-standardien myötä historiaa.
Toisena puhujana lavalle nousee Sinisen Meteoriitin Lead Designer Tuukka Uskali. Tuukka katsoo maailmaa myös vahvasti responsiivisen suunnittelun näkökulmasta, mutta kertoo erityisesti siitä millaista on tehdä mobiilipalveluita SharePoint-julkaisujärjestelmän päälle. Tuukan näkökulmana on avata sitä mitkä asiat perinteisissä julkaisujärjestelmissä ovat kenties hieman ristiriitaisia mobiilipalveluiden toteutuksen näkökulmasta.
Kolmantena esiintymisvuoroon pääsevät vihdoin “julkaisujärjestelmämiehet”, joita seminaarissa edustaa EPiServerin Petri Isola. Petrin tavoitteena on tietysti todistaa kaksi edellistä puhujaa aivan tyhjänpuhujiksi, ja todistaa julkaisujärjestelmien mahtipontisuus myös mobiiliaikakauden myllerryksessä.
Viimeisen sanan seminaarissa saa kehityspäällikkö Kaisa Aalto HS.fi:n dev-tiimistä. Kaisa kertoo miten HS.fi on vastannut mobiilimyllerrykseen, ja mitä heillä on suunnitteilla jatkossa – ja tietysti Kaisa paljastaa, että kenen edellisten puhujien sanomaan Kaisa uskoo eniten.
Ohjelma: Mobiilisivustot vai responsiivinen design? -seminaari 4.5.2012
Seminaarin osallistujiksi toivotaan erityisesti asiakasorganisaatioiden edustajia, koska seminaarin ohjelma on suunniteltu nimenomaan auttamaan asiakkaita tekemään parempia päätöksiä mobiilikanavien toteutuksen suhteen.
Seminaari on ilmainen.
>> Ilmoittaudu seminaariin (seminaarissa on tilaa)
Vierityspalkki.fi-blogi järjestää vuoden 2012 aikana neljä ajankohtaisseminaaria. Seminaarien organisoinnista vastaavat Perttu Tolvanen (Projekti55 Oy) ja Karoliina Luoto (Sitra). Seminaarit ovat ilmaisia osallistujille. Seminaariaiheina ovat mm. mobiilisivustot, web-projektien ohjaaminen asiakkaiden näkökulmasta ja julkaisujärjestelmät Suomessa. Jos olet kiinnostunut puhumaan seminaarissa tai yrityksesi haluaisi sponsoroida seminaaripaikan, niin ota yhteyttä Perttuun (perttu (at) projekti55.fi).
| More |