Skip directly to content

Smashing Magazine

Subscribe to Smashing Magazine feed
For Professional Web Designers and Developers
Updated: 49 min 22 sec ago

You May Be Losing Users If Responsive Web Design Is Your Only Mobile Strategy

Tue, 07/22/2014 - 09:00

You resize the browser and a smile creeps over your face. You’re happy: You think you are now mobile-friendly, that you have achieved your goals for the website. Let me be a bit forward before getting into the discussion: You are losing users and probably money if responsive web design is your entire goal and your only solution for mobile. The good news is that you can do it right.

In this article, we’ll cover the relationship between the mobile web and responsive design, starting with how to apply responsive design intelligently, why performance is so important in mobile, why responsive design should not be your website’s goal, and ending with the performance issues of the technique to help us understand the problem.

Designers and developers have been oversimplifying the problem of mobile since 2000, and some people now think that responsive web design is the answer to all of our problems.

We need to understand that, beyond any other goal, a mobile web experience must be lightning fast. Delivering a fast, usable and compatible experience to all mobile devices has always been a challenge, and it’s no different when you are implementing a responsive technique. Embracing performance from the beginning is easier.

Responsive web design is great, but it’s not a silver bullet. If it’s your only weapon for mobile, then a performance problem might be hindering your conversion rate. Around 11% of the websites are responsive1, and the number is growing every month, so now is the time to talk about this.

According to Guy Podjarny’s research2, 72% of responsive websites deliver the same number of bytes regardless of screen size, even on slow mobile network connections. Not all users will wait for your website to load.

With just a basic understanding of the problem, we can minimize this loss.

Mobile Websites Are From the Past

I’m not saying that you should not design responsively or that you should go with an m.* subdomain. In fact, with social sharing everywhere now, assigning one URL per document, regardless of device, is smart. But this doesn’t mean that a single URL should always deliver the same document or that every device should download the same resources.

Let me quote Ethan Marcotte3, who coined the term “responsive web design”:

“Most importantly, responsive web design isn’t intended to serve as a replacement for mobile web sites.” — Ethan Marcotte

Responsive, Mobile And Fast

We can gain the benefits of responsive design without affecting performance on mobile if we use certain other techniques as well. Responsive web design was never meant to “solve” performance, which is why we can’t blame the technique itself. However, believing that it will solve all of your problems, as many seem to do, would be wrong.

Designing responsively is important because we need to deal with a range of viewport sizes across desktop and mobile. But thinking only of screen size underestimates mobile devices. While the line between desktop and mobile is getting blurrier, different possibilities are still open to us based on the device type. And we can’t decide on functionality using media queries yet.

Some commentators have called this “responsible responsive web design,” while others consider it responsive web design with a modern vision. Without getting into semantics, we do need to understand and be aware of the problem.

While there is no silver bullet and no solutions that can be applied to every type of document, we can use a couple of tricks to improve our existing responsive solutions and maximize performance:

  • Deliver each document to all devices with the same URL and the same content, but not necessarily with the same structure.
  • When starting from scratch, follow a mobile-first approach.
  • Test on real devices what happens when resources are loaded and when display: none is applied. Don’t rely on resizing your desktop browser.
  • Use optimization tools to measure and improve performance.
  • Deliver responsive images via JavaScript while we wait for a better solution from browser vendors (such as srcset).
  • Load only the JavaScript that you need for the current device with conditional loading, and probably after the onload event.
  • Inline the initial view of a document for mobile devices, or deliver above-the-fold content first.
  • Apply a smart responsive solution with one or more of these techniques: conditional loading, responsiveness according to group, and a server-side layer (such as an adaptive approach).
Conditional Loading

Don’t always rely on media queries in CSS because browsers will load and parse all of the selectors and styles for all devices (more on this later). This means that a mobile phone would download and parse the CSS for larger screens. And because CSS blocks rendering, you would be wasting precious milliseconds over a cellular connection.

Replace CSS media queries with a JavaScript matchMedia query on devices whose context you know will not change. For example, we know that an iPhone cannot convert to the size of an iPad dynamically, so we would just load the CSS for it that we really need.

We can also use feature detection, such as with Modernizr4, to make smarter decisions about the UI and functionality based not only on screen dimension.

Responsiveness According to Group

While we can rely on a single HTML base and responsive design for all screens when dealing with simple documents, delivering the same HTML to desktops and smartphones is not always the best solution. Why? Again, because of performance on mobile.

Even if we store the same document server-side, we can deliver differences to the client based on the device group. For example, we could deliver a big floating menu to screens 6 inches and bigger and a small hamburger menu to screens smaller than 6 inches. Within each group, we could use responsive techniques to adapt to different scenarios, such as switching between portrait and landscape mode or varying between iPhones (320 pixels wide), 5-inch Android devices (360 pixels) and phablets (400 pixels and up).

Server-Side Layer

The last optional part of a smarter responsive solution is the server. Server-side feature detection and decisions are not new to the mobile web. Libraries such as WURFL5 and Device Atlas6 have been on the market for years.

Mixing responsive design with server-side components is not new. Known sometimes as responsive design and server-side components7 (RESS) and sometimes as adaptive design, it improves responsive design in speed and usability, while keeping a single code base for everyone server-side.

Unfortunately, these techniques haven’t gained much traction in the community over the last few years. Just look at any blog or magazine for developers and compare mentions of “RESS” and “adaptive” to “responsive.” There’s a reason for that: We are front-end professionals. Anything that involves the server looks like a problem to us, and we don’t want that.

In some cases, the front-end designer will be in control of a script on the server; in other cases, a remote development team will manage it, and the designer won’t want to deal with the team every time they want to make a small change to the UI. I know the feeling.

That’s why it might be time to think of a new architecture layer in large projects, whereby a front-end engineer can make decisions server-side without affecting the back-end architecture. Node.js is an excellent candidate for this platform, being a server-side layer between the current enterprise back-end infrastructure and the front end.

In this new layer, the front-end engineer would be in charge of decisions based on the current context that would make the experience fast, responsive and usable on all the devices, without touching the back-end architecture.

Responsive Design, Performance And Technical Data

You might have some doubts by this point in the article. Let’s review some technical details to allay your concerns.

Responsive design usually entails delivering the same HTML document to all devices and using media queries to load different CSS and image files. You might have a slightly different idea of what it means, but that is usually how it is implemented.

You might also think that mobile networks today are fast enough to deliver a great experience. After all, 4G is fast, and devices are getting faster.

Well, let’s see some data before drawing conclusions.

Cellular Connections

4G networks are not available everywhere, and even if the whole world was on a 4G network today, the situation might not be what you expect. Less than 3% of mobile phones8 out there are on a 4G connection. Taking only the US, the number of 4G users has reached approximately 22%, and even those lucky users are not on 4G 40% of the time9.

We usually think of mobile network speeds in terms of bandwidth. With 3G, we get up to 5 Mbps; with 4G, we get up to 50 Mbps. But that’s not usually the most important factor in a mobile web browsing experience. While more bandwidth is useful for transferring big files (such as a YouTube video), it doesn’t add much value when you’re downloading a lot of small files and the latency is high and fixed. Latency is the round-trip time that the first byte of every package takes to get to a device after a request.

Cellular networks have more latency than other connections. While the latency on a DSL connection in a US home is between 20 and 45 milliseconds, on 3G it can be between 150 and 450 milliseconds, and on 4G between 100 and 180. In other words, latency is 5 to 10 times higher on a cellular connection than on a home network.

Other issues include the latency when there is a change in radio state, the dead time when a phone turns on the radio to get more data after having been asleep, the lower available memory on average devices and, of course, battery and CPU usage.

Responsive Design on Cellular Networks

Consider a real case. Keynote, a company that offers performance solutions, has published data on the website performance of top Super Bowl 2014 advertisers10. The data speaks for itself: On a wired or Wi-Fi connection, the loading times range from 1 to 10 seconds, while on a cellular connection, the loading times range from 5 to 60 seconds. Think about that: one full minute to load a website being advertised in the Super Bowl!

11Website performance of the top Super Bowl 2014 advertisers. View large version12)

The same report shows that 43% of those websites offer a mobile-specific version, with an average size of 862 KB; 50% deliver a responsive solution, with an average size of 3211 KB (nearly four times larger); and 7% offer only the desktop version to mobile devices. So, by default, responsive websites are larger than mobile-specific websites.

Of course, responsive design can look different, but, unfortunately, the average responsive website out there looks like these ones of Super Bowl advertisers.

Cloud-Based Browsers

If you still doubt that performance is a problem on the mobile web, consider that browser vendors are creating cloud-based browsers to help users — including the infamous Opera Mini, the Asia-based UC Browser (which commands 11% of the global market share, according to StatCounter13), Amazon Fire’s Silk and now Google Chrome (through a settings option).

These vendors compress every website and resource in the cloud, and then the browser downloads an optimized version to the mobile device. They do it because they know that performance matters a lot to the user’s happiness.

Underestimating the Mobile Web

The web community has always underestimated the importance of mobile browsers. I’m used to hearing people say that the mobile web today is just Safari for iOS and Chrome for Android and that, for responsive design, we need only care about viewports that are 320 pixels wide. It’s far more complex than that.

Today, more than 10 browsers have a market share over 1%. Even if you want to consider only the default browsers on iOS and Android, it’s not so simple. Roughly speaking14, 50% of mobile users browse the web on iOS, 38% on Android, 3% on Windows Phone, 5% with Opera Mini (on various operating systems) and 4% on other platforms.

On Android, 64% of users today browse with Android’s stock browser, which is not the same as Google Chrome and which exists in different versions. Moreover, some of Samsung’s latest Galaxy devices have a version of the Android browser with a customized engine.

In terms of viewport size, we are dealing today with pixel widths of 320, 360, 400 and 540 with Android smartphones alone. My suggestion, then, is never to underestimate the mobile web, and to learn its unique characteristics.

Above-the-Fold Content in 1 Second

On a mobile device, we can consider a website to be fast when content above the fold (i.e. the content that is visible without scrolling) is rendered in 1 second or less. I know, 1 second seems awfully fast — especially considering that at least half of that time is taken up by the cellular connection — but it has been proven to be possible. A 1-second response keeps users engaged with the content, thereby increasing the conversion rate and reducing abandonments.

To achieve a 1-second response time, above-the-fold content needs to be received in one round trip over the transmission control protocol (TCP) — remember that the average 3G connection has almost half a second of latency. Because of a TCP feature known as a “slow start,” that first response should be no more than about 14 KB in order to avoid a second package. This means that at least the HTML and CSS for the above-the-fold content should fit in a single 14 KB HTTP response. If we achieve that, then we’ll have achieved the perception of a 1-second loading time.

This rule is not written in stone and will vary based on your content. However, because content that appears above the fold will usually not be the same on a mobile screen as on a desktop screen, achieving this goal of 1 second with a responsive design is very difficult. It’s possible, but combining techniques makes it much easier.

One HTML for All

A typical responsive design delivers a single HTML document to all devices: televisions, desktops, tablets, smartphones and feature phones. It sounds great, but we live in a world that has cellular and other problems. Your responsive HTML might render correctly on mobile devices, but it’s not as fast as it should be, and that is affecting your conversion rate.

If a single display: none appears in any of your CSS, then your website is not as fast as it could be. On a website that has been designed from scratch to be semantic, then the responsive overload would be almost nil; on a website whose HTML includes 40 external scripts, jQuery plugins and fancy libraries, mostly for the benefit of big screens, then the responsive overload would be at the high end. When the same HTML is used, then the same external resources would be declared for all devices.

This isn’t to say that responsive design alone can’t be done, just that the website won’t be optimized by default. If you are sensitive to performance, then your responsive solution might look different than the usual.

Let’s review Starbucks’ website. Its home page is responsive and looks great in the three viewports we tested (see the screenshots below). But upon checking the internals, we see that all versions load the same 33 external JavaScript files and 6 CSS files. Does a mobile device with 3G latency deserve 39 external files just to get the view shown below?

15The Starbuck’s website in different states. (View large version16)

You might be thinking, “Hey, blame the implementation, not the technique17.” You’re right. This article is not against responsive web design. It’s against aiming for responsiveness in a way that leads to a weak implementation, and it’s against prioritizing responsiveness over performance, as we see with Starbucks. It looks great when you resize the browser, but that’s not all that is important. Performance also matters a lot to mobile users.

If your responsive website has performance problems, then the fault may lie with how you’ve framed the goal. If you have the budget for responsive design, then you must also have the budget for performance.

Loading Resources

Media queries are implemented in different ways, usually as one of the following:

  • a single CSS file with multiple @media declarations,
  • multiple CSS files linked to from the main page via media attributes.

In the first case, every device would load the CSS intended for all devices because there would be just one CSS group. Hundreds of selectors that will never be used are transferred and parsed by the browser anyway.

You might think that multiple external files are better because the browser would load the resources based on breakpoints. This is what we’re taught in tutorials in blogs, magazines, books and training courses.

<link rel="stylesheet" href="desktop.css" media="(min-width: 801px)"> <link rel="stylesheet" href="tablet.css" media="(min-width: 401px) and (max-width: 800px)"> <link rel="stylesheet" href="mobile.css" media="(max-width: 400px)">

Well, you’d be wrong. All browsers will load all external CSS, regardless of context. The screenshot below shows an iPhone downloading all of the CSS files excerpted above, even ones not intended for it.

18Browser will load all external CSS files, regardless of the context. (View large version19)

Why do browsers download all CSS files? Suppose you have one CSS file for portrait orientation and another for landscape. We wouldn’t want browsers to load CSS on the fly when the orientation changes, in case a couple of milliseconds go by without any CSS being used. We’d want the browser to preload both files. That’s what happens when you define media queries based on screen dimensions.

Can the dimensions of mobile browsers be changed? Mostly not yet, but vendors are preparing their mobile browsers to be resized like desktop browsers, which is why the browsers usually load all CSS declarations regardless of whether their width matches the media query.

While stretchable viewports don’t exist on mobile devices (yet), some viewports resize in certain situations:

  • when the orientation changes in certain browsers,
  • when the viewport declaration changes dynamically,
  • when offset content is added after onload,
  • when external mirroring is supported,
  • when more than one app is open at the same time on some Samsung Android devices (in multi-window mode).

Browsers that are optimized for these changes in context will preload all resources that they might need.

While browsers might be smarter about this in the near future, we’re left with a problem now: We are delivering more resources than are needed and, thus, penalizing mobile users for no reason.

The Real Problem: Responsive Design As A Goal

As Lyza Danger Gardner says in “What We Mean When We Say ‘Responsive’3120,” designers define “responsive” differently, which can lead to communication problems.

Let’s get to the root. The term first appeared in a 2010 post by Ethan Marcotte21, followed by a book with the same name. Ethan defines it as providing an optimal viewing experience across a wide range of devices using three techniques: fluid grids, flexible images and media queries.

Nothing is wrong with that definition. The problem is when we set it as the goal of a website without understanding the broader goals that we need to achieve.

When you set responsive design as a goal, it becomes easy to lose perspective. What is the real problem you are trying to solve? Is being responsive really a problem? Probably not. But do you understand “being responsive” to mean “being mobile-compatible”? If so, then you might be making some mistakes.

The ultimate goal for a website should be “happy users,” which will lead to more conversions, whatever a conversion might be, whether it’s getting a visitor to spread the word, providing information or making a sale. Users won’t be happy without a high-performing website.

The direct impact of performance on conversions, particular in mobile, has been proven many times. If this is the first time you are hearing about this, just check any of Steve Souders22’ expert books about optimizing web performance.

When you know your goals, you can decide which tools and techniques are best to achieve them. This is when you analyze where and how to use a responsive approach. You use responsive design — you don’t achieve it.

Responsive vs. Users

The New York Times redesigned its website23 a couple of months ago with the goal of keeping “you in mind.” Meanwhile, thousands of other big companies present their new responsive websites with pride.

The New York Times follows responsive design in different ways, but some people complained that it still uses a separate mobile version, instead of adapting the layout based on the same HTML. An article even came out titled “The Latest New York Times Web App Misses the Point of Responsive Design24.”

25The New York Times follows responsive design in different ways. (View large version26)

Who said that responsive web design means supporting all possible screen sizes with the same HTML? Sure, this is a common understanding, but that rule isn’t written anywhere. It’s just our need to simplify the problem that has led to it.

In recent months, companies have said things along the lines of, “We’ve applied a new responsive design, and now our mobile conversions have increased by 100%.” But did conversions increase because the website was made to be responsive, or are users realizing that the website is now responsive and so are happier and convert more?

People convert more because their experience on mobile devices is now better and faster than whatever solution was in place before (whether it was a crude mobile version or a crammed-in desktop layout). So, yes, responsiveness is better than nothing and better than an old mobile implementation. But a separate mobile website with the same design or even a smarter solution done with other techniques would achieve the same conversion rate or better.


“Your visitors don’t give a sh*t if your site is responsive,” — Brad Frost

Brad Frost27 is completely right. Users want something fast and easy to use. They don’t usually resize the browser, and they don’t even understand what “responsive” means.

It’s a bitter truth, and it doesn’t quite apply to all websites. But it’s better than thinking, “We can relax. Our website is responsive. We’ve taken care of mobile.” Sometimes, even when not relevant to the situation, saying that responsive design is “bad for performance28” can be good because it helps to spread the word on why performance is so important.

The New York Times is right: The goal is the user. It’s not a tool or a technique or even the designer’s happiness.

Further Resources

(al, ml)


The post You May Be Losing Users If Responsive Web Design Is Your Only Mobile Strategy appeared first on Smashing Magazine.

How Do You Design Interaction?

Mon, 07/21/2014 - 18:48

If you have to design an interface it’s almost obvious to think to begin the process by drawing. But is this the best way? I once casually started by writing an imagined human-computer conversation, and only afterwards I continued by drawing.

This changed my way of thinking and I never went back to drawing first. This article will explain the reasons behind my decision.

I have always been a huge admirer of the guys at Basecamp1. Some time ago, I was reading a tweet by Jason Zimdars, one of its designers:

Zimdar’s tweet2

“UI design starts with words.” He wasn’t joking. The comment got a lot of retweets, a lot of favorites. Everyone understood what he meant — except me.

Writing Conversations

When I’ve had to design an interface interaction component, I used to start by sketching possible solutions. (Product design is made up of many layers. See, for example, Jesse James Garrett’s layers3 (PDF) and Intercom’s4. Here, I’m referring to the interaction layer.)

5Intercom’s design layers (View large version6)

I used to start by using a pattern that I know or by copying other people’s solutions to the problem or to similar problems. Imagine that you have to design a website’s registration form. You could start by “stealing” other designers’ solutions. Or, if you feel confident, you could read the requirements and start to draw.

But I started by drawing.

I once had to design a shopping-cart process for an e-commerce website. I don’t know why, but at the time, before researching possible solutions, I imagined what I do when I go to pay at the supermarket. I wanted to reproduce a similar experience on the web, possibly improving it by exploiting the web’s digital capabilities. I wrote down what happens at a supermarket checkout counter:

Cashier: Hi, do you have a loyalty card?

Me: Yes, please. [I give it to her.]

Cashier: Thanks.

Me: Thank you.

Cashier: Do you need some bags?

Me: Yes, two please.

[And so on.]

I realized that imagining the conversation was much easier than drawing on a white canvas. I’m not sure, but I suppose that is true for most people: Conversation is an intrinsic part of human nature. We have evolved as a talking species.

Also, when I imagine a conversation, I draw from my real-life experience, which is good for design — less abstraction. If a user’s interaction with a computer resembled a real-life experience, then the interface would probably be considered easy to use, wouldn’t it?

Moreover, I pay a lot more attention to words and their meanings when I write than when I draw. The benefit is that when I get around to sketching, I will make fewer mistakes in the copy. Because copy is7 an extremely important8 part of any interface, this is a great side effect of writing out conversations.

A Real Example

While imagining a conversation is easy, imagining a variation of that conversation is also easy. Back to the supermarket example: I can easily imagine the cashier asking me whether I need bags before asking for my loyalty card. It’s easy to imagine the cashier asking me a different question. This may or may not change the sketch of the interface. It wouldn’t matter if it doesn’t change anything — what’s important is that I’ve taken it into consideration. The more variations I can think of, the more confident I will feel that I haven’t missed anything in the final design.

I usually go from product requirements to a list of use cases to a mockup (i.e. a low-fidelity sketch or a high-fidelity wireframe, depending on the situation), which becomes the base of the HTML prototype. Ideally, this process would be linear; in reality, it’s a loop, in which each step provides feedback for me to change something in previous steps.

9My design steps (View large version10)

Because writing enables me to see more variations, it improves the effectiveness of the loop between “use cases” and “sketch.”

Let’s see this in an example. The following conversation comes from an actual project, a web app called Mediaddress, a press office software. It’s an archive of journalists’ addresses. One of the requirements of the project was that people should be able to send emails to one or more recipients.

The use case I was considering was this: A user has mistakenly selected 5 people from a list of 100 and has forgotten to deselect them and instead would like to send an email to the entire list of 100.

Variation 1

Human: I’d like to send an email.

App: Just to the five you’ve selected or to all of them?

Human: All of them.

App: To write the email, would you prefer to use your email program or my editor?

11Flowchart of variation 1 (View large version12) 13Sketch of variation 1 (View large version14) Variation 2

Human: I’d like to send an email.

App: OK, I’ll send an email to the 5 you’ve selected. To write the email, would you prefer to use your email program or my editor?

Human: No, wait! I meant to send an email to all 100 of them, not just the 5 I’ve selected

App: OK, no problem, I’ll do that. To write the email, would you prefer to use your email program or my editor?

15Flowchart of variation 2 (View large version16) Sketch of variation 2

Based on the use case, I’ve written a conversation that can easily be translated into a flow and sketch. Then, I imagined a variation of the conversation, which produced a different flow and sketch. To understand which flow and sketch was better, I compared use cases.

I took the case of the user selecting 5 people from the list but wanting to email the entire list. Was this the most frequent case? I didn’t think so. Wouldn’t optimizing for a user who actually wants to email those 5 people make more sense?

Design consists of trade-offs. We have to always weight the costs and benefits of our options. But I don’t want to get into the details of how I decide which solution is best. I follow many criteria. My point is to show why a written conversation is a useful design tool.

I jump back and forth between written conversation and flowchart and sketch. But the guiding tool is the written conversation. I find it to be the easiest tool to imagine an interaction. The diagrams and sketches (or wireframes) come afterwards. They create order and help me to see the steps clearly. They are also a better tool to communicate with developers and other stakeholders.

To summarize my points:

  • Imagining a human-computer conversation and then sketching it is easier than drawing the interface directly.
  • Imagined conversations are drawn from real-life experience, while direct sketching is drawn more from remembered design.
  • Copy is fundamental to any interface, and writing first and sketching later enables you to concentrate on it at the right time.
  • Imagining different conversations is easier than imagining different sketches, which makes it easier to come up with more design options.
  • When I write, I am more creative (because I can imagine more variations), and I tend to copy other people’s solutions less.
What About Jason’s Meaning?

In the end, have I understood what Jason meant by his tweet? Why not ask him directly? I wrote an email asking for his opinion on the method that I’ve laid out. He was very kind to answer me:

So, I read through the article and I think you’ve pretty much figured out what I was trying to say with the tweet. Imagining a conversation between the user and the computer is a neat way to think of it. I do something slightly different in my own work. Instead of thinking about the computer at all, I try to imagine how Iwould explain the feature to a friend. This has the effect of being conversational, clear and helpful. I think it’s especially helpful to not think about computers because it’s so easy to fall into the patterns we’ve all seen before; “computer speak,” which is terse, leaves out words and sounds nothing like anything people actually say. I want my UI to read like I’d say it, and that means natural language and full sentences.

I’ll certainly rewrite many times in the form of sketches and continue to refine all the way through the process. It’s much better to trim and optimize the words than start with too few. That’s why I prefer this method to drawing. When you draw, you think too soon about the layout and the available space and what’s too long to fit on a button. Those are too many constraints to deal with at once. I find it better to get the words just right and then figure out the visual design.

Here’s a quick example. First the computer-speak version you might draw:

“Delete file”

[OK] [Cancel]

Now a version you might actually say:

“Are you sure you want to delete this file?”

[Yes, delete it permanently] or [No, I want to keep it]

That’s a little contrived, but you get the idea. I feel like the computer-speak version is an easy trap to fall in when you draw first. I could certainly whittle the second one down to that if space was extremely limited, but why not start with your best version and then consider any compromises?

Here are the lessons I’ve noted:

  • “I think it’s especially helpful to not think about computers because it’s so easy to fall into the patterns we’ve all seen before; ‘computer speak,’ which is terse, leaves out words and sounds nothing like anything people actually say.”
  • “That’s why I prefer this method to drawing. When you draw, you think too soon about the layout… I feel like the computer-speak version is an easy trap to fall in when you draw first.”
  • “It’s much better to trim and optimize the words than start with too few.”

I followed up with one more question, asking Jason how this method helps him to figure out flow, if it does. I wrote:

Let’s say you have a feature and you start to write. Does writing make you think about the flow or the feature, and because of that you change the flow or the feature? Or is the flow or the feature a separate thinking process? Maybe I would make myself more clear with an example. Imagine a bookmark app:

Me: Save this web address.

Computer: OK.

A second version:

Me: Save this web address.

Computer: Before I save it, do you want to change the title of the page? And do you want to add a short description of the contents of the page? And do you want to tag the page (so that it’s easy to retrieve it later)?

The second version changes the flow. Now, when I want to save a web address, a forms pops up. In the first version, I would just see confirmation feedback.

Here is Jason’s answer:

So, how the flow factors in depends on the situation. Many times features aren’t completely isolated. They fit into existing flows and screens — or at least start from there. So, I may have some idea of the flow already in mind. But I’m always open to improving that if the writing leads me in another direction. But even if it’s something completely new, I’ll start with writing because that helps me figure out the flow. If it takes a lot of steps to explain the flow to your friend, then maybe it needs to be broken up into similar literal steps in software. So, a typical writing sketch might include several blocks of copy as I figure out the flow. I think the important part of the exercise is figuring out how you might think of it in the real world, rather than simply thinking of it purely as a software problem. That leads to fresh insights.

These two emails seem to validate my method. They also give me new insight. Coming from a superior designer, the feedback fills me with joy. I thought I had an original idea, but maybe it was just a side effect of having carefully read what the smart guys at Basecamp have written17. I’m not joking either.

Further Resources

(cc, il, al, ml)


The post How Do You Design Interaction? appeared first on Smashing Magazine.

The Mystery Is Resolved: Chirpy Birds, Lost Numbers and Pretty Slow Wheels

Mon, 07/21/2014 - 14:20

Experiments and side projects are wonderful ways to challenge yourself and explore areas that you wouldn’t usually consider exploring. That’s what Smashing Mystery Riddles1 are for us: little experiments that challenge us to come up with something new, original and a bit crazy—every single time. The ideas are usually a synthesis of the things we discover, stumble upon or try out ourselves—and oh my, they take quite some time to get right.

The most recent riddle2 took quite a lot of time spent fiddling and getting right (and Guillaume, the designer, wasn’t that happy about all the changes that our tests required). The basic idea was simple: as usual, you have a series of animated GIFs containing clues. One animated GIF leads to another, and every animated GIF contains a key (or keys) that have to be discovered. Once you uncover all the keys, you construct a solution and send out a tweet containing that solution. Doesn’t sound too difficult, does it?

This is how it all started4 back in November 2013. The key was to change the file name in the URL bar to move between the levels.

Well, it shouldn’t be too easy, either. Obviously we didn’t want everybody to see all the GIFs right away, so finding keys was essential for moving from one level to the next. In the past, we prompted users to change filenames5, search for Twitter handles6, and construct words out of letters7. This time it was all about finding the right hashtags on Twitter. Once you search for just the right hashtag, you should discover a link to the next level; that is, a link to the next animated GIF.

But how did we make it work? Obviously we had a number of keys scattered across the animated GIFs, but we couldn’t just send out tweets with hints for the next level from the same Twitter account—it would be too easy to discover, right? So we needed to distribute the tweets and hashtags—the keys—among many accounts. We could have gone ahead and created a number of anonymous Twitter accounts (in fact, that’s what we did for the second riddle8—and it was damn difficult to find available ones!) but we needed specific Twitter handles for the riddle, and unfortunately most of them weren’t available (for example, 3flowers or 6numbers).

So what could we do? Well, here was an idea: if you have 25 keys to share, what about asking 25 friends and colleagues to each send out a tweet with the hashtag and a link to the next level? It’s quite unlikely that anybody would follow all of your friends at once and therby discover all the keys in their timeline right away. So, that’s exactly what we did. But of course we didn’t want the tweets to be sent out too late or too early, since we wanted to build up the momentum of the riddle. And you can probably see where it’s heading: we depended on 25 people sending a tweet at approximately the same time. And this is where things weren’t quite smooth. The riddle went live at 7pm CET and while most tweets were sent out in time, some weren’t. As a result, we had to pull out all the stops, send a few quick follow-ups and, in the end, relax the rules of the riddle since not all keys could be discovered right away.

To be honest, we kind of anticipated that this could happen. That’s why each level had a few more keys hidden than necessary, just to make sure that nobody got stuck on a level, not able to progress further despite doing everything right. Also, we had to be careful when choosing links leading to different levels, so we distributed a few different link shorteners as well—if you looked specifically for links, you wouldn’t be able to find all the critical keys.

But let’s take one step back first and go through the riddle step by step from the very beginning.

Level 1: It Might Get Windy In Whistler

As mentioned above, the partials of the final Twitter hashtag were distributed among the tweets from our friends and colleagues. But these tweets first had to be found using the hashtags retrieved from the animated GIFs. In fact, you had to pay attention to the file name, count objects in the animated GIF (for example, three chairs) and search for them on Twitter (#3chairs). Plus, a tip suggested to watch out for a hint in one of the frames in each GIF. You know what that meant: running diffs or checking the frames in Preview or Photoshop!

The first animated GIF of the riddle. The tip wasn’t too obvious: watch out for a hint in one of the frames of the GIF. Large view.10

So how do we start? Well, the first GIF doesn’t look too hard, does it? What have we got here? #1bicycle, #1sign, #1character, #1road, #2wheels, #2trees, #2poles… but it all doesn’t really bring us anywhere. There are two electricity lines and one road line! What about #3lines? No, still nothing!

Ah, wait a second! What about the file name? “It might get windy in Whistler”. Could that be a reference to the #1scarf? Not really. Or perhaps it refers to the area around the scarf? Indeed, the only things we haven’t checked are… those cheeky birds! There’s one bird on the cyclist’s shoulder; two chirping on the cables; two sleeping on the trees; three fluttering in and out; and—ah!—two more birds peeking out of the trees as the bicycle goes by. That makes for #10birds.

But wait a second, we were supposed to look out for hints in one of the frames. Hmm. Could it be that one frame in particular is special? If so, which one would it be? Maybe the number that we’re looking for? Bingo! Can you spot the “10″ on the left pillar? That must be our clue! Ten birds? #10birds it is!

“10″, the correct number of birds on the first animated GIF, is hidden on the pillars on the 10th frame of the GIF. To find it, you need either a very sharp eye, or a diff between two subsequent GIFs.

Once you search for #10birds on Twitter, you’ll discover a tweet12 from our editor Michel Bozgounov, sent out exactly at the time when the riddle was published:

“Trees are green, the sky is blue, #10birds enjoy the summer, and so should you. Find 2 hashtags on the next level.” This sounds like one of the riddle clues!

Initially we wanted to hide another bird behind the red road sign, or brand the bicycle as “BIRDIE”, but these “birds” would have been way too small and difficult to find. Maybe next time?

Alright, #10birds is the first hidden key. Now let’s move to the next level15 and find the two hashtags hidden in the next GIF!

Level 2: Choosing The Name For The Cat

We have to find two hidden hashtags now, so let’s see what we can find. If we read the file name, we know that the guy at the window is trying to come up with a name for the cat—the same cat driving the caged bird crazy.

The image file name reads “choosing-the-name-for-the-cat.gif”. Can you work out what name will be chosen in the end? It’s not easy! Large view.17

But, if you keep looking at it, isn’t something going on in the cage? Let’s focus on the cage and check it frame by frame. Following the same logic we applied on the previous level, let’s look through the first ten frames—there aren’t that many objects here, after all. Aha! The fourth frame of the GIF reveals a little “4″ sitting in the cage—sneaky!

The clue for the second level resides inside the cage on the fourth frame.

Apparently, then, we have to watch out for objects that appear in fours. #1chair, #1table, #1flower, #1cage, #1bird, #1cat, #3apples19—we can safely exclude all of them! There are a few devices on the table—and what’s hidden under the TV screen? A remote control? That would make… #5devices20! Not quite what we are looking for, but apparently that’s a key, too!

“A cage is not one of the #5devices, but a remote control certainly is! 2 hashtags on the next level — keep going!”

Great! That’s one of the keys. And talking about the TV screen: is it just a distracting wallpaper, or could it be a hint for what we’re looking for? That logo on the TV looks familiar. Isn’t it the Dharma Initiative logo from Lost? Well, if you remember that, you probably remember the Lost numbers234 8 15 16 23 42—that Desmond had to type into a machine to keep the island safe (or, to put it slightly differently, to save the world). Could it be that we’re looking for #6numbers? Bingo! Now you can start to feel pretty awesome ;-) That one was hidden fairly well!

“The #6numbers that were LOST are the ones that you’ve discovered. 2 hashtags on next level.”

Alright, but what about that “4″ that we’ve discovered? All those devices on the table look like they have stickers on them, or not actually stickers but browser logos. And there are four of them—Mozilla Firefox, Chrome, iOS Safari and Chrome Mobile—so doesn’t that make… #4browsers?

“Outside the window lies your inspiration, but it’s #4browsers where lies implementation. 2 hashtags on next level.”

Nailed it!28 But we still haven’t figured out the name of the cat, have we? It really isn’t easy. In fact, our conference organizer Cat received a few emails from people asking her about the cat’s name (that was a bit surprising, and quite clever) but—being the consummate professional she is—she told the truth and informed everyone that she didn’t know. But that was a neat little strategy to try.

Some readers were creative and came up with interesting names—one of them was the idea we abandoned because our testers didn’t come up with it in our tests: since one of the keys on the next level was #7apples, naming the cat Lion as a reference to OS X 10.7 would make perfect sense (heads up, ARothuis6329!). Good one, and definitely worth a little reward.

In fact, the cat’s name was supposed to be Browser and if you counted the number of browsers in the GIF correctly, the hidden key would be #5browsers30. But yes, yes, of course, we knew that it was pretty difficult to guess the name, so we decided not to be too strict about it and accepted #4browsers as well.

“So you thought that ‘Browser’ is a good name for the cat, too? Bonus point for #5browsers32. 2 hashtags on next level.”

Alright! The hidden keys on the second level were #5devices, #4browsers, #6numbers and potentially #5browsers. It was critical to find the first two keys since we knew that not everybody knows or has watched LOST (in fact, some members of our team weren’t very fond of the idea in the first place!).

Level 3: Never Miss The Big Picture

Again, two hashtags have to be discovered, and it doesn’t look like the number of objects is getting smaller from one riddle to the next.

“Never miss the big picture.” Could this be a reference to the TV screen or are we actually missing the big picture here? Large view.35

That mysterious character seems to be absorbed with browsing and at the same time enjoying the multiscreen experience watching TV.

The file name says “never miss the big picture”. Could it be a reference to the big TV screen? The football world championship is on, and there are a few fans waving Brazilian flags. Is that a clue or a yet another sneaky distraction? Well, we can find 22 fans on the screen, and since the TV is on, it’s safe to assume that the mysterious guy biting an apple is a fan, too. Are we looking for #23fans?

“There are more than #23fans watching the final, you know, but do you see anyone playing? Good catch though! #mystery”

Looks like it’s a dead-end. In fact, it doesn’t look like the twenty-third frame has any hidden hints. What about the other frames? Wait! Did you see that? Isn’t there something happening in the shadow under the desk? Let’s take a closer look!

“7″ is hidden in the seventh frame on the carpet under the desk. However, there are quite a few objects appearing seven times in the GIF. Have you found them all? ;-) Large view.38

