I think I should make a series of all the A/B tests that I have personally come across in which removing a certain element worked for one company, and adding that same element worked for another. (To understand what I mean by element, you should read this post.) After all, every business is different. And so are their target audiences.
Few months back, I came across this wonderful test in which an SEO company went from a content rich page to one with only a form and headline texts, and improved their conversions. I was intrigued, and curious to know the science behind why such pages work, and why even giants like Facebook, LinkedIn and Quora have bare minimum homepages. I have added my findings about why they work, and what the challenges of such a page could be in the same post. Do give it a read.
In fact, we, at VWO, were so inspired by this test that we decided to give it a shot. And hey, have you checked our homepage recently? And may I add, it’s working well for us as well.
For today’s case study, I have a test the bang opposite of this!
PayPanther is an all-in-one solution for free Online Invoicing, CRM, Time Tracking, & Project Management software for freelancers & businesses.
PayPanther wanted to test between a long and a short version of the ‘pricing and signup’ page. The first time they made this page, they believed that a shorter page would drive more signups as there would be lesser distraction and content to read. In this test, they setup the original page to be pitted against a page which had 3 more sections: FAQs about pricing, testimonials, and another call to action button asking people to sign up.
This is how the original looked like:
And this is how the new page looked:
The test was run for a month on about 1000 visitors and the variation, containing FAQs and testimonials, won! It recorded an increase of 372.62% in signups.
Thrilled by the results, PayPanther has implemented this longer page as their default “pricing and signup” page. They even plan to do further tests to find out the most optimum headlines and button texts.
Why the Variation Won?
The FAQs section answered the common doubts and concerns the website visitors had. It, thus, created a sense of credibility and trust.
Adding testimonials work, always. I am yet to see a test in which adding testimonials hurt conversions. You can look at this, this, and this case study for examples. Of course, they have their own rules and to use them effectively, I suggest you read this excellent post to get the most benefit from testimonials.
Tell me know what you think about this case study. Have a similar test that you did on one of your webpages? Let’s talk about it in the comments section below.
Spread the awesomeness by sharing this post with your network on Twitter, Facebook and LinkedIn.
How does one design and develop for the responsive web? A lot of methodologies out there try to tackle this problem, but all of them rely on the same classic website development process. It boils down to the following: design and then develop. Let’s go nuts and flip this outdated methodology on its head.
Before we start flipping things around, let’s take a quick stroll down memory lane, just so we know where we’ve come from and where we are now.
It’s 1989, and Tim Berners-Lee, the man with the plan, conjures up HTML while working at CERN. It’s a language to link content across documents.
After four years, the Web went public, in 1993. It took a couple of years for someone to create the first columned layout using a table — at which point, something changed. I imagine this as being a turning point in web development. It was the moment when design could be moved to the front of the development process. You could now design a web page, slice it up and present it on the Web.
Luckily, we regained our sanity and ditched tables for layout. We proudly moved to semantic HTML, but we held on to our design-first approach. Let’s take a closer look at semantic HTML.
Semantic HTML is about picking the right HTML element to describe a given piece of information, rather than using HTML to define the way the information should look. If you’re a front-end developer, you’ve probably been doing this for the past couple of years. Great, keep it up!
In my opinion, writing semantic HTML is one of the key aspects of being a good front-end developer. It’s something I value greatly.
Because of that, it’s been a topic I’ve discussed a lot with colleagues who have valued it less or simply did not understand. To resolve these debates once and for all, I tried to give them a glimpse of the thought process behind my HTML writing.
I looked up a straightforward website and derived its HTML structure (without looking at the HTML, which would have been cheating). Then, I turned my HTML thought process into a step-by-step visualization. For many of my colleagues, this visualization turned out to be a real eye-opener. These couple of visuals created mutual understanding of what a front-end developer does and why semantic HTML is important. Also, interestingly, it revealed that not all front-end developers view semantic HTML in the same light.
Below is the website I used in the thought process experiment.
I’ve laid out the thought process below. On the left side is my view of the website. On the right is the written HTML as rendered in the browser. OK, let’s do this!
In my opinion, this landing page serves as an umbrella for all subpages. So, I’ll wrap the logo in an h1. I’ll add an img tag as well, so that the logo displays when printed.
All right, next up is the menu. I’m putting it at the top because this is a landing page. Also, let’s handle caps with CSS text-transform. I’ll wrap the menu in a nav and add a mandatory h1 called “Navigation” inside. Also, we’ll add an ordinary unordered list, with anchors as links to the other pages.
Is this image showing a train actually content? And should we, therefore, use an img tag? Or is it aesthetic, meaning we should handle it in CSS using background-image? I’m going with aesthetic, which means it won’t end up in the HTML outline.
What type of content is that white text below the image? What should I name it? How about “Introduction” — I’m not 100% sure, though. I’ll add an “Introduction” heading and hide it with CSS later on. This heading might be useful for screenreaders as well.
Wait a minute! That blue “Join us today” button is related to the introductory paragraph (“… if you joined us”). Also, it’s not a button but a link. I’m setting myself up for a CSS positioning nightmare.
At this point, I don’t know what to do with the “Book an event” button. It’s not related to “Join us today,” that’s for sure. It’s a button without context. I’ll just skip it for now.
Finally, some straightforward content: headings, paragraphs and links. To position them, we might need to wrap some of these in a div later on.
On to the events! Let’s go for an ordered list because shuffling the dates would be confusing. We’ll use the time element for dates and times. Let’s wrap a link around the subheading.
Now we know where the “Book an event” button should go. People need to know about upcoming events before they can book one — makes sense. So, we’ll put the button with the events making our CSS positioning nightmare even worse.
Below is the resulting HTML.
<h1>Greater Dunnellon Historical Society</h1>
<p>We’ve come together … if you joined us.</p>
<a href="/">Join us today</a>
<h2>A commitment to our history</h2>
<p>The Greater Dunnellon … in its heyday.</p>
<h3>Learn about Dunnelon's history</h3>
<p>Dunnellon was platted … South Williams Street.</p>
<a href="/">More history</a>
<h3>Your next event at the depot</h3>
<p>The depot provides … are also available.</p>
<a href="/">Make a reservation</a>
<h3><a href="/">Museum open Tuesdays</a></h3>
<dd><time>01/21/2015 from 11:00 am</time> to <time>4:00 pm</time></dd>
<p>Learn, teach and share history with Boomtown Sam!</p>
<a href="/">Book an event</a>
You probably noticed that I’ve made a lot of assumptions in order to come up with the HTML structure above. The introductory paragraph heading, the banner image and the call-to-action buttons — these were all places where I assumed something and added to or altered information on the page.
I’ve also made assumptions about where to position things on the page. In deriving semantic meaning from textual data, I’ve assumed that the visual designer intended to give information on the right side a lower priority than information on the left. Based of these assumptions, “Upcoming events” ended up below “A commitment to our history.” I put the navigation above “Introduction,” although it might have been better the other way around.
Assumptions are dangerous, not only because one could assume incorrectly, but also because somebody else will most likely assume differently. In this case, if you and I had independently written an HTML tree based on the design above, it would have been a miracle if they turned out the same.
HTML is about giving meaning to information. We should not end up with different descriptions of the same information. It seems that design clouds the meaning of the content and creates room for interpretation and assumption.
A content-first1 approach teaches us that visual design should always be based on actual content. Only with real content can we decide how best to present it to users. We’ll get to what “real” means in a minute.
With a content-first approach, we move from designing without content to designing based on content — a very important distinction. Remember the definition of semantic HTML: giving meaning to content.
Semantic HTML has no relation to appearance — that’s what CSS is for. Why put off the HTML until after the design phase if it doesn’t depend on the appearance? Let’s move it to the front and describe our content before designing it.
It’s a small change, but it makes a big difference. With this change, all assumption is taken out of the equation. We now know how our content will be structured. And before even drawing a pixel, we’ve got ourselves a website.
Do you hear that? That’s the sound of screenreader users celebrating.
Let’s go back to the slides. This time, we’ll do it the other way around. We’ll use the HTML that we’ve just written and imagine a designer using it for their visual design.
It’s difficult to imagine the call-to-action buttons ending up where they were in the original design. In terms of visuals but also content, this new setup makes a lot more sense.
When we were basing the HTML on the initial visual design, we could use the visuals for one viewport only. By turning things around and basing the design on the HTML, we can use the HTML for all possible viewports and contexts.
If I’ve piqued your interest, you might be wondering how to implement this approach in an actual project. Depending on the project, your team and your client, it might look something like the following.
Because we’re doing things content-first, we need to get our hands on the client’s content. Mark Boulton4 rightly points out that content-first is not about waiting for the final content before doing anything. When we talk about content-first, we mean that we want to know the structure of the content that we’re designing for. Having the final content already in hand would be fantastic, but most of the time it simply is not. In “Structure First. Content Always5,” Boulton says:
You can create good experiences without knowing the content. What you can’t do is create good experiences without knowing your content structure.
In my experience, this is true, and making sure everyone knows what “content first” means is important. So, make sure everyone understands that you’re talking about structure and that you don’t mean to pause the project and wait for the client to deliver the final content.
Before we start writing HTML, we need to determine what content to present on the page and how to prioritize it. This is where a priority guide comes in handy. Together with your client, write down all of the content types of your web pages on sticky notes, and then order them chronologically along the y-axis. For example, you could have a “product detail” sticky and a “post a review” sticky, and because someone would need to know about a product before reviewing it, “product detail” should come first. Your client might deem the “post a review” box to be more important, but that importance could be visualized later using color and composition, not by changing the order of content.
I find that clients are pretty good at this exercise, maybe because they are used to writing documents such as quotes and writing papers that must adhere to a certain hierarchy and chronological order to make sense. As I said, this exercise makes them really think about what’s important. Also, if there are multiple stakeholders, it shows how each is motivated and which stakeholders have the most influence.
We’ve set up our content types; let’s talk about content structure. Structuring content is exactly what HTML is good for. Let’s go for it. We’ve got our content types, and we understand semantic HTML, so let’s start adding structure to the various content types. This could be easy or challenging, depending on how high-level your content types are.
A basic “post a review” form could be pretty straightforward:
The “product detail” sticky might be a bit more challenging. In its most minimal form, it could be just a “title,” “image” and “short paragraph.” But your client might also want things in there like “product specifications,” “ordering options,” “related products,” etc. These other content types require further discussion and prioritization. In the end, you might conclude that “post a review” is actually a part of “product detail” because people will be posting a review of the product described in “product detail.”
<p>A groundbreaking Retina display. All-flash architecture. Fourth-generation Intel processors. Remarkably thin and light 13‑inch and 15‑inch designs. Together, these features take the notebook to a place it’s never been. And they’ll do the same for everything you create with it.</p>
<h1>Post a Review</h1>
<!-- 'post review' module here -->
These content types don’t stand on their own. They should be contained in an overall content hierarchy, as we saw in the series of images related to semantic HTML earlier. Together with this hierarchy, your content types should create a nice and correct HTML5 sectioning outline6. To test this, you can copy your HTML to the HTML5 Outliner7.
Below is an example of an initial web page setup.
Now, we could have also done a bit of content choreography8 to make sure each bit of content receives the right amount of attention from the user. In his excellent book Responsive Design Workflow9, Stephan Hay10 advises us to set up content reference wireframes at this point. In my opinion this would be a bit too early — it’s best to wait a bit longer on the composition, because color, typography and functionality will affect the way attention is distributed across the page.
Let’s continue with our basic HTML web page. Don’t show it to your client yet; mix in their brand identity first. Add their logo, and convert their typography rules and color schemes to CSS. This will make it easier for your client to identify with the content — the content will look less anonymous and more like their own.
While your client would be able to relate to the version shown above, they would probably have a hard time getting enthusiastic about it. In my experience, the client will be impressed with the amount of work done but will feel uncomfortable not knowing what the result will look like. I recently renovated my house, and I have to admit, after totally stripping it, taking down walls and removing old plumbing and electricity, I seriously doubted whether it would come together in the end. That’s when I understood how my clients feel.
You need to manage that feeling or else they’ll panic and fall back to the classic web development pattern, demanding design up front.
The version above is the “minimum viable web page.” It contains, if all has gone according to plan, the core content that your client’s users will be coming to the web page for.
If you’ve been using actual content, then even if all hell breaks loose, you could put this online as is. It wouldn’t be perfect, but the brand would be recognizable, and users would be able to access the information.
For now, hell is not breaking loose. So let’s move to the content choreography. Start resizing the browser window and view the page on some different devices. You’ll notice that on a wider viewport the line lengths will become uncomfortable to read. An ideal line contains between 45 and 75 characters11. So, you can regard points where it’s longer or shorter than that as indicators to tweak the layout or font size.
You have two options here: either make the adjustments live in the browser or boot up your favorite design tool. In my experience, designing in the browser is useful for tweaking things such as font size and color, while composition experiments are easier to do in Sketch or Photoshop or using pen and paper.
Tweaking CSS values in the browser might be tempting, but taking a screenshot and making some quick adjustments outside of the browser is usually faster. I find this results in more interesting design choices. When sketching, try to imagine how your solution would scale or break in smaller and bigger viewports and how your design choices relate to the content’s order and importance.
When you’re happy with the sketches, transform the result to CSS.
Now that we have set up the base version of the web page, we can start testing and iterating. Do some quick usability tests, which you can easily do by following the Don’t Make Me Think12 methodology. Sometimes creating a small prototype for this is easier than using the production version.
While tweaking the web page for each context, we can look into adding functionality and presentation styles based on contextual measurements13. For instance, in small viewports, we could move the menu out of view. Or when the user is viewing the web page late at night in a dimly lit environment14, we could load a style sheet with inverted colors. If enough real estate is available, we could turn an address into a Google Map.
If you look closely, you’ll notice that all of these enhancements are layered on top of the content. They only change the way the content is presented and interacted with; they never change the content (or priority of content) itself. This fits perfectly with a strategy of progressive enhancement: Start with the content, and work from there.
We’ll finish up this section with a short note about web applications. The methodology explained above is for content-driven web pages — pages that are and should be accessible to everyone in all contexts. Not all web applications fit this description. Many use HTML to describe the interface instead of the content. In these cases, this methodology might not be the best fit.
Advantages Over Design-First Approach
I’ve compiled a list of the challenges overcome and the advantages gained by this approach. Not to say that this approach does not introduce new challenges, but those new challenges mostly have to do with managing client expectations and team communication.
To the list!
Content — and, therefore, HTML — is the only constant across all devices. How you present your content and how users interact with it will differ between devices, but the content will remain the same. Starting with content means starting with everyone.
Describing content with HTML is not only about lists, paragraphs and headings. It’s also about choosing between buttons and links, dropdown and radio buttons, tables and definition lists. It’s about outlining all functionality with HTML first.
With the content nailed down, there’s less confusion about what things actually are. Something could look like a button in a visual design but in reality be a hyperlink. This creates miscommunication in a team, which is easily prevented by writing HTML first.
Because we’ve layered design on top of HTML, we have created an opportunity for the team to work together. Developers can work on implementing the HTML, while designers can think of compositions for various viewports and contexts. No more deliverable dependencies means no more tiny secret waterfalls.
This methodology enables designers to work concurrently with their developer buddies, allowing them to quickly test things in the browser. Some design problems might be easier to tackle in CSS. As Paul Boag explains15: “Developers might suggest ideas that you might have dismissed as impossible.”
It’s now clear what content should be generated or be manageable via the CMS. Hidden skip links, headers and labels are no longer hidden — all content is right there in plain sight. Design choices can now make content implicit, but that does not mean the content won’t end up in the HTML, because we’ve already written it. In my experience, none of these implicit content items end up in the CMS because they aren’t visible to everyone. By starting with HTML, this is easily resolved.
If you and the client have pinned down what content you want to communicate to users, that will very likely not change during the development process. A change would only happen if user research uncovers some previously unknown facts that warrant a change in course.
Content creates focus. By focusing on content and functionality early on in the process, you’re less likely to end up in a “red or blue?” discussion with the client. Too often clients are tempted to focus on details when they should be thinking of the big picture. With this layered setup, the focus starts with the big picture and then moves to the details during the project.
Having the HTML early on enables you to build the minimum viable product first. In later stages of the project, you can progressively enhance it to further improve the user experience. If you introduce usability testing in the project (which you should), you can use the results to decide what to enhance first. An asynchronous search filtering system might be cool, but your users might value other functionality more. Harry Roberts reminds us16 that “good enough” today is better than “perfect” tomorrow.
As we saw with the call-to-action buttons in the semantic HTML exercise, spotting user experience problems is easier when you’re working with content as the foundation.
Once you’ve finished the HTML, you can immediately start testing the content with visually impaired users. Most of the additional layering will be for the sighted.
Starting with content enables you to more easily define your HTML5 sectioning outline, to pick micro-formats17 or micro-data18 and to apply WAI-ARIA rules19. This results in better accessibility and makes the pages easier to index by search bots.
This approach entails going from a robust stable base to a very detailed flexible end product. By staying away from highly detailed solutions early on, you decrease the risk of putting a lot of hours into unneeded functionality. For example, you could build synchronous search first, and then later on in the project, if your user base turns out to heavily favor search, you could layer asynchronous search and filtering on top of it.
No longer are you creating pretty pictures of web pages. The focus has moved to quick sketches and tiny prototypes to solve design challenges, and the results are quickly transformed in CSS and moved to the browser. We’re throwing away fewer deliverables, which means we’re working more efficiently.
Talk To Your Client
As with everything, it’s all about communication.
If your client thinks the Web is a 1024 × 768-pixel box — and continues thinking this while you and your team are working on their shiny new website — then you’re going to run into a lot of trouble.
Many clients expect a visual design up front, because that’s what they’re used to getting. They don’t know any better.
Your job — not an easy one — is to explain to them why this is impossible. Enlighten them about the millions of different viewports, interaction methods and feature sets out there, and help them understand that you cannot capture all of that in a static design.
If your client understands the Web, you’ve won half the battle.
Editor’s Note: Designers could learn how to code, and developers could learn how to design. Sometimes it might not be an option. In this article, the author makes a suggestion to designers without coding skills on how to start crafting code. You might want to take the suggested tool with a grain of salt (or not) but the idea might be worth looking into.
This article will introduce you to uilang’s philosophy and syntax. We’ll start with a simple example to get you comfortable with the basics, before moving to something more exciting. At the end of this tutorial, you’ll (hopefully!) be able to code many typical interface widgets, such as popovers, tabs, overlays and much, much more.
The Bridge Between Designers And Developers
I strongly believe that designers should code the interfaces they design. They shouldn’t necessarily write production-ready code, but they should design the behaviors. Designers love these things. They could spend hours tweaking an animation delay or finding the right cubic-bezier curve. They usually just lack some technical skills to do so.
uilang tries to facilitate the communication between designers and developers by giving designers an extremely simple tool to prototype their interfaces. uilang reads like plain English, uses a one-line syntax declared right in the HTML and provides very few options in order to make its learning process and adoption as fast and easy as possible. We’ll cover the syntax in detail later, but here’s a sneak peek at it:
clicking on "button" toggles class "visible" on "div"
uilang is not exclusively a prototyping tool, though. It can safely be used on production websites to create, for example, tabs, photo galleries, popovers and more. Let’s see how it works!
uilang is based on a dead simple principle: manipulating classes on your elements. By just adding and removing classes when something is clicked, we can show, hide, transform and animate elements using CSS. This simple logic gives you endless possibilities. Let’s explore one of them by creating a simple notification banner like this:
We’ll start with the HTML markup, which is pretty straightforward:
<p>You have 3 unread messages.</p>
We’ll now use uilang to define a simple behavior: When the user clicks on an element that has a hide class, we’ll add a hidden class to the element that has a notification ID. The translation in actual uilang code looks almost the same as the explanation above:
clicking on ".hide" adds class "hidden" on "#notification"
This line of code should be written in a simple <code> element, right in the
HTML. uilang will automatically find the <code> element containing your
code and will ignore other <code> elements that you might have on the page.
Additionally, you’ll have to download and insert the uilang.js library5 (1 KB).
While both your <code> and <script> elements can
theoretically be inserted anywhere on the page, it’s recommended to place them at the very end of the document, just before the closing </body> tag:
<!-- Your content -->
<!-- Your uilang code -->
By respecting that order, you’re making sure to reach the best rendering performance. Thereby, your final HTML markup for the notification banner will look like this:
<p>You have 3 unread messages.</p>
clicking on ".hide" adds class "hidden" on "#notification"
We’re almost done! Now that the behavior has been defined, we’ll rely on CSS to fade out that notification banner once the hidden class has been applied to it:
Congrats! You now know how to code! You might not realize it yet, but this simple logic will let you build a wide range of widgets and interactions. Let’s have a closer look at the options provided by the syntax.
The syntax can be split into four parts:
clicking on ".hide"(1) adds(2) class "hidden"(3) on "#notification"(4)
any CSS selector
adds, removes or toggles
any class name
any CSS selector or the target keyword (which selects the clicked element)
That’s all you need to learn. Keep in mind that uilang is basically just HTML, so you can comment the code similarly:
<!-- I'm a comment -->
clicking on ".hide" adds class "hidden" on "#notification"
<!-- I'm another comment -->
clicking on "li a:first-child" toggles class "active" on "target"
Please note that uilang only supports click events. Hover effects can usually be achieved in CSS, and other events are simply beyond the scope of this language.
We’ve now covered the basics of uilang. It’s time to build a more advanced demo!
Apple-Like Explore Menu
We’ll create a collapsible, animated menu similar to the kind you can find on Apple’s website6. Check out the demo117 to see the result.
Nothing fancy, really, just a simple link to toggle the navigation, and the nav element containing our list of links:
<a class="explore" href="#">Explore</a>
<a href="#"><img alt src="images/1.jpg">West Coast</a>
<a href="#"><img alt src="images/2.jpg">Venice</a>
<a href="#"><img alt src="images/3.jpg">Peyto Lake</a>
<a href="#"><img alt src="images/4.jpg">Iceland</a>
<a href="#"><img alt src="images/5.jpg">Golden Gate</a>
Now, adding the toggling behavior with uilang will be extremely simple:
clicking on ".explore" toggles class "open" on "nav"
We’ll then use this open class in our style sheet to show and hide the nav. Just before we do that, let’s add a few things to complete our HTML markup: a meta tag for mobile users, the link to our style sheet and, obviously, the uilang.js library! The whole HTML might now look like this:
<meta name="viewport" content="initial-scale=1">
<link rel="stylesheet" href="style.css">
<a class="explore" href="#">Explore</a>
<a href="#"><img alt src="images/1.jpg">West Coast</a>
<a href="#"><img alt src="images/2.jpg">Venice</a>
<a href="#"><img alt src="images/3.jpg">Peyto Lake</a>
<a href="#"><img alt src="images/4.jpg">Iceland</a>
<a href="#"><img alt src="images/5.jpg">Golden Gate</a>
clicking on ".explore" toggles class "open" on "nav"
Note: For those wondering about the brevety of the code, keep in mind HTML5 considers as optional the <html>, <head> and <body> tags. Feel free to adopt a different style if you have another preference!
CSS: Where The Magic Happens
As always with uilang, the interesting parts of the code are in the style sheet. uilang’s role is exclusively to define the behaviors, not to execute them.
Let’s start by styling and positioning our elements, so that our navigation is ready to be manipulated with uilang. I won’t go into much detail — I assume you’re already comfortable with basic, standard CSS — so I’ve only commented some parts of the code. Please note that irrelevant style declarations, such as for fonts and colors, have been omitted for clarity.
/* Make sure the Explore link stays above the nav */
box-shadow: 0 1px 2px rgba(0,0,0,.15);
/* Allow mobile-friendly horizontal scrolling when the browser isn't wide enough */
/* Force the thumbs to display in a row */
padding: 80px 40px 40px;
Onto the interesting part: coding the toggling behavior! We’ll need two things:
By default, the nav and the thumbs should be hidden. This means we need to initially slide up the nav and make the nav and images transparent.
When the open class defined in our uilang code is applied to the nav, we need to reverse the default state: slide down the nav and fade in everything.
Step 1 is pretty easy: We’ll use translateY(-100%) to slide the nav up, opacity: 0; to hide the nav and images, and transition to animate these elements when the class is applied.
nav, nav li
This is not immediately related to uilang but, because uilang does rely on CSS for transitions and animations, we should probably remember a few important principles:
You can safely and smoothly animate only two properties: opacity and transform. Force yourself to stick with them.
When only the duration is specified in the transition shorthand property, all properties that might change in future will be animated and will use ease as their timing function.
Keep your animations fast! Animations are important because they help users to understand the flow between two states, but they should never get in the way. A good transition-duration is usually between 200 and 800 milliseconds.
While standard easing keywords are sometimes acceptable (such as with this demo), custom cubic-bezier curves are often preferable. Many tools enable you to find the right curve, such as Matthew Lein’s Ceaser10.
The examples in this tutorial use CSS transitions, but feel free to use CSS animations instead when needed! The principle is exactly the same, and keyframes might provide a finer level of control.
Now that our default state has been set up, we can go to step 2 and code the “open” state, which basically means reverting step 1 to the default values for the open class:
nav.open, nav.open li
/* Wait for the nav to slide down a bit before starting the animation on the thumbs */
Boom! You now have a fully functional animated navigation menu. A few things are missing that would make it truly great, though, starting with the scale animation on the images. If you look closely at the demo117, you’ll notice that the images not only fade in when they appear but also zoom in a little. Let’s add that behavior by making them slightly smaller by default:
We’ve already defined that nav.open li will reverse to transform: none; and that all properties will animate, so there’s nothing more to add.
Good! We’re almost done, but one important thing is missing: changing the icon on the “Explore” link when the nav is open or closed. To do that, we’ll need to define a new rule in our uilang code. We’re currently toggling an open class on the navigation to show and hide it; we’ll need to do something similar for the link itself.
clicking on ".explore" toggles class "close" on "target"
clicking on ".explore" toggles class "open" on "nav"
Here, target represents the clicked element. In this case, you could have just reused .explore instead of target. However, that wouldn’t be the same if you had multiple “Explore” links on the same page (.explore matches any “Explore” link, whereas target selects only the clicked “Explore” link).
Back to the CSS. We’re going to use pseudo-elements to display our icons. .explore::before will represent our grid icon (visible when the navigation is closed), and .explore::after will display the cross when the navigation is open. Both will benefit from the same transition-duration.
/* Hidden and scaled up by default */
The grid icon is already visible; the close icon is hidden but correctly positioned, ready to fade in as soon as “Explore” is clicked. We just have to reverse the default state when the close class defined in our uilang code is applied to .explore:
/* When the nav is open, hide and rotate the grid icon… */
-webkit-transform: rotate(45deg) scale(.8);
transform: rotate(45deg) scale(.8);
/* … and display the close icon */
Icing On The Cake
As a bonus, let’s end this tutorial by having some fun with CSS! The grid and close icons that we’re using on the “Explore” link are actually pretty simple, and using images for them (as we’re doing) would be a shame when we could just draw them in CSS. Let’s do this!
The grid icon is the most interesting one. While it might initially seem counterintuitive, we’re going to use gradients to draw it. The idea is that each of the nine squares will be drawn as a gradient from black to black. When you create a CSS gradient, you’re basically generating an image on the fly. This (background) image can then be sized and positioned anywhere.
It’s verbose and arguably crazy, but keep in mind that, while we’re essentially doing it for fun, this technique comes with real advantages, the most important one being undoubtedly the HTTP request you save from not requesting a file.
The close icon is much simpler but still requires some tricks to make it look great. We’ll use a similar technique: drawing a gradient from black to black for each bar of the cross in order to form a plus sign, then rotating the plus to make it look like a cross. To prevent the lines from looking jagged because of the 45-degree rotation, we’ll scale up the icon a little using the transform property, which provides us with decent antialiasing.
CSS is powerful, performant yet remarkably easy to use. uilang wants to stay invisible in your workflow and act as a gateway to using CSS to code interactions. After all, CSS might be the best “user interface” for creating prototypes.
Mobile application ecosystems — let’s count Android and iOS here — are unbelievably dynamic, but they also suffer from both software and hardware fragmentation. This is especially true for Android, but fragmentation also exists in the iOS ecosystem1, as experienced with the rollout of iOS 8. As the latest version of iOS was released, many existing apps were made clumsy on updated devices.
Even the new iPhone 6 and iPhone 6 Plus have had not-so-typical issues2 for Apple devices. In addition, a significant proportion of users with older devices have very few options: essentially, buy new hardware (i.e. a new device) to get everything working well.
In the Android world, things are different. As OEMs launch new devices, software updates and customizations for their devices, application and game developers get serious headaches3 trying to keep their latest products up to snuff and fully compatible with all possible device variants. Making a certain app or game work only on high-end devices is out of the question, though. Why would a developer want to miss out on a significant chunk of potential users?
Professional automated testing software is a solution to a common problem: how to produce high-quality, robust and reliable software with the ever-growing complexity of technology and under massive competitive pressure. Automated software testing is a cost-effective solution to this problem. Not to mention, it provides three business benefits:
increased testing efficiency,
increased testing effectiveness,
faster time to market.
This article walks through a sample use case for test automation and provides a downloadable example to get you started. Also, we’ll focus on different aspects of mobile test automation and explain how this relatively new yet popular topic can help mobile app and game developers to build better, more robust products for consumers. With the advanced example later in the article, we’ll show how image recognition can be used to test mobile games; specifically, we’ll run Appium’s test automation7 framework against Supercell’s Clash of Clan8 game to illustrate how image recognition can be built into the test-automation process.
Test Automation Is Perfect For Mobile App Development
Developing mobile applications is very different from developing PC software or even embedded software. Mobile development is meant to be agile9, and a lot of great tools and practices have been developed for that agility. However, doing something manually — such as testing an app — is never agile, which is why test automation has shown tremendous growth among app and game developers, speeding up their doings and yielding robust and better results.
To achieve compatibility between users, devices and the market, including test automation as a part of the agile development process10 is typical. Fortunately, a lot of tools are available, and test automation is a perfect fit for this process. For example, let’s say your typical development sprint is two weeks. You have daily standups and a lot of scrum activities, and you own internal policies that gear development to the final product. Test automation offers a significant value-add by enabling testing to be done in parallel — for example, as nightly test sessions. By the next morning, the tests will have been finalized and the results of the latest regression will be ready for review. Fixing an issue earlier will save a lot of time and get developers to finalize the product sooner; most importantly, it cumulates to better quality11, with fewer bugs.
Test automation offers the possibility to test mobile apps instantly and effectively. Once tests have been automated, they can be executed quickly and repeatedly, again and again. In almost all cases, this is the most cost-effective method for regression testing15 of software products that have a long maintenance life. In fact, test automation of any mobile app is the best way to increase the effectiveness, efficiency and coverage of the testing process. The true benefit of automation comes not only from the repeatability of tests, but also from the ability to execute tests that probably could not even be performed manually.
Things To Consider When Automating Mobile App Testing
Let’s look at how test automation (as opposed to manual testing) can improve the development process, add value and speed up development.
Costs and Assets
Regardless of whether you go for manual or automated testing, you’ll need the following assets and resources (all of which cost money): time, people, infrastructure, tools and training. Depending on the size of the project and the application, test automation will quite obviously provide a good return on investment. For example, once test cases have been created, automated tests can be run over and over again at no additional cost, and these can be more rapidly completed than any manual tests. Automated software testing can reduce the time required to run repetitive tests from weeks to hours. This is a significant time-saving that translates directly into cost-saving.
Integrated App Development And Testing Cycle
Increasing efficiency and productivity with automation actually starts with adopting a new mindset. Software tests have to be repeated often during all development cycles to ensure the best possible quality of an application. Every time source code is modified19, software tests should be repeated. For each release, your software should be tested on all supported variants of operating systems and all configurations of hardware. Manually repeating these tests would be costly and time-consuming. For example, running comprehensive tests manually on all variants of Android and on actual devices would take a lot of time.
Tools and Technology: Test Automation Frameworks
To get the most out of your efforts and maximize testing coverage, select the most robust and most cross-platform20 method. That automated methods can be used both to validate requirements and to reduce costs through automated test-case generation is well known. However, the full automatization of large software entities also comes with a cost that many companies haven’t been ready to pay for. Historically, one of the reasons has been a concern over the lack of adequate integration with well-established development life cycles.
Test Coverage and Reusability: Open Standards Mean No Vendor Lock-In
Automated testing can increase the depth and scope of tests and significantly improve software quality. Lengthy and thorough tests — often not doable with manual testing — can be run automatically. Ideally, test cases should have full access to an application and test all aspects of it21 — memory contents, data tables, file contents and internal program states — to determine whether the product behaves as expected. Automated tests can easily execute thousands of complex test cases during every test run, providing coverage that is simply not possible with manual testing. Developers, freed from repetitive manual tests, will have more time to create new automated test cases and build more compelling features (and then more test cases).
Improve Effectiveness and Finalize Sooner
In a nutshell, professional automated testing software is a solution to a common problem: how to produce high-quality, robust and reliable software with the ever-growing complexity of technology and under massive competitive pressure. Automated testing improves business results in three ways: greater testing efficiency, greater testing effectiveness and a shorter time to market.
Different Ways to Automate Mobile Testing
In general, there are three ways to automate the testing of mobile apps.
Handwritten Test Scripts
Typically, this is the best choice when you know what you’re doing and when you have programming-capable people doing the test scripts. Plenty of options are available for test automation frameworks, tools and integration — both commercial and open-source offerings. Having your engineers write all of the test scripts will take up some time and tie up resources, but it will get you exactly what you want: well-structured, thorough scripts that test precisely the aspects of your app that you want to test.
This approach is less error-prone because nothing needs to be written in code, but it is typically more limited in functionality. Tests can be quickly recorded and then played back again and again against different OS versions and device configurations. These tests focus on user interactions and user-driven activities. Some things might fall beyond a test’s scope (such as integration with other technologies and compatibility with other software).
Automatic Test Exercisers
Automatic test exercisers provide a great way to smoke-test applications. No specific tests are needed; rather, the focus is on testing user-interface logic (such as opening menus, clicking buttons, swiping and multi-gesture actions). Automatic test exercisers yield the least exact results but provide quick feedback on each iteration of an app.
Focus Areas In Testing For Mobile Apps And Games
User Interface and Functionality
A user interface and its overall functionality will directly affect how successful your app or game30 will be. These two things, which encompass visual appeal and gameplay, are the most important things to get right — and you must ensure that device fragmentation doesn’t break any of these. Various things in the UI need to be tested:
UI layouts and elements
Games especially are typically targeted at a high number of different screen resolutions and screen types. Regression testing should be done each and every time the UI’s layout changes to ensure that the game works.
Menu structure and functions
Testing menu structures, functionality and behavior can be automated with instrumentation and the help of different test-automation frameworks.
Surprisingly, so many apps and games out there get this wrong. If a screen’s orientation changes during an interaction, for example, what happens? What is supposed to happen? Does the app or game work well in both landscape and portrait modes?
A lot of screen resolutions exist, especially on Android, and auto-scaling will usually help developers. However, test your game across these resolutions to ensure that the graphics do not stretch.
Performance needs to be consistent across all device variants31 among your users. Because of this, test on as many real devices as possible. To determine how well your app or game responds to various levels of usage, including performance and battery usage, consider creating tests that last for hours. To determine whether your game runs effectively under a heavy load for a long time, run load (or stress) tests. These performance tests will measure, for example, how responsive your game is on real devices.
Usability and User Experience (i.e. Good Entertainment)
Testing usability, navigation flow and user experience simply cannot be done on a desktop with a mouse and keyboard. So, forget emulators and use only real devices35. And to test how usable and entertaining your app is, consider these two important things:
User interaction and responsiveness
Testing performance is critical because this will make make or break the user experience. Performance lag, for example, is easy to expose with real devices.
Interruptions, battery consumption and the effect of battery chargers on overall performance and usage all have a significant impact on the user experience — and entertainment value.
Nowadays, multi-user support is common in both apps and games. Testing multi-player capabilities is important and is naturally more challenging, requiring real users to measure performance. A typical case is a game communicating with the back-end server. In this case, connectivity is essential, to synchronize the back end with devices that need to get information about the gameplay. You should test a ton of different scenarios, many of which could severely affect the game’s experience, resulting in negative feedback and the game being uninstalled by users.
Integration with social networks is another important factor. Being able to share something across an ecosystem, with friends or just with oneself, is essential in many apps. Test this thoroughly with real Android and iOS devices, with different OS versions and different device configurations, to assess functionality and ease of use.
Security and Liabilities
Nearly all developers use some open-source components in their apps. This practice is widely accepted and highly recommended because it offloads the development of code for non-core functionality. However, identifying vulnerabilities and licensing restrictions with third-party code is often neglected by developers.
Breakdown: Android Test Automation Frameworks
Robotium42 is an Android test automation framework that fully supports native and hybrid applications. Robotium makes it easy to write powerful and robust automatic black-box UI tests for Android applications. With the support of Robotium, test case developers can write function, system and user acceptance test scenarios, spanning multiple Android activities.
UIautomator5143, by Google, provides an efficient way to test UIs. It creates automated functional test cases that can be executed against apps on real Android devices and emulators. It includes a viewer, which is a GUI tool to scan and analyze the UI components of an Android app.
Espresso44, by Google, is a pretty new test automation framework that got open-sourced just last year, making it available for developers and testers to hammer out their UIs. Espresso has an API that is small, predictable, easy to learn and built on top of the Android instrumentation framework45. You can quickly write concise and reliable Android UI tests with it.
Calabash46 is a cross-platform test automation framework for Android and iOS native and hybrid applications. Calabash’s easy-to-understand syntax enables even non-technical people to create and execute automated acceptance tests for apps on both of these mobile platforms.
And then there’s Appium. OK, let’s get into this one.
Appium: Executing Tests On Real Devices On A Cloud Service
In its architecture, Appium is an HTTP server written in Node.js that creates and handles multiple WebDriver sessions. Appium starts tests on the device and listens for commands from the main Appium server. It is almost the same as the Selenium server that gets HTTP requests from Selenium client libraries.
Appium enables users to execute tests on mobile devices regardless of OS. This is possible because the Appium framework is basically a wrapper that translates Selenium’s WebDriver commands to UIAutomation50 (iOS), UIautomator5143 (Android, API level 17 or higher) or Selendroid52 (Android, API level 16 or lower) commands, depending on the device’s type.
For Android, this is how Appium compares to other test automation frameworks:
One of the best things about Appium is that, despite sounding architecturally complex, it actually isn’t — at all. For developers, it provides support for various programming languages, freedom from having to select tools, compatibility across the most important platforms (Android and iOS), freedom from having to install and configure devices to test and more.
If you are familiar with Selenium, then you’ve got Appium covered. An Appium test is pretty much the same as a Selenium test: They use the same WebDriver, and DesiredCapabilities59 is used the same way. Configuring an application to run on Appium has a lot of similarities to Selenium — for example, those DesiredCapabilities. We’ll configure a sample test later in this article.
Also, Appium includes a component called the inspector. This inspector enables a host of functionality — for example, showing all of those UI elements in the application and enabling basic recording and playback.
However, you may not need the inspector because everything can be done in the code. The example later provides all of the scripts and instructions step by step, without using it.
If you’re on Linux, install pip if it’s not already:
$ sudo apt-get install python-pip
Install the Selenium module for Python:
$ sudo pip install selenium
Verify that Selenium is installed:
$ pip freeze | grep -i selenium
Ensure that Python 2.7.x or later is installed:
$ python --version
If it’s not installed, download and run the setup from Python’s download center64. To add Python environment variables, go to “System properties” → “Advanced System Settings” → “Environment Variables” → “System Variables” → “Edit Path,” and then insert C:Python27;C:Python27Scripts at the end (assuming you have installed Python in the default location). Make sure to restart the command prompt to bring new environment variables into effect.
Check whether Python’s pip module is already installed:
appium_example_android.py (for Android API level 17 and above)
appium_example_selendroid.py (for Android API level 16 and below)
Step 1: Create Account and Upload the APK
Create an account.66 Note that this service provides a freemium option, and you don’t need a plan to complete these examples using real devices on a cloud service. If you want to access hundreds of device models, then different plans are available.
Before proceeding with running the test script, you’ll need to upload the APK or IPA to Testdroid’s cloud service via HTTP POST. Let’s try that using cURL.
Open the test script, appium_sample_ios.py, in any text editor. Set screenshotDir to the path where you want those screenshots to be saved on your machine. Set your credentials on testdroid_username and testdroid_password in DesiredCapabilities. Set the myAppFile identifier against testdroid_app in DesiredCapabilities. It should look like this:
The screenshots will be available locally on your machine in the directory that you specified in step 2. Log into your cloud service and navigate to the project’s name, as defined in the _project attribute of DesiredCapabilities, to access the following log files:
Appium’s server log,
Logcat and instruments log.
Advanced Example: Using Appium For Mobile Game Testing With Image Recognition
In this example, We’re using Supercell’s popular mobile game Clash of Clans. It’s a fantastic game and I’ll bet many of you have played it, so you should be pretty familiar with its look and gameplay. This example does basic clicks through the game’s tutorial.
## Example script that tests Clash of Clans tutorial first steps
## Works on different resolutions, both iOS and Android
from time import sleep
from AppiumCloudTest import AppiumCloudTest, log
from selenium.common.exceptions import WebDriverException
# AppiumCloudTest takes settings from environment variables
driver = self.get_driver() # Initialize Appium connection to device
sleep(10) # Wait for game to load
# Use this to get detected screen hierarchy
# print self.driver.page_source
# Dismiss the in-app purchases dialog if it shows
okayButton = None
okayButton = driver.find_element_by_id('button3')
log("There was no in-app purchases dialog")
else: # iOS
self.driver.implicitly_wait(5) # Wait only 5 seconds to find it
okayButton = driver.find_element_by_accessibility_id('Okay')
# No need to sleep here
log("There was no in-app purchases dialog")
# Cancel iOS Game Center login
cancelButton = driver.find_element_by_accessibility_id('Cancel')
log("Cancelling iOS Game Center login…")
log("The Game Center login was not displayed")
# Check that a goldmine is on screen
rect = self.find_image("queryimages/tutorial_goldmine.png",
"There should be a goldmine on screen at beginning of tutorial")
log('Gold mine found at %s %s! Continuing…' % (rect, rect))
# Dismiss the bubbles
sleep(2) # second blabla
sleep(2) # Goblin appears
# Go to shop
# NOTE: tap_image does also assert, fails test if target not recognized
# Buy cannon
# Place the cannon
# Use gem to finish right away
# Bring it on!
# To be continued…
if __name__ == '__main__':
Let’s look some of the stages in this test script. The test_tutorial contains the following steps:
It first figures out whether the test executes on Android (self.isAndroid()) or iOS. As you can see, it looks for UI content differently. On Android, it tries to find a button by using an element’s ID (element_name) and on iOS by using an accessibility ID with a description (“Okay”). The same check happens for iOS’ Game Center login.
Screenshots are taken at various steps and stored in files entered as a parameter in a function call.
A check is done to see whether “goldmine” appears on screen by comparing two PNG files using a self.find_image call. If these pictures match (i.e. “goldmine” appears on screen), then the script continues executing the game’s tutorial.
The tutorial proceeds with the following steps:
Go to shop.
Place the cannon.
The information about all three of these items is stored in those PNG files: shopbutton.png, cannon.png and place_the_cannon.png.
Finally, the tutorial finishes and the battle starts. After the battle, the application is closed.
The video below shows how the test executes at each step. For the video, I’ve used three devices: one iOS (iPhone 4S) and two Android phones (Samsung Galaxy S3 Mini and HTC One X). You can also watch the video on YouTube70.
How Is Image Recognition Used Here?
The example shown uses image recognition (i.e. template matching71) to identify which features — basically, pixels and graphic content — are shown on screen and to compare the two pictures to each other. The algorithm built to recognize images was used on real devices and on two different platforms (Android and iOS), and it used a single test script for both platforms. This sort of image comparison is even very handy for recognizing UI elements and graphics that are resized and/or rotated.
Let’s say the template image has some distinctive features, such as text that can be easily abstracted from the background content. In this case, feature-based recognition can be used. In our example, if the “Button” text has been resized or rotated (or otherwise transformed), we can quickly and easily identify this and take further action.
The following functions explain the approach of comparing images:
def tap_image(self, query_image,
width_modifier=0.5, height_modifier=0.5, retries=2):
retries_left = retries
rect = None
while retries_left > 0 and not rect:
rect = self.find_image(query_image)
retries_left = retries_left - 1
image_name = os.path.split(query_image)
self.assertIsNotNone(rect, "Image %s is on screen" % image_name)
x = rect+rect*width_modifier
y = rect+rect*height_modifier
log('%s button found at %s %s (%sx%s), tapping at %s %s' %
(image_name, rect, rect, rect, rect, x, y))
def tap(self, x, y):
log('Tapping at %s,%s' % (x,y))
driver = self.get_driver()
touch_actions = TouchActions(driver)
action = TouchAction(driver)
else: # iOS
action = TouchAction(driver)
# TODO: Temporary hack
# On iPhone 4S = res. 480 x 320 for taps but screenshots are 960 x 640
Testing is crucial to ensuring success in the highly competitive landscape of mobile apps and games72. But even poorly planned testing can take up 20 to 50% of your total development effort, in which case it would also account for the single biggest cost in your budget. To ensure that testing is extremely efficient, covering the breadth of today’s mobile ecosystems and device models, the best option is an online cloud-based service.
If you only start thinking about testing a few days before the app hits the market, it’s too late. You’ll need to test a wealth of elements, data and functionality from day one. Here are some things to consider in making testing a part of your development process:
Plan carefully: Automate generic processes as much as possible.
When you’re building a mobile app, a well thought out strategy is critical, a great user experience and design are paramount, and solid development and testing are fundamental. Many aspects of testing can be automated, and this automation will increase the depth and scope of your testing and significantly improve the app’s quality. Ideally, test cases should have full access to the application and test all aspects of it — memory contents, data tables, file contents and internal program states — to determine whether the product performs as expected.
Your app will change during development: The same goes for testing.
Choose a testing technology and provider you can grow with.
If you already have an app on the market and are looking to create a similar one, then select a technology74 and vendor that meet your needs. For example, building your test cases according to a certain method or framework will enable you to reuse those test cases for your new application — at least to some extent. So, choose a technology and vendor that is able to handle your needs as your product scales up and as your testing has to cover new geographical areas and even support new platforms (for example, going from Android to iOS).
Test automation is available 24/7.
Automation will reduce the time it takes to test new features and even the app itself by running 24/7.
Use a cloud-based platform for truly global reach.
With an online cloud-based service, you’ll get instant access to hundreds of real Android devices75. Especially with Android, having access to devices that are used in volume holds significant value. Running automated tests on these devices is easy and fast and provides all of the information you’ll need, preprocessed, summarized and in full detail.
What are your thoughts on test automation for mobile? Please let us know in the comments section!
According to a recent report1, HTML is the most widely used language for mobile app developers. The main reasons among developers for selecting web technologies2 is cross-platform portability of code and the low cost of development. We’ve also heard that hybrid apps tend to be sluggish and poorly designed. Let’s prove whether it’s possible to deliver the native look and feel that we’re used to.
What Are Hybrid Mobile Apps?
Mobile apps can be generally broken down into native, hybrid and web apps. Going the native route allows you to use all of the capabilities of a device and operating system, with a minimum of performance overhead on a given platform. However, building a web app allows your code to be ported across platforms, which can dramatically reduce development time and cost. Hybrid apps combine the best of both worlds, using a common code base to deploy native-like apps to a wide range of platforms.
There are two approaches to building a hybrid app:
Compiled hybrid app
While both approaches are widely used and exist for good reasons, we’ll focus on WebView apps because they enable developers to leverage most of their existing web skills. Let’s look at all of the benefits and drawbacks of hybrid apps compared to both native and mobile web apps.
Developer can use existing web skills
One code base for multiple platforms
Reduced development time and cost
Easily design for various form factors (including tablets) using responsive web design
Access to some device and operating system features
Advanced offline capabilities
Increased visibility because the app can be distributed natively (via app stores) and to mobile browsers (via search engines)
Performance issues for certain types of apps (ones relying on complex native functionality or heavy transitions, such as 3D games)
Increased time and effort required to mimic a native UI and feel
Not all device and operating system features supported
Risk of being rejected by Apple if app does not feel native enough (for example, a simple website)
These drawbacks are significant and cannot be ignored, and they show that the hybrid approach does not suit all kinds of apps. You’ll need to carefully evaluate your target users, their platforms of choice and the app’s requirements. In the case of many apps, such as content-driven ones, the benefits outweigh the drawbacks. Such apps can typically be found in the “Business and Productivity,” “Enterprise” and “Media” categories in the app store.
Both Hojoki and CatchApp are very content-driven productivity apps, so we initially thought they would be a great match for hybrid development. The first three benefits mentioned above were especially helpful to us in building the mobile app for Hojoki in just four weeks8. Obviously, that first version lacked many important things. The following weeks and months were filled with work on optimizing performance, crafting a custom UI for each platform and exploiting the advanced capabilities of different devices. The learning in that time was crucial to making the app look and feel native. I’ll share as many lessons as possible below.
So, how do you achieve a native look and feel? To a mobile web developer, being able to use the features of a device and operating system and being able to package their app for an app store sounds just awesome. However, if users are to believe it is a native app, then it will have to behave and look like one. Accomplishing this remains one of the biggest challenges for hybrid mobile developers.
Make Your Users Feel at Home
A single code base doesn’t mean that the app should look and feel exactly the same on all platforms. Your users will not care at all about the underlying cross-platform technology. They just want the app to behave as expected; they want to feel “at home.” Your first stop should be each platform’s design guidelines:
While these guidelines might not perfectly suit all kinds of apps, they still provide a comprehensive and standard set of interfaces and experiences that users on each platform will know and expect.
DIY vs. UI Frameworks
Implementing all of these components, patterns and animations on your own can be quite a challenge. All kinds of frameworks exist to help you with that, ranging from commercial (Kendo UI12) to open-source ones (Ionic13) and from ones with a common UI (jQuery Mobile14 and Onsen UI15) to many platform-specific UIs (Sencha Touch7716 and ChocolateChip-UI17). Some are really good at providing a pixel-perfect layout, while others are rather sloppy, thus making it easy for the user to identify a web app. However, my impression is that their main drawbacks are performance-related, because most UI frameworks try to be as all-embracing as possible. Judge for yourself by taking a few minutes to try the demos on your own device.
Custom UI Components
Custom UI components also have many good use cases. Deciding between a platform’s UI and a custom UI will obviously depend on your target audience. If you want to do your own thing, you should have a deep understanding of UX design, because the guidelines linked to above were crafted by experts to meet the particular requirements of their platform’s users.
Whether you stick to a platform’s UI guidelines or do your own thing with custom components, know that there are certain design patterns that most people use every day and love. How are people usually introduced to a new app? Through a slideshow walkthrough or an instructional overlay. How do people navigate? With a tab bar or a sidebar drawer18. How do users quickly load or refresh data? By pulling to refresh. (Native-like scrolling will be covered extensively further below.)
One important part of a UI is the header bar, with its title and navigation elements, most notably the “up” and “back” buttons. To me, many popular frameworks fail to provide a HTML and CSS solution that compares to a native app. Mimicking this part of the UI with a minimal DOM and a few lines of CSS for each platform is actually fairly easy:
<!-- more actions (e.g. a search button on the right side) -->
Using the same DOM across all platforms is generally preferable because it results in cleaner code and, therefore, maximizes maintainability. I’ve found this to be easily possible for many UI components on iOS and Android (including the header bar, tab bar, custom navigation menu, settings page, popover and many more). However, this becomes much harder when adding support for Windows Phone, which comes with some very different design patterns.
Support High-Resolution Screens
Nowadays, smartphones and tablets with high-resolution screens make up the vast majority of mobile devices, making up more than 80% of iOS devices23 and over 70% on Android devices24. To make your images look crisp for everyone, you usually have to deliver twice the dimensions than what is actually shown in your app. Serving properly sized images for all different resolutions is one of the most discussed topics in responsive web design. There are various approaches, each with its benefits and drawbacks related to bandwidth, code maintainability and browser support. Let’s quickly review the most popular ones, in no particular order:
server-side resizing and delivering
HTML5 picture element
HTML5 srcset attribute
CSS media queries
Resolution-independent images (SVG)
As always, there is no silver bullet for responsive images. It pretty much depends on the type of images and how they are used in the app. For static images (such as the logo and tutorial images), I try to use SVG. They scale perfectly without any extra effort and have great browser support as long as you’re fine with Android 3+25.
When SVG is not an option, the HTML5 picture element and srcset attributes26 are definitely where front-end development is heading. Currently, their main drawback is the very limited browser support and, therefore, their need for polyfills.
/* Normal-resolution CSS */
background: url(logo.png) no-repeat 0 0;
/* HD and Retina CSS */
only screen and (-webkit-min-device-pixel-ratio: 1.25),
only screen and ( min--moz-device-pixel-ratio: 1.25),
only screen and ( -o-min-device-pixel-ratio: 1.25/1),
only screen and ( min-device-pixel-ratio: 1.25),
only screen and ( min-resolution: 200dpi),
only screen and ( min-resolution: 1.25dppx)
background: url(firstname.lastname@example.org) no-repeat 0 0;
background-size: 120px; /* Equal to normal logo width */
However, your app might already contain a lot of content (such as news articles), and adjusting all of the img tags or replacing them with CSS would be exhausting. A server-side solution is the best choice in this case.
Starting last year, more and more Android manufacturers have gone one step further with what is called XXHDPI (or very very high-resolution) screens. Whichever solution above fits your need, keep in mind that you’ll need images that are three times the original dimensions to support Android’s latest flagship devices.
Use System Fonts
A simple yet important way to make users feel at home is to use system fonts.
These are my recommended font stacks on the major platforms:
Furthermore, iOS 7 offers some interesting presets that automatically set the correct font family, font size and line height. It’s as easy as using font: -apple-system-body for normal text and font: -apple-system-headline for headings. This not only simplifies font declarations, but also improves accessibility through “dynamic type31,” Apple’s system-wide font-size setting. You can dig deeper into iOS 7 font presets in a post by Thomas Fuchs32.
An Icon Is Worth A Thousand Words
Iconography is an important part of the user experience on all major mobile platforms. As with fonts, you’re usually best off using icons that your target audience already knows. Recalling what I said about high-resolution screens earlier, make sure that your icons are scaleable. Implementing them as a font via CSS’ @font-face rule is a great way to achieve this, and it comes with wide browser support33. It even allows you to change an icon’s appearance (for example, its color, shadow and transparency) seamlessly via CSS. Here are my recommendations:
Get various platform icon fonts. Ionicons34 is our baseline set because it includes nearly everything we need. This includes specific icons for iOS and Android in addition to their general ones. The rest come from specific platform icon fonts for iOS35, Android set 136 and set 237 and Windows Phone38.
Combine them with a icon font generator.
Using multiple icon fonts is confusing and quickly adds up in size. That is why we use Fontello39 to combine the different sets, adjust key codes and export them for each platform. The result is <span class="icon">s</span>, which looks like a search icon on iOS, Android and Windows Phone, respectively. Also, check out the popular alternatives IcoMoon40 and Fontastic41.
Beyond that, mobile hardware and rendering engines are improving at a rapid pace, with new devices coming out every other day. Developers can make the performance of a hybrid WebView app difficult to distinguish from that of a fully native app on the iPhone 5 series and on Android phones comparable to Nexus 4 and 5.
Increase Perceived Speed
Building a performant app is one thing, but making it feel fast is a whole other. Whether your app needs some time for a certain task (such as some heavy calculation or client-server communication), presenting instant feedback is crucial to providing a fluid and responsive experience. A common technique is to delay tasks that the user doesn’t need yet, while predicting and preloading the steps the user might take next. A famous example is Instagram, which uploads photos in the background48 while the user is busy adding tags and sharing. Perceived speed can be very different from actual speed, so let’s use it in our favor. Here are some no-brainers.
Remove the Click Delay on Touch Devices
if ('ontouchstart' in window)
Internet Explorer 10+ is a bit easier. You just need some CSS:
Furthermore, remove the default tap highlight while adjusting your active states on mobile. I’d also recommend disabling user selections on actionable elements, because the selection menu would be quite disruptive if the user accidentally taps the button for too long.
Cross-platform tools like PhoneGap and Trigger.io also provide access to native loaders, which is great for showing a full-screen loading animation.
Get the Scrolling Right
Scrolling is one of the most important factors in the user experience of many apps. This is both a curse and a blessing because the success of its implementation will depend heavily on the scrolling niceties that your app relies on and on the mobile operating systems that need to be supported.
Scrollable content and a fixed header and/or footer bar are common to nearly all apps. There are two common approaches to achieving this with CSS:
Enabling scrolling on the body, and applying position: fixed to the header;
Disabling scrolling on the body, and applying overflow: scroll to the content;
Let’s look at some of the basic scrolling features.
The touch-friendly momentum effect enables users to quickly scroll through large content areas in an intuitive way. It can be easily activated with some simple CSS on iOS 5+ and in some versions of Chrome for Android. On iOS, this will also enable the content to bounce off the top and bottom edges.
Scroll to Top
Make It Easy To Hit Stuff
When performing a touch action, users will quite often miss their target by a few pixels, especially on small buttons (such as the ones in iOS’ top bar). Developers can assist users while keeping the design elegant by enabling an invisible touch area around small targets:
You’ll have to put the event handler on the button element, while restricting the styles to div.innerButton. Check out the full example, including CSS62, on JSFiddle.
Using Touch Gestures
Don’t Miss Out on Native Functionality
Building your app with web technology doesn’t necessarily mean that you can’t use native features. In fact, all major cross-platform development tools provide built-in access to the most important functionality. This includes APIs for device data, the file system, the network connection, geolocation, the accelerometer, notifications (including push) and much more.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6)
And here’s the code to copy a given string to the device’s clipboard on iOS:
Web developers often overlook how to handle bad situations in a hybrid app (for example, a connection timeout, a bad input, a timing issue, etc.). A hybrid app is fundamentally different from a website, mainly because there is no global refresh button, and an app can easily run in the background for weeks on some mobile operating systems. If the user runs into a dead end, their only option will be to restart the app, which entails force quitting and then restarting. Many people don’t even know how to do that, especially on Android 2.x (where it’s hidden deep in the app’s settings) and on iOS 6 and below (where you have to double-tap the home button, long-press the icon and kill it).
So, ignore the refresh button during development, and handle bad situations as they come up. For all other situations that would have unexpected outcomes, such as ones involving client-server communication, be prepared for things to go wrong, and provide a way out for users. This could be as easy as showing a full-screen error message — “Oops! Something bad happened. Please check your connection and try again” — with a big “Reload” button below.
How To Wrap It
A few cross-platform development tools provide that native bridge and simplify the whole process of wrapping it. Let’s dive into some options.
PhoneGap and Apache Cordova
PhoneGap68 is certainly one of the most popular tools for cross-platform development. The name itself is often used synonymously with hybrid mobile app development.
Both are open-source and free to use, with support for all major platforms and with an active community developing all kinds of plugins and extensions.
PhoneGap has shaped the hybrid lanscape significantly, and many new tools have emerged that offer additional services or that streamline the development process. They usually add a lot of convenience by enabling you to build an app in the cloud, thereby saving you the effort of locally installing all of the different platform SDKs and tools. Each tool has a different focus, level of platform support and price:
Sencha Touch7716 started out as a UI framework for the mobile web and has been around for years. Traditionally, developers have used Sencha to build an app while using another service, like PhoneGap, to deploy it as a hybrid app. Nowadays, Sencha offers this kind of functionality built in for free. Platform support includes iOS and Android (both via Sencha’s own native packager) BlackBerry, Windows 8 and more (via PhoneGap Build).
At Hojoki, we started using Trigger.io78 two and a half years ago because we were looking for a lightweight alternative to PhoneGap. Even though iOS and Android are its only supported platforms, it offers a good set of native APIs, custom plugins and third-party integration (including Parse push notifications, Flurry analytics and parts of Facebook’s SDK). Trigger.io’s command-line tools allowed us to integrate the app’s packaging into our Grunt79 build process, which is great if you love automation.
Once the 14-day trial is up, Trigger.io’s steep pricing82 is probably the biggest downside for many developers.
With MoSync83 having gone offline a couple of days ago, Trigger.io seems to be the only remaining tool that is not associated with PhoneGap.
Test on Real Devices
Building a mobile app with web technologies obviously tempts us to do most of our testing in a web browser. This might be fine when developing non-native features, but definitely avoid it when releasing. Test with as many manufacturers, platforms and form factors as possible before submitting the app. Android’s fragmentation brings endless possibilities of differences in browser rendering, unsupported features and manufacturer modifications. While iOS does much better with rendering differences, Apple has a growing number of devices with varying sizes, resolutions and pixel densities. Check out “Prioritizing Devices: Testing and Responsive Web Design84” to learn more.
When Facebook famously ditched most of its HTML5 and went native in 2012, it cited missing debugging tools and developer APIs85 as one of its main reasons. LinkedIn drew the same conclusions86 half a year later, stating that HTML5 itself is ready, but basic tools and the ecosystem don’t support it yet. From what I’m seeing, the situation is getting better, with remote debugging in WebView on Android 4.4+ and an increasing number of development tools on all platforms:
When building an app for web browsers, deploying a hot fix to users is a simple step, which means that testing can lose some of its importance. This obviously needs to be reconsidered when you’re releasing an app through an app store. Think of it like software development in the ’90s: You’re now living in the world of hard releases.
So, why is this bad? First, the submission process could easily take a week or two (Hello, Apple!). Secondly, even if your hot fix is released quickly, that doesn’t guarantee that users will update the app any time soon. Here are my suggestions:
Make testing a high priority.
Have some kind of “force update” logic to deprecate old client versions.
Use mechanisms like Trigger.io’s Reload9280 to fix code on the fly.
The tools mentioned above spit out a binary for each platform, which can then be submitted to the relevant store. From this point on, the process is exactly the same as publishing a “normal” native app. Some of the tools we’ve looked at might even have better documentation for this. Nevertheless, here are the official guides:
Now that our hybrid mobile apps have been in Apple’s App Store and in Google Play for two years, I’d like to recapitulate some of the benefits and drawbacks mentioned at the beginning of this article.
For us, a web startup company with very limited resources and no native iOS or Android experience, building an app for multiple platforms in just a few weeks would have been impossible. Choosing the hybrid path enabled us to reuse a lot of code from the web app and to iterate quickly based on user feedback. We’ve even managed to publish native apps for Windows 8 for the desktop and Microsoft Surface as well as Mac OS X with exactly the same code base. The effort of moving to another platform will depend largely on the capabilities of the given browser and device and on the level of your need for native functionality. We needed push notifications, in-app purchases and access to the user’s contacts, among other things. Depending on your needs, a lot of native functionality could make you heavily dependent on the native wrapping tool that you choose.
Finally, let’s see whether hybrid apps really can deliver a native look and feel. Below is a compilation of user reviews from the app stores. Both positive and negative comments are included, but many of the negative reviews are for early releases, which had the same UI for all platforms and was comparatively slow in performance.
★ Great idea, but not a good app. The app runs extremely slow on my Samsung Galaxy Ace and Tab. The app also looks and controls like an iPhone app. This is confusing when you have never had an iPhone.
★★ Another reason apps should not use WebViews for UI.
★★ Service great but WebView app sucks.
★★★ It’s the right app in concept, but it really is too laggy to be practically used. And I’m using Jellybean so there is no excuse.
★★★ It lags a lot and the UI is not beautiful.
★★★ Good but very very slow.
★★★★ This app is very handy, but is a little slow to boot up.
★★★★★ This is working really hard well since the update. It’s a great app to begin with and now it’s working smoother and faster than before.
★★★★★ Extremely smooth and effective.
★★★★★ The app work flawlessly…
★★★★★ Beautiful designed app! Love the interface and the great overview of all your tools! Good job! Keep shippin!
★★★★★ This is an absolutely beautiful aggregate that runs buttery smooth, even on a 3GS. Recommend to anyone doing any sort of project.
We’re definitely moving away from platform-specific app development and towards the many new technologies that are emerging. Larry Page said this98 when asked at Google I/O last year about the future of the web:
In the very long term, I don’t think you should have to think about, as a developer, am I developing for this platform or another, or something like that. I think you should be able to work at a much higher level, and software you write should run everywhere, easily.
The (mobile) web is a major success story in this regard. Being able to use this platform and still be able to distribute an app in all stores is a huge step forward. It will be interesting to see how this all plays out. Whatever happens, using a technology that over a third of the world’s population99 (over two thirds in Europe and the US) relies on probably won’t be a bad choice.
There are more than 16 million colors and any great blog-post that you come across on the internet will tell you the “feelings” conveyed by only a handful of colors. If you sell to people from different ethnicity and cultures, choosing colors for your website can become even more difficult as one color that relates to wealth and prosperity in a country may relate to mourning in another. How do you go about it then?
In this post I will help you choose colors for your website’s CTAs, background and other important entities that you want people to focus on. A believer of “one size doesn’t fit all” and “data (not opinions and experience) gets most respect“, I will not be able to spill out some magic potion and tell you the exact colors you should use. But I promise to take you through 3 actionable tips that you could go back and test right away to increase your website’s conversions.
1) Color the Primary Goal of your Website to Make it Stand Out
Imagine a shopping list of 20 items, all items written in blue ink except for one which is in red. If asked to scan this list for 10 seconds, which item do you think you are most likely to recall later? Multiple experiments have confirmed that outliers (or the item in red in the example) is what people remember most often. This is because of a phenomenon known as the Von Restroff effect (also known as isolation effect) which states that an item that stands out is more likely to be remembered than others.
Applying this to your websites, if you want your calls to action to get immediate attention, make them stand out. Use a color that has high contrast compared to your background and that hasn’t been used for any other entity on the page. Look at how Facebook and LinkedIn do it on their homepage:
Choosing a contrasting color for your primary CTA is not very difficult. You just have to look for a color diagonally opposite to that of your background color or most-used color on your page from the color wheel.
Let’s for a moment go back to the red button v/s green button case study. Have a closer look at the screenshot below. You will find that the color scheme of the original page has some emphasis towards green. The Performable logo is green, the screenshot used on the page has some elements in green and one of the features also has an icon in green. A quick scan doesn’t really make the CTA stand out from the rest of the elements. I wouldn’t be surprised if testing the original page against a variation with the CTA in yellow or orange would produce same or better results.
The important takeaway from this case study is to create a visual contrast for your goal. End of the day, it’s not the button color that is going to sell your stuff but how prominently you display it for people to take a decision before abandoning your website for the competitors’.
2) Choose Colors that are “All”-User Friendly
In United States alone, about 7% of males (roughly 10.5 million men) and 0.4% of females have some form of color blindness. In Australia, these percentages are 8 for men and 0.4 for women. The most common problem being difficulty in telling red from green.
Needless to say, when deciding colors for your website and the areas where you want people to focus on, it becomes imperative to keep in mind people who have some form of color blindness. And if you have a SaaS product, that shows some results in charts and graphs, it becomes even more important to choose the right colors so that they are easily distinguishable for everyone. See below, how a contrast between foreground and background appears to people with certain forms of color blindness. You will notice that while eyes with normal vision would easily be able to read the text, people with Protanopia and Deuteranopia (most common forms of color blindness) will just not be able to read what’s written.
Common solutions to ensure a great experience for everyone:
Choose colors many steps away from each other on the color wheel
Use tints (mixture of color with white) for background and shades (mixture of color with black) for foreground (or vice versa). Or make one element even more dark and the other even more light to create better contrast.
3) Train Visitors with your Color Key
Consider how bar graphs work. To look at data of one particular type, you just follow its color or pattern. Once you understand what a particular color or pattern bar stands for, you are able to compare easily focusing only on that particular color or pattern.
Similarly, if you use one color consistently on your website for a particular CTA (say signup), you will subconsciously train your users with the meaning of that color on the website. As an example, let’s suppose someone is evaluating a SaaS product on your website. And you have a shiny orange button for free trial on every page. When done evaluating their eyes will look for the orange thing, on whichever page they are, to sign up.
This way, you can even tell them which colors correspond to a heading, which means links and which call for a purchase.
See how CampaignMonitor does it beautifully. CTA buttons on all of their pages, which ask people to sign up for an account, are in green. And for no other CTA has the same color been used. This createa a consistent visual memory for visitors.
How has your experience with website colors been? Tried any A/B tests that worked well? Or may be which didn’t? Would love to hear all of it in the comments section below!
If you thought measuring the success of your inbound campaign is a tedious job, well don’t worry, you are not alone. According to a study conducted by Hubspot, 25% of marketing professionals admitted to ‘proving ROI’ as the biggest challenge they face.
For measuring success, it is important to understand that the effectiveness of an inbound campaign is the collective result of various activities. Let’s have a look at how we can evaluate the success of an inbound campaign across various stages of the conversion funnel.
Measuring the Inbound Campaign at Top of the Funnel (ToFU)
The primary objective of your activities at ToFU is to attract a greater share of the target market. Hence, all metrics at this stage must focus on what percentage of the audience are you reaching out to. Here’s a list of what you should measure:
Growth in Traffic
You know your inbound campaign is doing well if the number of visitors to your website increases during the campaign period. A simple way to keep track of this is through Google Analytics. Follow this path in Google Analytics to see the growth in your visitor traffic: Reporting -> Audience -> Overview
Another important factor you should keep in mind while analyzing website traffic is the percentage of new vs returning visitors. Repeat visitors indicate visitor loyalty to your website. A low rate of repeat visitors means that your inbound campaign does not offer long term benefit to users.
In order to keep activities in line with the objectives, you must focus on maintaining a higher percentage of new visitors at ToFU. You can focus on generating greater visitor loyalty during later stages of the funnel.
Sources of Traffic
Besides growth in traffic, you must also keep in mind where your visitors are coming from. Analyzing traffic sources tells if your SEO efforts are bringing fruit. A good chunk of organic traffic is indicative of well performing keywords. On the other hand, referral traffic helps you gauge the effectiveness of your link-building efforts. You should keep an eye on the ‘referring urls’ to develop a greater understanding of the sources of traffic. Follow this path in Google Analytics to have a look at the referral traffic on your website: Reporting -> Audience -> Overview -> Referral Traffic
The most popular metric to track for social performance is the wide reach of your social channels. These can be easily assessed by tracking the number of ‘likes’ on your Facebook page, number of ‘followers’ on Twitter or LinkedIn. However, these numbers in absolute terms do not make much sense for measuring success. So instead of simply looking at the number of ‘likes’ on your Facebook page, try and analyse how these ‘likes’ have grown over a period of time. Have your likes seen a sudden upward trend during a certain campaign? A comparison of growth trends will help you understand performance in a better way. Follow this path on your Facebook page to view the ‘likes’ trend for your page: See Insights -> Likes -> Net Likes
You can go through this article for tips on how you can drive your social leads through the sales funnel.
Blog Views and Social Shares
Analyzing individual blog posts helps you differentiate between a good post and a bad one. By continuously monitoring the views and shares of individual posts over a period of time, you will be able to identify patterns so as decide what kind of posts work best for you. Keep in mind that a highly viewed post might not result in good engagement (comments) and shares. Have a look at how our post on ‘Snackable Content’ gathered popularity on various social channels.
Email Click Through Rate
CTR is the most important metric of analysing e-mail marketing campaigns. A high CTR indicates that your message is clear and relevant for the target audience. However, the ideal CTR varies from one type of message to another. For example, newsletter e-mails sent to an opt-in list would have a higher CTR than a promotional message sent to the same set of customers. Hence you should define the target CTR for each form of e-mail and try achieving that for each campaign.
Measuring the Inbound Campaign at Middle of the Funnel (MoFU)
Once you have attracted a large chunk of your target audience towards your offering, the next important step is to keep the audience hooked to your offer until they make the final decision to buy. Here’s what you should do to analyse whether your inbound campaign is going to help generate qualified leads or not:
Analyse your social media properties to see if your audience is engaging with you or not. Facebook provides its users with a ‘Talking About This’ score which measures the level of engagement on your page.
In addition, you can also measure the engagement on individual messages on your Facebook page using Facebook insights. Follow this path to view the post wise engagement on your Facebook page: See Insights -> Posts -> All Published Posts
Lead Generation and Conversion
Conversion rates need to be tracked for various channels of your inbound campaign. At a broad level, you must link all your campaigns to a pre-defined goal (based on your conversion objective) and see which inbound campaign is performing the best according to your goals. Follow this path in Google Analytics to see the goal conversion rate for your campaigns: Reporting -> Acquisition -> Campaigns -> Conversions (All Goals)
If you are using your blog as an inbound channel, the call-to-action (CTA) on your blog becomes an important metric to measure success. The CTA helps drive viewers of your blog to take the required action.
Visitor to lead ratio
Attracting visitors from a channel is of no use unless these visitors are taking the required action on your landing page. The visitor to lead ratio is defined as the percentage of visitor who converted to a lead. You can calculate this percentage for all you inbound channels and thus analyse which one is giving the best results.Visitor to lead Conversion = Leads Generated / Total Visitors
Bounce Rate and Time on Page
You can measure the level of engagement on your blog by tracking the average time spent on the blog and the bounce rate. A high bounce rate indicates that your are not attracting the right kind of audience to your blog.
All said and done, we would all agree that measuring the performance of your inbound campaign is probably as important as executing it in the first place. The key to success lies in finding out the best way to do it. ‘Coz if you don’t measure it, you will never be able to say that it works! Have you defined measurement criterion for your inbound campaign? Do share your insights with us.