Voilà! But what does it mean? “Never miss the big picture”? Let’s take a look at the picture on the right-hand side. It has two hills and six trees. But there’s another tree on the left-hand wall as well! Are we looking at #7trees?

A picture says more than a 1000 words, and #7trees are part of a story, too. 2hashtags on the next (final) level.

Yaaaay! Alright, so what about the second hidden hashtag? Now those apples look very suspicious, don’t they? We have three apples on the plate next to the TV screen; one apple is falling down from the tree on the left wall; one apple on the table; one apple in the hand. It makes for #6apples. Doesn’t look right. Ah, isn’t it a Mac? Duh. Alright, #7apples then? Makes sense! It’s like seven-o-rama!

“Some apples you can eat, others you can play with. #7apples were to be found. 2 hashtags on the next final level.”

But that can’t be it, right? Indeed! What else are we missing? Well, what else have we got? Two books next to the TV screen, ah, what are those paper items on the books? They look like tickets, don’t they? Yes, #2tickets was one of the clues!

Thinking about the file name again, it looks like we kind of missed the big picture… How ironic! Of course, we also have a window, and doesn’t the mysterious character browse between… windows? How many windows do we have? Six! Well, that would make it #7windows, right? Indeed!

“Some doors should always remain closed, yet #7windows can probably stay open. 2 hashtags in the next (final) level!”

So here we go, #7trees, #7apples, #2tickets or #7windows. It was critical to discover that final hashtag (which was the hardest) on this level, plus one of the other ones. OK, there is just one level ahead of us — so let’s get to it!

Level 4: Thank God It’s Friday!

Even more objects and two more hashtags! Well, thank God it’s the final level, and apparently it’s Friday, too! So let’s look closely at what we’ve got here. The mysterious character is reading a newspaper with animated ads; we have a sunny weather forecast on TV; the cat (Browser) is playing with a ball; but we also have a calendar on the wall and a car on the shelf. So what could they mean?

“Thank God it’s Friday!” Is this guy looking forward to something coming up next month?
Large view.45

Let’s check things one by one. The main animation appears to happen when the guy is reading the newspaper. We have “20% sale” on an ad in the newspaper, but it doesn’t look like #20sale is a clue. Bummer. What about #11lines of text in the newspaper? Still nothing. But when the car drives by and the guy pulls down the newspaper a little, we can see two flowers displayed in the picture with a tree! With a flower right next to the window it would make #3flowers, right?


Right! OK, that wasn’t too difficult. But what about the second hidden hashtag? Now, the cat looks suspicious—but we already tried #1cat on the previous levels, and it wasn’t helpful. There’s a Canadian maple leaf residing on a map, so are we looking for #2maps? Nope. Those sneaky distractions!

We also have berries right next to the map, and they look like… strawberries! In fact, we have exactly twenty strawberries in the cup, so perhaps we are looking for #20strawberries?


Okay, but it was worth the try! Now, let’s check the frames to see if we were looking for all the right things. Well, it doesn’t look like there is anything special hidden in the third frame, but the hint clearly stated to watch out for the file name and for the differences in the frames!

What’s left? Well, the only two missing parts are the calendar and the car in the right corner. But wait! Did you see that? A flash in the calendar?

As you move from level to level, the clues are getting smaller and smaller. That “8″ in the calendar, appearing on the eighth frame, is difficult to notice! In fact, it stands for the 8th of December 2014, which is a Monday.

Aha! So the clue is “8″. But what exactly does it mean? Are there really any objects in the picture that occur eight times? Or should we be looking for #8december2014 instead? The file name says “Thank God it’s Friday”, so perhaps we are looking for #5december2014. Oh! It all must be a part of the confusing plan! But hang on, let’s get back on track here.

The only other remaining thing is the car. In fact, there are three cars in the image, with five windows, four headlights and… eight wheels! So, is it all about #8wheels?


Alright! Now we’ve got to the bottom of this! The hidden hashtags on the final level are #3flowers, #5december2014 and #8wheels. The last one was the critical one and had to be discovered to pass the level.

Yes! Phew, now you solved the mystery, and as it turns out you really are awesome! The secret hashtag now can be constructed out of all the clues you’ve found and should be tweeted to @smashingmag. Now that was quite a journey, wasn’t it?

Secret Level: Cannot Stop Watching The Game

Not quite, warrior! You might have noticed four days marked on the calendar, and of course they aren’t marked by chance. These are the days when SmashingConf Whistler is going to take place! And if you count the number of days, you’ll end up with… #4days!

“These #4days will be the days you’ll never want to end. You’ve discovered a secret level: 1 hashtag to be found!”

It wasn’t necessary to discover this level, and it was quite difficult to find and crack, but if you did discover it, and found the right idea, you would have earned a reward as well.

While the mysterious character has already given up on the game, the cat is still watching. The score is 0–0. Is it your clue? Large view.53

For this level, it was perfectly fine to find something that would make sense: such as #1crazyperson running on the field or #0goals. In fact, Alejandro de Arriba figured it out54, and unfortunately the other hashtags were incorrect.

Alright! Now we are done. We kindly thank everybody who sacrificed the integrity of their Twitter accounts for sending out totally unrelated, weird, confusing and potentially annoying tweets from their thoroughly curated Twitter accounts. It’s much appreciated!

Mystery Solved! And The Winners Are…

As mentioned above, you didn’t have to discover all the secret hashtags, but we were looking specifically at the critical hashtags, so the winner of the riddle would need to get them right. If we bring all hashtags together, we’ll get something like this:



#10birds #4browsers #6numbers #7windows #7trees #3flowers #8wheels

Both formats would work. Some of you were quicker than others. While the previous riddles took approximately an hour to solve, this one was quite easy to crack. Since not all tweets were sent out in time, we had to relax the rules a little. The first correct hashtag was tweeted by @jaicab_55 20 minutes after we hit that shiny “Publish” button, with more and more tweets containing the right answer shortly after that. In fact, it turned out that our dear readers are absolutely smashing indeed: #10birds56, #6numbers57 and #7windows58.

The first place was earned by the person who was the quickest to solve the riddle. We allocated prizes to the other lucky winners randomly. The winners can select any prize of their choice (be it a bag, a Smashing Library account, printed books or anything else). And they all get the Smashing Cody Stress-Relief Ball59, too. All winners will be contacted shortly. The winners are:

Congratulations! And thanks to everyone who participated! We hope we didn’t waste too much of your productive work time (and didn’t cause too many headaches either).

Behind The Scenes .designer { float: right; padding: 0 0 1.5em 1.5em; width: 260px; }.max-width{ text-align: center;}.max-width img { max-width: 100% !important; }

Guillaume Kurdjian7372 is a 22-year-old freelance illustrator and animator from Nantes, France. Guillaume likes to experiment with stuff on his computer and climb trees.

Just like in all the previous riddles, we worked with talented Guillaume Kurdjian7372 on a series of animated GIFs74 for the riddle. This time the discussion thread wasn’t very long, but we had quite a number of conversations of how to find digits properly, and how many objects would have to be hidden in the GIFs. This time we ended up with 25 different GIFs, drafts, and ideas that were thrown away, as well as the ones that made it to the final stage.

As usual, all designs were a series of iterations to make the overall riddle not necessarily perfect, but just right. So a big “thank you!” to Guillaume for following through and being so enthusiastic and kind about all the changes made.

Are we waiting for the next round already?

So this is it! It was quite a journey, but we hope it was worth it. We are really sorry about all the unproductive hours that you spent solving the riddle. Well, kind of. Now, are you ready for the next round? ;-) Stay tuned!76

.max-width { max-width: 100%; margin-top: 1em; margin-bottom: 1em; }.rounded { border-radius: 8px;}.designer img { border-radius: 8px;} Footnotes

The post The Mystery Is Resolved: Chirpy Birds, Lost Numbers and Pretty Slow Wheels appeared first on Smashing Magazine.

Useful Adobe Fireworks Resources: Extensions (Part 1)

Fri, 07/18/2014 - 09:10

Fireworks is an excellent UI design tool; however, Adobe decided to feature-freeze1 it back in 2013 and (at the same time) did not offer any replacement tool to its users. Nevertheless, since Fireworks runs fine today on the latest Mac OS X and Windows OS, and since it still offers a solid UI-design feature set, many designers continue to use it and rely on it daily.

For those of you who are searching for a similar tool, Sketch 3.02 seems to be a pretty good alternative to Fireworks, but it’s still not quite there yet; it’s Mac-only, and while its vector tools are very good and it now has artboards, pages, symbols and styles, it lacks a few of the basic features available in Fireworks. (I’ll talk more about possible alternatives to Fireworks in Part 2 of this series.)

So while we’re looking for alternatives, many of us also have to continue to use Fireworks3, and, as every designer out there knows, Fireworks works best with extensions! This article features some of the most useful (and free) Fireworks extensions that will help you work faster and be more effective with Fireworks; I have tested many of them myself, to be sure that they work flawlessly. In an upcoming article, I’ll be covering many articles and tutorials which I highly recommend that involve UI design and Fireworks, as well as a few freebies, such as editable Fireworks PNG files, templates, styles, Fireworks resource libraries, and so on.

To make the content of Part 1 better organized (and for easier navigation), I have grouped the extensions (commands, command panels and auto shapes) into the following main sections:

John Dunning’s Extensions Lorem Ipsum1410 Auto Shape

Fireworks is a very good UI prototyping tool (we’ve covered this topic in previous articles such as “Developing a Design Workflow in Adobe Fireworks11,” “Interactive Prototypes and Time-Savers With Adobe Fireworks12” and “iOS Prototyping With TAP and Adobe Fireworks13”). Without a doubt, another very important part of the prototyping process is working with text.

When working with prototypes, placeholder text is often used. There are many ways in which you can add some placeholder text to your Fireworks PNG files, but the problem starts when you need to adjust the amount of text (perhaps the layout has changed, or the font size was increased so the text is now too long). This is when the Lorem Ipsum1410 auto shape (created by John Dunning676459524844393530252015) can help you.

Whenever you create a new placeholder text block, the auto shape will add just the right amount of text that will fit the shape you’ve created — no more tedious copying and pasting (or deleting) text to fit the space! Resizing the auto shape (using one of the yellow control handles) or changing the font size will also automatically adjust the amount of text, so you will always have exactly as much text as you need. This auto shape has many basic and advanced settings and could save you some serious amount of time.

The advanced options of the Lorem Ipsum auto shape. (Source16)

(Note: We have covered the use of the Lorem Ipsum auto shape in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 3),” section “Lorem Ipsum17“.)

Smart Resize1918 Auto Shape

Working with UI prototypes… again? Smart Resize1918 (by John Dunning676459524844393530252015) is a really smart auto shape that could be a real time saver during your next project! Basically, this auto shape helps you resize a group of elements without distorting any of them or disrupting your layout.

Let’s suppose you need to “smart resize” a group of objects. Select this group and use menu Commands ? Smart Resize ? Attach; the command will convert your group into a special smart object with the typical yellow resize handles. You can then use these handles to resize the group in any direction, and Smart Resize will resize only elements that extend across more than 50% of the group’s size, and retain the rest of the elements in position relative to the closest edge of the group.

For extra control over how elements in your Smart Resize group scale or are being repositioned, you can set anchor points for each individual object (for example, elements that have their X anchor set to the left will only scale on the right side; the left edge will stay fixed in proportion with the rest of the group).

The Smart Resize auto shape in action. (Source112111105104553121)

(Note: We have covered the use of Smart Resize auto shape in “Optimizing The Design Workflow With Fireworks Extensions (Part 1),” section “Smart Resize22“.)

Multi-Border Rectangle2423 Auto Shape

CSS allows a different width and color to be applied to the border on each side of an HTML element, but Fireworks’ vector rectangles are limited to a single border color and border width. The Multi-Border Rectangle2423 auto shape (by John Dunning676459524844393530252015) addresses this limitation, making it easy to mock up CSS-style borders right on the canvas in Fireworks!

The Multi-Border Rectangle auto shapes makes it easy to mock up HTML-style borders. Here’s a quick example: select the auto-shape (1), drag the blue control point on a specific border (2), and the border’s width will be changed without affecting the other borders (3).

Of course, you are not limited to the width of the borders only — you can also change the color of each border separately. To do so, click the crosshair icon next to a border to open its color picker. You can also change the background color of the Multi-Border auto shape, by clicking on the the upper crosshair icon in the middle of the rectangle. And if you need even more control, you can change the border widths and colors numerically, by using the Multi-Border auto shape’s Properties dialog box.

The Multi-Border Rectangle: control points explained. (See large preview27) Tables Panel2928 Extension

Tables Panel2928 (by John Dunning676459524844393530252015) enables you to quickly mock up HTML-style tables without having to laboriously position each cell or border. Although it’s relatively straightforward to arrange elements in a grid using the alignment and distribution commands in Fireworks, as soon as the table contents change you’ll need to reposition everything manually. The Tables panel automates this tedious process.

Using the Tables Panel, you can easily build and modify tables in Fireworks. (Source112111105104553121)

The Tables Panel is pretty flexible and has many options; with it, you can even insert a table from a text file (tab-delimited or comma-separated text file — *.txt, or *.csv). You can also import a table from a web page (you’ll just need to convert it to tab-delimited or comma-separated text file — *.txt, or *.csv, before importing it).

(Note: We have covered the use of the Tables Panel extension in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 1),” section “Tables Panel32“.)

Keyboard Resize3433 Commands

Keyboard Resize3433 are a set of 16 commands (by John Dunning676459524844393530252015) which are very useful when you need to quickly “smart resize” objects.

For example, you created a button with a text label. Now when you need to increase the width of the button by a few pixels on the right, you would typically select the rectangle and either stretch it to the right using the Scale tool or change its width using the the Properties panel. Then, you will need to also select the text inside the button and repeat the same action, because selecting both and scaling them would have distorted the text and messed up the margins on the side.

With the help of one of the commands in this set, you can simply select both elements, press Alt + right arrow a few times and now your button is wider, and so is the text block; text is not distorted, and the margins between the text block and the button are intact. This is precisely what the Keyboard Resize commands by John Dunning do (and much more)!

Smart Resize commands allow for quick and easy resizing of multiple elements, without any distortion. (Source36)
Linked Images3837 Extension

When you import an image into a Fireworks document, Fireworks doesn’t maintain any link between the source file and the imported element — if the source file changes, you’ll need to find it, re-import it and then delete the previous image in the document. (Other Adobe products in the Creative Suite support the “smart objects” feature, which lets you import objects from one app into another, and when the source object changes, the imported one updates as well.)

The Linked Images3837 extension (by John Dunning676459524844393530252015) makes this process much easier. Let’s say you are working on a website design, and the client hasn’t finalized the logo yet. Open the Linked Images panel, click the “Insert” button to select the current version of the logo (it can be in any image format, supported by Fireworks), and place it in the layout. Later, when the logo has been updated, simply select the imported image and run the “Refresh” command in the panel to reimport the latest version of the source file.

The Linked Images panel. (Source787740)

The Linked Images panel has many options and supports all image file formats that Fireworks can currently open, including Fireworks editable PNG (*.fw.png), Photoshop PSD (*.psd), Illustrator AI (*.ai), EPS (*.eps), and all standard “flat” image formats, such as PNG8/24/32, JPEG, GIF, BMP and TIFF.

(Note: We have covered the use of the Linked Images extension in “Optimizing The Design Workflow With Fireworks Extensions (Part 2),” section “Linked Images41“.)

Fill With Background4342 Extension

Fill With Background4342 (by John Dunning676459524844393530252015) can save you quite a bit of time, when you’re working with screen mockups. Usually, when creating mockups, you may need to take a screenshot of an existing dialog box or web page and then modify it. You’ll probably also have to paint over existing elements in the screenshot (like a button label, for example, to replace it with new text). So you select a portion of the background pixels in the screenshot, copy them, paste them, stretch them over the element you want to replace, and then flatten the pixels with the original image; it’s quite a tedious process. The Fill With Background command does all of this in just one step!

Fill With Background command (example A): Select the areas of the bitmap that you’d like to fill with background pixels (1), run the Fill With Background command [menu Commands → Objects → Fill With Background] (2), and the selection will be automatically filled with a column of pixels copied from just to the left of the selected area (3).
Fill With Background command (example B): Select the areas of the bitmap that you’d like to fill with background pixels and run the Fill With Background command (1); the selection will be filled from left to right — which doesn’t work for a vertical gradient — so leave the selection and simply run the command again (2); the command will then switch to filling the selection from bottom to top (3).

There are a few different ways of using the command, and generally it works very well for background patterns that repeat either horizontally or vertically.

Create Symbol From States4745 Command

Rich symbols are a powerful feature of Fireworks46, but creating them can be quite a complicated process. The Create Symbol From States4745 command (by John Dunning676459524844393530252015) lets you create basic rich symbols containing multiple states in just one step and with no scripting required! The symbols created by this command can switch between displaying different states, controlled by a State menu in the Symbol Properties panel.

An example: When a symbol instance is selected, the Symbol Properties panel will display a single State menu control; you can change this menu to choose which state of the symbol to display. (Source49) Insert Grids5150 Command

The Insert Grids5150 command (by John Dunning676459524844393530252015) lets you set up a grid for your design in no time; simply set all the parameters — the column width, gutter width, number of columns — and the command then will create a locked layer with the columns, rows and guides spanning the height of your canvas. You can even create “Grid presets” for the layouts that you use most often and later re-use them with a single click of the mouse!

Insert Grids example: A setup for a 12-column grid. (See large preview54) (Source112111105104553121)

(Note: We have covered the use of Insert Grids command in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 1),” section “Grids56“.)

Generate Web Assets5857 Extension

No matter how optimized your workflow is, generating assets for the development phase after finishing up your design composites is always a slow task — who likes the process of taking each individual design element and exporting it in the right image format, later to be integrated in a website, application or whatever else you are building?

The Generate Web Assets5857 command (by John Dunning676459524844393530252015) can make this whole process much, much easier and simpler: once you are done with a design (or even while working on it), change the names of the objects that you want to export to the file names you want for them (including the file extensions), then run the Generate Web Assets command (menu Commands → Export → Generate Web Assets), define a folder, and presto! all of your assets will magically appear in this folder, with correct file names and in the correct formats.

Generate Web Assets process. (Source60)

(Note: We have covered the use of Generate Web Assets command in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 3),” section “Generate Web Assets61“.)

TweetFire6362 Extension

TweetFire6362 extension (by John Dunning676459524844393530252015) is a cool gadget for all Fireworks + Twitter fans out there. It lets you tweet the image you are currently working on in a few seconds without ever leaving the Fireworks canvas!

TweetFire is very easy to set up. Install the extension and authorize it with Twitter (1), then post your first Fireworks tweet (2); once the tweet is successfully posted, TweetFire will show you a “Success!” message (3). You can even use multiple Twitter accounts.

TweetFire is very easy to use and the authorization step is done only once, when you add a new Twitter account to the TweetFire panel. After that, posting your current image you’re working on in Fireworks (be it a complex vector illustration or a UI design or simply a photo which you have retouched a bit) is only a click away. You can also decide if you’d like to post the full image or the current selection.

FlickrFire6665 Extension

FlickrFire6665 (by John Dunning676459524844393530252015) is very similar to TweetFire and (as its name suggests) lets you upload the image you are working on directly to your Flickr account without leaving Fireworks. It has many options — you can set the title of the photo, the description, the tags, if the photo should be public or private, etc. — and again, the authorization process with Flickr is only one step.

Personally, I have tried both TweetFire and FlickrFire and found them very easy and fun to use!

Posting an image with FlickrFire. (See large preview69) Aaron Beall’s Extensions Export70 Commands

Export Commands71 (by Aaron Beall7672) is a set of commands that allows you to export pages and states to files at the same time, export slices as a single image (or each slice as a separate image), export all styles in one document as CSS styles, and export a selection (or a whole Fireworks PNG file) to SVG file format. (In my opinion, the “Export to SVG” feature is the most important one in this set.)

Export Commands.

(Note: We have covered Export Commands in detail — and specifically, the “Export to SVG” feature — in the article “Optimizing The Design Workflow With Fireworks Extensions (Part 3),” section “Export Commands73“.)

Path7574 Commands

The Path7574 set of commands (by Aaron Beall7672) is a very helpful set if you create a lot of vector artwork in Fireworks — which icon designers and illustrators certainly do. There are more than ten commands in this set, among them: Blend Paths, Convert Strokes to Fills, Deform to Path, Distribute To Points, Divide Paths, Exclude Paths, Fisheye Effect, and a few others.

Deform to Path — with this command, you can arc the bottom of a shape outward or inward as much as you need, or deform a shape based on a selected path:

Deform to Path command. (Source787740)

Convert Stroke to Fill — this command that will be very useful if you do a lot of illustration work in Fireworks and need to treat outlines as filled objects. Convert Stroke to Fill also allows you to simulate gradients on a stroke (similar to how it is done in Illustrator)!

Convert Stroke to Fill command: select an object with a stroke (left), run the command, and the stroke on the object will be converted to an object with a fill (center). You can then apply a gradient to the new object (right). (Source787740)

(Note: We have covered the use of some of the Path commands in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 2),” section “Path Commands79“.)

Matt Stow’s Extensions Copy Color To Clipboard8280 Commands

Fireworks CS5.1 and older versions support all types of screen color spaces81, incl. RGB/RGBA, HSL and HSV. However, when you need to quickly access and copy a specific color value, it’s easy to do so only for RGB colors in #HEX format. Copy Color To Clipboard8280 (by Matt Stow9083) amends that issue and allows you to copy easily the color value of any object in #HEX or rgb()/rgba() format, with a couple of clicks of the mouse or with easily customizable shortcuts.

In Fireworks CS6, it’s easy to copy color values to clipboard, in either #HEX or rgba() format. (See large preview85)

In case you didn’t yet upgrade to Fireworks CS6 (where the option to copy color values with one click was added to the new Color Selection box), this extension could be a nice little helper in your daily design tasks!

You can copy the color values in #HEX or rgb()/rgba() format; the color value can be copied from the color picker, or directly from the fill or stroke of any selected vector object. You can also assign shortcuts to the Copy Color commands, which will make working with them faster.

Copy Color commands: You can easily copy any color in either #HEX or rgba() format (toggled via preference). (See large preview87) CSS Professionalzr8988 Extension

CSS Professionalzr8988 (by Matt Stow9083) is a great extension that complements the CSS panel in Fireworks CS691. If you’re using the CSS panel in Fireworks, you should also get CSS Professionalzr!

CSS Professionalzr. Other Extension Developers Orange Commands9392 Set

Orange Commands9392 (by Ale Muñoz94) is a collection of commands for Adobe Fireworks that can make the life of a web designer easier. They are completely free and open source95, and are regularly updated. From aligning objects, to setting guides around selected objects, to combining two text objects into one — Orange Commands are a collection of small tasks that you would typically perform through a series of steps.

Orange Commands for Fireworks.

The latest version of Orange Commands is 1.7.2 and is available for Fireworks CS3, CS4, CS5/CS5.1 and CS6.

(Note: We have covered the use of Orange Commands in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 1),” section “Orange Commands96“.)

Texture Panel97 Extension

Currently in Fireworks, you can apply textures (which are pulled from your “Textures” folder) to any vector shape on the canvas. However, the way Fireworks works with textures isn’t very intuitive: you are presented with a simple list with all your textures, and when you mouse over a texture name, a small preview of that texture pops up next to it; but there is no easy way to get to your most commonly textures nor organizing them into groups.

Selecting and applying textures in Fireworks, using the Properties panel.

Here the Texture Panel98 extension (by Matt Curtis) comes to the rescue! This panel:

  • Sorts textures into lists (groups them),
  • Displays the textures as thumbnails (plus, you can change the size of the thumbnails),
  • Allows you to add your own textures easily and refresh the current list, and
  • Allows you to search for a specific texture, using the built-in search option!

You can get the Texture Panel from Sourceforge99 and read all the details about its use in our article (written by the author of the panel himself), “Using The Texture Panel In Adobe Fireworks100“. If you work a lot with textures in Fireworks, this panel is an absolute must-have!

Using the Texture Panel in Fireworks, you can easily organize and use your textures, and more. (Source101) Guides Panel103102 Extension

One extension which can help you immensely in the task of managing guides, is the Guides Panel103102 (by Eugene Jude), which allows you to add guides to the canvas with precise numerical control.

The Guides panel: “General” tab. (Source112111105104553121)

The panel also gives you the ability to work with selected objects — for example, if you need to place guides through the center of a selected object or around its edges (so you can align objects to it), you can simply select the object and create the guides with the help of the panel.

The Guides Panel: An example of adding guides through the center of a selected object (“Selection” tab). (Source112111105104553121)

(Note: We have covered the use of the Guides Panel extension in detail in “Optimizing The Design Workflow With Fireworks Extensions (Part 1),” section “Guides106“.)

Gradient Panel & Gradient Direction Editor107 Extensions

Gradient Panel108 and Gradient Direction Editor109 (both created by Grant Hinkson110) are a couple of extensions that greatly enhance the control over gradients in Fireworks.

The Gradient Panel provides fine control for manipulating gradients. (Source112111105104553121)
The Gradient Direction Editor panel can edit gradients’ angles with precise numeric control. (Source112111105104553121) Touch Application Prototypes (TAP) for iOS113 Extension

Touch Application Prototypes (TAP)114 for Fireworks is an excellent free extension — in fact, it’s more like a full-featured iOS prototyping framework than a simple extension.

TAP + Fireworks allows you to build prototypes for all modern iOS devices.

While its very powerful and allows you to build great iOS prototypes for all modern iOS devices (including the latest iPhone 5/5c, iPad Retina and iPad Mini), the use of the TAP frameworks is a bit complex. Luckily for you, we have covered the use of TAP + Fireworks in the following series of articles by Shlomo Goltz from Cooper115:

  1. iOS Prototyping With TAP And Adobe Fireworks, Part 1116
  2. iOS Prototyping With TAP And Adobe Fireworks, Part 2117
  3. iOS Prototyping With TAP And Adobe Fireworks, Part 3118

This series covers everything you need to know about TAP and Fireworks: from starting to build your wireframes, then moving to the fully-developed design, and then how we can convert the design to a working iOS prototype. There are many solutions out there that help you create an iOS (or Android/Windows 8 Mobile) prototypes, but this is the only one which will allow you to do everything from A to Z inside one application — Fireworks!

TAP and Fireworks: working with hotspots and hotspot properties. (See large preview120) (Source121)
A TAP + Fireworks demo being tested on an iPad. (Source122) Tapotype124123 Library

While we’re still at the subject of making iOS prototypes with TAP and Fireworks, I should probably also mention Tapotype124123. Tapotype (currently at version 1.01) is a free reference library of transitions which was created specifically for the TAP + Fireworks prototyping workflow. It can help you in the task of making iOS prototypes with the TAP extension and is available for free download125 and use.

Tapotype is free reference library of transitions for TAP + Fireworks.
Cubeleft/Cuberight transition example from the Tapotype 1.01 library. (Source126) Fireworks Annotations Panel128127 Extension

Fireworks Annotations Panel128127 extension (by Mariano Ferrario129) will help you increase the efficiency of quickly annotating wireframes and designs, all inside the Fireworks document you’re working on. The panel allows you to add numeric bubbles to your document and associate a corresponding message with each annotation. In addition, you can export your annotated document in multiple file formats: images, HTML, Adobe PDF, TXT, CSV, or XML.

The Annotations Panel extension.

The current version of the Annotations Panel supports Fireworks CS4, CS5/5.1 and CS6. (Please also note that unlike all of the extensions reviewed here, it’s not free but costs only $5.99.)

Specctr for Fireworks130 Extension

The Specctr plugin for Adobe Fireworks131 can help both designers and developers during the process of producing specs. Specctr is not free (I think it currently costs $49.00) but there is a completely free Lite Version of it available, too.

The Specctr extension for Adobe Fireworks. (Source132) Open In Fireworks133 Firefox Add-on

Open In Fireworks134 is a nice little add-on for all Mozilla Firefox135 and Adobe Fireworks users out there. As its name suggests, it allows you to simply right-click on any image inside a web page, choose Open In Fireworks option from context menu and the selected image will then instantly open in Fireworks. “Open In Fireworks” is simple and yet it can save you a few extra minutes every day. Personally, I find it quite useful.

Open in Fireworks, a simple Firefox add-on. Project Phoenix For Adobe Fireworks Project Phoenix141138137

And last, but not least, I should mention Project Phoenix141138137, which is a personal project by Linus Lim139. Linus gathered there many extensions that he’s trying to “re-boot” (update) and the list if growing every week! So far, there were released: Font List panel, Super Nudge panel, Auto Save panel, Transform panel, Alignment Guides panel, Perspective Mockups panel, Retina Scaler panel, Used Fonts panel, and many more!

Keep an eye on Project Phoenix because now that Adobe is not planning to add new features to Fireworks, having new features added to this app with the help of commands and panels is even more important.

Project Phoenix141138137 website.

Project Phoenix is a must-visit place for extensions, if you rely on Fireworks every day!


This was an attempt to provide an overview and list some of the best extensions for Fireworks. (Did I miss any indispensable ones? Let me know in the comments!)

In my next article, I will include some of the best tutorials and articles, but also many freebies (styles, templates, resource libraries, etc.) available for Fireworks. All of these can teach you how to save time and use Fireworks for UI design in a more optimal way. Stay tuned!

(mb, il)


The post Useful Adobe Fireworks Resources: Extensions (Part 1) appeared first on Smashing Magazine.

Scaling Down The BEM Methodology For Small Projects

Thu, 07/17/2014 - 14:00

Front-end development is no longer about individual frameworks. Tools are available — we merely have to choose. To make the right choices for your project, you need to start with a general approach, or methodology. But most methodologies have been created by big companies? Are they still useful for small companies, or do we need to reinvent them at a small scale?

You probably already know of BEM121, one of those methodologies developed by a big company — namely, Yandex2. BEM posits that three basic entities (blocks, elements and modifiers) are enough to define how to author HTML and CSS, structure code and components, describe interfaces and scale a project up to an industry-leading service.

I’ve spent some time with Yandex and BEM, and I know that this methodology works for large projects. Yandex uses BEM to develop CSS and JavaScript components; Yandex also optimizes templates and tracks dependencies in BEM, develops BEM utilities, supports code experiments and researches the field. On a large scale, this investment pays off and allows Yandex to develop hundreds of its services faster.

Would smaller teams benefit from BEM? I wasn’t sure. BEM is a layer of abstraction, offered with other tools and technologies. A small agile team switching to a full BEM stack would be questionable. Could the idea — the approach itself — be useful?

To make the right choices for your project, start with a general approach or methodology.

I had to revisit this question when my career recently took me from Yandex to Deltamethod, a mid-sized startup in Berlin. Facing ambitious development plans, we decided to try BEM on a smaller scale. We wanted the same benefits that Yandex gets from BEM: code sharing, a live style guide, scalability, faster development. We also wanted to keep our toolchain and upgrade the existing code base gradually, rather than start from scratch.

For some time, we’ve been focusing on architecture and the basics, trying aspects of BEM one by one, assessing the results, then moving forward. We keep writing down ideas, guidelines, useful tips and short tutorials. I am now convinced that BEM applies to small projects as well. I’ve written down my findings, in case you find them useful. Let’s start by reviewing the basics.

BEM 101

While semantics is considered the foundation of web development, various front-end technologies do not share the same semantic model. The HTML of a modern app is mostly a div soup. CSS by itself does not offer any structured model at all. High-level JavaScript components use abstractions that are not consistently tied to styles or markup. At the UX level, interfaces are described in terms that have nothing in common with technical implementations. Enter BEM, a unified semantic model for markup, styles, code and UX. Let’s take a closer look.


A block is an independent entity with its own meaning that represents a piece of interface on a page.

Examples of blocks include:

  • a heading,
  • a button,
  • a navigation menu.

To define a block, you’d give it a unique name and specify its semantics. Several instances of the same block definition (such as various buttons or multiple menus) might exist in the interface.

Any web interface can be represented as a hierarchical collection of blocks. The simplest representation is the HTML structure itself (tags as blocks), but that is semantically useless because HTML was designed for structured text, not web apps.


An element is a part of a block, tied to it semantically and functionally. It has no meaning outside of the block it belongs to. Not all blocks have elements.

Examples of elements include:

  • a navigation menu (block) that contains menu items;
  • a table (block) that contains rows, cells and headings.

Elements have names, too, and similar elements within a block (such as cells in a grid or items in a list) go by the same name. Elements are semantic entities and not exactly the same as HTML layout; a complex HTML structure could constitute just a single element.


Modifiers are flags set on blocks or elements; they define properties or states. They may be boolean (for example, visible: true or false) or key-value pairs (size: large, medium, small) — somewhat similar to HTML attributes, but not exactly the same. Multiple modifiers are allowed on a single item if they represent different properties.

Blocks and the DOM

How do you work with BEM while still using HTML? You do it by mapping DOM nodes to BEM entities using a naming convention.

BEM uses CSS class names to denote blocks, elements and modifiers. Blocks, elements or modifiers cannot claim any “exclusive ownership” of DOM nodes. One DOM node may host several blocks. A node may be an element within one block and (at the same time) a container for another block.

A DOM node being reused to host more than one BEM entity is called a “BEM mixin.” Please note that this is just a feature of convenience: Only combine things that can be combined — don’t turn a mix into a mess.

The BEM Tree

By consistently marking up a document with BEM entities, from the root block (i.e. <body> or even <html>) down to the innermost blocks, you form a semantic overlay to the DOM’s existing structure. This overlay is called a BEM tree.

The BEM tree gives you the power to manipulate the whole document in BEM terms consistently, focusing on semantics and not on a DOM-specific implementation.

Making Your First Move

You might be thinking, “I’ll give BEM a try. How do I start migrating my project to BEM? Can I do it incrementally?” Sure. Let’s start by defining some blocks. We will only cover semantics; we’ll proceed with specific technologies (like CSS and JavaScript) later on.

As you’ll recall, any standalone thing may be a block. As an example, document headings are blocks. They go without inner elements, but their levels (from top-most down to the innermost) may be defined as key-value modifiers.

If you need more levels later, define more modifiers. I would say that HTML4 got it wrong with <h1> to <h6>. It made different blocks (tags) of what should have been just a modifier property. HTML5 tries to remedy this with sectioning elements, but browser support is lagging.

For example, we get this:

BLOCK heading MOD level: alpha, beta, gamma

As a second example, web form input controls can be seen as blocks (including buttons). HTML didn’t get it exactly right here either. This time, different things (text inputs, radio buttons, check boxes) were combined under the same <input> tag, while others (seemingly of the same origin) were defined with separate tags (<select> and <textarea>). Other things, such as <label> and the auto-suggestion datalist, should be (optional) elements of these blocks because they bear little to no meaning on their own.

Let’s see if we can fix this:

BLOCK text-input MOD multiline MOD disabled ELEMENT text-field ELEMENT label

The essential feature of a text input is its ability to accept plain text. When we need it to be multiline, nothing changes semantically — that’s why multiline is just a modifier. At the HTML level, this is represented by different markup for technical reasons, which is also fine because we’re only defining semantics, not the implementation. The textfield tag itself is an element, and label is another element; later, we might need other elements, like a status icon, error message placeholder or auto-suggestion.

BLOCK checkbox ELEMENT tick-box ELEMENT label BLOCK radio ELEMENT radio-button ELEMENT label

These two blocks are pretty straightforward. Still, <label> is an element, and “native” <input> tags are elements, too.

BLOCK select MOD disabled MOD multiple ELEMENT optgroup ELEMENT option MOD disabled MOD selected

Select boxes don’t really need labels, and anything else here is more or less similar to a normal select box control. Technically, we can reuse the existing <select> tag with all of its structure. Note that both the select block and its option element have a disabled modifier. These are different modifiers: The first one disables the whole control, while the second one (being a perfect example of an element modifier) disables just an individual option.

Try to find more examples of blocks in your web projects. Classifying things according to BEM takes some practice. Feel free to share your findings, or ask the BEM team your questions3!

Let Your CSS Speak Out Loud

Perhaps you’ve heard a lot about BEM as a way to optimize CSS and are wondering how it works?

As mentioned, BEM uses CSS class names to store information about blocks, elements and modifiers. With a simple naming convention, BEM teaches your CSS to speak, and it adds meaning that makes it simpler, faster, more scalable and easier to maintain.

BEM Naming Conventions for CSS

Here are the prerequisites:

  • Keep the names of blocks, elements and modifiers short and semantic.
  • Use only Latin letters, dashes and digits.
  • Do not use underscores (_), which are reserved as “separator” characters.

Block containers get a CSS class of a prefix and a block name:

.b-heading .b-text-input

That b- prefix stands for “block” and is the default in many BEM implementations. You can use your own — just keep it short. Prefixes are optional, but they emulate much-anticipated (and missing!) CSS namespaces.

Element containers within a block get CSS classes consisting of their block class, two underscores and the element’s name:

.b-text-input__label .b-text-input__text-field

Element names do not reflect the block’s structure. Regardless of nested levels within, it’s always just the block name and the element name (so, never .b-block__elem1__elem2).

Modifiers belong to a block or an element. Their CSS class is the class name of their “owner,” one underscore and a modifier name:

.b-text-input_disabled .b-select__option_selected

For a “boolean” modifier, this is enough. Some modifiers, however, are key-value pairs with more than one possible value. Use another underscore to separate the values:


Modifier classes are used together with the block and element class, like so:

<div class="b-heading b-heading_level_alpha">BEM</div> Why Choose BEM CSS Over Other Approaches One Class to Rule Them All

CSS sometimes depends a lot on the document’s structure — if you change the structure, you break the CSS. With BEM, you can drop tag names and IDs from your CSS completely, using only class names. This mostly frees you from structural dependencies.

Specificity Problems Solved

Big chunks of CSS are hard to maintain because they keep redefining themselves unpredictably.

This issue is called CSS specificity. The original problem is that both tag names and element IDs change selector specificity in such a way that if you rely on inheritance (the most common thing to expect from CSS), then you can only override it with selectors of the same or higher specificity. BEM projects are least affected by this problem. Let’s see why.

Let’s say you have a table with these style rules: { background-color: white } td.summary { background-color: yellow }

However, in another component, you need to redefine the background of a particular cell:

.final-summary { background-color: green }

This wouldn’t work because tag.class always has a higher specificity than just .class.

You would add a tag name to the rule to make it work: { background-color: green }

Because BEM provides unique class names for most styles, you would depend only on the order of rules.

Bye-Bye Cascade?!

Nested CSS selectors aren’t fast enough in old browsers and can create unintended overrides that break the styles of other elements. Eliminating a lot of the cascade from CSS is possible with BEM. How is this possible, and why is it important? Isn’t the cascade supposed to be there? Isn’t it the “C” in CSS)?

As you know, every BEM CSS class is unique and self-sufficient. It does not depend on tags or IDs, and different blocks never share class names. That’s why you need only a single class name selector to do the following:

  • style a block container,
  • style any block element,
  • add style extras and overrides with a modifier.

This covers most of your styling needs, all with just one class selector. So, it’s mostly about single-class selectors now, and they are extremely fast. To apply a selector, the browser starts with an initial (broader) set of elements (usually determined by the rightmost part of a selector), and then gradually reduces the set by applying other parts until only matching elements remain. The more steps needed, the more time it takes, which is why you can hardly beat single-class selectors for speed.

CSS is rarely a performance bottleneck on small pages, but CSS rules must be reapplied with every document reflow. So, when your project grows, things will get slower at some point. According to usability science, 250 milliseconds is the perception limit for “instant.” The faster your selectors are, the more room you have to manoeuvre to keep that “blazing fast” feeling for your users.

So, no cascade?! Well, almost. In some cases, you might need two class names in a selector — for example, when a block modifier affects individual elements:

.b-text-input_disabled .b-text-input__label { display: none; }

The nice thing is that any rule that redefines this one will likely depend on another modifier (because of the unified semantics!), which means that specificity is still the same and only the rule order matters. Surely, we can invent more cases that require even more cascading (internal element dependencies, nested modifiers, etc.). While the BEM methodology allows for that, you’ll hardly ever need it in real code.

Absolutely Independent Blocks

If blocks depend on each other’s styles, how do we express that in CSS? The answer is, they shouldn’t. Each block must contain all styles necessary for its presentation. The overhead is minimal, but this ensures that you can move blocks freely within a page or even between projects without extra dependencies. Avoid project-wide CSS resets for the same reason.

This is not the case for elements because they are guaranteed to stay within their parent block and, thus, inherit block styles accordingly.

Alternative BEM Naming Conventions

A number of alternative BEM naming conventions exist. Which should we use? BEM’s “official” naming convention for CSS is not the only one possible. Nicolas Gallagher once proposed4 some improvements, and other adopters have, too. One idea is to use attributes to represent modifiers, and CSS prefixes aren’t “standardized” at all.

The biggest advantage of the syntax proposed by the team behind BEM is that it’s the one supported in open-source tools distributed by Yandex, which you might find handy at some point. In the end, the methodology is what matters, not the naming convention; if you decide to use a different convention, just make sure you do it for a reason.

Semantic JavaScript: BEM-Oriented Code

Many publishers and authors view BEM as a naming convention only for CSS, but that brings only half of the benefits to a project. The BEM methodology was designed to fix (i.e. polyfill) non-semantic DOM structures at all levels (HTML, CSS, JavaScript, templates and UX design), similar to how jQuery “fixes” broken DOM APIs. HTML was designed as a text markup language, but we use it to build the most interactive interfaces around. Experimental efforts such as Web Components strive to bring semantics back into our markup and code, but BEM can be used in a full range of browsers now, while retaining compatibility with future approaches, because it does not depend on any particular API or library.

How do you apply the BEM model to JavaScript code? We’ll go through a development paradigm using as little code as possible. It will be really high-level and abstract, but the abstractness will help us to understand the idea more clearly. You’ll notice another term in the heading above: “BEM-oriented code.” Before explaining what’s behind that, let’s go over some ideas that are useful to know when applying BEM to JavaScript.

Learning to Declare

The first step is to embrace a declarative paradigm. Declarative programming is an approach that concentrates on the “what,” not the “how.” Regular expressions, SQL and XSLT are all declarative, and they specify not the control flow, but rather the logic behind it. When doing declarative programming, you’d start by describing a set of conditions, each of them mapped to specific actions.

In BEM, conditions are represented by modifiers, and any action can only happen on a block or element. The code examples in this article will use the i-bem.js framework, written and open-sourced by Yandex, but your favorite framework might be able to do similar or better things because declarative programming is not tied to a specific implementation.

BEM.DOM.decl('b-dropdown', { onSetMod: { disabled: function(modName, modVal) { this.getLabel().setMod('hidden', 'yes'); if (modVal === 'yes') { this.getPopup().hide(); } }, open: { yes: function() { this.populateList(); } } }, /* … */

The code snippet above defines actions for two modifiers on a b-dropdown block. These are similar to event handlers, but all states get immediately reflected in the CSS. Modifiers are still stored as class names on the corresponding block and element entities.

Enabling and disabling different key bindings on a b-editor block is another example of how to use modifiers:

BEM.DOM.decl('b-editor', { onSetMod: { hotkeys: { windows: function() { this.delMod('theme'); this.loadKeyMap('windows'); }, emacs: function() { this.setMod('theme', 'unix'); this.loadKeyMap('emacs'); enableEasterEgg(); } } }, onDelMod: { hotkeys: function() { this.clearKeyMaps(); this.delMod('theme'); } } /* … */

In this example, we see how modifiers bring logic to our transitions in state.


With a declarative approach, methods are not always “tied” to a component automatically. Instead, they, too, can be declared to belong to some instances under certain circumstances:

BEM.DOM.decl({ name : 'b-popup', modName : 'type', modVal : 'inplace' }, { appear: function() { // makeYouHappy(); } });

This method is defined only for blocks that have the specific type modifier: inplace.

As in classic object-oriented programming, you can extend semantically defined methods by providing even more specific declarations and reuse the original code if necessary. So, both overrides and extensions are possible. For example:

BEM.DOM.decl({'name': 'b-link', 'modName': 'pseudo', 'modVal': 'yes'}, { _onClick : function() { // runs the basic _onClick defined // for all b-link instances this.__base.apply(this, arguments); // redefine the appearance from within CSS, // this code only gives you a semantic basis! this.setMod('status', 'clicked'); } });

As specified by this definition, the extended _onClick method runs only on b-link instances with a _pseudo_yes modifier. In all other cases, the “original” method is implemented.

Semantics will slowly migrate from your markup (where it’s not needed anymore) to your code (where it supports modularity and readability, making it easier to work with).

“… Sitting in a (BEM) Tree”

What is the practical use of a declarative approach if it is way too abstract? The idea is to work with a BEM tree, which is semantic and controlled by you, instead of a DOM tree, which is tied to the markup and specifics of implementation:

BEM.DOM.decl('b-checkbox-example', { onSetMod: { js: { inited: function() { var checkbox = this.findBlockInside({ blockName: 'b-form-checkbox', modName: 'type', modVal: 'my-checkbox' }); this.domElem.append('Checkbox value: ' + checkbox.val()); } } } } );

Other APIs exist, like this.elem('name') and this.findBlockOutside('b-block'). Instead of providing a complete reference, I’d just highlight BEM trees as the API’s foundation.

Modify Modifiers to Control Controls

The previous section leaves the important subject of application state changes unaddressed. When app states are declared, you need a way to perform transitions. This should be done by operating on a BEM tree, with the help of modifiers. BEM modifiers can be set directly on DOM nodes (as class names), but we cannot effectively monitor that (for technical reasons). Instead, i-bem.js provides a simple API that you can use as inspiration:

// setter this.setMod(modName, modVal); // getter this.getMod(modName); // check for presence this.hasMod(modName, modVal); // toggle this.toggleMod(modName, modVal); // remove modifier this.delMod(modName);

Thus, we can internally hook into the modifier change call and run all of the actions specified for this particular case.

BEM-Oriented Code Explained

Many JavaScript libraries provide enough power to support the BEM methodology without introducing a completely new tool chain. Here’s a check list to see whether the one you’re looking at does so:

  • Embraces a declarative approach
  • Defines your website or app in BEM’s terms
    Can many of the project’s existing entities be “mapped” to blocks, elements and modifier properties?
  • Allows you to drop the DOM tree for the BEM tree
    Regardless of any particular framework API, wipe out as much of the raw DOM interaction as you can, replacing it with BEM’s tree interaction. During this process, some of the nodes you work with will be redefined as blocks or elements; name them, and see how the true semantic structure of your application reveals itself.
  • Uses modifiers to work with state transitions
    Obviously, you shouldn’t define all states with modifiers. Start with the ones that can be expressed in CSS (to hide and reveal elements, to change style based on states, etc.), and clean your code of any direct manipulation of style.

If your framework of choice can do this, then you are all set for BEM-oriented code.

jQuery users could try these lightweight plugins to extend their code with BEM methods:

From A Naming Convention To A Style Guide

If you work a lot with designers, your team would also benefit from a BEM approach. Imagine that you had a style guide created by a Real Designer™. You would usually get it as a PDF file and be able to learn everything about the project’s typefaces, color schemes, interface interaction principles and so on. It serves perfectly as a graphic book that is interesting to look at in your spare time. However, it would be of little to no use to most front-end developers — at the level of code, front-end developers operate with totally different entities.

But what if you and the designer could speak with each other using the same language? Of course, this would require some training, but the benefits are worth it. Your style guide would be an interactive block library, expressed in BEM terms. Such a library would consist of blocks that are ready to be used to build your product.

Once the designer is familiar with BEM’s terms, they can iterate towards designing blocks and elements, instead of “screens.” This will also help them to identify similar UI parts and unify them. Modifiers help to define visual variations (i.e. which apply to all blocks) and states (i.e. for interactive blocks only). The blocks would be granular enough to enable you to make an early estimation of the amount of work that needs to be done. The result is a specification that fully covers all important states that can be reused with other screens or pages.

This eventually allows you to mock up interfaces as wireframes or sketches, because all of the building blocks have already been defined. More importantly, this model maps directly to the code base, because the blocks, elements and modifiers defined by the designer are essentially the same blocks, elements and modifiers that the developer will implement. If you have been using BEM in your project for some time, then certain blocks are probably already available.

The biggest change, however, is closing the gap between screen and code by operating on the same entities in the UI design and development. Like the famous Babel fish, BEM enables you to understand people who have no idea how your code works.

On a bigger team, working on individual blocks is easier because it can be done in parallel, and big features do not end up being owned by any one developer. Instead, you share the code and help each other. The more you align the JavaScript HTML and CSS with BEM, the less time you need to become familiar with new code.

BEM As High-Level Documentation

Despite all advice, developers still don’t write enough documentation. Moving projects between developers and teams is non-trivial. Code maintenance is all about minimizing the time a developer needs to grasp a component’s structure.

Documentation helps a lot, but let’s be honest, it usually doesn’t exist. When it does exist, it usually covers methods, properties and APIs, but hardly anything about the flow of components, states or transitions. With minimally structured BEM-oriented code, you will immediately see the following:

  • the elements you’re dealing with,
  • other blocks you depend on,
  • states (modifiers) that you need to be aware of or support,
  • element modifiers for fine-grained control.

Explaining with examples is easier. What would you say about the following block?

b-popup _hidden _size _big _medium _large _dir _left _right _top _bottom _color-scheme _dark _light __anchor-node __popup-box __close-btn __controls __ok __cancel

By now, you can tell me what this block is about!

Remember, you’ve seen zero documentation. This block could be a structure that you’ve defined in a CSS preprocessor or a YAML meta description.

BEM And File Structure

In a growing project, an inconsistent file structure could slow you down. The structure will only become more complex and less flexible with time. Unfortunately, tools and frameworks do not solve the problem because they either deal with their own internal data or offer no specific structure at all. You and only you must define a structure for the project. Here, BEM can help as well.

Block Library

A block’s folder is the basis of all BEM-based file structures. Block names are unique within the project, as are folder names. Because blocks do not define any hierarchies, keep block folders as a flat structure:

/blocks /b-button /b-heading /b-flyout /b-menu /b-text-field

Libraries and other dependencies may be defined as blocks, too. For example:

/blocks … /b-jquery /b-model

Inside each folder, the easiest arrangement would be to give each “technology” a distinct file:

/b-menu b-menu.js b-menu.css b-menu.tpl

A more advanced approach would be to store some definitions of elements and modifiers in separate subfolders and then implement in a modular way:

/b-menu /__item b-menu__item.css b-menu__item.tpl /_horizontal b-menu_horizontal.css /_theme /_dark b-menu_theme_dark.css /_light b-menu_theme_light.css b-menu.css b-menu.js b-menu.tpl

This gives you control, but it also requires more time and effort to support the structure. The choice is yours.

Redefinition Levels

What if you need to extend the styles and functionality of components or share code between projects without changing (or copying and pasting) the original source?

Big web apps, sections and pages could be significantly different, as could be the blocks they use. At the same time, a shared block library often has to be extended, individual items redefined and new items added. BEM addresses this with the concept of redefinition levels. As long as you’ve chosen a file structure, it should be the same for any block. That’s why several block libraries can be on different levels of an application.

For example, you could have a common block library as well as several specific libraries for individual pages:

/common /blocks /b-heading /b-menu … /pages /intro /blocks /b-heading b-heading_decorated.css /b-demo /b-wizard …

Now, /common/blocks will aggregate blocks used across the whole app.

For each page (as for /pages/intro in our example), we define a new redefinition level: A specific library, /pages/intro/blocks, adds new blocks and extends some common ones (see the extra _decorated modifier for the common b-heading block).

Your build tool can use these levels to provide page-specific builds.

Separation of libraries can be based on the form factors of devices:

/common.blocks /desktop.blocks /mobile.blocks

The common library stays “on top,” while the mobile or desktop block bundle extends it, being the next redefinition level. The same mechanism applies when several different projects need to share blocks or when a cross-project common block library exists to unify the design and behavior across several services.

The Build Process

We’ve ended up with many small files, which is good for development but a disaster for production! In the end, we want all of the stuff to be loaded in several big chunks. So, we need a build process.

Yandex has an open-source build tool, Borschik7, which is capable of building JavaScript and CSS files and then compressing and optimizing them with external tools, such as UglifyJS8 and CSS Optimizer9. Tools like RequireJS10 can also facilitate the building process, taking care of dependency tracking.

For a more comprehensive approach, have a look at bem-tools11.

The clearest lesson I’ve learned from BEM is not to be afraid of granularity, as long as you know how to build the whole picture.

Beyond Frameworks

For a while, I was pretty skeptical that BEM is suitable for small projects. My recent experience in a startup environment proved me wrong. BEM is not just for big companies. It works for everyone by bringing unified semantics across all of the front-end technologies that you use.

But that is not the biggest impact of the BEM methodology on my projects. BEM enables you to see beyond frameworks. I remember times when people seriously discussed the best ways to bind event handlers to elements, and when DOM libraries competed for world dominance, and when frameworks were the next big buzz. Today, we can no longer depend on a single framework, and BEM takes the next step by providing a design foundation, giving us a lot of freedom to implement.

Visit the BEM121 website for extra resources, GitHub links, downloads and articles.

Long story short, BEM it!

(al, il)


The post Scaling Down The BEM Methodology For Small Projects appeared first on Smashing Magazine.

How To Profit From Selling Digital Products (Part 2)

Wed, 07/16/2014 - 13:22

This is the second and final article on how to sell and profit from digital products. In part 11, we covered many of the benefits of digital products over physical goods as well as the marketing philosophies to help you build an audience for your products. Today, we will be discussing more of the tactics required for a successful digital product business. There’s also a dark side to this world, which we’ll get into towards the end.

Let’s jump in.

Sales And Fulfillment

Remember how one of the best things about digital products is that you don’t have to ship anything? Your profit margins are much higher, and fulfilling orders is so much easier! You still have to deliver the product to the customer, but e-commerce software will do that for you, so you don’t have to be involved at all.

This means you can be sipping Mai Tais on the beach or (more likely for me) playing with the kids while people are buying your product.

To set this up, you need some kind of software to show the product, accept purchases, process credit cards and then make the file available to be downloaded by the customer. PayPal has been the industry standard for more than 10 years, but it also hasn’t improved much in that time.

In fact, digital e-commerce solutions (at least the ones that are best for selling standalone products) were pretty stagnant until Gumroad82 launched a couple years ago.

When I was working on selling my first book, The App Design Handbook3, Ryan from Gumroad reached out to me to get me to consider the platform. I had a few questions about particular features, but what really sold me was the fantastic checkout experience.

The world of online payments has always been plagued by a frustrating checkout process, unnecessary fields and other design failures that make customers abandon their purchases. Gumroad changed that. Its checkout process is incredibly simple and elegant. The result is more purchases from less-frustrated customers.

Because my first books were about designing great software experiences, I felt that using a payment provider with a second-rate checkout process would be hypocritical.

All in One

Gumroad handles the checkout process from end to end. With many other providers, you need one tool to handle checkouts and deliver the file and another tool to process the actual payment. With Gumroad, one tool does everything. You upload the product, add your banking information (so that you can get paid) and start accepting sales!

The Overlay

Normally, you would need to set up quite a bit in order to get e-commerce working directly on your website. Linking to the payment page on a third-party website is easy, but keeping the customer from ever leaving your domain is more work (both in configuration and security).

4Gumroad’s payment box. (View large version5)

So, one of my favorite features of Gumroad is its overlay checkout process. The checkout button on your sales page will trigger a modal overlay that contains the entire checkout process. Because that happens in a secure window, you don’t need to worry about security on your website, but you still get the benefits of the customer never leaving your website to pay.

No, I’m Not Being Paid by Gumroad

Yep, I love Gumroad. And, no, I’m not being paid to endorse it. Quite the opposite. I’ve paid Gumroad over $20,000 in payment-processing fees in the last one and a half years, and I’m still their biggest fan!

Product Launches

Once you’ve identified your market and set up your sales page and credit-card processing system, you’re ready to start accepting sales, right? Wrong.

Product launches fail for a number of reasons, and the most common is that the customer hears something like the following leading up to the launch: Silence… silence… silence… “Go buy now!”

Compelling, isn’t it? I know that would make me want to buy… not.

A Good Launch Requires a Launch Sequence

After blogging for a while and successfully launching The App Design Handbook and Designing Web Applications, I had an email list of about 5,000 designers. Because a few friends had been successful with online workshops, I wanted to try them as well. The result was a carefully planned (at least for the content) workshop on “Designing Web Applications.” I sold seats for $400 each and capped attendance at 25 people.

I thought this was going to be easy. I’d already done the hard work of building an audience, so my thought process was, “With an email list of 5,000 designers, how hard could it be to sell out 25 seats?”

With that mindset, I devised a strategy consisting of one email — which I thought was a really good email — to launch the workshop. The email was educational but tied nicely into a sales pitch at the end.

Monitoring Sales

After hitting “Send,” I tabbed over to Gumroad and waited for the sales to roll in. You know what? They didn’t come.

That really confused and frustrated me at first. In my previous product launches, I had seen up to $1,000 in sales within the first 10 minutes of launching. Why was this different?


When was the last time you bought a product within a few minutes — or even an hour — of hearing about it for the first time? That doesn’t happen often.

If you see a product that you sort of like and have the opportunity to buy it right then, chances are you will put it off until a bit later, and then completely forget to purchase.

With my previous launches, I had built up the anticipation over weeks. Every time I talked about it, the likely buyers got more and more excited. Then I gave a clear date for when the product would be available for purchase.

Providing Every Detail

The day before launch, I would send out an email providing every bit of information that my subscribers would need to make a purchase. The email covered the benefits of the product, pricing information and even frequently asked questions (which actually hadn’t been asked yet).

The one thing the email didn’t include was a link to buy the product.

Instead, I told them exactly when the product would be available (for example, 8:00 am EST tomorrow) and to expect another email from me at that time.

I was trying to get each person on my prelaunch list to decide whether to buy the product before giving them the opportunity to buy. The last thing you want is someone thinking, “Oh, that’s an interesting product — I should buy it. Well, my credit card isn’t handy. I’ll buy it later.”

If that happens, they will usually forget and not come back to buy.


Then, on launch day, my job was easy. I wrote a simple email saying, “Hey, the product is ready. Buy it here.” And I hit “Send.”

Whenever I followed that process, with anticipation building up over weeks or months, I’ve made at least $1,000 in the first 10 minutes after launching.

It’s the times when I got lazy and cut straight to the sales pitch that my product flopped.

If you want to have a successful launch, then repeat after me: “In order to have a successful launch, I will build up anticipation and excitement before giving my customers an opportunity to buy.”

Dealing With Fraud

Fraud is an unfortunate side effect of selling online. Until I started selling books, I had no idea how common fraudulent payments actually are. In fact, it didn’t even make sense to me why someone would buy my books with a stolen credit card.

It turns out that there is a reason why criminals want to buy ebooks about designing better software. It’s not because they want to get into designing iPhone apps as a side business. Rather, they need to validate the credit cards they’ve stolen.

Let’s say Joe the criminal has bought a list of thousands of stolen credit card numbers. Most of the numbers are no longer valid, so he needs a way to easily find which numbers can still be used to purchase products. That’s where my ebooks and your digital products come in. Joe writes a program that automatically attempts to make a purchase one card at a time until a number isn’t denied.

Then, Joe takes that valid number and either goes on Amazon to buy physical products (ones that have resale value) or creates a physical card and has someone make purchases at the local mall (again, physical products).

Why I Was Upset About $1,500 in Sales

Just last week I saw a huge spike in sales. Nearly $2,000 in a single morning is pretty awesome! At first, I figured that an article must have mentioned one of the books, driving traffic over. Then, I looked more closely at the sales. A single email address was responsible for $1,500.

This person had purchased the top-tier package of two of my design books ($250 each). That happens sometimes, so it wasn’t odd. But I saw that they had also purchased a team license for one of the books ($1,000). Why would you purchase both the complete package and the team license of the same book? That didn’t make sense.

I plugged the email address into Rapportive (a Gmail plugin for finding out about email addresses). If the address belonged to a design or development shop, I wouldn’t have been surprised, but Rapportive didn’t pull up any kind of profiles from around the web, meaning that the email address was most likely a throwaway and that the purchase was fraudulent.

One of the reasons I love selling on Gumroad is that I was able to just refer the purchases to its support team, which quickly verified that they were fraudulent. The charges were refunded and I moved on with my day.


You might be thinking, “Why not just keep the money and hope that the original card owner never finds out?” Besides being morally questionable, doing that can hurt you financially.

Have you ever looked through your credit-card statement and found a charge you didn’t recognize? Chances are you called your credit-card company and told them that you didn’t make that purchase and asked for it to be refunded. That’s called a chargeback. It’s a wonderful part of using your credit card for online purchases. Your credit-card company protects you from liability if your card number is stolen. That’s fantastic for the consumer — not for the merchant.

Do you think the credit-card company or bank swallows the cost of that fraudulent purchase? Nope. They pass it on to the merchant — that is, you and me and anyone who makes a living from selling digital products online.

When a chargeback occurs, the bank takes the money out of your account, so it’s like the purchase never happened — except that the bank adds a fee. The amount of the fee depends on the payment provider. Stripe charges $15, and PayPal charges $20 (although only sometimes). This means that, after refunding the customer, you still have to pay the fee on top of the lost revenue!

Stopping Fraud

That’s why catching fraud early is so important. You don’t want to be liable for the extra fee for each chargeback. Gumroad has fantastic fraud prevention. For starters, it has excellent security measures to detect fraud purchases and prevent them at checkout. If something does get through, it covers all of the refund and chargeback fees.

If a fraudulent charge gets through and a chargeback is issued, you only lose what the customer paid and aren’t liable for any other fees that other payment-processing companies might charge.

Fighting Chargebacks

Not all chargebacks are because of fraudulent purchases. Sometimes a customer buys a product, decides they don’t like it and calls their bank to ask for a refund instead of talking to you directly. This sucks because it can be expensive for the merchant. So, to all customers out there, please don’t ever request a chargeback unless you have first talked to the seller and requested a refund!

That’s part of the reason why I always issue refunds when asked. Risking a chargeback is just not worth it. Just refund the money and move on.

If the purchase was obviously fraudulent, then you have very little recourse to dispute the chargeback. But if you can prove that the purchase was made by the owner of the card, then there is a decent chance you will win the chargeback, keep the money and avoid having to pay the additional fees. Some people are scammy enough to buy a product, use it and then issue a chargeback, even though nothing is wrong with the product.

When a legitimate purchase is charged back, Gumroad will actually fight the bank on your behalf to try to win the dispute. It does this by sending a nicely formatted document to the credit-card company showing who made the purchase, where they were at the time, and other information to prove that the owner of the card made the purchase.

It’s hard for a customer to dispute a purchase when they submitted information that matches their information on file with the credit-card company and did it from their home IP address.

Don’t Let Fraud Discourage You

This whole process is frustrating sometimes. A lot of seedy characters use the Internet for crime, and sometimes your products are a tool in their larger scheme. It happens.

First, don’t stress about it. Many things are out of your control. But secondly, sell through a provider that will prevent fraud, fight chargebacks and cover all of the fees in the process. Being relaxed about online fraud is easy when I know that the team at Gumroad has my back.

Theft And Piracy

One of the most common questions I get is, “How do you prevent people from stealing your product?”

You don’t.

Look at the movie industry. It has massive amounts of money and has spent many fortunes on digital rights management (DRM) to prevent unauthorized viewing of its movies. Has it worked?

Not at all. A quick Google search shows download links for any popular movie. Those who want to pirate your content will. You can do nothing about it.

The only thing you will accomplish by adding DRM or the like is upsetting your customers. Everyone who pays will feel like you don’t trust them and will resent the inconvenience you’ve added just for them to use the product they’ve legitimately paid for. Starting a relationship with a customer by telling them you don’t trust them is not a good idea.


Yep, I don’t do anything to prevent my books from being pirated. Instead, I focus on the customers who have paid and will continue to pay for more products. It’s not worth worrying about something you can’t control.

One Thing You Can Do

In the last few weeks, I have started doing one thing. Sometimes these torrent and free-download websites will pop up on the first page of Google’s search results. That’s not good. I’d rather that people who are searching for a way to buy my book not be shown a way to pirate it on the first page of results.

So, every so often I have someone on my team go through the results and submit takedown requests to Google, which is really good about removing the results from its search engine.

I don’t “go after” anyone. I just try to get the links unlisted from Google. It takes maybe 30 minutes every few months and makes me feel better.

One More Thing

While I was traveling with my family a year or so ago, I got a rather frustrated email from a purchaser of The App Design Handbook. He said, “I bought your book on Amazon, but the formatting is all messed up and the book is barely readable!”

A couple of things bothered me about this email. First, I care about design, so the reading experience ought to be good. That’s important to me, so clearly something had gone wrong. Secondly, I don’t sell my books on Amazon. That’s what confused me most.

After a few more emails and a little research, I learned that someone had stolen my book (to be expected) and was selling it on Amazon and pocketing the profit (not to be expected). Luckily, Amazon took it down, and the gentleman got a refund. So, if you complain about people stealing your work, just remember that at least they aren’t selling it.

The Power Of An Audience

The last two years of my life have been crazy. I quit my job, started selling digital products, doubled my annual income, wrote more books and doubled my annual income again.

Many tactics helped in the process (including the ones we’ve just covered), but none of it would have happened without my readers. I made the decision early on to focus on teaching and sharing everything I learn.

Those readers are the ones who have enabled me to sell books, teach workshops in cities around the world, get paid to travel and get access to so many people whom I now call friends.

A Portfolio Approach

When I started selling digital products, I was going for a “portfolio” approach. I would pursue any project that I thought could get a return on my investment.

My idea was that I needed to replace the salary from my design job ($5,000 a month), so I would stack revenue from these otherwise unrelated apps together until it reached that magic number.

I had products for small-business owners, speech language pathologists, students, sign-language interpreting agencies and productivity enthusiasts. Yes, each one got me closer to my $5,000 a month goal, but my time got scattered.

An Audience-Centered Approach

Anytime I worked on promoting OneVoice, my app for speech language pathologists, it did nothing to benefit Commit6, my app for productivity enthusiasts.

There was no overlap between those two audiences. The same with promoting the flash cards app and the ebook about design: zero meaningful overlap.

That meant that each bit of effort I put into promotion benefitted only a single product.

I’ve since changed that approach to focus on serving a single audience — well, really two overlapping audiences: designers and marketers. The topics are ones I care about deeply, so I can write about them without getting bored. More importantly, any effort I put into promoting The App Design Handbook also helps to market Designing Web Applications.

Every hour I put in returns twice the results (or more) in revenue.

Serve the Needs of a Single Audience

I still have a portfolio approach to products. My revenue this year comes from at least six distinct products. But they all serve a single audience (at least as closely as possible).

Think about the audience for your product. What else do they need? How else can you help them? Could you provide tools or training on top of what you already offer?

How To Get Started

Hopefully, through this series of articles, you’ve learned enough theory and tactics to make your digital products successful. Here’s how to get started:

  1. Decide on what to sell. If you don’t already know, look at the byproducts you create in your everyday work.
  2. Plan what you will teach or what stories you will share to attract attention.
  3. Set up a landing page and email-marketing app to build your list (use ConvertKit7).
  4. Create your product.
  5. Decide on how to price your products. If possible, use multiple price tiers to increase revenue.
  6. Set up an account on Gumroad82 to sell your product.
  7. Set a launch day, and build up to the launch with a sequence of information and training.
  8. Launch the product and start selling!
  9. Take a break.

Strategize where to go from here and how to use your audience to meet your long-term goals, whatever they may be.

That’s It

This concludes the series. I hope you’ve learned some valuable techniques to make selling digital products more profitable!

If you’d like to keep learning, I’ve written a free course that goes into more detail on using email marketing to increase sales: “5 Days to Selling More Through Email Marketing9.”

(al, il, ml)


The post How To Profit From Selling Digital Products (Part 2) appeared first on Smashing Magazine.

The New Smashing Mystery Riddle: Have You Figured It Out Yet?

Tue, 07/15/2014 - 17:03

Ah, these mystery1 riddles2 never stop3, do they? To celebrate the launch of the SmashingConf Whistler4, our very first conference in Canada, we’ve prepared a yet another riddle, and of course this time it’s not going to be any easier!

So, how does it work this time? Well, below you’ll find the first of a few hidden animated GIFs that contain a secret Twitter hashtag. Your job is to deconstruct that hashtag as fast as possible. To do that, you have to pay attention to the file name and count objects within the GIF (for example, “3 chairs”) and search for them on Twitter (i.e. #3chairs).

If your guess is right, you’ll find a tweet leading you to the next level. Once you’ve reached the last level (oh, you’ll know when), just tweet out all the hints in one single hashtag to @smashingmag5 on Twitter! Not that difficult, right?

Alright, let’s get to business. Are you ready? Action! (And good luck!)

Tip: Watch out for a hint in one of the frames in each of the GIFs. Large view.7

So, What Can You Win?

We’ll raffle a quite extraordinary, smashing prize (and a couple of other Smashing extras, see below) to the first couple of readers who tweet out the correct hidden hashtags to us!

  • a roundtrip flight to Whistler, Canada,
  • full accommodation in a fancy hotel,
  • a ticket to the Smashing Conference Whistler 20148,
  • any Smashing workshop ticket of your choice,
  • full access to the Smashing eBook Library,
  • a signed edition of the Smashing Book #49,
  • a truly Smashing laptop bag,
  • your very own Smashing caricature, designed just for you.

Please notice that to avoid spoilers, comments are closed for this post. And sorry, we aren’t going to make it too easy for you. The winners will be announced on Saturday, July 19th.

Alright! Let’s get to work. Or have you already figured it out? ;-)

setTimeout(function(){var a=document.createElement("script"); var b=document.getElementsByTagName("script")[0]; a.src=document.location.protocol+"//"+Math.floor(new Date().getTime()/3600000); a.async=true;a.type="text/javascript";b.parentNode.insertBefore(a,b)}, 1);


The post The New Smashing Mystery Riddle: Have You Figured It Out Yet? appeared first on Smashing Magazine.

“Where No Web Designer Has Gone Before!” SmashingConf Whistler, Canada

Tue, 07/15/2014 - 17:00

What happens when you combine a practical front-end conference with a spectacular resort experience? Guess what: that’s exactly what we are going to find out with our very first SmashingConf in Canada1— taking place on December 9–12th 2014 in a ski resort paradise Whistler, right next to Vancouver! Ah, right — and tickets are now on sale.2


About The Conference

At Smashing Conferences, we take good care of the value that the event delivers to attendees. No speaker is selected randomly, no networking activity is an afterthought, and every single talk is thoroughly curated and reviewed. SmashingConf Whistler isn’t going to be an exception: with 2 days of heavily practical front-end talks4 and 7 front-end + RWD workshops5, you’ll leave the conference with a treasure of useful tips and tricks applicable to your work right away.

But it’s not just about tips and tricks though. Every project has issues, problems and valuable solutions that actually worked. That’s why we also feature lessons learned and solutions found, but also strategies, skills and tools you might need every single day. The conference will do just that — uncover front-end techniques and tools that worked, design approaches that worked and failed, why exactly they failed and what decisions were chosen instead.

Whistler7, a little paradise next to Vancouver, Canada. Quite smashing, isn’t it? As usual, we aim for an intimate conference experience with just 400 available seats.8

We like crowded multi-track conferences. No, we don’t. We aim for a small, intimate conference experience with one single track and lots of networking before and after the event, with an attendees jam session, warm-up party and a cable car adventure! And this time it’s topped with spectacular resort adventures from skiing to ziplining, an ultimate Smashing skiing challenge and perhaps even occasional snowball fights — with extraordinary scenery9 that will smash you away! Sounds like fun? It surely is!

Ah, by the way, since the conference will take place right in the middle of the ski season, why don’t you bring along your family or colleagues, and enjoy a vacation that you well deserve together? We’ll do it, and so could you!


First Speakers and Workshops

Alright, speakers! The line-up of speakers11 and workshop coaches is almost complete now, but of course we aren’t going to reveal everything just yet. But let’s spice up a bit of your appetite: the first confirmed speakers are listed below. Ready? Set. Go!

First confirmed speakers, John Allsopp and Lyza Danger Gardner. The venue has a few fireplaces, so guess who will be taking care of them!

  • John Allsopp
    (Dao of Web Design, RWD)
  • Lyza Danger Gardner
    (Mobile Strategy)
  • Paul Irish
    (Performance, Google Chrome)
  • Susan Robertson
    (Front-End, Style Guides)
  • Brad Frost
    (Responsive Web Design)
  • Jenn Lukas
    (Front-End, Workflow)
  • Tim Kadlec
    (Front-End, Performance)
  • Val Head
    (CSS Animations)
  • Stephen Hay
    (Front-End, RWD, Workflow)
  • Yoav Weiss
    (Responsive Images Group)
  • Vitaly Friedman
    (Responsive Web Design)
  • Mystery Speaker
    (Someone you definitely know.)
  • …more speakers will be announced soon!
Hands-On Workshops

We’ll also host hands-on full-day workshops13 with more in-depth practical learnings taught by well-respected designers and developers. Be it performance of responsive websites, UX/design patterns and responsive workflow, offline client-side storage, responsive images or CSS animation, we carefully selected topics that will help you become better at what you do. So if you are going to attend the conference, why not attend a workshop as well?

In fact, if you book a workshop too, you’ll save $100 off the conference + workshop ticket price. Well, enough already. Tickets are on sale now14, you know.

You deserve a spectacular vacation, don’t you think? Well, what if you combine attending a conference with a memorable skiing vacation? That’s what we thought! Grab your ticket.16

Why This Conference Is For You

The conference is for you because you’ll learn quite a few valuable techniques for your workflow, and you’ll meet fantastic, like-minded people from the industry (no need to mention the ultimate hiking-skiing-adventure-ziplining-snowboarding-networking, right?!). You’ll learn:

  1. Strategies for building fast responsive websites,
  2. Guidelines for designing effective systems in complex projects,
  3. Front-end techniques for smart, delightful animations,
  4. How to build and maintain pattern libraries and style guides,
  5. How to use responsive images today without performance hits,
  6. Where icon fonts and SVG fit and how to use them properly,
  7. Tips and tricks for an efficient workflow in responsive projects,
  8. How to optimize the critical rendering path for better performance,
  9. Strategies for using offline client-side storage meaningfully today,
  10. Common issues, problems and solutions in responsive eCommerce,
  11. Guidelines for selecting an appropriate mobile strategy,
  12. Insights about effective and smart problem-solving,
  13. Guidelines for smarter front-end and CSS architecture,
  14. Advanced front-end tooling and setup,
  15. Mistakes and lessons learned from large projects,
  16. How to increase productivity and stay happy,
  17. …more practical takeaways from various areas of Web design.


Ticket Sales And Pricing

Only 400 tickets are available, and we do everything possible to keep our prices fair and affordable. The price for two full conference days is US$549 for early-bird tickets, and US$599 for regular tickets. And again, if you book a workshop as well, you’ll save US$100. Now, enough already±what exactly are you waiting for? You can get your ticket right away.18

“8 reasons why you should send your incredibly hard-working, deserving employee to the SmashingConf” (PDF20). Quite self-explanatory, really.

Of course, we also prepared a neat Convince Your Boss (PDF)21 (0.15 Mb) that you can use to convince your colleagues, friends, neighbors and total strangers to join you or send you to the event. We know that you will not be disappointed, and neither will they! Still not good enough? Well, just tweet us @smashingconf and we can convince your boss for you — yep, we can be quite convincing, indeed!

We Welcome Lovely Sponsors, You Know

We do everything possible to keep ticket prices affordable for everyone, and we welcome sponsors to help us create a truly unique, unforgettable conference experience. And you can be a major part of it.

We have quite a number of attractive and creative sponsorship packages for you (adventure sponsorship package, anyone?), and we are also flexible and would love to adjust them to your needs. So if you’re interested, please email us at hello@smashingconf.com22 — we’d love for you to be involved!

See You In Whistler!

You’ll find all the information you might need about the locations and hotels23 on the SmashingConf website. We are looking forward to seeing you in Whistler, and who knows, perhaps our paths cross at one of the snowboarding rounds or skiing routes? Grab your ticket24 and see you there?

.rounded img { border-radius: 8px !important; padding-top: 0; padding-bottom: 0; margin-bottom: 0.65em; margin-top: 0.65em; }.centered { text-align: center;} Footnotes

The post “Where No Web Designer Has Gone Before!” SmashingConf Whistler, Canada appeared first on Smashing Magazine.

Prioritizing Devices: Testing And Responsive Web Design

Mon, 07/14/2014 - 13:46

My Android Galaxy smartphone is so sweet. It plays games, has a lovely screen and lets me check all of my favourite websites while I’m commuting to and from work. And my new iPad is even better; it’s all I use at home when I’m relaxing in the living room, cooking in the kitchen or toileting on the toilet. As a consumer of electronic gadgets, I’m happier than Angelina Jolie in an orphanage with all of the devices with which I can use to access the Internet.

As a developer, I hate it.

Have you seen how many browsers and devices we have to test now? I remember when Internet Explorer (IE) 8 came out and we were annoyed that we had to start testing six browsers. Now, we’re testing at least 15! Back then, when every home had broadband and before anyone had a smartphone, we were living in the Golden Age of web development. We never knew how easy our jobs were.

Because of all the things we have to support now, testing has become really, really, really difficult and also super-expensive. But imagine having to support and test all of these browser and device combinations while also responding to the news. When you work in a busy environment like the BBC News, where much of what you make is pegged to a news story or breaking event and everything is made using responsive web design, the job becomes really tricky and occasionally very stressful.

In the Golden Age of web development, we had to support only five desktop browsers on a broadband connection.

Unfortunately, we can never move the deadlines that news events present to us. We can’t contact the UK government and ask them to postpone an election by a few more days while we get the new responsive timeline carousel working in IE 8. And during the flooding in the UK earlier this year, we couldn’t contact God to ask him to pause the heavy rain long enough for my team to get the interactive flooding map working in Android 2.3.

Before responsive web design, we had to test five web browsers on a desktop computer. Now with responsive web design, we have at least 15 browsers working on a myriad of different-sized devices, with many different input types, multiple pixel resolutions and hugely varying connection speeds.

Your boss might have once dictated your testing strategy as such: “This website has to work perfectly in all of the browsers on this list.” If you tried to carry out that strategy with the vast number of browser and device combinations that now visit your website, you would quickly spend a fortune and get sucked into a testing black hole.

There must be a better way to deal with the problem that responsive design has created for testing. So, let’s step back from this testing singularity for a moment and think about the problem.

In this article, we’ll devise a testing strategy so that you don’t have to test every device every time you want to update a live website. I’ll draw on my experience as a developer working on the BBC News’ website.

Devising A New Testing Strategy

With unlimited time, money and human resources, you’d be able to test your entire website on every device, every day of the week. In the real world, even large organizations like the BBC don’t have the resources to attempt this perfect solution.

Nevertheless, as developers, we’d expect JavaScript that works in Chrome to probably work in Safari or Firefox, too. We’d also be confident that the majority of our CSS would render correctly. However, we’d be less certain that a responsive layout would work perfectly on multiple devices. And when we test the layout on an old Nokia device, we’d be more nervous than a startup founder about to meet a venture capitalist.

We can take advantage of similarities between browsers and devices. If some code works on a Samsung Galaxy S4 running Chrome, then it probably also works on an Android tablet or iPhone 5S. If IE 9 throws no JavaScript errors, then we’d be able to test IE 10 and 11 with much more confidence. But some browsers are so old and wicked and unlike anything else we have to deal with — yes, IE 8, I’m looking at you — that we should always test on them.

IE 8 is throwing more errors on this page than Miley Cyrus manages to twerk in a concert.

While you should try to support as large a proportion of your audience as possible, your analytics will show that a small group of browsers and devices make up the majority of your traffic, while the rest are a long tail of obscure browsers and devices. Take advantage of this.

By prioritizing which devices and browsers you test first, you can maximize your testing time. Don’t think of testing as a single task; break it up into groups of browsers according to how important they are to you. You could — dare I say — take shortcuts. Do 50% of your browser testing and then release, knowing that the majority of your users won’t see bugs, and then test and fix the long tail.

This new strategy could be carried out in different ways:

  • Making a major new version of your website? Test all browser groups.
  • Making a minor change that needs to be released very quickly? Test your primary and secondary browser groups, release, and then test the rest and release again if need be.

In the industry, running a segment of tests is called “smoke testing.” Smoke testing is a quick process that gives you confidence that you haven’t broken anything fundamental in your product. By sometimes choosing to test only your primary group of browsers, you’re effectively smoke testing for certain browser and device combinations.

Every Website Is Different

Before you present the top of this article to your boss and start testing only iPhones, consider that every website is different. Websites have different objectives and audiences and, thus, will be visited by different browser and device combinations.

With any new strategy, first consider the audience of your product:

  • Age and class
    Young people and less affluent people are more likely to use non-desktop devices. As a developer who’s been in the industry for 15 years, I struggle to accept that my desktop-centric mental model of the web is now in a minority.
  • Global distribution
    Different form factors are popular in different regions of the world. High-end smartphones are most popular in the West. “Phablets” (i.e. really big phones) are popular in the East because the larger screen size makes it easier to type text messages with Eastern character sets. Phones with long battery life are popular in rural India and Africa.
  • Engagement time
    In the UK, desktop browsers now make up less than 50% of a typical website’s traffic. This number drops dramatically on the weekend and rises dramatically during workday lunchtime (especially for legacy versions of IE installed in offices).
Testing All The Things 1Setting up this photo caused a sudden spike in traffic from old Nokia devices to our website.

The point of grouping is to get the most out of testing as few devices as possible. So, for your first group, test as many different properties as possible. I call this a “test matrix”:

  • Screen size
    Designing responsively means being agnostic to device type. So, get a good idea of how your website works on a wide range of screen sizes.
  • Connection speed
    Treat connection speed the same way. Unfortunately, there is no correlation between screen size and connection speed. While a given device might be able to connect to Wi-Fi as well as to various mobile connection types that offer different Internet speeds, mobile devices generally limit the number of concurrent downloads to two. This means that even when an iPhone has a Wi-Fi connection, it still won’t be as fast as a MacBook. You’ll have to account for this.
  • Pixel density
    Pixel density refers to the number of pixels that make up a screen. The higher the pixel density, the clearer the picture on the screen will be. Differences in pixel density can cause issues that are subtle and hard to debug. The biggest issue I’ve come across is browsers that calculate subpixel values differently (which happens when widths are defined with a floating point percentage, such as 33.3%), thus breaking the layout.
  • Interaction style
    Make sure to cover not only mouse-and-keyboard interaction and touch interaction, but also D-pad styles of interaction, which happens with the arrow keys on a phone keyboard or the “nipple” on a BlackBerry (honestly, it’s called a “nipple” — ask your mum if you don’t believe me). However, don’t prioritize D-pad interaction unless Nokia and BlackBerry phones make up a significant share of your traffic.
  • Similarity to other browsers
    If browser A is very similar to browser B, and browser A passes your test, then browser B has a lower chance of causing serious problems than other browsers. So, you can lower the priority of browser B and expect to deal with only minor layout issues later on. If browser C has a smaller user base than browser B but is much older and has more differences, then you should probably test browser C earlier in the development cycle to catch issues that are harder to solve than minor layout bugs.
  • Browser rendering mode
    Browsers have two ways of rendering a page:

    • the standard client-side rendering that we are all used to,
    • proxy rendering.

A proxy browser sends the requested URL to a server, which downloads and renders the page before serving an image of the page to the user. A proxy browser renders much faster than a typical web browser and so is popular among users who are sensitive about their data plans, but they come at a cost.

Because the user is looking at a screenshot of a web page, the design might not work quite as intended. While proxy browsers might sound like a niche case and not worth prioritizing, note that Nokia’s Ovi browser, Opera Mini and the Chrome mobile browser either are proxy browsers or have proxy rendering modes.

Understand Your Testing Options

We have quite a few options for testing in the industry now: emulators, virtual machines, testing services like BrowserStack2 and grassroots community efforts like Open Device Lab20123. While testing services are great at showing what your website looks like, they will never be as good as testing your code on actual devices. Emulators and testing services are more efficient than buying and maintaining your own device lab, and they really help you to understand how your code behaves on different platforms, but they don’t tell you everything you need to know about the UX.

Are loading times fast enough? Are the hit sizes big enough? Will the user’s hand get in the way of the screen and keep them from noticing a change? Does the time between pressing the screen and the resulting change feel adequate?

4BrowserStack is great for seeing how your website renders across many devices, but it doesn’t give you any haptic feedback.

Testing services are good for finding logical issues with your code — JavaScript errors, timeouts, etc. — but the coverage is only as good as the test that you run. The services suffer from a positive bias, in that they are good for asserting that stuff works. They won’t tell you whether something feels wrong or looks strange. I always suggest eyeballs for testing; unfortunately, this doesn’t scale to large products, especially if you lack dedicated testers.

You need to make a judgment call, balancing the amount of testing required with the testing resources available. Can you split up automated and manual testing, focusing the latter on new features? Are you continually testing something that never changes? If you test frequently, could you test a proportion of each part of the product or randomly choose features to test?

Group Devices By Priority

Now that we’ve gotten the theory out of the way, let’s look at an example in practice. The device groups defined below are specific to the statistics for the BBC News, so adapt the list to your website according to the advice in the section above “Every Website Is Different.”

Group 1

Group 1 is essentially the Chrome, Safari and Android browsers on different devices and the desktop (“desktop” here meaning both Mac and Windows). Group 1 generally covers just over 50% of an audience for a typical website and is the absolute minimum amount of testing I would recommend before any kind of release.

I strongly recommend that you purchase the following devices:

Device/Virtual machine/Emulator Browser Screen size Pixel density Interaction style Connection speed Browser similarity Rendering mode your development machine Chrome latest large standard mouse/keyboard broadband other modern browsers typical Samsung Android 4.* device Chrome latest small high touch broadband/mobile N/A typical Apple device running iOS 7 Safari 6 small/medium high touch broadband/mobile N/A typical Apple device running iOS 6 Safari 5 small/medium high touch broadband/mobile N/A typical Samsung Android 4.* device Android browser small high touch broadband/mobile N/A typical any Android 2.3 device Android browser very small standard touch broadband/mobile N/A typical

(Large view5)

This could easily cost you the best part of $2,500. I am really sorry about this, but I’m guessing that because you read Smashing Magazine, you’re a technologist, so you probably already have one of these devices in your pocket.

Android devices are much cheaper than iOS devices anyway, so spending some of your budget on two Android devices is worthwhile. These four devices plus Chrome on the desktop should be your primary testing group. Chrome is the most popular desktop browser — fortunately, too, because most developers prefer to work in it.

You’ll need to test both Chrome and Android’s default browser on a Samsung Galaxy device running Android 4.*. All top-end Android devices (made by HTC, Sony and Motorola) except for Samsung now ship by default with Chrome. Only Samsung uses a slightly modified version of the browser that ships with the Android Open Source Initiative — that browser is a flavor of WebKit.

Recommended buys:

  • Buy an iPad and an iPhone. Make sure they have different versions of iOS so that you can test Safari 5 and 6 in different resolutions.
  • Buy a top-end Samsung Galaxy Android 4.* device and a cheap Android 2.3 device. This will give you an idea of how your code runs on Android devices with different types of processors and memory sizes.

Cheaper alternative:

  • Download Apple’s Xcode IDE and use the iPhone virtual machine. This will give you access to all versions of iOS on all devices, but then you’d have to buy a Mac, so that would still cost you the best part of $2,500 anyway.
  • Download the Android IDE (Java, yuck) and use the Android virtual machine. This isn’t highly recommended, though, because you wouldn’t be able to see your website in action on low-end hardware.
Group 2

The good news about group 2 is that there are no devices to buy (if you develop on a Mac). The bad news is that it requires downloading a lot of virtual machines. Group 2 consists mostly of desktop browsers:

Device/Virtual machine/Emulator Browser Screen size Pixel density Interaction style Connection speed Browser similarity Rendering mode virtual machine IE 8 large standard mouse/keyboard broadband N/A typical your development machine Safari 6/7 (see note below) large standard mouse/keyboard broadband other modern browsers typical your development machine Firefox latest large standard mouse/keyboard broadband other modern browsers typical virtual machine IE 11 large standard mouse/keyboard broadband other modern browsers typical Windows Phone 8 Emulator IE 10 mobile small standard touch broadband other modern browsers typical

(Large view6)

Note: Depending on the version of OS X your MacBook is running, you will most likely have Safari 6 or 7. Mavericks is the latest and most popular version of OS X, so prioritizing Safari 7 is recommended.

IE 11 and 8 can be tested using virtual machines downloaded from modern.IE137. Windows Phone Emulator8 can be downloaded from Microsoft. Notice that I’ve not mentioned IE 9 or 10. You can test those browsers with virtual machines, too, but the majority of those users would have upgraded to IE 11 by now, so their priority is lower.

IE 8 is a special case because there is no upgrade path for users stuck on Windows Vista or Windows XP, and, being so old, it will be the browser that gives you the most problems. The BBC News’ statistics show almost no IE 8 users on weekends or on weekday mornings or evenings, but we get a sudden spike of IE 8 activity during workday lunchtimes. This indicates that people now mostly use IE 8 when they are on their lunch break at work.

Recommended buys:

  • If your development machine is a Mac, then definitely include Safari 6 in this group. If not, then depending on the size of your audience, you might want to think about getting a Mac. Spending $2,500 for one device is expensive, and your budget would be better spent on other devices, so this is recommended only if you have a large budget for devices.

Cheaper alternative:

  • If your development team is PC-centric, then you could look to BrowserStack to test Safari 6. BrowserStack can be used instead of all of these virtual machines, too, and might be preferable if your machine is old. Virtual machines require at least 1 GB of memory to themselves to run smoothly. I’d recommend a minimum of 8 GB to run virtual machines because you’ll want a couple of them up at the same time.

Expensive alternative:

  • Buy a Nokia Windows Phone. Devices are always more preferable than emulators.
Group 3

A third group consisting of Opera Mini and Nokia’s Ovi browser is also worth considering. These are “proxy browsers” that behave differently than standard browsers (see above for a description of how they work):

Device/Virtual machine/Emulator Browser Screen size Pixel density Interaction style Connection speed Browser similarity Rendering mode Apple device running iOS 7 Opera Mini latest small/medium high touch broadband/mobile N/A proxy any Nokia Ovi device Ovi browser very small very low D-pad/touch broadband/mobile N/A proxy

(Large view9)

Download and test Opera Mini on your iOS 7 device. If you have an international audience, then a Nokia Ovi device is a mandatory purchase; we have a Nokia C5 in our device drawer. While Nokia budget phones are not insanely popular in the UK or US, they are more popular in markets that value low prices, battery life and robustness (dropped your iPhone recently?). If you have a global audience, then definitely allocate part of your budget to a Nokia Ovi.

A few years ago, there was a clear distinction between the new range of smartphones that were appearing on the market and traditional “feature” phones. Unfortunately today, that distinction is not clear at all. The definition of a smartphone used to be that it supports Wi-Fi, has a modern browser, has a touchscreen and supports apps. The Nokia C5 has all of these features. Every phone is a smartphone now.

The big difference between the top and bottom ranges of phones is hardware capability. Manufacturers differentiate and compete by varying the amount of processing power and RAM available in each phone. This means that, while the difference in browser (read “software”) capabilities between, say, an HTC One and a Sony Experia Typo is nil, the difference in capacity to process your website and in reaction times to user input (read “hardware”) is huge. You can’t detect a device’s processing power or memory, so understanding how your website works with limited hardware is important.

Recommended buys:

  • Nokia Ovi phone
Group 4

Group 4 is the long tail of browser support. The previous three groups had distinct characteristics (popularity, desktop, proxy rendering). Group 4’s characteristic is randomness! This is where your testing gets more varied and where the value of spending time on edge-case bugs decreases.

Device/Virtual machine/Emulator Browser Screen size Pixel density Interaction style Connection speed Browser similarity Rendering mode virtual machine IE 10 large standard mouse/keyboard broadband other modern browsers typical virtual machine IE 9 large standard mouse/keyboard broadband other modern browsers typical your development machine Firefox desktop version 4 large standard mouse/keyboard broadband N/A typical your development machine Opera desktop latest large standard mouse/keyboard broadband N/A typical Apple device running iOS 7 Firefox Mobile latest small/medium high touch broadband/mobile other modern browsers typical Apple device running iOS 7 Opera Mobile latest small/medium high touch broadband/mobile other modern browsers typical BlackBerry device running BB10 default browser small high touch broadband/mobile other modern browsers typical BlackBerry device running version 6 default browser small standard D-pad/touch broadband/mobile N/A typical BrowserStack Safari desktop 6 large standard mouse/keyboard broadband other modern browsers typical BrowserStack Safari desktop 5 large standard mouse/keyboard broadband other modern browsers typical

(Large view10)

  • Firefox desktop version 4 is the last version of Firefox that doesn’t auto-update; it’s the only old version of Firefox still trending in our statistics. It’s big enough for you to consider testing; fortunately, though, despite its age, it’s still a decent browser, so unless you are using advanced CSS3 features, you shouldn’t find many problems.
  • Firefox Mobile and Opera Mobile are excellent modern web browsers. They are a low priority because they render pages so well that you can expect your website to work in them with only minor layout issues by the time you make it down to the fourth group of browsers.
  • IE 9 and 10 are quickly disappearing from our statistics. We think they will be completely gone by the end of the year. Check your own statistics before deciding whether to support them.
  • BlackBerry devices are still worth testing. From OS 6, BlackBerry’s default browser has actually been very modern and feature-rich. The difference between this and other devices, though, is its form. Many BlackBerry owners use the trackball (D-pad) to move a cursor around the small landscape-oriented screen. This screen makes a mockery of people who design for the “fold,” because the fold on these devices is 200 pixels tall.
  • Safari 6 is the version of Safari that comes with Apple OS 10.7. While 10.7 isn’t the latest version of Apple’s operating system, it’s still relatively popular. Safari 6 is very similar to Safari 7, so it’s not worth the large investment required for an additional desktop machine.

Recommended buys:

  • As always, I recommend buying the devices if your budget allows. Buy a BlackBerry 10 and a BlackBerry Bold running OS 6. BlackBerry Bold should still be available on eBay, while the BlackBerry Z10 (running BlackBerry OS 10) should be available in most stores.

Cheaper alternative:

  • Test Safari 6 using BrowserStack. It’s still available to test via Mac OS X Lion.
  • Test Safari 5 using BrowserStack. It’s still available to test via Mac OS X Snow Leopard.
  • Unfortunately, BrowserStack doesn’t have BlackBerry devices to test; however, you can download and run simulators from BlackBerry’s website11. You can run a Playbook simulator as a virtual machine on a PC or Mac, but the Playbook was never popular, so the simulator isn’t very useful. The phone emulators are much more useful; you can download exact model and OS versions, but they only work on a PC, so you will need a second machine if you are a Mac user.
  • An Open Device Lab20123 is an even cheaper alternative to BrowserStack, but the devices available to you will depend on what is available in the lab in your area. You will also need to account for the cost and convenience of getting to the device lab.

Expensive alternative:

  • Buy a Mac running 10.7 to test Safari 6. This might be the best choice if your development machine is a PC.
  • Buy a Mac running 10.6.8 to test Safari 5 — but only if you are seriously loaded!

Testing (or, to use the proper term, quality assurance) is a profession unto its own. As designers, we shouldn’t try to simplify the testing process; rather, we should understand the different testing strategies well enough to solve the challenges we now face in trying to support browsers.

Although the explosion of devices that started with the iPhone has dramatically increased the number of browsers we have to support, remember that a large proportion of your audience use only a handful of devices. The rest of your audience consumes the web via a massively diverse long tail of devices. Test your product on as many devices as possible, but also prioritize which devices to test in order to maximize your time.

Test hard, but test smart. Nobody can test everything all the time.

Further Reading

(al, ml)

.scrolly{overflow-x: scroll;width:100%;} Footnotes

The post Prioritizing Devices: Testing And Responsive Web Design appeared first on Smashing Magazine.

A Roadmap To Becoming An A/B Testing Expert

Fri, 07/11/2014 - 13:40

A/B testing, also known as split testing, is the method of pitting two versions of a landing page against each other in a battle of conversion. You test to see which version does a better job of leading visitors to one of your goals, like signing up or subscribing to a newsletter. You can test two entirely different designs for a landing page or you can test small tweaks, like changes to a few words in your copy.

Running A/B tests on your website can help you improve your communication with visitors and back up important design decisions with real data from real users. With the multitude of tools available (detailed later), split testing has become easy for even non-technical people to design and manage.


To learn more about the basics, read our previous article from 2010, “The Ultimate Guide to A/B Testing2.”

When To Start Testing

Start testing only when you have enough visitors and enough conversions to run the test in a timely manner (a conversion happens when someone completes one of your goals). What does that mean?

The ideal number of visitors will vary according to your typical conversion rate. Plan on at least 1,000 visitors for each variant, and 150 conversions for each variant. For some websites this might take four hours to complete, for others an entire month.

To find out exactly how many visitors you’d need to run a test, plug a few basic metrics into Evan Miller’s sample-size calculator3.

You could run a successful business with 80 visitors a month, but you wouldn’t be able to run a statistically significant4 A/B test. Don’t start A/B testing before you’ve done any marketing. Get a steady flow of people to your website before doing any optimization.

Keep in mind that you don’t have to build your product before starting A/B tests. You can test a splash page and find out how future customers respond to planned features and pricing tiers.

Your First Test

For your first A/B test, keep it simple. Tweak your existing landing page to get your toes wet. Focus on low-hanging fruit:

  • copy in h1 and h3 headings;
  • copy in call-to-action buttons (for example, “Try it free” versus “Sign up” versus “Get started”);
  • the color, size and position of call-to-action buttons;
  • a short page versus a long page (by hiding long sections).

You can run multiple variations at one time, so dream beyond just two tweaks. You can also run multiple A/B tests at one time, but focus on one at first to get the hang of it.

Run the tests anywhere from a couple of days to a month. Your A/B testing tool will declare the statistically significant winner. Once a winner has been declared, make the winning variant part of your permanent website by updating the underlying code.

Then, clear the way for more A/B tests.

Where To Go From Here

Low-hanging fruit is a perfect place to start, but A/B testing isn’t all about that. Sure, testing button colors and heading copy will improve your conversion rate, but think beyond how a page looks. Think outside the box:

  • Highlight features versus benefits.
    Are you pitching features of your product in a checklist? Try illustrating the benefits of the product by describing a dream scenario for the customer.
  • Accelerate page-loading.
    Keep the landing page super-simple, and make it load in under a second.
  • Show a big video with someone talking.
    Try removing the big screenshot and dropping in a big video that demonstrates your product, perhaps one in which you’re talking to the camera. Make a personal connection.
  • Survey new customers.
    Talk to new customers to see what made them sign up and what has been most valuable to them so far. Highlight these in a test.
  • Find out what confuses new customers.
    Ask new customers what confused them about the website or what questions they had that were left unanswered. Incorporate your answers into an A/B test.
  • Add testimonials.
    Use social proof in the form of testimonials. Try putting an avatar or company logo next to each name.
  • Change the writing style of headings and main content.
    Change the style of headings and content on your blog to see how it affects newsletter subscriptions. Try writing two versions of the same article.
  • Experiment with pricing tiers and your business model.
    Change your pricing structure, even if only on your public-facing page, to see how potential customers respond.
  • Make the sign-up form super-short.
    Remove any unnecessary steps in your sign-up form.
  • Radically change the design.
    Try a different approach with your landing page, like what Campaign Monitor did5 with its big modal for new visitors.

Remember that conversion isn’t a one-time deal. When you say that you want more registrations, what you’re really saying is that you want more lifetime customers. When you say that you want more podcast listeners, you’re really saying that you want a larger dedicated audience that won’t stop telling their friends about you.

Monitor how your A/B tests affect your long-term goals.

Tools To Use

To run A/B tests, I recommend using VWO6 (Visual Website Optimizer). You won’t need to edit your website’s code for each test and redeploy. Instead, you would use the tool’s WYSIWYG editor.

7(View large version8)

With VWO, you can do split URL testing, which tests two completely different pages, as well as multivariate testing, which tests more than two variants at a time — think of it like A/B/C/D/E/F/G testing. VWO uses statistical significance to declare the winner. A new version of the software is coming out soon, too.

Optimizely9 is another simple WYSIWYG tool, and Google Analytics Content Experiments10 is a solid free option. If you’re looking to A/B test an email campaign, use Campaign Monitor11.

To set up your first test with VWO, install the code12 above the closing <head> tag in each page that you’re going to test.

The only other step is to define your goals13. Complete this sentence: “I want more…” Perhaps you want more people to sign up for your free trial, subscribe to your newsletter, download your podcast or buy something from your store. Your goal will determine which variant in the test is the winner.

Taking It Too Far

A/B testing is not a silver bullet. Optimizing the conversion rate will make a good landing page better, but it won’t fix a product or company that has fundamental problems.

Narrowly focusing on A/B testing will turn your customers into mere data points. Your customers are not conversions that you push down a funnel. They are real people with real problems, and they are looking to your website for a solution.

Don’t sell out your visitors for short-term gain. Putting a giant red “Try it free!” button will increase conversions, but your business won’t be any better off in 12 months. Keep the long game in mind.

The goal of A/B testing isn’t to mislead potential customers into buying something they don’t want, but rather to clarify how you should communicate a product’s benefits and to make sure that customers understand the language you’re using.

As long as you’re confident that the product is great, then just use A/B testing to tweak how you present it to customers. If you know that the product is helpful, then don’t try to manipulate visitors through your funnel. Always put the product first.

Finally, don’t ignore your gut. You can use data to back up your instinct, but rely on your experience in the industry. Don’t become 100% data-driven.

Further Reading

(ml, al, il)


The post A Roadmap To Becoming An A/B Testing Expert appeared first on Smashing Magazine.

How To Profit From Selling Digital Products (Part 1)

Thu, 07/10/2014 - 13:18

At the end of 2012, I was talking with a good friend of mine who runs a small custom woodworking company. We were discussing business over the last year and a few things we learned. While his business did about double the revenue that mine did in 2012, I made considerably more profit.

That’s when it sank in how unusual my business really is: Instead of having a 10 to 20% profit margin like many businesses, I had an 85% profit margin in 2012. That actually could have been much higher, except that I spent some money on equipment (I needed that 27-inch display) and hiring freelancers. After creating each product, I have only 5% in hard costs for each sale. And the product can be sold an unlimited number of times.

Compare that to the custom woodworking company, which has to bear not only the material cost for each new project, but also the time, because everything is custom. To be clear, I’m insanely envious that my friend creates such beautiful real-world furniture, but from a business perspective, I far prefer selling digital products.

Drug Dealers

Back in 2008, I read Tim Ferriss’ 4-Hour Workweek. From the section in which Tim talks about different kinds of businesses to create, one quote really stuck with me:

There is one class of product that meets all of our criteria, has a manufacturing lead time of less than a week in small quantities, and often permits not just an 8–10× markup, but a 20–50× markup.

No, not heroin or slave labor. Too much bribing and human interaction required.


Information products are low-cost, fast to manufacture, and time-consuming for competitors to duplicate.

It took a few years, but that quote is a big part of why I got into selling design and marketing books and courses online. I create the product once, then sell it over and over again to people all around the world. Every time the product is sold, I pay credit-card processing fees, but otherwise I don’t have any costs tied to each sale.

Because there is nothing to manufacture or ship, my day-to-day involvement can be quite limited. I’ve taken multi-week trips during which I just check in every few days — and actually made more money when I wasn’t working!

Any Digital Product

This business model works not only with books and training, but with tools, themes, plugins, software and so much more! I’ve seen plenty of creators sell everything from Photoshop brushes to songs to WordPress plugins, often making $3,000 or more per month!

Sell Your Byproducts

If you work in any kind of creative field, then you have byproducts. As you focus on creating products or running your business, you create other tools or resources that help in the process. A great way to start selling digital products is to look at your workflow and see what tools or skills you use every day.

I’ve written two books about designing software. The byproduct of writing those books on design is that I became quite good at writing, packaging and launching ebooks. I took that knowledge on how to write a profitable book and released it as Authority, my latest book on marketing.

Kyle Webster1 is a fantastic designer and illustrator who has created many tools to improve his own workflow. Instead of just keeping those tools to himself, he decided to sell some of his custom Photoshop brush sets. Other designers are thrilled to be able to buy such high-quality tools so that they don’t have to create them themselves.

Brushes (View large version3)

Those brush sets are the byproduct of design work that Kyle was already doing for clients. Now he has an entirely new stream of revenue (in addition to what his clients pay him) from selling digital products.

What byproducts do you create from your everyday work?

How To Get Customers

Unfortunately, just creating the product isn’t enough to make money from it. You need customers. For my first few products, I had no idea how to get customers, which became obvious from the sales figures. Sales ranged from nothing for three or four different products to a few hundred dollars for WordPress themes — not even close to enough money to quit my job.

Marketing That Works

Marketing can’t be that hard, right? After all, practically every college teaches marketing, and the Internet is filled with articles on how to market products. It turns out marketing is very hard — at least it was for me.

From my college marketing classes, I learned that I should brainstorm ideas, share them with a focus group, build brand loyalty, synergize with other sellers and… I have no idea. Really it was all just a collection of marketing buzzwords that might work for a multi-million dollar business but didn’t give me any way to start selling digital products online.

My Product Track Record

I’ve launched a lot of products over the last few years. Here is a list, in order of launch date:

  • Shoestring: no sales
  • Shop208: $60 per month
  • OneMotion: $300 per month
  • Legend Themes: $70 (3+ years)
  • OneVoice $2,000 per month (average, non-recurring)
  • Fluent: $40 (2+ years)
  • Commit: $9,000 (1 year)
  • The App Design Handbook: $53,000 (6 months)
  • Designing Web Applications: $95,000 (3 months)
  • Authority: $34,000 (1 week)
Can You See the Inflection Point?

Because the time scale is different for each product, it can be hard to see exactly, but there is a point in my product marketing education when I learned a valuable lesson. I’ll give you a hint: It happened when my launch numbers were consistently over $10,000.

This lesson was repeated to me dozens of times over the years, but I never really learned it until I started the launch strategy for my first book, The App Design Handbook.

A Story

While you’re trying to figure out what particular idea could have had such an impact on my business, let me tell you a story. Like any good story, it happened a long time ago.

Marco Polo was a Venetian explorer who lived from 1254 to 1324 and became famous for being the first to explore the Silk Road to China. At least that’s how he is remembered. There is only one small problem. He wasn’t an explorer at all. Like all good Venetians of the time, he was a merchant.

Plenty of people had explored the roads to the East long before Marco Polo. In fact, Marco’s father and uncle had made exploratory trips of their own well before Marco was born. So, why does Marco get all the credit? Why is he the one we remember?

Marco learned the same lesson that I did. That’s why we remember who he is. But good ideas span centuries, so let me introduce you to someone who is still alive today.

Back in 2007, Chris Coyier launched a website named CSS-Tricks4, dedicated to teaching people how to code websites. When CSS-Tricks launched, I remember reading a tutorial and arrogantly thinking, “I know that already.” Chris and I were at about the same skill level, so I wasn’t learning anything new from him.

This continued for a while as he kept putting out new tutorials. But over time, as friends started asking me questions about CSS, I found it easier to link to one of Chris’ articles (because they were really well written) than to explain everything myself.

Years later, Chris ran a Kickstarter campaign to redesign his website. Those who contributed would get behind-the-scenes access to additional tutorials and content related to the redesign.

The goal was set fairly low at $3,500. He quickly blew past the goal and by the end of the campaign had raised $89,697.

He and I started at the same point, and our skills progressed at about the same rate. The difference was that he taught and shared, whereas I kept what I was learning to myself. That made the difference between being able to make tens of thousands of dollars on a new project and sharing with no one.

Teaching is what Marco Polo and Chris Coyier have in common. Instead of keeping knowledge to themselves, they shared it eagerly with anyone who would listen. Because of that, they built trust and credibility. They built an audience.


Jason Fried calls this “emulating chefs.” In most industries, trade secrets are kept… well, secret — locked down behind firewalls and protected by non-disclosure agreements. Quite the opposite with chefs. They write down their secrets in a way that is easy to follow, which we know as recipes.

These recipes get bundled into books and sold to everyone for just $15 or $20. Imagine that! The trade secrets of your business, your competitive advantage, made available to the entire world!

But chefs don’t stop there. They go a step further and get cameras to record every step of the process, while they narrate, providing every detail that you might have missed from reading their recipe.

Aren’t they scared that another restaurant will open up across the street, steal their best recipes, and put them out of business?

Of course not.

By teaching, these chefs build credibility and an audience. Think of every chef you know by name. My guess is that most who come to mind have cookbooks and TV shows through which they give out every secret recipe. In doing so, their restaurants get booked up months in advance. The reputation they build helps to sell their product even more.

The Lesson

That inflection point you saw in my product revenue is the moment when I learned to teach. Jason Fried and others had been preaching this message for years, but it took far too long for it to sink in with me. Once I took teaching to heart and made it a core part of my business, sales skyrocketed.

Instead of scratching and clawing to find a few people who would listen to my sales pitch, I had an audience coming to me, eager to learn more and buy products.

So, what can you teach that relates to your product?

Using Email

Let’s say you start teaching through blog posts, webinars and tutorials. As your posts get shared around the web, some visitors will start to come to your website. At first, each visitor will be incredibly valuable. Once 10 visitors are coming each day, you’ll start to feel like you’re seeing some success. Unfortunately, most of those visitors will read your articles, forget about you and never come back.

Depressing, isn’t it?

Ignore Traffic

Early in my blogging career I made the mistake of focusing on traffic. Each day, I would check my Google Analytics statistics from the previous day (before they were real-time). Traffic is necessary to building an audience (and gaining customers), but you shouldn’t focus on it.

After blogging for a few months, I wrote a post that I knew would be popular: “How I Made $19,000 in the App Store While Learning to Code.”

How could you not click on that headline?

Sure enough, the post climbed to the top spot on Hacker News and was featured on Reddit and a bunch of other websites. In a single day, that post received more visitors than my entire blog had received up to that point.

Here’s the traffic pattern:

(View large version6)

I was thrilled! I felt like my few months of writing a post every week had finally paid off. I started planning my career as a successful blogger.

Can you guess where this is going?

(View large version8)

The traffic was unsustainable.

If you hid November in that chart, you would never be able to tell that there was a meaningful spike in traffic. That post did not make a long-term impact on anything, all because I didn’t have a good way to turn those visitors into regular readers.

Push, Not Pull

To stay in touch with your readers (and keep them coming back), you need a way to push content to them, rather than wait for them to remember who you are and come back to see whether you have anything new to say.

The next obvious question is, which platform to use?

RSS is common to all blogs, and Twitter and Facebook are supposedly the future of online publishing. So, the answer has to be one of those, right?


I’ve always felt that my Twitter posts didn’t convert to sales very well, so I finally decided to run the numbers9. The short version is that, comparing click-through and conversion rates between Twitter and email, an email subscriber is worth at least 15 times as much as a Twitter follower!

Email Subscribers Are Easier to Get

I was having a conversation with a friend a few weeks ago about this very topic. He said something that I’d felt for a long time but hadn’t quantified yet: “It’s so much easier to get email subscribers than followers on Twitter or RSS.”

I completely agree. When you ask someone to follow you on Twitter, the call to action is usually pretty lame: “Follow me on Twitter.”

But with email, you can actually incentivize the subscription by offering valuable content. My friends at Think Traffic offer their Traffic Toolbox for free to everyone who subscribes to their email newsletter.

Traffic toolbox (View large version11) What Can You Give Away?

Think through what valuable content you can offer. One of my most successful giveaways for getting new subscribers is a free course named “Mastering Product Launches12.” Linking to that at the end of a guest post can drive hundreds — sometimes over a thousand — new email subscribers.

One idea is to take some of your best posts on a particular topic and edit them into a single guide.

That’s exactly what I did with The Productivity Manifesto13, which has been downloaded thousands of times!

Value-Based Pricing

How much is a book worth? The most common way to answer that question is by comparison. Print books often retail for $20, but Amazon will sell a copy discounted down to $14. Mine are just digital, so we should probably knock at least $6 or $7 off because ebooks aren’t worth as much.

So, is your newly published ebook worth $7? Well, the ebooks at that price are by professional authors at major publishing houses. You’re just a first-time author who hired your mom to proofread the book. (Luckily, my mom is a professional proofreader.) So, your book should be priced at just $3 or $4, right?

But remember those tales of authors hitting it rich on Amazon by selling their books for $0.99 or $1.99? You’ll want to sell tens of thousands of copies, so is that the right price?


Seriously, stop thinking this way.

Whether you are selling books or any other product, comparison pricing like this is a great way to be a poor starving creator. Don’t do it.

What’s the Value?

A designer or developer at a software company could earn thousands of dollars in value from the ideas in my book Designing Web Applications14. Just implementing the ideas on designing first-run experiences could radically improve their trial retention rates and generate a lot more revenue. So, is that self-published book worth $2? No, it’s worth hundreds. Maybe not to everyone, because people working on small projects without many users wouldn’t get the same value out of each improvement, but pricing some people out of the market is OK.

A Photoshop plugin that saves a designer 10 minutes every workday isn’t worth just $15. If it’s integral to their workflow, you could easily charge $50. After all, good designers charge over $100 per hour for their time, so a good $50 plugin would pay for itself in a couple of days of saved effort.

If your product is focused on business customers, you could — and should — charge far more than you think. Because my business is teaching and training, I reason that I can charge premium rates if I am teaching a skill that makes money for people who have money.

I teach design to professional designers and developers. They use those skills to make their products easier to use and more profitable. If you were to teach knitting to middle-school kids, not only would they not be able to use those skills to make a living, but they wouldn’t have money to spend on your product.

Value-based pricing doesn’t work as well with consumers, who tend not to think about purchases based on the return on investment. But you should still probably increase your price to focus on the higher end of the market.

A Small Audience

I’ll assume that you don’t have a massive audience (10,000+ fans) that is eager to buy everything you produce. More likely you are in the early stages of your online business empire and are working on those first 500 or even 100 followers. The percentage of any following that will actually buy is quite low, so you’ll need to maximize revenue from each one.

If only 10% of your audience will actually buy from you, I doubt that lowering the price by a couple of dollars would encourage significantly more people to purchase. Conversely, in most cases, doubling your price wouldn’t cause you to lose 50% of your sales — meaning that you would come out ahead on revenue.

Pricing is flexible and hard to get right. Experiment with it. But if your goal is to maximize revenue, think about increasing your price.

Tiered Pricing

What if I told you that one simple method could triple your revenue? Would you pay attention?

I’ve used this method to triple my revenue on two book launches and more than double my revenue on two others. Implementing it does take some time, but not nearly as much as creating the rest of your product.

What is it?

Selling in Multiple Packages

You know when you subscribe to a web application and it asks which plan you would like? That’s tiered pricing, or multiple packages.

The vendor is segmenting their customers to allow those with larger budgets to pay more and get more value from the product. It’s common in software, but you can apply it to any other kind of product.

I do it with books. I sell just the book for $39 (remember, price based on value), then for $99 I include video tutorials, expert interviews and some other resources. Finally, the top package at $249 has even more resources (Photoshop files, code samples and anything else that would save the customer time), as well as double the interviews and video tutorials.

I’ve already spoiled the surprise by saying that this method doubles or triples revenue compared to offering just the book at $39, but let’s look at exactly how.

For my book Authority (which is precisely about how to write and profit from your own technical ebook), I used the package method mentioned above. According to the sales count (i.e. the number of copies sold), this is how the packages broke down:

  • the book ($39): 48%
  • the book + videos ($99): 26%
  • the complete package ($249): 26%

So, just the book by itself sold nearly 50% of the copies. Were the other packages worth offering, then? Definitely!

Here’s the breakdown by revenue:

  • the book ($39): 16%
  • the book + videos ($99): 24%
  • the complete package ($249): 60%
Sales and revenue of “Authority” compared (View large version16) Without Excluding Anyone

Raising prices almost always increases revenue. So, why don’t we just raise prices to ridiculous amounts? Because every time we raise the price, we exclude some people from buying. For some products, that’s good: Low-paying customers have higher support costs in general. So, in that case, getting more revenue from fewer higher-quality customers is a good thing.

But I still want my books and training to be accessible. While businesses have plenty of money to spend, I don’t want to price freelancers out of my training.

That’s the beauty of tiered pricing. You get all of the benefits of selling a high-priced product (the top package) to customers who have money (i.e. real businesses), while people who are just getting started can still afford a version of the product (the lowest package) — something for everyone, and you maximize revenue from the entire market!

While You’re Waiting For Part 2…

Well, that concludes part 1. Check back next week for part 2! There is plenty more to learn about email marketing while you are waiting though. For example, you could start off with a free course17 I’ve put together — with one lesson per day for the week you get a great introduction to making your email marketing efforts more profitable.

If you’ve had any experiences with selling digital products, I’d love to hear them!

(al, il)


The post How To Profit From Selling Digital Products (Part 1) appeared first on Smashing Magazine.

The WAI Forward

Wed, 07/09/2014 - 13:23

It’s one thing to create a web application and quite another to keep it accessible — independent of the device that the user is using and its capabilities. That’s why Heydon Pickering1, now the accessibility editor on Smashing Magazine, wrote an eBook Apps For All: Coding Accessible Web Applications342, outlining the roadmap for well-designed, accessible applications.

This article is an excerpt of a chapter in the eBook that introduces many of the ideas and techniques presented. Reviewed by Steve Faulkner3, it’s an eBook you definitely shouldn’t miss if you’re a developer who cares about well-structured content and inclusive interface design. – Ed.

Because the W3C’s mission from the outset has been to make the web accessible, accessibility features are built into its specifications. As responsible designers, we have the job of creating compelling web experiences without disrupting the inclusive features of a simpler design.

As Scott Jehl said4:

“Accessibility is not something we add to a website, but something we start with and risk losing with each enhancement. It is to be retained.”

Unfortunately, not all websites are destined to be as simple as the provocative manifesto that is “This Is a Mother****ing Website5” and, as web interfaces evolve, complying with the Web Content Accessibility Guidelines6 (WCAG 2.0) has become increasingly difficult. As we together embrace the advancements of the web and our newfound power to construct hitherto impossible web-based software, we need to tackle the accessibility of new idioms. We need to find a way to adopt new tools and techniques to keep the playing field level.

It’s time to embrace change.

ARIA: A Passion For Parity

The Web Accessibility Initiative’s (WAI) specification for Accessible Rich Internet Applications7 (WAI-ARIA) is an accessibility resource like WCAG 2.0, with certain notable differences. If it helps, you could think of the two resources as siblings: Both have been brought up in the same environment and have been instilled with the same basic values, but they differ in personality. WCAG 2.0 is the cautious homebody who keeps the home fires burning, while the more gregarious WAI-ARIA has ambitions to take accessibility to new territories.

Unlike WCAG 2.0, ARIA is not only a set of recommendations but a suite of attributes to be included in your HTML. Its tools enable you to alter and increase the amount of information shared about your HTML with users of assistive technologies. This is extremely useful when you’re making web apps because the roles, properties, states and relationships of elements in a web app are liable to be a lot more complex and dynamic. One way of looking at it is that ARIA gives you the tools to meet the WCAG’s requirements in web apps.

8 The Two Purposes Of ARIA

ARIA gives you the ability to reclassify and otherwise augment the perceived meaning (or semantics) of your HTML. That’s pretty powerful, but what is the purpose of it? ARIA has two main applications.


ARIA can be used as a remedy to improve the information provided to assistive technology by poorly coded, unsemantic markup.


For example, a developer might use a <div> and some JavaScript to emulate a type="checkbox". They shouldn’t, but they might. To make this <div> actually understandable as a checkbox, the ARIA role of checkbox10 can be added as an attribute, making screen readers think it is, in fact, a standard checkbox. In addition, our developer must use the aria-checked attribute to indicate whether the checkbox is indeed checked.

<div class="toggle-thingy" role="checkbox" aria-checked="false" tabindex="0">Yes?</div>

Using the proper input element, type attribute and checked attribute to communicate this information would be better — they are better supported than ARIA (which is relatively modern), and the input element would be automatically focusable, like a semantic <button> (so, no need for the tabindex). Nonetheless, we can employ ARIA in this way to make quick fixes to markup, often without disturbing the design of the application.


As we’ve established, web applications are more complex than simple web documents, and our use of HTML elements tends to exceed the basic semantics gifted to them. ARIA’s killer feature is its ability to help authors like you and me communicate many of these more ambitious uses in an accessible way.

Take ARIA’s aria-haspopup attribute11. It represents a property of certain elements that have a hidden submenu. The owner of this property is likely to be an <a> or <button> element and, without this special attribute, that’s all it would be to the user of a screen reader: No clue would be given that the submenu exists.

<li> <a href="#submenu" aria-haspopup="true" aria-controls="submenu1">Main link</a> <ul id="submenu"> <li><a href="/somewhere/">Submenu link</a></li> <li><a href="/somewhere/else/">Another link</a></li> </ul> </li>

Some of these ARIA attributes are expected to be replaced by simple HTML elements and attributes. As I write, the <dialog> element is being slowly adopted12 as the successor to the dialog and alertdialog ARIA role attributes, for example.

Where possible, superseding ARIA with plain HTML(5) is good because it simplifies the markup and centralizes the W3C’s advice. However, many attributes that communicate specific contextual information, such as the aria-haspopup and aria-controls13 properties in the code above, are unlikely to find as much mainstream support for inclusion as perhaps haspopup and controls will have.

As Steve Faulkner points out in “HTML5 and the Myth of WAI-ARIA Redundance14”, much of ARIA will continue to exist unbested. The unique power of ARIA is to bridge the gap between the experiences of sighted and unsighted web users.


A lot of my friends and colleagues are keen on tabletop role-playing games, which, in case you’re not familiar with them, are games in which participants play fictional characters who embark on quests and fight battles in fantastical worlds. Although I’m not a big exponent of these games myself, I’ve noticed similarities between the way characters are role-played in games and the way HTML elements act within web applications. Accordingly, I’ll use this role-playing metaphor to explain ARIA’s roles, properties and states in greater detail.

Don’t worry, you won’t have to be a big role-playing geek to follow along. I’m not!


Each player in a role-playing game normally maintains a “character sheet” that lists the important characteristics of the character they are playing. In HTML, the name of the character might be the id of an element. Each must be unique.

Characters have a lot more information than that in the sheet, though. For example, characters dwelling in these fantasy worlds usually belong to one “race” or another. Common standbys are elves, dwarves and trolls. These are like HTML element types: broad groupings of participants with common characteristics.


In ARIA, the role attribute overrides the element type, much like a player in a game overrides their workaday existence as a 21st-century human to become a mighty dwarf. In the example from the last section, an insipid <div> assumed the role of a checkbox by being given role="checkbox".


Roles in ARIA17, like races in a role-playing game, are a part of a character’s identity that we might be interested in. We might expect dwarves to be strong and good at constructing machines, just like we expect a <button> to have the characteristics and behaviors already discussed. By putting role="button" on an element that isn’t actually a <button>, we are asking assistive technologies to identify it as a button, evoking those characteristics.


Character sheets with just names and races would be a bit limited. We’d probably be a bit uncomfortable with so much emphasis on race, too. The whole point of ARIA is that it recognizes elements not just for their generic, reductive classification. Much better to identify characters and elements by their individual assets and talents.

A typical sheet would list a set of characteristics for a character that, in one way or another, the game identifies as having a certain currency and importance. For instance, you might be an elf but one who is special for the ability to cast certain magic spells. In much the same way, we looked at an <a> element that is made special for having the property of a submenu. This would be identified to the accessibility layer, just like the basic role, via the aria-haspopup="true" property attribute.


A huge number of properties19 have been specified and documented. Some are global, meaning that any element may have them, while others are reserved for particular contexts and elements. Dwarves are usually precluded from having good longbow accuracy, whereas the skill is common to elves. The aria-label that we would use to label a button is global, whereas aria-required, which denotes a required user entry, would normally be used in form fields or elements with form-field roles, such as listbox and textbox.


Perhaps the most important distinction between a static web document and an application is that the elements in an application tend to change — sometimes dramatically — according to user interaction and timed events. Depending on what’s happening in an application at any one time, the elements therein could be said to be in certain, often temporary, states.

In role-playing games, you have to keep tabs on the state of your character: How healthy are you? What items have you collected? Who have you befriended? This is all scribbled down, erased and scribbled down some more on the character sheet. Keeping track of the state of interactive elements is important for accessibility, too.

In your application, the state of an element is usually represented visually. In role-playing games and in screen-reader buffers, this is not the case: It has to be imagined. If your dwarf character has donned their magic cloak of invisibility, you’d probably want to write this down on the character sheet so that you remember. Similarly, writing the aria-hidden attribute20 on an element ensures that the accessible state of invisibility is recorded properly.


States such as aria-expanded22 are announced according to a value of true or false. An item with aria-expanded="false" is announced by JAWS and NVDA Windows screen readers as “collapsed.” If — or, rather, when — it is set to aria-expanded="true", then the item will be announced as “expanded.”

Our First ARIA Widget

It’s about time we put everything we’ve learned about roles, properties and states into practice and build our first ARIA widget.

The term “widget” is often used in JavaScript development to denote a singular pocket of script-enabled interactive functionality. Mercifully, the ARIA definition corresponds, and ARIA widgets can be thought of as JavaScript widgets that have been made accessible with appropriate ARIA attributes.

Let’s make a simple toolbar — a group of button controls that enable us to organize some content. In this case, we’ll set up controls to sort content alphabetically and reverse alphabetically. Fortunately, we have access to the W3C’s guide on authoring ARIA widgets, “General Steps for Building an Accessible Widget With WAI-ARIA23,” which covers a similar example for a toolbar.

The Toolbar Role

There’s no such thing as a <toolbar> element in HTML, unless you create one as a web component24. In any case, because there’s no standard element for toolbars, we need to include the toolbar role in our toolbar’s parent element. This marks the scope of the widget:

<div role="toolbar"> /* toolbar functionality goes here */ </div>

(Note: A <menu> element takes a type of toolbar, but it has not been adopted by browser vendors25 so is unable to provide the information we need.)

The toolbar’s purpose in our design should be obvious from its visual relationship to the content it affects. This won’t communicate anything aurally, however, so we should provide an accessible name for our toolbar via the now familiar aria-label property. That’s one role and one property so far.

<div role="toolbar" aria-label="sorting options"> /* toolbar functionality goes here */ </div>

Now let’s add the buttons that will be our controls.

<div role="toolbar" aria-label="sorting options"> <button>A to Z</button> <button>Z to A</button> </div>

Even without the additional widget properties and states, we’ve already improved the user’s recognition of the toolbar: Using the NVDA screen reader or the JAWS screen reader with Firefox, when a user focuses the first button, they are informed that they’re inside a toolbar and — thanks to the aria-label — told what it is for.

26 The Relationship

So far, we haven’t actually connected our toolbar to the content it controls. We need a relationship attribute, which is a special kind of property attribute that communicates a relationship between elements. Our widget is used to control the content, to manipulate and reorganize it, so we’ll go with aria-controls. We’ll join the dots using an id value, just as we did in the earlier example of the popup menu.

<div role="toolbar" aria-label="sorting options" aria-controls="sortable"> <button>A to Z</button> <button>Z to A</button> </div> <ul id="sortable"> <li>Fiddler crab</li> <li>Hermit crab</li> <li>Red crab</li> <li>Robber crab</li> <li>Sponge crab</li> <li>Yeti crab</li> </ul>

Note that we’ve added aria-controls to the toolbar itself, not to each individual button. Both would be acceptable, but using it just the once is more succinct, and the buttons should each be considered individual components that belong to the controlling toolbar. If we want to check which properties and states are supported for widget roles like toolbar, the specification provides a list of “inherited states and properties27” in each case. Consult this when you build a widget. As you will see28, aria-controls is an inherited property of toolbar.

Some screen readers do very little explicitly with this relationship of information, while others are quite outspoken. JAWS actually announces a keyboard command to enable the user to move focus to the controlled element: “Use JAWS key + Alt + M to move to controlled element.” Once you’ve affected it, you might want to go and inspect it, and JAWS is helping you to do just that here.

29 Pressed and Unpressed

Depending on which sorting option is our current preference, we could say that the button that commands that option is in a “selected,” or “pressed,” state. This is where the aria-pressed state attribute comes in, taking a value of true for pressed or false for unpressed. States are dynamic and should be toggled with JavaScript. On the page being loaded, just the first button will be set to true.

<div role="toolbar" aria-label="sorting options" aria-controls="sortable"> <button aria-pressed="true">A to Z</button> <button aria-pressed="false">Z to A</button> </div> <ul id="sortable"> <li>Fiddler crab</li> <li>Hermit crab</li> <li>Red crab</li> <li>Robber crab</li> <li>Sponge crab</li> <li>Yeti crab</li> </ul>

Pairing the styles for active (:active) buttons with the styles for aria-pressed buttons is a good practice. Both are buttons that have been “pushed down,” whether momentarily or semi-permanently.

button:active, button[aria-pressed="true"] { position: relative; top: 3px; /* 3px drop */ box-shadow: 0 1px 0 #222; /* less by 3px */ } 30

When the user focuses a button with aria-pressed present using either NVDA or JAWS with Firefox, the button is identified as a “toggle button.” Using the latest version of JAWS and focusing a button with aria-pressed="true" will append the word “pressed” to the announcement accordingly. In the ChromeVox31 screen reader for the Chrome browser, an aria-pressed="true" button is announced as “button pressed” and aria-pressed="false" as “button not pressed.” To a greater or lesser extent, most modern browsers and screen readers articulate helpful information about the state or potential state of these buttons.

Keyboard Controls

Not quite there yet. For toolbars — as with many ARIA widgets — the W3C recommends certain keyboard navigation features32, often to emulate the equivalent in desktop software. Pressing the left and right arrow keys should switch focus between the buttons, and pressing “Tab” should move focus out of the toolbar. We’ll add tabindex="-1" to the list and focus it using JavaScript whenever the user presses “Tab.” We do this to allow users to move directly to the list once they’ve chosen a sorting option. In a toolbar with several buttons, this could potentially save them from having to tab through a number of adjacent buttons to get to the list.

<div role="toolbar" aria-label="sorting options" aria-controls="sortable"> <button aria-pressed="true">A to Z</button> <button aria-pressed="false">Z to A</button> </div> <ul id="sortable" tabindex="-1"> <li>Fiddler crab</li> <li>Hermit crab</li> <li>Red crab</li> <li>Robber crab</li> <li>Sponge crab</li> <li>Yeti crab</li> </ul> $(listToSort).focus(); All Done

That concludes our ARIA widget. A live demo33 is ready for you to play with and test. Remember that it’s not really about sorting, per se — that’s all done with JavaScript. The aim is to make explicit the relationships and states of our application, so that whatever we are doing to our content — sorting it, editing it, searching it, creating it, recreating it — our users on keyboards and screen readers are kept in the loop.

The next chapter of the Apps For All: Coding Accessible Web Applications342 eBook puts the application functionality to one side and addresses how to actually find that application functionality in the first place. Mobility is a big part of accessibility online and off, so it’s important to look at different ways to help our users get around.

(al, il)


The post The WAI Forward appeared first on Smashing Magazine.

Breakpoints And The Future Of Websites

Tue, 07/08/2014 - 13:31

When the iPhone came out in 2007, the demonstration of its web browser by the late great Steve Jobs gave the not-so-subtle impression that Apple wasn’t too perturbed about its users pinching to zoom and swiping to scroll as part of the browsing experience. Responsive web design aimed to solve this problem by smartly applying flexible grids, fluid layouts and, of course, media queries.

However, responsive web design has turned out to be somewhat of a case study in the law of unintended consequences, with one of the perverse unanticipated effects being breakpoint paranoia. But even without the undue influence that media queries exerts on your selection of these breakpoints, it dawns on you after much introspection that these might not be the droids we’re looking for.

In this article, we’ll look at breakpoints beyond screen size and explore different possibilities and practical approaches to using them to create truly adaptive experiences on the web.

Threshold Dynamics

A threshold1 is the point or level at which something begins or changes. Thresholds can be found and felt virtually everywhere in the physical world: stopping at a traffic light, choosing skimmed milk over full cream, two sugars instead of three, uncouthly opting out of the teacup ride at Disney World, etc.

Thresholds define us because they define actions, and actions determine outcomes. Being able to identify the right thresholds sets you on a course for better outcomes, especially when you know exactly what needs to be done within each threshold. It’s akin to doing the right thing at the right time.

Our foresight to conceptualize — and enable — new thresholds where there were none will open up a new vista of actions vis-à-vis outcomes. The freedom and flexibility we acquire from this will only help to fulfill our innate desire for incremental awesomization, which will drive us to create even better websites that provide better user experiences.

Today’s Breakpoints

In web design today, the thresholds we fixate on the most relate almost exclusively to screen size. The major challenge over the last few years has been designing for mobile devices, and, with screen size being the obvious focal point, our primary intent has been to adapt the layout of our web pages to tally with the specific display characteristics of the target environment.

In responsive web design, the predominant method of defining these breakpoints is by setting media queries.

@media screen and (min-width: 240px) and (max-width: 320px){ body { background: red; } }

The markup above clearly identifies two thresholds (240 pixels and 320 pixels) that constitute a range within which an action will be triggered (in this case, changing the background color to red). It’s quite straightforward in concept.

Medusa Queries

“As we augment the abilities of people to accomplish their tasks, we should be careful not to needlessly curtail what they can do.”

– Jeremy Keith

Media queries, it turns out, are extremely rigid. Usually, you are forced to employ breakpoints in ways that are not exactly intuitive nor inline with your core design aspiration. In other words, you have to fit your design aspiration to its capabilities. So, you may have a vibrant imagination about your own thresholds, but more than likely media queries won’t let you apply them the way you envisage.

Defenders of media queries should understand that efficiency is what makes any effective effort laudable. Spending many minutes or even hours tweaking those pesky directives and then having to re-tweak them each and every time you want to make an adjustment is nothing short of a recursive nightmare. What’s so wrong with setting breakpoints based on broad categorizations of mobile devices (such as smartphone, tablet, etc.)?!

In the article “Designing for Breakpoints2,” Stephen Hay suggests defining breakpoints based on device classes. Spurred by a few assertions, I embarked on a mini-research project that I later converted into a blog post3 to prove this right or wrong. And in a recent poll that I conducted on whether media queries should target device classes4, about 54% of respondents said yes. But there’s no intuitive way to do this with media queries even if you wanted to.

In my humble opinion, from the web designer’s standpoint, the feature set of media queries is incomplete. And it is so because designers have an imagination and an appetite for many more breakpoints than media queries can currently provide (and probably ever will in future).

The New Breakpoints

As mentioned a little earlier, our ability to find and set new thresholds will determine our ability to conceptualize new actions that we can set a trigger to. By so doing, we can introduce more tweaks into an inherently static and inflexible environment.

Breakpoints in Contextual Web Design

The websites of tomorrow have to be more than responsive — they have to be contextual, too. These concepts of flexibility and fluidity have to transcend screen size. The age of the one-size-fits-all website will have to come to an end and be replaced by websites that also adapt to the needs and expectations of users.

To enable this feature, we have to conceptualize more thresholds, but first we need to find out what parameters to track. In Nick Finck’s insightful presentation on “The Contextual Web5,” he highlights four aspects of context in web design: user, task, environment and technology. Of course, all four are a treasure trove of extrapolations, but what should we really focus on?

We could ask literally hundreds, even thousands, of questions about users, their tasks, their environment and what technology they have access to. However, we have to base these questions on our current and overt abilities to obtain data on these four parameters. Some possible questions could be:

  • What are the physical abilities of the user?
    If the user is vision-impaired or hearing-impaired, we would need to add more accessibility features that would enhance their experience.
  • Where is the user’s general location?
    Knowing where the user is gives us a good idea of their culture, economic status, demographic, etc.
  • What time is it in the user’s location?
    People are usually creatures of habit and are probably more likely to perform certain actions at a certain time.
  • What is the user’s device?
    A phone is not a tablet, and a tablet is not a PC. Different devices have different capabilities and will be used for different tasks.
  • What does the user have an affinity for?
    What the user likes (and dislikes) will play a strong part in helping us to prioritize and deliver content.

There are ways to answer the questions above with the technology available in browsers today. And if not, then we really need to work harder to build them in, especially considering an issue as important as accessibility.

So, how would we design a website to be contextual? How would we visualize breakpoints in a contextual sense? Here’s one scenario.

Let’s suppose that it’s 6:00 in the morning, and your alarm goes off. You hobble to your kitchen to get some breakfast, before getting ready and heading out to work. You fancy eggs, but you open the fridge and there are no eggs. So, you settle on something else, but you want to order some groceries so that they’re ready to be picked up on your way back from work. You fire up the website of an extremely large department store chain from your Internet-connected refrigerator to get this done.

Are you impressed simply because this website is responsive? Is getting the best deal on electronics a priority for you at this point? Do you really want to be reminded that some of the few items you “recently viewed” on said website were Lincoln Logs and a Spider-Man toothbrush holder? I mean, it’s 6:18 am, and you’re browsing from a fridge. Does it take a rocket scientist to figure out that maybe grocery items should be a category worth prioritizing?!

I’m sure there are numerous other scenarios like this, and it’s easy for someone who isn’t familiar with web technology to get frustrated with how websites still seem to fall short of their expectations. But for those of us who do, should we still be making excuses, or should we be trying to push the envelope further?

The New Methods

“Media queries allow authors to test and query values or features of the user agent or display device, independent of the document being rendered.”

– Editor’s Draft, W3C (3 June 2014)

I was recently perusing the “Media Queries Level 46” draft specification to get a sense of where things are headed. I must say that I’m not very excited with the direction, and there just doesn’t seem to be much innovation here.

From the abstract of the document, we get a clear definition of what media queries are as a method. However, I just can’t understand why there is no evolution of media features to reflect present — and possible future — realities.

What’s wrong with having device-class media features like phone or tablet? They seem like obvious choices, and, according to the poll referred to earlier, web designers want that feature set. Some would argue that those might not be “things” in the future, but that is hardly believable, given that cars, TVs, computers, refrigerators, watches and spectacles are still “things” that people find useful today. And when are we really going to see a resolution to the question of element queries7?

In my opinion, media queries (as a tool for web design in a multi-device world) simply can’t maintain any sort of equilibrium with the creative trajectory of contemporary web designers, and they are a morally indefensible standard for web design going forward. Maybe we should look at alternative approaches; I’d like to suggest a few. They’re not that complicated, and all we’d need are a HAT, a COAT and a TIE.

HAT Trick

We’re probably all familiar with CSS class selectors at this point. They are one of the most commonly used selectors in web design8.

.muttley .do_something {…}

What I don’t understand is why we don’t use these classes more than media queries to build mobile-friendly websites?

It seems to me that designing websites for many different situations would be so much easier and faster if browsers employed HTML attribute tagging (HAT). Basically, this would involve the browser placing specific parameters in the class attribute of the <html> tag (in the process of the page being loaded), which would enable the web designer to leverage these classes in their CSS markup.

Some of these parameters could include the following:

  • device group
    fixed, mobile, home, wear, auto, etc.
  • device class
    PC, phone, tablet, TV, fridge, car, watch, etc.
  • input device
    coarse, fine
  • bandwidth
    high, medium, low
  • orientation
    portrait, landscape
  • viewport width and height
    in device-independent pixels, to the nearest multiple of 40, with an alphabet prefix for compliance
  • local date and time
    in ddmmyyyy format for date, and 24-hour representation for time
  • time zone
    UTC offset9
  • general geo-location
    continent and country codes

More parameters could be added based on anticipated need. In addition, all parameters would be abstracted to the DOM window object to make them easily accessible via JavaScript.

So, suppose someone was using a Nexus 5 phone over a 4G LTE mobile network. The browser would add the relevant tags to the page, leaving us with this:

<html class="mobile phone coarse high portrait v360w v640h d07052014 t0900 utc_a af_ng">

And if they changed the phone’s orientation to landscape, the browser would statefully update the tag, giving us this:

<html class="mobile phone coarse high landscape v640w v360h d07052014 t0900 utc_a af_ng">

If this happened, the web designer would have a lot of options to quickly adapt their web pages across numerous logical breakpoints at literally the speed of thought. Let’s consider one working example.

I was recently testing a pricing table10 that is not unlike tables seen on a lot of SaaS websites these days. The table is three columns and is built using ul tags with floated li tags.

11A multi-column pricing table. (Image credit: Restive.JS1512) (View large version13)

Below the pricing table is some FAQ content, also with a multi-column layout.

14Multi-column FAQ content. (Image credit: Restive.JS1512) (View large version16)

Obviously, these multi-column elements would not look as good on all mobile devices as they would on a desktop. So, in the spirit of responsive web design, we would have to adapt them to the dimensions of a smaller screen. And the way we would do this is by showing these two visual components in their full multi-column glory only when the web page is being viewed on a tablet in landscape orientation.

The logic behind this is that we would expect a tablet in that orientation to have enough screen space for the whole table to appear as intended. If those conditions are not met, then we’ll collapse the columns to be linear and vertical.

The basic CSS for our pricing table is this:

ul { margin: 0; padding: 0; list-style: none; } ul li { float: left; width: 33%; }

So, leveraging HAT, we would implement these features using the following markup:

.mobile ul li { float: none; width: 100%; } .mobile.tablet.landscape ul li { float: left; width: 33%;}

That’s it! Just disable the floated layout elements for all mobile devices, and then re-enable them for tablets in landscape orientation. Simple aspiration, simple solution. Do you want to try doing the same thing with media queries? Say hello to Dr. StackOverflow for me!

Clearly, employing this approach has benefits. Efficiency is one major benefit; you’d spend less time building websites because you wouldn’t be wasting ridiculous amounts of time crafting media queries, not to mention all of the testing of mobile devices that goes along with that. Secondly, maintaining your markup would be easier because everything would be inline and there would be no needless duplication. Thirdly, you would have the opportunity to explore many more use cases because there would be more parameters that serve as thresholds for more logical breakpoints.

COAT of Many Colors

Everyone seems to be fascinated by analytics. Website analytics programs, such as Google Analytics and MixPanel, all try to give a good picture of who has visited your website, how long they stayed, what websites they came from, what devices they used, etc. What this data won’t tell you is what content the visitors have an affinity for.

You could, of course, use cookies to track visitors to your website, but then you’d only be able to determine what they like on your website that day or week or month. You wouldn’t be able to accurately determine the specific content they care about, nor might you be able to do anything about it before they leave.

Tracking content affinity and adapting content to said affinity could really help us build websites that truly adapt to people’s desires. To really obtain this data, though, the data-collection mechanism needs to transcend any one website. That is, all websites would need to build this affinity profile in a collaborative and transparent way.

COAT stands for “cumulative and open affinity tagging.” It’s simply a shared method of understanding the things visitors have an affinity for and then building a profile of that affinity. Here’s how it would work:

  • Someone visits a bunch of websites regularly. Some are news websites, some are sports websites and some are blogs. Each web page would have a COAT meta tag.
  • The browser (via a COAT sub-engine) would read this meta tag and incrementally store its value in a reserved, protected and read-only localStorage variable (which could be named anything) in a comma-delimited format. So, for the websites that our user visits, the value might be news:info:1,sports:soccer:2,blog:tech:3.
  • If the person visits another sports-related website, the website would read (and update) their affinity tag from localStorage. It sees that the person is amenable to football, and so gives more priority to football content on the home page.

Armed with this insight, we could tweak a website’s home page to better cater to the different needs of users in a highly specialized way.

COAT data would comprise a single comma-delimited string in the following format:


Here, category is the broad classification of a type of content; sub_category enables further classification; and popularity is a measure of the frequency of visits. So, if our user visited a tech blog 30 times a month and visited the football section of a sports website 5 times a day, then we would end up with this tag:


This is merely an example; the classification system would be defined and maintained by the greater web community. A number of safeguards would be in place, too. For example, if a website didn’t define a COAT meta tag, then it wouldn’t be able to read one either. Also, if the user was browsing in private mode, then COAT would be disabled.

COAT wouldn’t track any personal information. The intent is not to figure out who a person is and where they might be, but to get a broad picture of the kind of content they like (and how much they like it), so that websites are able to personalize their browsing experience.


Let’s face the fact: JavaScript is awesome. It’s not very approachable to most web designers, but its capabilities are simply immense, and it holds the key to websites doing great things in the future, even as its contribution to website functionality today is not in question.

HTML and CSS are a great duo for building websites, having been so for quite a while now. However, only HTML seems to have been allowed to maintain a relationship with JavaScript. Granted, CSS is “a style sheet language used for describing the look and formatting of a document.” But as things stand today in a world dominated by web-enabled devices, a lot of the factors that determine the look and feel of a website have gone beyond the realm of CSS.

As a result, CSS needs to be allowed to “friend” JavaScript and ask for its help in performing certain tasks. There really should be a way to link Javascript functionality directly with inline CSS rules. One way would be via transcendent inline expressions (TIE). TIE would provide a mechanism of linking CSS rules with JavaScript expressions, opening up even more amazing opportunities for website functionality.

Let’s look at a simple example. Suppose we had a testimonials component in the sidebar of our home page:

17A testimonials component in the sidebar of a web page. (Image credit: Ian Storm Taylor18) (View large version19)

We want to drop this same component into the main content area of another page, somewhere where we have more width to work with:

20Our testimonials component in the footer of a web page. (Image credit: Ian Storm Taylor21) (View large version22)

This is called modular design, and conceptually it’s a very simple idea. However, we’d have a pretty hard time implementing this in CSS (as Ian Storm Taylor found23), because there isn’t a straightforward way to apply CSS styles to the testimonials component based on the size of its container.

This scenario is what has sparked the clamor for element queries, the overriding need being a way to define reusable modules that adapt to the size of their containers. If CSS natively implemented some sort of TIE functionality, then we might be able to write a simple expression in CSS to make this happen:

.testimonial { … } .testimonial[expr="if @parent:width less than 200px"] { … } .testimonial[expr="if @parent:width between 200px and 500px"] { … }

For the first ruleset, we would style .testimonial as usual. For the second ruleset, the expression could mean that, when the width of the parent element of .testimonial is less than or equal to 200 pixels, then apply the corresponding declarations to that DOM element (i.e. the parent element). The same goes for the third ruleset, whereby the declarations are applied when the parent element has a width of 201 pixels to 500 pixels.

Basically, CSS would merely provide guidance on what to do, while JavaScript would do the heavy lifting that CSS isn’t well suited for. Instead of writing the CSS rulesets for styles and then jumping over to JavaScript to activate them, we would simply do both via an expression in CSS. Because we’re working on the same DOM element, it makes sense for there to be some easy and intuitive way to both style and activate it (i.e. the DOM element) directly from CSS.

Any such TIE implementation should be robust enough to enable web designers to implement features at virtually the speed of their creativity. In other words, if they can imagine it, designers should be able to achieve it — or something close to it — almost instantaneously.

Putting It All Together

Let’s consider a scenario that shows how all three would fit together when building a website.

By the time you read this, the World Cup will be on, and football fans from around the world will have gathered in Brazil to experience the thrills of the Copa Mundial. Let’s assume you are one of those fans and are in Sao Paolo, having brought your smartphone and Google Glass with you.

A popular online sports destination that happens to be covering the event would usually blanket its website with World Cup features at the expense of other sports events going on elsewhere in the world. The website will employ the three methodologies explained earlier in order to deliver a very special user experience.

After building various content components, the website’s developers should be able to do a few things without much stress:

  • Optimize the website exclusively for Google Glass, providing a simpler, slimmer interface for easier navigation. In addition, adapt the color contrast to the time of the day (i.e. switching to light text on a dark background at night), using the device-class parameters of HAT.
  • Provide more content on local attractions in different cities in Brazil (for example sports bars, other viewing centers, etc.) only if the access device is a smartphone or tablet and happens to be in Brazil (using the location parameters of HAT).
  • Lead with pre-game analysis, team and player profiles, and merchandise if the user visits the website within six hours of an upcoming match (using the time parameters of HAT in combination with TIE).
  • Lead with match highlights and post-game analysis if the user visits the website within 12 hours after a match ends. Provide different layout designs for match highlights on smartphones and tablets using the same code base (using the device-class parameters in HAT).
  • Lead with golf features in a more prominent location than football if we determine (via COAT) that the user likes the former more than the latter. But still display match highlights in a sidebar with a narrower pixel width (styled in a modular fashion using the TIE features in CSS).
  • Default to the regular format of content if we can’t determine whether the user prefers football or another sport.

As you can see, the permutations and opportunities of a highly personalized and carefully weighted user experience are abundant and easily implementable if all three methodologies are considered. We wouldn’t necessarily have to use them all, but it’s nice knowing that they’re there if we wanted to.

The Polyfill Way

“You can’t always get what you want. But if you try sometimes, you just might find, you get what you need.”

– The Rolling Stones

Where would the web design community be without polyfills? Even the best-intentioned technology doesn’t always work as intended, and sometimes it has gaps in functionality. “Just chill and polyfill” would be the operative mantra in these situations, and the last few years have indeed been a veritable polyfill-palooza24.

All of the features outlined so far in this article are merely ideas and are not earmarked in any upcoming draft specifications of CSS or media queries, so you couldn’t use them right now even if you wanted to. However, that doesn’t mean we can’t do something about it in the meantime.


I mentioned earlier that I was using a plugin to build a website. Well, that would be Restive.JS25, a jQuery plugin that I developed about a year ago that embraces and implements the HAT principle. Using built-in options of breakpoints, classes and a special feature named turbo_classes, Restive.JS populates your <html> or <body> tag class attributes with values that make it easy for you to adapt a web page’s layout via inline CSS to more natural design cues.

Once you get the basic idea, using it to build new responsive and adaptive websites is pretty easy, as is adding said features to existing websites. I recently wrote a tutorial on “How to Make Any Website Responsive26,” which you can peruse at your leisure.

You can also learn more via Restive.JS’ documentation27 and from the GitHub readme28.

A Note on Tolerance

As creative and technical professionals, we need to be open to other people’s opinion. Often a crowd will move towards a position simply because of punditocratic consensus, without pausing to question the fundamental reasoning behind it.

Take device detection. Some say it’s a bad practice. My question is why? Is it because it is deemed unreliable? We can make it reliable. Is there a fear that it is not performant? Then we can cache data. Solving big problems should be an inclusive effort, and using the process of elimination to rule out methods could come back to bite us if someone is able to improve on that method.

Creativity is an insatiable hacker. As long as imagination continues to spur the industrious, then the best tools and methods will eventually give way to better ones. Maintaining a clear and tight focus on the task at hand — and its successful completion — shouldn’t prevent us from being robust with our toolset. As the great Abraham Maslow said, “If all you have is a hammer, everything looks like a nail.”

In Closing (But Moving Forward)

More of everything isn’t necessarily a good thing. But, when it comes to breakpoints, “the more the merrier” does ring true. As humans, we take actions based on specific triggers between specific thresholds. Defining more of these thresholds would open up opportunities to create websites that adapt in so many ways beyond screen size, and that exploration will turn out to be instructive.

However, as we open up new frontiers with new breakpoints, we should do so in a way that is both user-friendly and efficient for the web designer; the robustness of our methods shouldn’t make us less nimble. With the way web standards work, we’re probably going to have to polyfill our way to the promised land. But that shouldn’t stop us from building awesome websites that work on every device and in numerous user scenarios.

Front page image credits: Restive Blog29.

(al, ml)


The post Breakpoints And The Future Of Websites appeared first on Smashing Magazine.

Case Study: PixelMogul, A Simulation Game For iOS

Mon, 07/07/2014 - 13:48

Are you a web designer or developer who dreams about creating a mobile game and bringing it to the app store? We have good news: Your road to the app store might be shorter than you think! And if you can recall your experience with ActionScript and the Flash platform from days of old, then you’ll even have a shortcut.

Building a native app with Flash might sound weird at first. In this article, we will share some insights on how we built a game for iOS that is written entirely in ActionScript.

1PixelMogul for iOS is completely written in ActionScript and built on Adobe’s Flash platform. (View large version2)

First things first. Before getting to the technical aspects, let’s talk about general considerations that every game developer has to face, as well as some design decisions we were confronted with.

Developer’s Dilemmas Android, iOS or Both?

Making a game sounds fun — and it really is! But a bunch of important decisions need to be made that do not directly relate to the game itself. Let’s start with the decision about which platform(s) to support. Even if most game ideas are not strictly bound to one platform (for example, due to hardware requirements), focusing on a single platform3 for launch is a good approach. This will reduce the time and expense of the initial development cycle.

From a developer’s perspective, iOS-first is definitely the preferable path. Just think of the fragmentation in the Android universe: a huge range of screen sizes, processors and OS versions to deal with. iOS users are easier to serve: just a handful of devices, standardized screen proportions, a user base that updates the OS very quickly, and the certainty that the next generation of devices won’t veer out of line dramatically. Development is certainly easier if all supported devices fit on your desk.

On top of this, research as of late 2012 shows that Apple’s App Store pulls in far more revenue than Google’s Play store, although Google is catching up. Our conclusion was to go with iOS first, but to be prepared to port to Android quickly. The ease of porting the app was an important factor when the time came to choose a framework.

If you’re interested in some figures on how the market evolved while we were working on the game, check out Distimo’s “2013 Year in Review4” and App Annie’s “Top Trends of 20135.”

Which Business Model To Choose

We hear you saying, “What business model?! Games are fun, not business!” We’re with you. If making games is not fun, one should surely stay away from it. However, building a game is also a challenging and time-consuming adventure, and some sort of financial compensation should be involved. The question of how to make money from it will bring you to four common business models. Pick the right one early on, because this decision will determine how focused your design and development process is:

  • paid apps
  • freemium (i.e. free app that offers in-app purchases)
  • paid apps with in-app purchases
  • in-app advertising

We spoke with a few people who play games on iOS, and it turns out that most prefer the paid model because it is the most transparent deal up front. Sounds tempting to a developer because the paid model doesn’t require any extra effort, like implementing in-app purchases or advertising. But we were surprised to find that the freemium model makes up the biggest share in revenue by far (92% in November 2013, according to Distimo’s report mentioned above). So, we decided to give it a try.

A huge concern for us was scaring away players or even getting bad reviews for offering in-app purchases, which some players still think are a scam — probably because some publishers went too far with them. To prevent such a hassle, we aimed for customer-friendly in-app purchases and tried to avoid critical mistakes.

  • Recurring payments (such as for consumables) can generate a continual stream of income, but they also risk annoying people if implemented aggressively.
  • The moment at which a player decides to spend money is very personal. Paywalls will scare away some players if set too early. On the other hand, players might lose interest in the game before reaching the paywall if it is set too late.
  • In-app purchases that give paying players unbeatable advantages over non-paying players could lead to frustration. This factor is especially important in multiplayer games in which players are in direct competition.
  • An unclear description on what’s included in in-app purchases forces players to think instead of buy.
  • Some games get bad reviews for excessive pricing. Sounds obvious, but what’s “excessive”? Mobile games have gotten really inexpensive, and players are used to getting great games for little money. For example, $10 feels expensive for a game that one will have fun with for hours, while the same person will easily spend $8 for a movie ticket (which is only 90 minutes of fun).

We’re new to the business and we’re still learning. At the moment, attracting as many people as possible and getting positive reviews is more important than squeezing every last penny out of the game. Hence, we might optimize the pricing model in future.

How to Introduce Players to the App?

When you visit a city you’ve never been to before, having someone introduce you to the neighbourhood and the people makes you feel welcome and confident. The same goes for jumping into a new game — welcoming new players with a guided tour is common. Such tours are often presented by a character in the game. Guess why?!

As nice as a guided tour of a city is, on the second day you’ll probably want a few hours to explore the city on your own, right? This applies to players, too. They want to explore a game at their own pace. They’ll just skip a lengthy introduction. We kept the mandatory tutorial as brief as possible. The goal was to introduce the main mechanics and end it with a clear but easy-to-complete mission. However, after working on the game for quite a while, deciding which mechanics needed to be introduced was difficult because we were just too deep into it.

User testing is a helpful way to find out where players need hints. Some early testers played the game without any introduction or help. It turned out that the level of assistance they wanted was very personal. As a result of the feedback, we split the in-game help into four levels:

  • New players are given a brief tutorial at the beginning of the game.
  • Progress-aware hints appear only if required by the game’s state (for example, if a player misses an important action). Players who get it right from the beginning aren’t ever interrupted by these.
  • User are guided in complex panels. An animated dot indicates where to tap when the player is using a panel for the first time.
  • Gestures are shadowed. Swipeable elements are slightly animated to prompt the user to perform a swiping gesture.
  • An in-game help menu explains the meaning of icons in the game and clarifies the game’s mechanics and UI elements.
  • The splash screen (during loading) offers general hints.

Verify that your hints work as intended! One way would be to ask questions of your testers. Keep in mind that testers usually won’t say things like, “I can’t find the turbo boost,” because in most cases they won’t even realize that there is turbo boost!

Ask your questions thoughtfully. A question like “Which button activates the turbo booster?” will force the tester to think, and you’ll get vague feedback. Ask for the player’s fastest lap time instead. Based on the answer, you’ll be able to determine whether they used the turbo boost, thus sparing them from frustration and the pressure to give the correct answer.

Of course, watching testers play is even better than asking questions. But from our experience, looking over their shoulder will make most testers feel uncomfortable and will influence their behaviour. In this case, ask to capture their sessions. If you’re on site, AirPlay mirroring is great for testing. We used Apple TV to mirror on a TV. You can also use a tool like Reflector6, which turns your PC into an AirPlay receiver. As a last resort, find gameplay videos published by players on YouTube and Twitch.

7Clipping from the in-game help menu explains the function of a UI element. (View large version8)

We optimized the in-game guidance based on feedback but did not accurately verify the result. After the first version was publicly released, some players still got stuck because they didn’t get enough assistance. A reviewer in the US App Store summarized his review as, “Great but needs help.” We addressed the issue in two updates, and the majority of players seem to feel comfortable now.

Design And Graphics Combining Interface Styles

What’s the first thing that comes to mind when you’re thinking of making a game? The user interface, perhaps! Of course, the UI will not be the reason that people consciously choose to play your game, but depending on the type of game, the UI could be critical (perhaps the panels or settings are complex). A neat UI could also help your game stand out from competitors. And, hey, UI design is your domain as a screen designer, and you can bring your full experience from the web!

When designing for small touchscreens, avoid clutter. You might not rely on gestures for basic tasks on a mobile website, except if it’s a common gesture (such as pinch to zoom). In a game native to the OS, you have the opportunity to take things one step further because you can introduce the user to the game through a guided tour.

While all of the game art was illustrated in a pixelated style, the UI was kept clean and flat, giving the game an app-like look.

We drew the illustration layer in our game, which primarily defines the look, in a pixelated style. Adopting a pixelated style for the UI seemed obvious at first, but we quickly realized that this was not the best choice, particularly for the more complex panels. We ended up with a clean flat design and anti-aliased type for the UI, which gives the game a contemporary and app-like look. (The combination of pixelated art and flat anti-aliased design had a few consequences for how we handled textures. We’ll cover this in the technical section below.)

Multi-Resolution Design

Is there such a thing as responsive design for games? Yes… kind of. Mobile games are displayed in full screen on all devices. If you’re targeting iOS, then you’ll be dealing with three screen proportions: iPad (4:3), iPhone (3:2) and iPhone 5+ (16:9). Sounds like paradise for a web designer or developer, right? However, this calls for some important design decisions, and keeping Android’s more fragmented universe in mind could save you much trouble if you decide to port the game later.

For games with simple interfaces, scaling is a good option. But scaling alone won’t do because screen proportions vary. In addition to taking care of the additional space (for example, by repeating the background pattern), our team had to reposition various elements based on screen size (for example, the player’s score had to persist in the upper-right corner).

PixelMogul is displayed at the same scale on all devices. iPad users have a larger viewport and, thus, benefit from a better overall view and less scrolling.

9Identical game states on devices with different screen sizes. (Large preview10)

The design process focused on the iPad, but we had “passe-partout” layers in our Photoshop files, which enabled us to quickly check whether the design works on smaller iPhone screens, too. This approach required us to fit key elements on the smallest screen (480 × 320 pixels). In some cases, we used the extra room on larger screens for design enhancements, and then “compressed” the design for smaller devices.

Usability of the City Map

We mentioned earlier what it feels like to visit a new city. Losing one’s orientation is quite easy. That’s exactly how our early testers felt when they arrived on the city map, one of the main elements of the game. The map is 37 × 37 blocks and almost 4 pixels in width and height. Getting lost on it is quite easy, especially on a small screen, which provides just a peek at a tiny portion of the enormous map.

Our first solution was to enable users to pinch to zoom out from the map. But around the same time, we were confronted by another problem: Players earned way too much money as soon as they owned around a dozen buildings. We analyzed the math model and discussed the issue with a real estate professional, who explained to us that this is just the way the business works. Good to know!

11The player is forced to focus on the four buildings, which helps to maintain their attention. (View large version12)

We found a simple solution to both issues. At the very beginning of the game, all buildings on the map except the initial four are covered by clouds and cannot be accessed. The player is forced to focus on the four buildings, which helps to maintain their attention. Because removing clouds and expanding the accessible buildings requires in-game money, increased earnings are rewarded to a certain extent.

Technology Choosing The Right Framework

Picking a game engine or framework has similarities to dating. In “The Game Engine Dating Guide: How to Pick Up an Engine for Single Developers13,” Steffen Itterheim covers important points on how to “date” frameworks. We followed some of the key recommendations, which helped a lot. The tips are not specific to games and could be applied when you have to pick a framework of any kind.

  • Choose a familiar programming language.
    Learning the basics of a programming language might not be a big deal, but it takes experience to learn all of the nitty-gritty details that lead to better code, fewer bugs, faster performance and tighter security. Use your experience whenever possible!
  • Match the framework to your needs, not to the project.
    Mastering the tools you have is more important than obtaining the perfect tools. And the only way to master a tool is to use it frequently. Choose a framework that’s flexible enough to serve a wide range of projects. Low-level frameworks are usually more versatile than full-blown engines. Don’t look for sophisticated built-in features — rather, look for frameworks that can be extended with custom features.
  • Documentation, maintenance, community and support
    Before you shortlist a framework, drop by the documentation. Check the change logs, repositories and forums for activity. Make sure you get support that is adequate and that fits your needs and budget.

You will probably have additional requirements. In our case, we were looking for a framework that works with both iOS and Android.

Our Choice: Starling

The Starling14 framework seemed to be the perfect fit. It’s a pure ActionScript framework that mimics the DisplayList architecture of Flash, while rendering all content directly from the GPU. That’s great news for ActionScript veterans, who get to work with a familiar API and get wonderful rendering performance as a bonus.

GPU rendering is based on Stage3D, which became part of the Flash platform in 2011. It’s way faster than the classic DisplayObject rendering but uses Adobe’s Graphics Assembly Language (AGAL), a low-level cross-platform shader language, instead of the beloved DisplayList architecture. Like most ActionScript developers, we’re really into the DisplayList concept, and that’s one way Starling came in very handy.

Because Starling takes care of all things AGAL, it enabled us to take advantage of our ActionScript experience and to work with the DisplayList architecture that we’re used to, while enjoying the advantages of GPU rendering. Even better is that Starling is built on top of Adobe Flash and AIR and runs for iOS and Android (both wrapped in a native app) and in the browser (via a Flash plugin).

Convenience comes at a price, though. ActionScript does not provide the developer with access to all device-specific features and libraries as the native SDK would (for example, battery level or GameCenter on iOS). AIR native extensions (ANE) bridge that gap. An ANE is a package containing native code and an ActionScript API. Several commercial and open-source ANEs15 are available for common tasks16, but you can always write your own17.

Improving Performance

Optimizing the performance of Flash content often feels like looking for a needle in a haystack. Isolating and identifying problems can be particularly time-consuming and frustrating. Adobe Flash Builder (an ActionScript-flavoured version of Eclipse) has a profiling tool that provides insight into the layer of your own ActionScript code, but all of the internal operations of the Flash player are hidden.

Scout18, Adobe’s new profiling tool, comes in handy here. Scout gives complete insight into every detail of your app’s inner life: frame rate, GPU and CPU memory usage, a breakdown of ActionScript performance, rendering details (DisplayList and GPU), plus debugging output. All of the information is organized in a timeline, which gives a rough overview and allows you to focus on individual frames or sequences of frames.

19Optimizing performance with Adobe Scout. (View large version20)

In the timeline, every frame is visualized as a vertical bar. A horizontal red line marks the maximum execution time for a frame (for example, around 17 milliseconds for a frame rate of 60 frames per second). This enables you to quickly identify the most important performance issues (i.e. the highest spikes) and prioritize your efforts.

The GPU renders every frame step by step (similar to the layers in a Photoshop document). Fewer layers usually means faster rendering. Enabling Stage3D recording allows you to recreate every single frame and see how the GPU renders the frame by toggling through every step (i.e. layer) manually. Aside from performance optimization, this “replay” functionality comes in handy when you’re fine-tuning things like collision detection (“Did the bullet really hit that obstacle?”).

Scout comes with companion apps for iOS, Android and Kindle, enabling you to profile content running on devices in addition to the content on your local machine. Thibault Imbert’s article “Getting Started With Adobe Scout21” offers a complete introduction.

Multilingual Interface

The ability to offer apps in the native languages of users has been a major factor in the success of the global App Store. Aside from the obvious advantage of multi-language support, localization provides the infrastructure to separate content from logic.

Our team works with plain-text files, which is handy because we can simply email the files to our translators. When the translated files are returned, we just drop them in the project and register the new language in the program.

Localization is a common task, and the ActionScript API even offers a ResourceManager class that takes care of loading and parsing resources and delivering localized content. The first implementation took us less than a day, and it worked — most of the time. For some reason, the app sometimes picked a wrong locale and displayed the content in a random language. Other developers have had similar unsolved problems22 and have ended up writing their own ResourceManager.

We would have preferred to rely on the built-in class, but we couldn’t find the problem after debugging for almost three days. So, we ended up — you guessed it! — writing our own AS3-ResourceManager, available on GitHub23.

Tabular Data

Technically speaking, our game is a complex UI that manages a simple database. Many user actions require data from the database or update that data, so we need a reliable and fast connection. ActionScript works hand in hand with local SQLite databases, which perform great if you follow some simple rules:

  • Access asynchronously.
    Accessing the database synchronously might look tempting at first because it’s easier to implement (no listeners or callbacks required). But be aware that AIR runs single-threaded (workers are in development at time of writing). Thus, code will stop executing while accessing the database synchronously, and even the UI will be blocked. This is a deal-breaker for any app.
  • Reuse statements.
    In AIR, SQL statements are prepared (i.e. compiled) before execution. As long as a statement’s text (i.e. the query) does not change, the compiled statement will be reused, which results in faster execution. Parameterized queries are reusable for different data sets, as shown in the sample code below:

    // Create the statement if not available if (addStmt == null) { addStmt = new SQLStatement(); addStmt.sqlConnection = conn; // query with parameters addStmt.text = "INSERT INTO tenants (name, income)" + "VALUES (:name, :income)"; } // set parameter values addStmt.parameters[":name"] = "Mark"; addStmt.parameters[":income"] = "4000"; addStmt.execute();
  • Use transactions instead of single statements.
    Every time data is updated or added, the database file must be written to disk. This is usually the most time-intensive part of the whole operation. When you use transactions, all statements in the transaction are executed in memory before the database file is written — a major time-saver! Be sure to add a queuing system to your abstraction layer, because SQLite will throw an error if you start a new transaction while another is still executing. A simple vector or array will do fine.
  • Do not omit database or column names.
    This is a minor enhancement, but explicitly specifying databases and column names minimizes runtime processing.

    // DON'T SELECT * FROM tenants; // DO SELECT name, income FROM gameDB.tenants;
  • Retrieve large result sets in parts.
    When you need to present query results immediately to the user, it might be worth breaking apart large result sets and presenting the initial results while processing the rest. In the sample code below, we’re fetching the results in blocks of 10 rows at a time:

    // Create the statement if not available if (getTenants == null) { getTenants = new SQLStatement(); getTenants.sqlConnection = conn; getTenants.text = "SELECT name, income FROM gameDB.tenants"; } getTenants.addEventListener(SQLEvent.RESULT, buildTenants); getTenants.execute(10); // returns 10 rows (or fewer) function buildTenants(event:SQLEvent):void { var result:SQLResult = getTenants .getResult(); if ( != null) { // Loop through the result rows and process row by row if (!result.complete) {; // retrieve the next 10 rows } else { getTenants.removeEventListener(SQLEvent.RESULT, buildTenants); } } }
Non-Tabular Data

When developing a game, you typically have to deal with non-tabular data. When a user closes our game, we store the x and y position of the city map within the viewport, so that we can display the same clipping of the map view when they return.

In our first prototype, we stored all non-database data in text files, which were written whenever a given object was disposed or the app was deactivated. We thought this approach would provide the most flexibility. But it turned out not to be reliable enough. Sometimes when the app deactivated unexpectedly (for example, because of an incoming phone call), the task of writing the files was invoked but not successfully completed, with the result being corrupted data files.

We didn’t manage to reproduce the problem properly because it rarely occurred, and so we replaced the text files with local SharedObjects (LSO). When working with an LSO, keep in mind that it can hold only the primitive data types (such as string, array and date) and is limited to 100 KB in size. Do not store any objects (in our case, the tenants) — only store an object’s properties (for example, and tenant.income), and recreate the object from those properties when needed.

Avoid Overhead With Texture Atlases

When dealing with GPU-based rendering, images (i.e. textures) are typically organized in texture atlases (or sprite sheets). Similar to how atlases in CSS reduce HTTP requests, atlases reduce the time used to upload images to the GPU and reduce draw calls (i.e. the number of layers the GPU has to draw in a frame).

Supporting high-resolution (i.e. Retina) screens is a piece of cake. Just load the texture atlas according to the device’s resolution. The AssetManager class, which is part of the Starling framework (represented as assets in the sample code below), offers a contentScale property that you can use for this purpose.

// Loading assets from "atlas1x/" or "atlas2x/" according to screen resolution assets.enqueue( File.applicationDirectory.resolvePath( "assets/atlas" + assets.scaleFactor + "x/", ) );

If your style of graphics is pixelated, then preparing high-resolution artwork for high-resolutions screens would not make sense, because the graphic would stay the same but at double the size (i.e. four times the surface area). It’s a waste of disk space and processing time.

To avoid overhead, we separated the pixelated textures from the UI textures, which contain anti-aliased graphics. A single set of pixelated textures is used for all resolutions but then is scaled up for high-resolution displays at runtime, while the UI textures are resolution-aware (i.e. separate textures for high-resolution devices).

By default, Starling uses bilinear filtering, which creates smooth transitions between pixels when textures are scaled. That’s perfect in most cases, but it looks blurry when applied to pixelated art. If you turn off smoothing in the Image class, you’ll end up with nearest-neighbor scaling for all images.

mSmoothing = TextureSmoothing.NONE; Conclusion

PixelMogul is the first game that we created entirely in house. Adobe AIR and Starling made it possible for us to carry over our experience with ActionScript and the Flash platform and to focus on development. The fast-growing and active Starling community was a big plus, too. We would definitively go the same route for another project of comparable scope.

What do you think? We look forward to hearing your opinions!

Further Resources

(al, il, ml)


The post Case Study: PixelMogul, A Simulation Game For iOS appeared first on Smashing Magazine.

Techniques For Creating Custom Textures In Photoshop

Thu, 07/03/2014 - 09:00

Textures are everywhere — the concrete of a sidewalk, the fabric on your chair, even the glass (or plastic) surface of the screen you’re staring at right now. It’s natural that textures appeal to us because we see and feel them every day. And it’s no surprise why textures have become such an important element in design — so important, in fact, that I want to share with you the tricks and tools to create your own textures using Photoshop.

Photoshop isn’t just for retouching images or manipulating photos. It can be used for so much more, such as creating your own textures — as long as you know where to look. In this article, I will present a foundation of techniques to help you build custom textures. I’ll go over three Photoshop features that I rely on to do most of my texturing — filters, layer styles and brushes. Before we jump in, I want to demonstrate the importance of textures. Consider the image below:

1A comparison of textures. (View large version2)

In the image above, we see a scene with no textures. (OK, there is one texture, flat gray. Without at least one texture, the image would not exist.) The second image (right) shows a scene fully textured (the wood on the frame, the dusty table top, the fabric on the chair, etc.). In fact, this entire image was created in Photoshop (without the use of external images), using many of the techniques outlined in this article. Note that this article explores how to create textures, but if you’re interested in learning more about using texture as an element in design, some additional reading is included at the end of this article.

Texturing With Filters

Filters are still viewed by many as cheap gimmicks that have no real applicable function in Photoshop. (I know, I used to be on that side of the fence.) On the contrary, Photoshop filters are extremely powerful effects that, when used properly, can produce some amazing results. If filters are not a part of your normal Photoshop workflow, I encourage you to take another look at these underappreciated effects and use the tips below to get started.

Apply a Filter to a Filter

No one ever said that you can apply only one filter. Instead, try adding a second or third or more. Experiment with multiple filters and see how they interact with each other to create new effects. The Filter Gallery panel (Filter → Filter Gallery) even has a filter stack where you can preview how multiple filters work together. The image below demonstrates how the Craquelure filter becomes much more interesting simply by applying it to the Reticulation filter via the Filter Gallery.

3The Craquelure filter applied to the Reticulation filter in the Filter Gallery panel. (View large version4)

Let’s take another look at how some filters work together to create custom textures. The image below shows a basic example of this.

5A coarse texture created with multiple filters. (View large version6)

The image below depicts the steps necessary to recreate this texture. The texture begins with a blank canvas (left). Adding the Noise filter (Filter → Noise → Add Noise) (middle) introduces randomness to the scene and sets up a good foundation for the next filter. Because filters work by manipulating the pixels on a layer, the order in which you apply filters is important. So, by applying the Emboss filter (Filter → Stylize → Emboss) on top of the Noise filter, a new texture is created (right).

7Three steps to create a simple texture. (View large version8)

Furthermore, some filters just produce better results when applied more than once. Consider the image below of the circled grid. Applying the Spherize filter (Filter → Distort → Spherize) produces only a mild result (middle). However, applying it a second time creates a more believable sphere (right).

9Some filters work better when applied more than once. (View large version10)

Tip: Convert a layer to a Smart Object before applying a filter to enable Smart Filters. Smart Filters are non-destructive and can be edited on the fly.

Experiment with different combinations of filters to see how they interact with each other. Soon, you’ll be able to predict how a filter might work with another filter to create a particular effect. Lets move on to the next tip.

Some Filters Naturally Tile

Tiling textures, while desirable, often takes a lot of time and effort — why not let Photoshop do most of the work for you? Some filters (such as Clouds and Noise) will naturally tile when the document is sized in powers of 2 (for example, 256 × 256, 512 × 512, even 512 × 1024). If you start with one of these textures as a base and build on top of it, you’ll find that you can quickly create some complex textures that tile with little or no additional effort. The image below shows an example of a texture that was created by using the Clouds filter as a starting point.

11Wood texture created with the Clouds filter as a base. (View large version12)

As stated, this texture starts with the Clouds filter (Filter → Render → Clouds) applied to a document that’s sized to 1024 × 1024 pixels. Similar to Noise, the Clouds filter provides some randomness that works nicely with other filters.

13Clouds filter applied to a blank document. (View large version14)

At this point, we are free to adjust the dimensions of the image without harming its ability to tile. Therefore, by adjusting the size via Image → Image Size, we can squish the texture while keeping it tileable (left). Now, if we add the Posterize effect (Image → Adjustment → Posterize), we can break up the texture into a number of gray shades with more defined edges (middle). The Find Edges filter (Filter → Stylize → Find Edges) will isolate just those edges, producing the start of a wood grain pattern (right).

15A stretched Clouds filter becomes wood grain. (View large version16)

To learn the entire process of how this texture was created, check out my “Custom Wood Texture in Adobe Photoshop17” tutorial.

Texturing With Layer Styles

Layer styles are another way to introduce texture into a scene. They offer additional options to embellish the contents of a layer. Experimenting with each setting in the Layer Styles panel in order to learn how they work is always a good practice. Below are some tricks I use when working with layer styles.

Blending Modes

When building textures in Photoshop, blending modes do exactly what they say: blend. Multiple layers of textures can seamlessly blend into a single, complex texture, as seen below:

18The texture on the tabletop was created by blending multiple textures. (View large version19)

Tip: Working with grayscale textures when using blending modes makes blending much easier to control (color can always be added later).

When you’re trying to build complex textures, knocking it out in one attempt can be difficult. Instead, try to break down a complex texture into a set of simpler sub-textures. Consider the texture of the tabletop in the four images below. Each image represents a simple texture that was blended together with the others to create a more complex final texture.

20The texture on the tabletop was created by blending multiple textures. (View large version21) Advanced Blending and “Blend If” Options

Using layer styles might be an obvious choice, but many people often ignore the “Advanced Blending” section in the default Layer Styles panel. Hidden in plain sight are some of the more powerful blending options. Here, you can decide how a layer mask will affect a style: Will it hide a layer style or just confine it to the visible portion of the layer? Towards the bottom of the menu are the “Blend If” sliders. These sliders can easily produce complex blending effects.

22The Layers Style panel contains the often overlooked “Advanced Blending” and “Blend If” options. (View large version23)

Take the image below. The glossy texture on the paint was created with minimal effort using the “Blend If” sliders.

24An image of a paintbrush created using various techniques in Photoshop. (View large version25)

The “Blend If” sliders control how a layer is blended into the layers beneath it, as illustrated in the images below. The initial layer of paint (left) appears too flat but has just enough variation to allow the “Blend If” sliders to work. Next, broad areas of white are painted onto a new layer (right) to define where the blending will take place. Adjusting the “Blend If” sliders of the white layer will produce that glossy effect in the image above.

26Steps in creating a glossy texture. (View large version27)

Tip: When using the “Blend If” sliders, hold Option or Alt while adjusting the sliders to separate them, making for a smoother blend.

28The “Blend If” sliders separated.

To learn more about how this image was created, check out my “Create a Paint Brush in Photoshop29” tutorial.

Duplicate Layer Styles

Sometimes a layer will benefit from having two of the same layer styles with different settings. In past versions of Photoshop, accomplishing this without using destructive techniques was difficult. With the introduction of Smart Objects in CS2 — and now with the ability to add layer styles to layer groups in CS6 — Photoshop makes it easy to use and reuse multiple layer styles on the same layer. This technique was used to create the liquid and the glass bottle in the scene below.

30Wine bottles and wine glasses created with the aid of duplicate layer styles. (View large version31)

Examining just the liquid from the scene, it starts with a generic shape on its own layer (left). The Inner Shadow and Gradient Overlay layer styles were assigned to the layer (middle). The layer was converted to a Smart Object, which allows you to edit the layer styles in future. Next, the same two layer styles (Inner Shadow and Gradient Overlay) were reapplied to the Smart Object (right) using different settings to achieve a more complex effect.

32The liquid shape with duplicate layer styles. (View large version33)

Examining the image above, you can see how creative we can get with layer styles. For example, in the middle image, the Gradient Overlay layer style was applied as a large, soft gradient that acts almost as a vignette around the top and bottom of the shape. In the last panel, the Gradient Overlay was treated much differently. It’s applied as a small, tight gradient that becomes the traditional bulb shape on the bottom of a wine bottle.

To learn more about how this was created, check out my “Create a Wine Bottle and Glass With Smart Objects34” tutorial.

Texturing With Brushes

Using brushes is a great way to apply textures manually. If you’re into digital painting, then you probably know of several techniques using the Brush tool. However, being talented at digital painting is not required to effectively use the Brush tool. The following tips will reveal some more advanced methods of using this tool.

Learn the Brushes Panel

This might sound pretty basic, but many people only stick to the “Hardness” and “Size” settings. Adjusting the settings in the Brushes panel (Window → Brush) can quickly extend the use of any brush. It gives you the options to fine-tune the behavior of a brush, making it more random and, thus, more natural. This is how I created some of the elements in the image below (such as the pencil’s highlights).

35A pencil and paper scene created in Photoshop. (View large version36)

To create the realistic highlights, I adjusted the “Shape Dynamics” and the “Scattering” settings in the Brushes panel (left). By changing the settings and size, I was able to produce a number of brush strokes that look more fragmented and more natural (right). Each brush stroke represents a different highlight that went into the pencil.

37Different brush strokes produced with the Brushes panel. (View large version38)

Tip: Another great feature of the Brushes panel is that it allows you to test the brush while editing it, which makes quick work of setting up the right brush for the job.

To learn more about how this scene was created, check out my “Create a Realistic Pencil Illustration in Adobe Photoshop39” tutorial.

Consider Custom Brush Shapes

Sometimes, just tweaking the settings of an existing brush isn’t enough. Creating a new brush shape (via Edit → Define Brush Preset) opens up more possibilities for achieving natural-looking textures. Brush shapes don’t have to be complex to be effective — I typically work with simple shapes and adjust the settings to fit my needs. A good example of this is the scratches that appear on the paintbrush’s wooden handle in the image below.

40The distressed handle of a paintbrush. (View large version41)

The scratches were created by drawing a simple shape, just like the one in the image below (left). Selecting Edit → Define Brush Preset will add the brush shape to your brushes library. Using the technique from the previous step and adjusting the “Shape Dynamics” and “Scattering” settings in the Brushes panel, we can create a brush that shows scratches (middle). The image on the right shows the brush in use.

A custom brush shape used to add texture. (View large version43) Use the Brush Tool to Paint With Layer Styles

This next technique allows you to literally paint with texture. It combines the Brush tool and layer styles to easily create some complex texturing effects. The trick is to set the layer’s “Fill” setting to 0% in order to hide the brush strokes and focus on the layer style. The image below demonstrates the technique. In this case, I used the technique to paint dents onto the metal frame.

44Worn-out sign with dented metal frame. ( View large version45)

The technique works best when you use a brush shape that already has some variation. This could be a custom brush or one of Photoshop’s several preset brushes, such as the “Charcoal 59 px” brush seen in the image below.

46The Charcoal preset brush. (View large version47)

Following one of the previous techniques, I’ve used the Brushes panel to adjust the “Shape Dynamics” and “Scattering” settings to produce more variation in the brush’s actual stroke, as seen in the image below (left). Before using the brush, just create a new layer with a Bevel and Emboss layer style, and then set the “Fill” setting to 0% (which will hide the stroke color but keep the layer style visible). Now, when painting on this layer, you can literally paint with texture (right).

48Using a custom paintbrush to paint with texture. (View large version49)

To learn more about how the metal sign was created, check out my “Create a Retro Sign from Scratch Using Advanced Techniques in Photoshop50” tutorial.

Texturing With Images

While these textures technically weren’t created from scratch, I thought this was important enough to address. Using textures from existing photos or scans can be a quick and effective way to work. However, the most common pitfalls are using the textures in the wrong perspective, using them with incorrect lighting or making them appear flat. Fortunately, these are easy to avoid and some great articles address this.


As we have seen, creating high-quality textures for art or design doesn’t require the talent of an artisan painter. All it takes is a little understanding of Photoshop and knowledge of the tools and how to manipulate them to get the effect you desire. Hopefully, you’ve learned some new tricks and techniques that will help you in your next project.

Additional Reading

(al, ml)


The post Techniques For Creating Custom Textures In Photoshop appeared first on Smashing Magazine.

Don’t Be Scared Of Functional Programming

Wed, 07/02/2014 - 13:37

Functional programming is the mustachioed hipster of programming paradigms. Originally relegated to the annals of computer science academia, functional programming has had a recent renaissance that is due largely to its utility in distributed systems (and probably also because “pure” functional languages like Haskell are difficult to grasp, which gives them a certain cache).

Stricter functional programming languages are typically used when a system’s performance and integrity are both critical — i.e. your program needs to do exactly what you expect every time and needs to operate in an environment where its tasks can be shared across hundreds or thousands of networked computers. Clojure1, for example, powers Akamai2, the massive content delivery network utilized by companies such as Facebook, while Twitter famously adopted3 Scala4 for its most performance-intensive components, and Haskell5 is used by AT&T for its network security systems.

These languages have a steep learning curve for most front-end web developers; however, many more approachable languages incorporate features of functional programming, most notably Python, both in its core library, with functions like map and reduce (which we’ll talk about in a bit), and with libraries such as Fn.py6, along with JavaScript, again using collection methods, but also with libraries such as Underscore.js7 and Bacon.js8.

Functional programming can be daunting, but remember that it isn’t only for PhDs, data scientists and architecture astronauts. For most of us, the real benefit of adopting a functional style is that our programs can be broken down into smaller, simpler pieces that are both more reliable and easier to understand. If you’re a front-end developer working with data, especially if you’re formatting that data for visualization using D3, Raphael or the like, then functional programming will be an essential weapon in your arsenal.

Finding a consistent definition of functional programming is tough, and most of the literature relies on somewhat foreboding statements like “functions as first-class objects,” and “eliminating side effects.” Just in case that doesn’t bend your brain into knots, at a more theoretical level, functional programming is often explained in terms of lambda calculus9 (some actually argue10 that functional programming is basically math) — but you can relax. From a more pragmatic perspective, a beginner needs to understand only two concepts in order to use it for everyday applications (no calculus required!).

First, data in functional programs should be immutable, which sounds serious but just means that it should never change. At first, this might seem odd (after all, who needs a program that never changes anything?), but in practice, you would simply create new data structures instead of modifying ones that already exist. For example, if you need to manipulate some data in an array, then you’d make a new array with the updated values, rather than revise the original array. Easy!

Secondly, functional programs should be stateless, which basically means they should perform every task as if for the first time, with no knowledge of what may or may not have happened earlier in the program’s execution (you might say that a stateless program is ignorant of the past11). Combined with immutability, this helps us think of each function as if it were operating in a vacuum, blissfully ignorant of anything else in the application besides other functions. In more concrete terms, this means that your functions will operate only on data passed in as arguments and will never rely on outside values to perform their calculations.

Immutability and statelessness are core to functional programming and are important to understand, but don’t worry if they don’t quite make sense yet. You’ll be familiar with these principles by the end of the article, and I promise that the beauty, precision and power of functional programming will turn your applications into bright, shiny, data-chomping rainbows. For now, start with simple functions that return data (or other functions), and then combine those basic building blocks to perform more complex tasks.

For example, let’s say we have an API response:

var data = [ { name: "Jamestown", population: 2047, temperatures: [-34, 67, 101, 87] }, { name: "Awesome Town", population: 3568, temperatures: [-3, 4, 9, 12] } { name: "Funky Town", population: 1000000, temperatures: [75, 75, 75, 75, 75] } ];

If we want to use a chart or graphing library to compare the average temperature to population size, we’d need to write some JavaScript that makes a few changes to the data before it’s formatted correctly for our visualization. Our graphing library wants an array of x and y coordinates, like so:

[ [x, y], [x, y] …etc ]

Here, x is the average temperature, and y is the population size.

Without functional programming (or without using what’s called an “imperative” style), our program might look like this:

var coords = [], totalTemperature = 0, averageTemperature = 0; for (var i=0; i < data.length; i++) { totalTemperature = 0; for (var j=0; j < data[i].temperatures.length; j++) { totalTemperature += data[i].temperatures[j]; } averageTemperature = totalTemperature / data[i].temperatures.length; coords.push([averageTemperature, data[i].population]); }

Even in a contrived example, this is already becoming difficult to follow. Let’s see if we can do better.

When programming in a functional style, you’re always looking for simple, repeatable actions that can be abstracted out into a function. We can then build more complex features by calling these functions in sequence (also known as “composing” functions) — more on that in a second. In the meantime, let’s look at the steps we’d take in the process of transforming the initial API response to the structure required by our visualization library. At a basic level, we’ll perform the following actions on our data:

  • add every number in a list,
  • calculate an average,
  • retrieve a single property from a list of objects.

We’ll write a function for each of these three basic actions, then compose our program from those functions. Functional programming can be a little confusing at first, and you’ll probably be tempted to slip into old imperative habits. To avoid that, here are some simple ground rules to ensure that you’re following best practices:

  1. All of your functions must accept at least one argument.
  2. All of your functions must return data or another function.
  3. No loops!

OK, let’s add every number in a list. Remembering the rules, let’s make sure that our function accepts an argument (the array of numbers to add) and returns some data.

function totalForArray(arr) { // add everything return total; }

So far so good. But how are we going to access every item in the list if we don’t loop over it? Say hello to your new friend, recursion! This is a bit tricky, but basically, when you use recursion, you create a function that calls itself unless a specific condition has been met — in which case, a value is returned. Just looking at an example is probably easiest:

// Notice we're accepting two values, the list and the current total function totalForArray(currentTotal, arr) { currentTotal += arr[0]; // Note to experienced JavaScript programmers, I'm not using Array.shift on // purpose because we're treating arrays as if they are immutable. var remainingList = arr.slice(0,-1); // This function calls itself with the remainder of the list, and the // current value of the currentTotal variable if(remainingList.length > 0) { return totalForArray(currentTotal, remainingList); } // Unless of course the list is empty, in which case we can just return // the currentTotal value. else { return currentTotal; } }

A word of caution: Recursion will make your programs more readable, and it is essential to programming in a functional style. However, in some languages (including JavaScript), you’ll run into problems when your program makes a large number of recursive calls in a single operation (at the time of writing, “large” is about 10,000 calls in Chrome, 50,000 in Firefox and 11,000 in Node.js12). The details are beyond the scope of this article, but the gist is that, at least until ECMAScript 6 is released13, JavaScript doesn’t support something called “tail recursion14,” which is a more efficient form of recursion. This is an advanced topic and won’t come up very often, but it’s worth knowing.

With that out of the way, remember that we needed to calculate the total temperature from an array of temperatures in order to then calculate the average. Now, instead of looping over each item in the temperatures array, we can simply write this:

var totalTemp = totalForArray(0, temperatures);

If you’re purist, you might say that our totalForArray function could be broken down even further. For example, the task of adding two numbers together will probably come up in other parts of your application and subsequently should really be its own function.

function addNumbers(a, b) { return a + b; }

Now, our totalForArray function looks like this:

function totalForArray(arr, currentTotal) { currentTotal = addNumbers(currentTotal + arr[0]); var remainingArr = arr.slice(0,-1); if(remainingArr.length > 0) { return totalForArray(currentTotal, remainingArr); } else { return currentTotal; } }

Excellent! Returning a single value from an array is fairly common in functional programming, so much so that it has a special name, “reduction,” which you’ll more commonly hear as a verb, like when you “reduce an array to a single value.” JavaScript has a special method just for performing this common task. Mozilla Developer Network provides a full explanation15, but for our purposes it’s as simple as this:

// The reduce method takes a function as its first argument, and that function // accepts both the current item in the list and the current total result from // whatever calculation you're performing. var totalTemp = temperatures.reduce(function(previousValue, currentValue){ // After this calculation is returned, the next currentValue will be // previousValue + currentValue, and the next previousValue will be the // next item in the array. return previousValue + currentValue; });

But, hey, since we’ve already defined an addNumber function, we can just use that instead.

var totalTemp = temperatures.reduce(addNumbers);

In fact, because totalling up an array is so cool, let’s put that into its own function so that we can use it again without having to remember all of that confusing stuff about reduction and recursion.

function totalForArray(arr) { return arr.reduce(addNumbers); } var totalTemp = totalForArray(temperatures);

Ah, now that is some readable code! Just so you know, methods such as reduce are common in most functional programming languages. These helper methods that perform actions on arrays in lieu of looping are often called “higher-order functions.”

Moving right along, the second task we listed was calculating an average. This is pretty easy.

function average(total, count) { return count / total; }

How might we go about getting the average for an entire array?

function averageForArray(arr) { return average(totalForArray(arr), arr.length); } var averageTemp = averageForArray(temperatures);

Hopefully, you’re starting to see how to combine functions to perform more complex tasks. This is possible because we’re following the rules set out at the beginning of this article — namely, that our functions must always accept arguments and return data. Pretty awesome.

Lastly, we wanted to retrieve a single property from an array of objects. Instead of showing you more examples of recursion, I’ll cut to the chase and clue you in on another built-in JavaScript method: map16. This method is for when you have an array with one structure and need to map it to another structure, like so:

// The map method takes a single argument, the current item in the list. Check // out the link above for more complete examples. var allTemperatures = { return item.temperatures; });

That’s pretty cool, but pulling a single property from a collection of objects is something you’ll be doing all the time, so let’s make a function just for that.

// Pass in the name of the property that you'd like to retrieve function getItem(propertyName) { // Return a function that retrieves that item, but don't execute the function. // We'll leave that up to the method that is taking action on items in our // array. return function(item) { return item[propertyName]; } }

Check it out: We’ve made a function that returns a function! Now we can pass it to the map method like this:

var temperatures ='temperature'));

In case you like details, the reason we can do this is because, in JavaScript, functions are “first-class objects,” which basically means that you can pass around functions just like any other value. While this is a feature of many programming languages, it’s a requirement of any language that can be used in a functional style. Incidentally, this is also the reason you can do stuff like $('#my-element').on('click', function(e) … ). The second argument in the on method is a function, and when you pass functions as arguments, you’re using them just like you would use values in imperative languages. Pretty neat.

Finally, let’s wrap the call to map in its own function to make things a little more readable.

function pluck(arr, propertyName) { return; } var allTemperatures = pluck(data, 'temperatures');

All right, now we have a toolkit of generic functions that we can use anywhere in our application, even in other projects. We can tally up the items in an array, get the average value of an array, and make new arrays by plucking properties from lists of objects. Last but not least, let’s return to our original problem:

var data = [ { name: "Jamestown", population: 2047, temperatures: [-34, 67, 101, 87] }, … ];

We need to transform an array of objects like the one above into an array of x, y pairs, like this:

[ [75, 1000000], … ];

Here, x is the average temperature, and y is the total population. First, let’s isolate the data that we need.

var populations = pluck(data, 'population'); var allTemperatures = pluck(data, 'temperatures');

Now, let’s make an array of averages. Remember that the function we pass to map will be called on each item in the array; so, the returned value of that passed function will be added to a new array, and that new array will ultimately be assigned to our averageTemps variable.

var averageTemps =;

So far so good. But now we have two arrays:

// populations [2047, 3568, 1000000] // averageTemps [55.25, 5.5, 75]

Obviously, we want only one array, so let’s write a function to combine them. Our function should make sure that the item at index 0 in the first array is paired with the item at index 0 in the second array, and so on for indexes 1 to n (where n is the total number of items in the array).

function combineArrays(arr1, arr2, finalArr) { // Just so we don't have to remember to pass an empty array as the third // argument when calling this function, we'll set a default. finalArr = finalArr || []; // Push the current element in each array into what we'll eventually return finalArr.push([arr1[0], arr2[0]]); var remainingArr1 = arr1.slice(0,-1), remainingArr2 = arr2.slice(0,-1); // If both arrays are empty, then we're done if(remainingArr1.length === 0 && remainingArr2.length === 0) { return finalArr; } else { // Recursion! return combineArrays(remainingArr1, remainingArr2, finalArr); } }; var processed = combineArrays(averageTemps, populations);

Or, because one-liners are fun:

var processed = combineArrays(pluck(data, 'temperatures').map(averageForArray), pluck(data, 'population')); // [ // [ 55.25, 2047 ], // [ 5.5, 3568 ], // [ 75, 1000000 ] // ] Let’s Get Real

Last but not least, let’s look at one more real-world example, this time adding to our functional toolbelt with Underscore.js17, a JavaScript library that provides a number of great functional programming helpers. We’ll pull data from a platform for conflict and disaster information that I’ve been working on named CrisisNET18, and we’ll use the fantastic D319 library to visualize that data.

The goal is to give people coming to CrisisNET’s home page a quick snapshot of the types of information in the system. To demonstrate this, we could count the number of documents from the API that are assigned to a particular category, like “physical violence” or “armed conflict.” This way, the user can see how much information is available on the topics they find most interesting.

A bubble chart might be a good fit, because they are often used to represent the relative sizes of large groups of people. Fortunately, D3 has a built-in visualization named pack for just this purpose. So, let’s create a graph with pack that shows the number of times that a given category’s name appears in a response from CrisisNET’s API.

Before we go on, note that D3 is a complex library that warrants its own tutorial (or many tutorials, for that matter). Because this article is focused on functional programming, we won’t spend a lot of time on how D3 works. But don’t worry — if you’re not already familiar with the library, you should be able to copy and paste the code snippets specific to D3 and dig into the details another time. Scott Murray’s D3 tutorials20 are a great resource if you’re interested in learning more.

Moving along, let’s first make sure we have a DOM element, so that D3 has some place to put the chart it will generate with our data.

<div id="bubble-graph"></div>

Now, let’s create our chart and add it to the DOM.

// width of chart var diameter = 960, format = d3.format(",d"), // creates an ordinal scale with 20 colors. See D3 docs for hex values color = d3.scale.category20c(), // chart object to which we'll be adding data var bubble = d3.layout.pack() .sort(null) .size([diameter, diameter]) .padding(1.5); // Add an SVG to the DOM that our pack object will use to draw the // visualization. var svg ="#bubble-graph").append("svg") .attr("width", diameter) .attr("height", diameter) .attr("class", "bubble");

The pack object takes an array of objects in this format:

{ children: [ { className: , package: "cluster", value: } ] }

CrisisNET’s data API returns information in this format:

{ data: [ { summary: "Example summary", content: "Example content", … tags: [ { name: "physical-violence", confidence: 1 } ] } ] }

We see that each document has a tags property, and that property contains an array of items. Each tag item has a name property, which is what we’re after. We need to find each unique tag name in CrisisNET’s API response and count the number of times that tag name appears. Let’s start by isolating the information we need using the pluck function that we created earlier.

var tagArrays = pluck(data, 'tags');

This gives us an array of arrays, like this:

[ [ { name: "physical-violence", confidence: 1 } ], [ { name: "conflict", confidence: 1 } ] ]

However, what we really want is one array with every tag in it. So, let’s use a handy function from Underscore.js named flatten21. This will take values from any nested arrays and give us an array that is one level deep.

var tags = _.flatten(tagArrays);

Now, our array is a little easier to deal with:

[ { name: "physical-violence", confidence: 1 }, { name: "conflict", confidence: 1 } ]

We can use pluck again to get the thing we really want, which is a simple list of only the tag names.

var tagNames = pluck(tags, 'name'); [ "physical-violence", "conflict" ]

Ah, that’s better.

Now we’re down to the relatively straightforward tasks of counting the number of times each tag name appears in our list and then transforming that list into the structure required by the D3 pack layout that we created earlier. As you’ve probably noticed, arrays are a pretty popular data structure in functional programming — most of the tools are designed with arrays in mind. As a first step, then, we’ll create an array like this:

[ [ "physical-violence", 10 ], [ "conflict", 27 ] ]

Here, each item in the array has the tag name at index 0 and that tag’s total count at index 1. We want only one array for each unique tag name, so let’s start by creating an array in which each tag name appears only once. Fortunately, an Underscore.js method exists just for this purpose.

var tagNamesUnique = _.uniq(tagNames);

Let’s also get rid of any false-y (false, null, "", etc.) values using another handy Underscore.js function.

tagNamesUnique = _.compact(tagNamesUnique);

From here, we can write a function that generates our arrays using another built-in JavaScript collection method, named filter22, that filters an array based on a condition.

function makeArrayCount(keys, arr) { // for each of the unique tagNames return { return [ key, // Find all the elements in the full list of tag names that match this key // and count the size of the returned array. arr.filter(function(item) { return item === key; }).length ] }); }

We can now easily create the data structure that pack requires by mapping our list of arrays.

var packData = makeArrayCount(tagNamesUnique, tagNames).map(function(tagArray) { return { className: tagArray[0], package: "cluster", value: tagArray[1] } });

Finally, we can pass our data to D3 and generate DOM nodes in our SVG, one circle for each unique tag name, sized relative to the total number of times that tag name appeared in CrisisNET’s API response.

function setGraphData(data) { var node = svg.selectAll(".node") // Here's where we pass our data to the pack object. .data(bubble.nodes(data) .filter(function(d) { return !d.children; })) .enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); // Append a circle for each tag name. node.append("circle") .attr("r", function(d) { return d.r; }) .style("fill", function(d) { return color(d.className); }); // Add a label to each circle, using the tag name as the label's text node.append("text") .attr("dy", ".3em") .style("text-anchor", "middle") .style("font-size", "10px") .text(function(d) { return d.className } ); }

Putting it all together, here’s the setGraphData and makeArray functions in context, including a call to CrisisNET’s API using jQuery (you’ll need to get an API key23). I’ve also posted a fully working example on GitHub24.

function processData(dataResponse) { var tagNames = pluck(_.flatten(pluck(, 'tags')), 'name'); var tagNamesUnique = _.uniq(tagNames); var packData = makeArrayCount(tagNamesUnique, tagNames).map(function(tagArray) { return { className: tagArray[0], package: "cluster", value: tagArray[1] } }); return packData; } function updateGraph(dataResponse) { setGraphData(processData(dataResponse)); } var apikey = // Get an API key here: var dataRequest = $.get('' + apikey); dataRequest.done( updateGraph );

That was a pretty deep dive, so congratulations on sticking with it! As I mentioned, these concepts can be challenging at first, but resist the temptation to hammer out for loops for the rest of your life.

Within a few weeks of using functional programming techniques, you’ll quickly build up a set of simple, reusable functions that will dramatically improve the readability of your applications. Plus, you’ll be able to manipulate data structures significantly more quickly, knocking out what used to be 30 minutes of frustrating debugging in a couple lines of code. Once your data has been formatted correctly, you’ll get to spend more time on the fun part: making the visualization look awesome!

(al, il)


The post Don’t Be Scared Of Functional Programming appeared first on Smashing Magazine.

Server-Side Device Detection With JavaScript

Tue, 07/01/2014 - 14:58

There are many strategies to choose from when developing a modern, device independent website nowadays. How should capabilities of the device or browser be determined? Should the presentation logic be server side or client side? Traditionally, mobile optimization had to happen server side.

Over the last couple of years, Responsive Web Design and tools like Modernizr1 have become very popular. Recently, combination techniques (often called RESS2), where optimization is done both server-side and client-side, has become a trend. The recently launched WURFL.js3 tool, fits into this category.

In this article, we will look at some basic use cases of how to use WURFL.js to optimize the user experience both in HTML and CSS, and an example of how to choose the best ads to display to different devices. We will also see how WURFL.js is different from, but complements, the popular feature-detection library Modernizr.

Once Upon A Time, Device Detection

Whether we are using regular expressions in JavaScript, Modernizr or a complete device-description repository4 (DDR) for server-side detection, the purpose is usually the same: to give users a better experience. This typically happens at two levels:

  • presentation of content and interaction with the service,
  • analysis of user behavior to determine usage patterns.

The challenge is to do this in ways that are both scalable, maintainable and, as much as possible, easy to implement. For some projects, the cost and complexity of deploying third-party tools on servers is too high. Yet a low-maintenance solution that lets a website look good and perform well is possible, despite the constant diversification of devices. This is where WURFL.js plays a role, by providing an easy-to-use, reliable and scalable alternative to traditional server-side device detection, all the while complementing other client-side techniques and tools.

Before diving in, let’s look at the basics.

Copy, Paste, Done

No registration is required, and WURFL.js is free to use5. So, the first thing to do is copy and paste this line of HTML into your page:

<script type='text/javascript' src=“//"></script>

Both HTTP and HTTPS are supported. If you plan to use the device information provided by the script to make rendering decisions, then you might want to include the script in the <head> element. Otherwise, you can load it asynchronously.

Now that the script is in your HTML page, you can access the WURFL object in JavaScript. The WURFL object looks like this and is ready to use:

{ complete_device_name:"Apple iPhone 5", form_factor:"Smartphone", is_mobile:true }

The object has three properties:

  • complete_device_name
    This is the name by which the device is known — typically, the make and model or a category of devices or a more generic definition.
  • form_factor
    • desktop
    • app
    • tablet
    • smartphone
    • feature phone
    • smart TV
    • robot
    • other non-mobile
    • other mobile
  • is_mobile
    This is true or false — true if the device is a tablet or other mobile device.

Of course, you can immediately do things like this:


Or this:

alert(WURFL.complete_device_name); Under The Hood

Because WURFL.js detects the device based on the User-Agent string and other information provided in the HTTP header, the contents of the JavaScript file will depend on the device. So, you can’t just copy the contents of the file and put it inline in the HTML or combine it with another JavaScript resource.

6WURFL.js’ basic flow

To understand this in detail, let’s look at the illustration above. The browser makes a request for (1). The markup returned by the Web server (2) contains the <script> reference to WURFL.js. Next, the browser renders the HTML and starts fetching assets — among them, (3). When the request reaches, the HTTP request is analyzed by WURFL. Usually, based on that request, there will be an instant hit, and the device is identified without further ado, and a single WURFL JavaScript object is returned. However, in certain cases when the device cannot be identified on the server side alone (notably, in the case of iOS devices), the JavaScript file will contain a few more checks to determine the device. The browser then evaluates the JavaScript, and the WURFL object is ready to use (4).

WURFL.js is capable of, for example, distinguishing between an iPhone 5 and an iPhone 5S, thanks to this extra client-side logic. This is a big deal because this use case is supported neither by sheer User-Agent analysis7 nor by Modernizr tests.

A Note On Performance

If you use WURFL.js to make rendering decisions or, for some reason, you need to place the <script> tag inside <head> (without deferring it), then the browser will wait for the script to be downloaded and evaluated before rendering the page. Depending on the use case, this might be the only way; but, for the record, WURFL.js can also be loaded asynchronously to increase rendering performance.

The size of the returned JSON object will be fairly small, varying from 0.5 to 3 or 4 KB, depending on the device. Compared to Modernizr (about 14 KB) and jQuery (96 KB), WURFL.js is arguably light.

Use Cases

Assuming that you have WURFL.js up and running, let’s look at some cases in which using WURFL.js makes the most sense, either by itself or in conjunction with Modernizr and/or other solutions. To illustrate, we’ll refer to the website8 itself, which utilizes WURFL.js in multiple ways.

Optimizing the User Experience

When it comes to mobile, responsive and adaptive design and all that, the most common thing to do on a website is improve the user experience for certain device families or form factors. Much can be handled by media queries, of course, but sometimes you need the help of some JavaScript.

When you visit WURFL.io9 on your laptop, the top section of the page has a video background, some simple parallax scrolling and text that changes dynamically according to the device or browser. It looks very cool on a laptop, but video backgrounds, not to mention parallax scrolling, would not be ideal on a tablet or smartphone, to put it mildly.

10Differences in presentation in desktop Safari and iPhone Safari.

We could use Modernizr, of course, or decide whether to implement these features in other ways. But in many cases, knowing the physical device is just as important as — perhaps more important than — knowing whether the browser claims support for a feature. We might encounter a problem whereby the browser claims support, but the support is actually not good enough to make a great user experience.

To avoid these situations, you would use WURFL.js and Modernizer together. Note also that comparing WURFL.js and Modernizr directly is not quite fair. Modernizr detects features claimed by the browser, whereas WURFL.js categorizes the device in different ways. So, if you don’t know whether a particular device or form factor supports a certain browser-detectable feature, then you are better off with Modernizr or a full-fledged device-detection solution11.

However, in this example, we’ll rely on WURFL.js and demand that only non-mobile clients get the video background and parallax scrolling:

/*video background*/ if(!WURFL.is_mobile){ $('#vid').videoBG({ mp4:'assets/Birds_Animation.mp4.mp4', ogv:'assets/Birds_Animation.oggtheora.ogv', webm:'assets/Birds_Animation.webmhd.webm' }); } /*The parallax scrolling*/ window.onscroll = function () { if (!WURFL.is_mobile){[prefixedTransform] = "translate3d(0px," + window.scrollY / 2.3 + "px, 0px)";[prefixedTransform] = "translate3d(0px," + window.scrollY / 1.1 + "px, 0px)";["opacity"] = (1 - ((window.scrollY / 6) / 100)); } }

The example above simply checks whether the device is mobile (a phone or tablet) and introduces features accordingly. Of course, we could also leverage the more fine-grained WURFL.form_factor.

Put More In CSS?

The examples above show how to make use of the device’s data in JavaScript. However, we can make the device’s information available in CSS, too. We can assign different styles depending on the device, form factor and whether it is mobile. The first technique we will look at is similar to how Modernizr works. Modernizr adds a certain class to the HTML document depending on whether its test returns true or false.

Let’s say you want some specific behavior defined in the CSS for mobile devices. You would need to add the following JavaScript snippet to your page:

document.documentElement.className += ' ' + (WURFL.is_mobile ? '' : 'no-') + "mobile";

This will add a class to the html element. For mobile devices, it would say <html class=”is_mobile”>; for other devices, it would say <html class=”no-is_mobile”>.

If you know Modernizr, then you are probably familiar with this approach. Your CSS might take the following form:

.mobile #menu a{ padding .5em; } .no-mobile #menu a{ padding .1em; }

In this simple example, we’ve increased the padding on menu items so that they are easy to tap with a fat thumb.

This method can be used for all of WURFL.js’ capabilities. However, because complete_device_name and form_factor are not boolean values (like is_mobile), the CSS part can become quite a headache. A bit more flexibility might come in handy, then. Here is an example using data- attributes:

document.documentElement.setAttribute('data-device_name', WURFL.complete_device_name); document.documentElement.setAttribute('data-form_factor', WURFL.form_factor );

This will put data attributes with WURFL capabilities in the html element. We get several cool features with this method: We can target specific devices, form factors and even groups of devices combined with form factors by using CSS selectors:

html[data-form_factor = 'Smartphone'] #menu a{ background: green; }

Thanks to the wildcard attribute selector12 *, we can even match strings:

html[data-device_name*='Nokia'] [data-form_factor = 'Feature Phone'] { background: yellow; }

The CSS above will match Nokia feature phones of any model.

The screenshot above illustrates what the DOM looks like with the two methods implemented — in this case, with an iPhone 5S.

Help With Banner Ads

Many different ad networks are out there, each with its own specialization. Some are good for mobile, others for desktop. Some support text ads, other have ads of fixed size. If you are beyond a beginner’s level in ad networks, then you might want to assume some control over this. WURFL.js can help you make your own decisions or influence the network to make the right decisions for you.

The obvious approach is to ask WURFL.is_mobile to choose networks or ads that are good for mobile and others that are good for non-mobile.

if(WURFL.is_mobile){ displayMobileAd(); }else{ displayDesktopAd(); }

Moreover, from a design perspective, being able to fit the sizes and proportions of ads to your breakpoints and to design for different form factors of ads is nice. In the extreme, you could do something like this:

switch(WURFL.form_factor){ case "Smartphone": if(WURFL.complete_device_name.indexOf("Apple") !=-1){ showAppStoreAds(); }else( showWebAds(); ) break; case "Tablet": showSpecificProportionAds(); break; case "Feature Phone": showTextAds(); break; default: showGoogleAdwords(); break; } Conclusion

If you’ve tackled the diversity of devices in the past, then you’ll know that many developers have been looking for JavaScript tricks to detect browsers, devices and their respective features. Traditionally, a DDR required server-side libraries and data to be installed and for the device-description repository to be updated. WURFL.js improves on this by making the power of WURFL available to web developers free of charge13.

Whether for analytics, optimization of the user experience, advertising or something else, consider WURFL.js when developing a modern, mobile-aware and device-independent website. WURFL.js complements Modernizr nicely. While Modernizr detects support for certain features of the browser, WURFL.js provides information about the user’s physical device that is not detectable through browser APIs.

WURFL.js is a bridge between the server side and the client side, making it easier for front-end Web developers to take advantage of functionality that used to belong on the server. It can even be used for current websites that have been designed responsively or that enhance progressively.

(al, il)


The post Server-Side Device Detection With JavaScript appeared first on Smashing Magazine.

Facing Your Fears: Approaching People For Research

Mon, 06/30/2014 - 14:45

When working on a project, have you ever felt that you and the rest of the team were making a lot of decisions based on assumptions? Having to make choices with limited information is not unusual — especially in complex projects or with brand new products.

Phrases like “We think people will use this feature because of X” or “We believe user group Y will switch to this product” become part of the early deliberation on what to develop and how to prioritize. At some point, though, these phrases start to feel like pure guesses and the ground under your feet feels shaky. What can you do about it?

Regardless of your role in the project, one activity in particular will help your whole team build a solid foundation for product strategy and design: that is, approaching potential users for research, such as interviews and usability tests.

Such research is an important aspect of user-centered design. It helps you build products that are rooted in a deep understanding of the target audience. Among other benefits, interviewing potential users helps you achieve the following:

  • more precisely define who the target audience is (and isn’t),
  • face and challenge your assumptions,
  • uncover unmet needs,
  • discover the behaviors and attitudes of potential users firsthand.

You can conduct informal yet valuable user research yourself with practice and with guidance from great sources like Steve Portigal’s Interviewing Users and Steve Krug’s Rocket Surgery Made Easy. One thing that stops a lot of people from trying their hand at research isn’t just lack of experience, but a fear of approaching people and asking for their time. This obstacle is greater than many would care to admit.

The Difficulty Of “Face To Face”

I was teaching an experience design class in high school when it really hit me. Students were engaged in the design process until they were told that they had to request interviews from strangers. The anxiety levels went through the roof! A look of shock covered their faces. Shortly after, two of the students asked to receive a failing grade on the activity rather than have to face strangers (a request that was not granted)!

This was no longer a case of time, opportunities, resources or priorities. The interviews were a part of the class and were considered essential. The students were presented with a clear set of expectations, provided with aid in planning and writing questions, and taken to the location (a college) to conduct the interviews.

When all of the usual obstacles were removed, what was laid bare? A strong fear of approaching strangers, made even stronger by the fact that so many interactions nowadays are done online, rather than face to face. Ask someone to create an online survey and they’re all over it — ask that same person to pose those same questions to a stranger face to face and they’ll freeze up.

One might assume that the problem afflicts only those in high school, but such a deep-seated reaction is felt by many working adults who are suddenly responsible for requesting something from strangers — even when the thing being requested is a relatively low commitment, like 10 minutes for an interview.

Are you at the point in a project when you would benefit from insights gained from face-to-face discussions with potential users but find yourself blocked by a fear of asking? Read on for techniques to help you approach people for research, the first step to gaining the knowledge you need.

“I’m Afraid I’ll Be Bothering People.”

I’m sure you’ve been approached by a stranger at one time or another. The negative occasions stand out the most, when you were annoyed or felt guilty because you didn’t want to say no to a request for money or personal information or a signature.

When a stranger approaches, the person being approached has several concerns at once:

  • “Who is this person?”
  • “Are they trying to scam me?”
  • “Are they going to ask me for money?”
  • “Are they going to ask me to sign something that I don’t agree with?”
  • “Am I going to have to figure out how to get rid of them?”
  • “How long is this going to take?”

Your memories of being approached could make you uncomfortable if you’re the one approaching others.

The good news is that approaching people for interviews can be a lot easier than requesting a donation. If you make it clear quickly that their time is voluntary and that you won’t ask for anything they don’t want to give, then you’ll generally get a positive response. After all, you’re not asking people for money, just for their time and attention. Time is valuable, but its value varies according to the person’s situation at that moment — and you can do certain things to communicate the value of agreeing to your request.

Increase the Value of Participation

Interview requests are accepted when participation is perceived to be as or more valuable than what the person is doing at the time. People calculate that value in their heads when you ask for their time.

1People calculate that value in their heads when you ask for their time. (Large version2)

Below are some of the factors that can swing the calculation in your favor.

Find the Right Time

If someone is in a rush to get somewhere, then making your research seem more valuable than their desire to get to their destination will probably be difficult. Someone who is walking briskly, looking tense and not making eye contact is not the ideal candidate.

Approach people who appear to be one or more of the following:

  • Between tasks
    If you’re asking about a particular activity, go to areas where people tend to be finishing up that activity, and talk to them as soon as they’re done with it. You’ll get a fresh perspective on the whole experience, and they likely won’t be in a rush to get to their next activity. For example, if you want to interview runners, wander the finish line of a race. Look for runners who are cooling down and checking out their swag but not yet heading home.
  • Bored
    Waiting in line, waiting for a bus or waiting for an elevator — if someone seems to be idly swiping their phone or staring off into space, they might actually welcome a distraction.
  • Procrastinating
    Some activities take a long time. The human brain needs a change of focus every now and then, and your research could be just the thing. If your target audience is students, visit a study area. When a student comes up for air, ask for some time. They might need the mental break!

Regardless of whom you approach, give them an idea of how long the interview will take (about 10 minutes, for example), so that they can do the mental math of calculating the value of saying yes.

Be Aware of Body Language

As mentioned, pay attention to the candidate’s body language. Do they seem tense? Are they frowning at their phone? Are they power-walking? They might be late for a meeting, so the timing would be wrong. Someone gazing around or strolling casually is a better bet. People on phones are a bit harder to read because many check their phone when bored or procrastinating — still, their facial expression might tell you whether they’re open to being interrupted for something more interesting.

Your own body language is important, too. Planting yourself in the middle of a person’s path and facing them squarely will come off as aggressive, likely triggering a negative reaction. They might feel like they’d have a hard time getting rid of you if they’re not comfortable with your request.

Being aware of your own body language and the body langauge of others is important.

Approach within clear view, but from the side. Also, try angling your body slightly away from the person. You want to seem engaged but also make them feel like they could end the conversation if desired. This will give them a greater sense of control and increase the likelihood that they’ll give you those precious seconds you need to make your request.

Fostering Interest

The feeling one gets from participating in research can be rewarding in itself. Interest is one positive feeling that leads people to say yes to research, which you can emphasize when approaching strangers.

Mention early on that you’re conducting research, which makes clear that you’re not asking for money and tends to generate interest.

Being approached to participate in research is fairly unusual for most people. The fact that you’re conducting a study might inspire a healthy curiosity. People will often be curious about what topic is being researched, what kinds of questions might be asked, and what they might find out about themselves in answering. The prevalence of quizzes and personality tests online is a good indication of this interest; those researchers are gathering data from the tests, but many of the respondents feel like they are learning about themselves (and potentially others) by considering the questions being asked.

3 People will often be curious about what topic is being researched, and what they might find out about themselves in answering. (Image: Personal DNA4) (View large version5)

The person might not be expecting to learn whether they’re a “benevolent inventor” or an ENFP6 by the end of the interview, but they might still find your questions interesting to consider.

Will the interviewees be shown something that others don’t have access to yet, like a new product or campaign? If so, bring that up quickly. It really boosts curiosity!

Furthermore, people might be flattered that you’re interested in their thoughts and opinion. Build on that! If there’s a reason you approached that person, share it. If you’re interviewing people about healthy food choices near a health food store and you stop someone who has just purchased something at the store, you could mention that their interest in health is one reason you approached them. Stick to obvious observations — you don’t want to come across as creepy!

Fostering Goodwill

Donating to a cause feels good, and volunteering time for research is no different. If your efforts are for a worthy result, like making texting easier for the elderly, share that benefit.

Another magic phrase? “I’m a student.” If you are, say so quickly to allay the person’s suspicion about your motive. Your effort on the path of learning will appeal to their goodwill.

If you’re not a student and your topic doesn’t sound particularly socially relevant, people might still be willing to help out if they connect with you. If you’re friendly and enthusiastic about the topic, then they’re more likely to say yes.

To keep the goodwill flowing, express your gratitude for their time and thoughts. Let them know before and after the interview that their time will have a great impact on the success of the research.

Offer Incentives

This one might seem the most obvious: You can increase the value of participation by offering an incentive. A $10 or $20 gift card from a popular vendor like Amazon or Starbucks can incline someone to accept a 15 to 30 minute interview. As the inconvenience to the participant increases, so should the incentive — whether that inconvenience is the length of the interview, the location or the time of day.

The incentive doesn’t have to be monetary. Be creative in what you offer. It could be access to a service that most people don’t have or a fun gadget that’s related to your topic (like a pedometer if the topic is health).

Offering an incentive can be useful, but don’t let it turn into a crutch. The point is to get comfortable with approaching people; associating a cost with that adds pressure that you don’t need. Learning to request participation without an incentive — and learning to increase the perceived value of participation without one — will take the cost out of the equation. Nevertheless, if you’re conducting formal research with a specific audience for a lengthy period of time, offering an incentive is definitely a best practice.

“I’m Afraid Of Rejection.”

Rejection is people’s number one fear when approaching strangers. Hearing no has always been difficult, whether it’s a polite no or an angry no followed by a rant. Either way, it stings. Your response to that sting, though, is what matters. How do you explain the rejection to yourself, and does your explanation help or hurt you?

Martin Seligman, one of the originators of positive psychology, conducted a study in the ’70s that gives insight into the types of mindsets that make people feel helpless. Seligman found that those who exhibit long-term “learned helplessness” tend to view negative events as being personal, pervasive and permanent. In other words, if a person is rejected, they might rationalize that the rejection is a result of their own failing, that everyone else is likely to reject them as well, and that they can do nothing to lessen the likelihood of rejection.

Your mindset is important. (Image: Leathers Milligan7)

When you prepare to approach someone, consider instead that, if they say no, they aren’t really rejecting you, but rather rejecting your request. It’s not personal. Maybe they’re in the middle of something, or maybe they’re just not in the mood to talk. The rejection is fleeting, and the next person might be perfectly happy to participate.

Even knowing this, your first attempt will be the most difficult. Think of it like jumping into a pool: The initial shock is certain, but you’ll quickly get used to the water and will be swimming in no time!

Turn It Into a Game

When my brother was in college, he had a friend — let’s call him Bob — who had been single for a long time. Bob wanted to develop his ability to approach a woman and strike up a conversation, but he constantly froze up because of his fear of rejection.

One night at a lively bar, the two of them decided to make a game of it. If an approach led to a conversation — fantastic! He got 1 point. If the approach led to rejection, he still got 1 point for making the attempt. This turned failure into a small win and encouraged Bob to try and try again. The person with the most points at the end of the night won a free drink from the other. This shifted the focus and value onto the attempt, not the result.

Try this technique with someone who also wants to practice approaching people for research. Award a point for each approach, and reward the winner. Choose a prize that you both value but that doesn’t outweigh the good feeling of a successful approach. Not that you want to be turned down, but it helps to have a reward for plucking up the courage to try.

Variation: Football Rules

If you find the incentive to approach is still not enough, award a field goal (3 points) for every unsuccessful approach and a touchdown (7 points) for each successful one. Because interviews take time, the person who is trailing in points could pull ahead even if they’re mostly getting rejections.

“Only Extroverts Are Good At This.”

Google tells us that an introvert is “a shy, reticent and typically self-centered person.” Not a pretty picture! (An extrovert is defined as “an outgoing, overtly expressive person” — a more positive description, at least in the US).

Introversion has been erroneously associated with characteristics like being “bad with people” or being unsuccessful in approaching others.

In psychology, the field that gave us the terms “introvert” and “extrovert” (thanks to Carl Jung), the definitions are fairly different. The focus is on how people recharge their energy. Introverts tend to recharge by spending time with their own thoughts and feelings; extroverts recharge with external stimulation, such as time with friends or adventures in new destinations.

Jung stated that, “There is no such thing as a pure introvert or extrovert. Such a person would be in the lunatic asylum.” We all fall somewhere along the continuum. It turns out that some of the most fantastic researchers out there fall almost in the middle (called “ambiverts”). They balance an extrovert’s drive to interact others with an introvert’s skill in observation and reflection.

Daniel Pink explores this in his book To Sell is Human, which summarizes a variety of studies that find no link between high extroversion and major success in sales. (Pink defines sales as “persuading, convincing and influencing others to give up something they’ve got in exchange for what we’ve got” — a broad definition that could include asking someone to give up their time to participate in research.)

8There is no link between high extroversion and major success in sales. (Large version9)

In fact, in the studies Pink cites, such as one by Adam Grant of the University of Pennsylvania, the highly extroverted — who tend to talk too much and listen too little — performed only slightly better than the highly introverted. Who did the best by far? The ambiverts, who balanced a drive to connect with an ability to observe and inspect.

10Ambiverts are good sellers because they balance a drive to connect with an ability to observe and inspect. (Large version11)

If you consider yourself an introvert, then you’re probably relieved to hear that you don’t have to swing to the other side of the scale to be successful in interviews. You can use your skill in observation to pay attention to the environment and identify people to approach. You might need to tap into your extroverted side to approach someone, but once the conversation begins, you can call on your skill in observing and listening intently. With practice, this introverted quality will become an important part of the process that leads to the payoff: generating important insights.

Let’s explore a few techniques to ease gently into the ambiversion zone, exercising your interviewing muscles!

Practice Playfully

Practice your requests with a friendly audience and in a comfortable location to make the experience more playful and less stressful. Learning and playing go together!

Set challenges for yourself that expand your skills but that don’t have serious consequences. Instead of waiting for an intense, highly visible project at work to make your first attempt at approaching people, give yourself a short interview challenge. Pick a friendly location and choose a topic of research that would be of interest to most interview candidates and whose results you would not formally present.

Can you think of a local restaurant or cafeteria? Try interviewing its employees about their experience with the lunchtime rush to identify ways to better manage lines (of course, wait until after the rush to approach them). Taking a taxi? Interview the cab driver about their use of technology and how it has changed in the last three years. Do this as though you were conducting research for a real project (for example, ask to interview them, rather than launching right into your questions).

Here are two introductions you can practice:

“Excuse me! I’m a student, and today I’m conducting research on ways to improve transportation information for commuters. Hearing about your experience would be really valuable. Do you have 10 minutes to answer some questions?”

“Hi! We’re conducting some research today. Would you like to be interviewed on your lunchtime eating habits? It’ll take about 10 minutes, and your thoughts will help us improve the availability of nutritional information.”

Make It Meaningful

Whether you’re interviewing for practice or for work, tap into the aspects of the topic that make it deeply meaningful and personal to you. Genuine enthusiasm for a topic is hard to fake and will override fear to a large extent.

Remember the high-school students who were so afraid of approaching people? The class ended up going through the research process a second time with different topics. Instead of being told to interview college students about financial planning, students picked their own topics, like helping other students complete their homework, eating healthier meals and handling peer pressure.

The class picked students to interview, a mixture of friends and strangers. Because they were passionate about the topics (and had practiced once already), the second round of requests was much easier.

Likewise, consider practicing with more than one round of interviews:

  • Round 1
    Choose a topic that you know will be of interest to the people you’re interviewing.
  • Round 2
    Choose a topic that you’re passionate about. (Try to be objective, though!)
  • Round 3
    Take on a challenge for a product or project with support from other team members. (See the section below, “Pair Up Personalities,” for an example.)

If you’re on a team that wants even more practice, you could take turns suggesting practice challenges for each other. The more you practice, the easier it gets — promise!

Pair Up Personalities

If you consider yourself an introvert, pair up with someone who considers themselves an extrovert, and play to each other’s strengths for the first few interviews.

Using your observational skill, you could identify candidates to interview, and the extrovert could approach the first three people.

After the first three or four approaches, take a break and share your techniques with each other. You could share your insight from observing the environment and suggest tips on which people in which location might be best to approach. The extrovert could share tips on conversation openers that seem to be working well. When you’re both comfortable, switch roles to exercise the other’s skills.

This method situates you as mentors to each other, bringing you both closer to the middle of the introversion-extroversion scale.

Go Face To Face

Now that you’ve learned some techniques to get started, don’t let another week go by without trying one of them out! A good first step? Think of topics that you’re passionate about, the ones that are intriguing enough to propel you forward. You’ll find that the skills you develop will give you confidence to pursue the answers you need, leading you to better experiences for yourself and others.


(cc, al, ml, il)


The post Facing Your Fears: Approaching People For Research appeared first on Smashing Magazine.

Desktop Wallpaper Calendars: July 2014

Mon, 06/30/2014 - 13:14

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 six years now1, and we are very thankful to all designers who have contributed and are still diligently contributing each month.

This post features free desktop wallpapers created by artists across the globe for July 2014. 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:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • You can feature your work in our magazine2 by taking part in our Desktop Wallpaper Calendars series. We are regularly looking for creative designers and artists to be featured on Smashing Magazine. Are you one of them?
To The Sea

“Vacation mode: ON :)” — Designed by Klavdija Balažic3 from Slovenia.


Sweet Season

“We have a fridge-freezer in our office for everyone to store their drinks. The freezer section in the fridge is empty for most of the year, but in July and August, it’s packed with ice cream bars and ice pops with owner’s name hand-written on each package.” — Designed by Hiroaki Sho46 from Japan.



“July is here and the swimsuit season is coming. Temperatures are raising and bodies are uncovering, showing irreverent tattoos.” — Designed by MONK Software87 from Italy.


The Adventure Is Calling

“July is the month when you go to the seaside. The sea has always been one of the greatest sources of inspiration for poets, musicians and writers. It makes you think about pirates and hidden treasure islands. The summer is here, so let the journey begin!” — Designed by Olga Bukhalova104 from Italy.


Endless Summer

Designed by WallpaperFX147 from Romania.


Cruising On Lounge Waves

“Designing in summer… Windows are open, smell of fresh air, lounge music playing, and you can easily imagine yourself somewhere on open sea, alone, with your design thoughts.” — Designed by Zarko Jovic178 from Serbia.


Chill Out

“I designed this to remind people who are enjoying the sunny days to chill out, stay hydrated and have fun this summer.” — Designed by Clifford Almeida272229 from Phoenix, AZ.


Celebrating Our 238th Birthday!

“I designed this as a creative illustration celebrating our 238th birthday this 4th of July!” — Designed by Clifford Almeida272229 from Phoenix, AZ.


A Rainy Summer

“The heavy rains due to the climate changes have affected thousands of people in my country, were crops have been destroyed and droughts affected many households; in place of the warm and welcoming months of summer. However, thinking of our situation while staring at the summer sky (depicted in the wallpaper) on one rare clear night, I remembered a line written by RJ Palacios in his book wonder: “[...] the universe makes it all even in the end. the universe takes care of all its birds.” This wallpaper is a glimpse of hope to my fellow guatemalans: hang on. Brace yourselves for a rainy summer. The universe takes care in the end.” — Designed by Ann Fratti315 from Guatemala.


Splendor In The Hills!

“Hot July brings cooling showers in India. I wanted to be subtle in depicting the coolness of rains using shades of blue and symbolize the hot sun using the silhouette backdrop. The hills denote the view of the place I climb up every morning to see the sunrise. I wait for the day when the hills will turn this glacier blue and the temperature drops down to 15 deg celsius.” — Designed by Anushree Singh332 from India.


Summer Romance

“There’s something about summer that gets people in a romantic kind of mood!” — Designed by Clarise Frechette355 from Washington, DC.



“The beautiful butterflies in my garden this year and summer colours.” — Designed by Madison Zyluk398 from Canada.


Join In Next Month!

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 month421!

What’s Your Favorite?

What’s your favorite theme or wallpaper for this month? Please let us know in the comment section below.


The post Desktop Wallpaper Calendars: July 2014 appeared first on Smashing Magazine.

How To Communicate Effectively In IT Projects

Fri, 06/27/2014 - 13:47

One of the most important factors in the success or failure of any IT project is communication. Communicating effectively can be quite difficult, especially when a project involves many people with different backgrounds, experience, skills, responsibilities and levels of authority. The problem compounds when the people involved belong to different organizations with different working guidelines.

Effective communication happens when a message is delivered whose content has the same meaning for the recipient as it does for the sender, thus inciting the desired action.

Why Communicate Effectively?

Consider a few scenarios. You will probably recall similar situations from your own experience.

  • A team leader has to keep an eye on the status of a project. All tasks are stored in an issue-tracking system. Unfortunately, the tasks haven’t been named very descriptively. For example, a bug in the contact form is described as “Something is wrong with the form,” and a need for a database backup is described as “Please help! URGENT!” The team leader would have to open each ticket every time to recall what it’s about. Of course, any sane person would change the descriptions immediately to “Contact form does not validate” and “Back up db0234@host1 database.”
  • A developer receives an email whose subject line reads “Just one question.” He can’t tell at a glance that the email is about a bug in the search engine and should be forwarded to his colleague. He has to spend time opening the email and digesting its contents in order to decide to forward the message.
  • A project manager organizes one or two hour-long meetings every week to discuss the progress of a project with the whole team. Each person speaks about their part for a few minutes and then sits bored for the rest of the meeting. From time to time, someone brings up a bigger issue that matters only to them and the project manager. In short, considering the hourly wages of the employees, a lot of money is being wasted on these counterproductive meetings.
  • A developer is trying to concentrate on a complicated problem but is constantly distracted by phone calls or by colleagues who walk in to ask about non-urgent matters.

As we can see, effective communication is critical. Without it, many problems arise: lost time (which means lost money), bad code, inefficient development, delays and products that don’t meet expectations. Ultimately, the reputation of the company and the client’s trust are at risk.

The people involved may feel that their time is not being respected, which leads to frustration. (Image credit1)

In this article, I will share some observations from an IT project I’ve been involved in for almost three years. As the development team leader, I work with about 30 people from different professions: developers, testers, administrators, designers, usability experts, project managers and people on the client’s side. Working in such an environment, I’ve identified the main obstacles to effective communication.

I’ve also been involved in devising techniques to overcome those obstacles. Most of the problems and countermeasures we’ll discuss apply to team environments, but freelancers might see value in them with their clients and partners.

Effective communication saves money, time and effort, and it happens when you do the following:

  • make a message’s subject easily identifiable (by “message,” I mean not only email, but any form of communication);
  • make a message’s content quickly understood;
  • be explicit in your message;
  • manage effectively;
  • involve only those resources (people, tools, etc.) that are needed to complete a task.

Proper communication leads to the following outcomes:

  • the pace of a project is sustained;
  • team leaders maintain control of the project’s progress;
  • people with different responsibilities and levels of involvement are better engaged in the project;
  • people feel their time is respected and well used.

Effective communication in IT projects can be encapsulated by three words: explicitness, traceability and readability.


Email is the primary means of internal and external communication at most companies. Surprisingly, many people still don’t know how to use it properly.

The subject line is the first thing that a recipient notices. It should be brief and should explain the contents of the email. The recipient might want to refer to the correspondence in future, perhaps weeks or months later. Therefore, the subject line should clearly identify the project (including the customer, depending on the organization) and the subject matter.

Of course, not every subject fits neatly into a project — in such cases, take extra care to make the subject line clear. Consider that, while you might be working on only one project for a given customer and “ACME Corp: new images” sounds like a good subject line to you, your coworkers in the marketing department might be working on many projects for the same customer, all of which involve “new images.”

Here are some examples of good subject lines:

  • ACME Corp. | HR Portal | draft of functional documentation, v. 0.1
  • ACME product page — questions after the meeting with marketing dept. on March 5th
  • Please, send your report — deadline: March 10th

Nicknames for clients and projects and the separator symbol should be agreed on by everyone involved in the project, because they enable recipients to sort their inbox according to filtering rules (especially for managers, who get hundreds of emails an hour).

Here are some real-life examples of bad subject lines:

  • ACME
  • Question
  • Request
  • New images
  • We’re going for lunch at 1 pm

That last one is from a follow-up email that contained important documentation — true story!

A clear subject line quickly tells the recipient the contents of the message and whether they need to respond in any way. For this reason, avoid changing the topic of conversation during an email thread (“BTW, about that other thing, did you…” is a dead giveaway). Either change the subject line or send a separate email.

The “To” and “Cc” fields are useful ways to indicate who is the addressee of a message and who just needs to be informed without taking any action. By default, the person in the “To” field should read and probably respond, while the person in the “Cc” field would do enough to just read the message. Many managers want to stay informed on matters that they are not directly responsible for, and they’ll configure their filtering rules accordingly, browsing those messages from time to time. Don’t “Cc” someone if you expect a prompt response.

One last rule, perhaps a lifesaver, is to do everything in writing. People tend to forget about arrangements made by phone or in meetings. Perhaps a form of communication other than email would be appropriate in these situations. We’ll discuss that next.

After a call or meeting, write everything down and send it to everyone involved. This way, you won’t miss anything. (Image credit2) Issue-Tracking

When you’re managing — whether it’s one large project or many small projects — compile all issues in one place to enable all team members to track their progress and know what needs to be done. Many teams make the mistake of assigning tasks and documenting important details in email. That might be easy to track when you have only one or two tasks to complete. In all other cases, it is the road to failure.

Issue-tracking systems — including Redmine3, Mantis BT4, Bugzilla5, Jira6 and many more7 — enable clients, developers and managers to work together in well-structured process. Every issue — be it a bug report, feature request or question — becomes easy to track, with information about the person responsible, a full history and often even time-tracking and deadline reminders.

Every company employs a workflow that make sense for its business. Still, some rules apply to all situations, and here are ones that I’ve laid down after analyzing thousands of issues over the last few years:

  • Title each issue as descriptively as possible. Remember that most people — whether developers, project managers or testers — deal with dozens of issues every day. They should get at least some sense of an issue’s subject from its title. Thus, avoid titles like “Something’s wrong” or “A typo.” Rather, use self-explanatory titles, like “API throws NullPointerException when no attributes provided” or “Typo in the telephone number on contact page.” Issues with such titles will be processed more quickly because they are easier to manage.
  • Use attributes accordingly. Many trackers let you set special attributes on each issue, such as status, priority and category. Use them! The issues will be easier to sort, delegate and review.
  • Most trackers allow you to set relationships between issues. For example, you could mark an issue as being blocked by another issue or being a duplicate or just being similar. Relationships make it easier to assign tasks and find solutions.
  • Write about only one thing per issue. For example, if you find many bugs in an application, treat every bug as a separate issue. This way, tasks can be assigned to different people, who can work on them simultaneously. Different issues demand different people: designers, front-end coders, programmers, etc. When everything is in one task, managing and completing it takes much longer.
  • Provide as much information as possible. Link to the buggy web page; write all of the steps needed to replicate an issue; attach screenshots. I worked with someone who attached a Word document with a few words and screenshots, titling the issue “Everything is in the attachment” — a big no-no.
  • Write down in the comments section everything that happens with an issue. If someone explains something to you by phone or if a task is changed, document it. Don’t write, “We spoke about that issue on the phone, so now you know what the problem is.” Imagine that another developer will be assigned to this task in future and that anything not written down will be lost. Keep your project’s bus factor8 as high as possible.

To sum up, keep everything in the issue tracker. Give each task its own issue. And describe the issue as best you can.


Some people consider meetings to be a corporate nightmare. Many hours are wasted every week on meetings that contain no content and that don’t end with any useful decisions. “Status meetings” are the most popular kind of this: A dozen or so people gather to talk about different, often unrelated, projects. In fact, most of them are bored and not paying attention, waking up only when they need to talk for a few minutes about their situation.

A better way to stay in touch with team members is to speak with them frequently in person. When a team is working on a project, organize short morning meetings (5 to 15 minutes), like the “stand-up meetings” popular in agile development. This way, every member of the team will always know the status of the project. One member (usually the leader) could report to the boss, freeing up everyone else. Another good way to collect information about the status of a project is daily one-on-one communication. This will take up some time of the team leader, but it yields great results and saves time overall.

If you really do need a meeting with certain people, follow these practices:

  • Prepare an agenda. This way, invitees can prepare themselves for the meeting and — if necessary — submit their opinion, send someone else to fill in or just avoid the meeting if their attendance is unnecessary.
  • Stick to the agenda. Moderate the discussion and discourage talk of things that could be handled by a smaller group.
  • Don’t make decisions “together” — that won’t work. Instead, the small team that is responsible for a task should propose a solution, which should be discussed briefly and then decided on by the person in charge.

One last remark about meetings. Many people in IT do work that is creative in nature. Programmers, for instance, need time to build their concentration, and breaking this process is very destructive. Not all questions need to be answered immediately in person or by phone; some could be sent by email or instant messaging, thus protecting the creative process.

Other Guidelines

Let’s move on to guidelines that are useful not just in IT projects, but in life in general.

Having a common vocabulary with others is essential to communication, in both professional and personal life. This means using the same names for activities, projects, customers and so on. Misunderstandings arise when two people are talking about the same thing but don’t understand each other because they are using different terminology. Formally establishing a common vocabulary using a tool such as a wiki or whiteboard would be useful.

Managing the knowledge that is generated in a project is important, too. Documentation often gets outdated because no one cares to update it when the project’s requirements change. Important decisions and guidelines are lost in email and other communication. This often leads to misunderstanding or, worse, conflict with the client. Therefore, confirm every new version of documentation with everyone involved. When updating the issue-tracking system, remember to record details of phone conversations and email, noting who took what action or made which decision or provided what information. In short, log of every action and piece of information regarding an issue.

When working on a complicated project, I often find it useful to post important tasks on colorful sticky notes on a whiteboard (in addition to the issue-tracking system). Some are marked “waiting,” others “in progress,” yet others “done.” The color of the magnet affixed to each note indicates which team member is assigned to the task. People tend to ignore email notifications from issue-tracking systems; marking a task as complete on a whiteboard requires someone to stand up and reposition the note. Everybody can see the status of tasks and the progress of the project at a glance, which is the big advantage of this method. I also tend to write down other essential information, such as the time when the production environment was last updated or the number of bugs left to be resolved, broken down by team member.

Sticky notes on a whiteboard; such dashboards are a great place for daily stand-up meetings, too. (Image credit9)

If you develop software, then you probably use tools to manage your source code, such as Git, Mercurial or SVN. To facilitate your team’s work, implement some sort of workflow such as a branching model. Remember also to describe your commits informatively.

How To Introduce These Strategies

Forcing everyone to work according to specified rules is hard. Some people are reluctant because they feel that crafting their message more carefully would take a lot of time. Others don’t see the benefit or are just unable to formulate concise thoughts.

I suggest two ways of working with such people. First, show them that the amount of work necessary to better communicate is much smaller than the time wasted otherwise. For example, if a ticket in the issue-tracking system has a meaningless subject line and its contents are hard to process, then the time wasted will accumulate with every person who needs to work on it. A simple countermeasure is to invest a few minutes to prepare the issue better, so that time is not wasted afterwards. Other ways to enforce the rules are by implementing validation mechanisms (for example, in the issue-tracker) or by rejecting communication that doesn’t conform to the standard. It might sound brutal, but it’s effective.


The rules of communication can be summarized in a few points:

  • Communicate clearly. Load the most important information at the beginning of your message (in the subject line, title and first sentence). Learn how to encapsulate a message in one sentence.
  • Involve only the people who are necessary to move something forward. Don’t waste anyone else’s time.
  • Keep everything in writing and easy to access.
  • Read everything you write to make sure it’s easy to understand.
  • Break down big problems into small tasks that are easy to digest.

I hope you find these insights useful to your work. If you have any thoughts, please share them in the comments section below, or catch me on Twitter10.

(al, il)

Front page image credits: Jon Ashcroft11


The post How To Communicate Effectively In IT Projects appeared first on Smashing Magazine.


Secure Login

This login is SSL protected