![]() |
Web Dev
Time is our most valuable resource. We’re losing it all of the time and they’re not making any more of it. It’s sobering to think every moment that passes, is a moment we’ll never get again.
I have to remind myself that life is short. Anything that isn’t a life experience, time with friends or family, or time spent going for our dreams, should be called into question.
That being said, the little sneaky time-suckers like tweets, texts, emails, notifications, and meetings, always have a way of finding their way back into our routines.
Every few weeks I have to re-assess my time and hit the productivity reset button. Here are a few strategies I use. I hope they can help you in some way.
It is important to spend the time we do have, accomplishing something of note. It has been my experience that people can rarely do more than three major projects at a time and do them well.
I always stop and make sure that I’m clear on the top three projects or goals that I want to accomplish. This is important because I find that time typically fits into one of three categories:
“Core time” means you’re in the zone and you’re actively working, focused on a core task for great work. “Support time” is the necessary emails, tweets, texts, calls and meetings to do your work. “Waste of time” is the unnecessary emails, tweets, texts, calls, articles, Youtube videos and meetings.
In order to have the most “core time” possible, you have to first identify what that time is and what goals that time needs to accomplish. Decide on your three best projects now and set them as the backbone of your productivity.
I tend to be my “sharpest” in the early part of the day. This is the time when I need to be writing, coding, and designing (my critical 3). We’re only capable of a few hours of maximum productivity each day and I like to spend that precious time doing the things that are most important to long-term goals.
With carefully planned recovery and downtime throughout the day, I’m still able to be focused and productive, but just not at the levels I am in the morning. The afternoon is good for learning, building relationships, tackling emails and sharing on Twitter.
Knowing when I perform best has been a huge factor for my career. It’s hard to keep the discipline to keep that time sacred, but it’s entirely necessary. Know yourself and identify when you are at your best. I promise it will help you set your best possible routine.
We tend to really care about what people think, and we genuinely want to be someone that can be counted on to be there for our teammates. The problem with this is that there are no boundaries and you’ve left yourself vulnerable to distractions and not getting anything critical done.
In the end, you and your team only truly want one thing: that you get your work done. Educating yourself and the people you work with on how to maximize “core time”, will help you set boundaries and hold your time sacred.
The fact of the matter is that people respect those that command it. Be someone that is disciplined with your time and be sure to let everyone know it. What you do with your time is crucial and we can’t make it up like we tend to try to tell ourselves we can.
I use these points to keep my time in check. It’s a very difficult thing to do because there is so much opportunity out there and so many cool things to watch, read, and discuss.
I hope that these have flipped some light switches in your own mind and that they’ve provided the start of a new productivity strategy for you.
Be smart and disciplined with your time. It will really show by the end of next year.
The post Keeping Your Time in Check appeared first on Treehouse Blog.

Control of personal information in the digital space, and particularly on mobile devices, presents a unique design challenge.
Most people aren’t aware that their personal data is being collected and shared. Many users don’t take the time to validate their expectations and most never read privacy policies.
People only seem to become aware of such concerns when something happens that doesn’t meet their expectations, such as seeing their friend’s picture in a Facebook ad or seeing banner ads that match their most recent purchase. And when people do become aware and their expectations are violated, trust in the brand is eroded.
People want transparency and control, but they want it on their...read more
By Ilana Westerman
This FSF comes from Wish.co.uk all the way across the pond in England. This site is basically a one stop shop for a ton of fun services in the UK area. These services include tours of stadiums, indoor sky diving, and even learn how to drive a tank.
 If you would like to see your website or company featured on Free Shirt Friday click here.
Trying to increase your Google rank that is like no other?
As a mobile UI or UX designer, you probably remember the launch of Apple’s first iPhone as if it was yesterday. Among other things, it introduced a completely touchscreen-centered interaction to a individual’s most private and personal device. It was a game-changer.
Today, kids grow up with touchscreen experiences like it’s the most natural thing. Parents are amazed by how fast their children understand how a tablet or smartphone works. This shows that touch and gesture interactions have a lot of potential to make mobile experiences easier and more fun to use.
The introduction of “Human Interface Guidelines” and Apple’s App Review Board had a great impact on the quality of mobile applications. It helped a lot of designers and developers understand the core mobile UI elements and interactions. One of Apple’s popular suggestions, for instance, is to use UITabBar and UINavigationBar components — a guideline that many of us have followed, including me.
In fact, if you can honestly say that the first iPhone application you designed didn’t have any top or bottom bar elements, get in touch and send over a screenshot. I will buy you a beer and gladly tweet that you were ahead of your time.
My issue with the top and bottom bars is that they fill almost 20% of the screen. When designing for a tiny canvas, we should use every available pixel to focus on the content. In the end, that’s what really matters.
In this innovative industry, mobile designers need some time to explore how to design more creative and original interfaces. Add to that Apple’s frustrating rejection of apps that “think outside the box,” it is no surprise that experimental UI and UX designs such as Clear and Rise took a while to see the light of day. But they are here now. And while they might be quite extreme and focused on high-brow users and early adopters, they show us the great creative potential of gesture-driven interfaces.

Pulling to refresh feels very intuitive.
For over two years now, I’ve been exploring the ways in which gestures add value to the user experience of a mobile application. The most important criterion for me is that these interactions feel very intuitive. This is why creative interactions such as Loren Brichter’s “Pull to Refresh” have become a standard in no time. Brichter’s interaction, introduced in Tweetie for iPhone, feels so intuitive that countless list-based applications suddenly adopted the gesture upon its appearance.
A great way to start designing a more gesture-driven interface is to use your main screen only as a viewport to the main content. Don’t feel obliged to make important navigation always visible on the main screen. Rather, consider giving it a place of its own. Speaking in terms of a virtual 2-D or 3-D environment, you could design the navigation somewhere next to, below, behind, in front of, above or hidden on top of the main view. A dragging or swiping gesture is a great way to lead the user to this UI element. It’s up to you to define and design the app.
What I like about Facebook and Gmail on iOS, for instance, is their implementation of a “side-swiping” menu. This trending UI concept is very easy to use. Users swipe the viewport to the right to reveal navigation elements. Not only does this make the app very content-focused, but accessing any section of the application takes only two to three touch interactions. A lot of apps do far worse than that!

Facebook and Gmail’s side-swiping menu
In addition to the UI navigation, your app probably also supports contextual interactions, too. Adding the same two or three buttons below every content item will certainly clutter the UI! While buttons might seem to be useful triggers, gestures have great potential to make interaction with content more intuitive and fun. Don’t hesitate to integrate simple gestures such as tapping, double-tapping and tapping-and-holding to trigger important interactions. Instagram supports a simple double-tap to perform one of its key features, liking and unliking a content item. I would not be surprised to see other apps integrate this shortcut in the near future.
When designing an innovative mobile product, predicting user behavior can be very difficult. When we worked with Belgium’s Public Radio, my team really struggled with the UI balance between music visualization and real-time news. The sheer number of contextual scenarios and preferences made it very hard to come up with the perfect UI. So, we decided to integrate a simple dragging gesture to enable users to adjust the balance themselves.

By dragging, users can balance music-related content and live news.
This gesture adds a creative contextual dimension to the application. The dragging gesture does not take the user from one section (news or music) to another. Rather, it enables the user to focus on the type of content they are most interested in, without missing out on the other.
What action is triggered when the user taps an item? And how do you visualize that it has actually happened? How fast does a particular UI element animate into the viewport? Does it automatically go off-screen after five seconds of no interaction?
The rise of touch and gesture-driven devices dramatically changes the way we design interaction. Instead of thinking in terms of screens and pages, we are thinking more in terms of time, dimension and animation. You’ve probably noticed that fine-tuning user interactions and demonstrating them to colleagues and clients with static wireframe screenshots is not easy. You don’t fully see, understand and feel what will happen when you touch, hold, drag and swipe items.
Certain prototyping tools, including Pop and Invision, can help bring wireframes to life. They are very useful for testing an application’s flow and for pinpointing where and when a user might get stuck. Your application has a lot more going on than simple back-and-forth navigation, so you need to detect interface bugs and potential sources of confusion as soon as possible. You wouldn’t want your development team to point them out to you now, would you?

Invision enables you to import and link your digital wireframes.
To be more innovative and experimental, get together with your client first and explain that a traditional wireframe is not the UX deliverable that they need. Show the value of interactive wireframes and encourage them to include this in the process. It might increase the timeline and budget, but if they are expecting you to go the extra mile, it shouldn’t be a problem.
I even offer to produce a conceptual interface video for my clients as well, because once they’ve worked with the interactive wireframes and sorted out the details, my clients will often need something sexier to present to their internal stakeholders.
When designing gesture-based interactions, be aware that every time you remove UI clutter, the application’s learning curve goes up. Without visual cues, users could get confused about how to interact with the application. A bit of exploration is no problem, but users should know where to begin. Many apps show a UI walkthrough when first launched, and I agree with Max Rudberg that walkthroughs should explain only the most important interactions. Don’t explain everything at once. If it’s too explicit and long, users will skip it.
Why not challenge yourself and gradually introduce creative UI hints as the user uses the application? This pattern is often referred to as progressive disclosure and is a great way to show only the information that is relevant to the user’s current activity. YouTube’s Capture application, for instance, tells the user to rotate the device to landscape orientation just as the user is about to open the camera for the first time.

Fight the learning curve with a UI walkthrough and/or visual hints.
Adding visual cues to the UI is not the only option. In the Sparrow app, the search bar appears for a few seconds, before animating upwards and going off screen, a subtle way to say that it’s waiting to be pulled down.
The iPhone ushered in a revolution in interactive communication. Only five years later, touchscreen devices are all around us, and interaction designers are redefining the ways people use digital content.
We need to explore and understand the potential of touch and gesture-based interfaces and start thinking more in terms of time, dimension and animation. As demonstrated by several innovative applications, gestures are a great way to make an app more content-focused, original and fun. And many gesture-based interactions that seem too experimental at first come to be seen as very intuitive.
For a complete overview of the opportunities for gestures on all major mobile platforms, check out Luke Wroblewski’s “Touch Gesture Reference Overview.” I hope you’re inspired to explore gesture-based interaction and intensify your adventures in mobile interfaces. Don’t be afraid to go the extra mile. With interactive wireframes, you can iterate your way to the best possible experience. So, let’s stop talking and start making.
(al)
© Thomas Joos for Smashing Magazine, 2013.
Since Chitika has pretty much become the publishing and advertising platfom for Yahoo! (my words not theirs) I have been hitting them up to see if they can do something special for ShoeMoney users.
I know a lot of people are new to the space and need a little push to get started. Â Sometimes that push can lead to some magical things
. Â That was my exact case. Â That famous Adsense check for 130k on the left. Â That came about because of a phone call I got from Google suggesting I place their ad on my site
.
Free Money:
For each person who signs up in the next couple days to become a publisher they will instantly have $5 deposited into their account. Â Go here and sign up now to get your free $5:
http://chitika.com/publishers/apply
ShoeMoney exclusive contest:
Now here is the really cool part that gives everyone a chance to win a cash prize. The user that signs up through the ShoeMoney link below that earns the most as a publisher will get $500!
Each publisher that places a Chitika ad on their site and gets at least 10 clicks will be entered to win one of 5 $100 cash prizes.
Lets recap:
Sign up to Chitika through this link and instantly get $5 deposited into your account AND after you get a couple clicks you are entered to win $100 in bonus money.
Why is Chitika doing this? Â
Simple. Â They are putting their money where their mouth is. Â Keep in mind you can run Google Adsense on the same page as Chitika and they are confident you will see a increase in earnings. Â They are closing the gap against Google every day to become the #1 way for website owners to make money. I have made a LOT of money with Chitika over the years and it continues to be my goto network of choice.
Whats’s in it for ShoeMoney?
I have not been compensated in any way shape or form for doing this post. Â (other then getting free money and a cool contest for you) Â As you can see their is no affiliate link and it’s their normal signup page.
So get after it:
http://chitika.com/publishers/apply
Trying to increase your Google rank that is like no other?
Illustrations for REMOTE: Office Not Required are being done by the fantastic Mike Rohde again. This one is for the essay “Stop Commuting Your Life Away”. The book is due out in October of this year.
In this Treehouse Quick Tip, teacher Jim Hoskins will show you how to write a simple JavaScript module. Modules are useful in writing JavaScript, because they allow us to write code that is less likely to interfere with other code on our page.
It allows us to selectively expose parts of the code to other programs running on our page. This makes our JavaScript code more resilient and easier to maintain.
The post How to Write a Module in JavaScript – Quick Tip appeared first on Treehouse Blog.

For the past several months, I’ve been actively investigating the UX jobs market as part of an effort we announced back in January to explore the employment issues endemic to our field. Through in-person research in several major cities and by working with Didus, a UX-focused recruiting and career development agency, I’ve seen the opportunities and problems up close.
In part, this research has exposed the immaturity of the UX field. For all the growth, interest, and importance surrounding user-centered ideas and practices, our professional milieu is still a disorderly jungle. The fundamental issue is that we’re growing outward faster than we’re firming things up inward, and new concepts enter the conversation before old ones have been fully established, methodized, and universalized.
This...read more
By Jonathan Anderson | UX Magazine, Didus
When the mockups for the new Financial Times application hit our desks in mid-2012, we knew we had a real challenge on our hands. Many of us on the team (including me) swore that parts of interface would not be possible in HTML5. Given the product team’s passion for the new UI, we rolled up our sleeves and gave it our best shot.
We were tasked with implementing a far more challenging product, without compromising the reliable, performant experience that made the first app so successful.
We didn’t just want to build a product that fulfilled its current requirements; we wanted to build a foundation that we could innovate on in the future. This meant building with a maintenance-first mentality, writing clean, well-commented code and, at the same time, ensuring that our code could accommodate the demands of an ever-changing feature set.
In this article, I’ll discuss some of the changes we made in the latest release and the decision-making behind them. I hope you will come away with some ideas and learn from our solutions as well as our mistakes.
The first Financial Times Web app ran on iPad and iPhone in the browser, and it shipped in a native (PhoneGap-esque) application wrapper for Android and Windows 8 Metro devices. The latest Web app is currently being served to iPad devices only; but as support is built in and tested, it will be rolled out to all existing supported platforms. HTML5 gives developers the advantage of occupying almost any mobile platform. With 2013 promising the launch of several new Web application marketplaces (eg. Chrome Web Store and Mozilla Marketplace), we are excited by the possibilities that lie ahead for the mobile Web.
The first shock that came from the new mockups was that they were all fixed height. By “fixed height,” I mean that, unlike a conventional website, the height of the page is restricted to the height of the device’s viewport. If there is more content than there is screen space, overflow must be dealt with at a component level, as opposed to the page level. We wanted to use JavaScript only as a last resort, so the first tool that sprang to mind was flexbox. Flexbox gives developers the ability to declare flexible elements that can fill the available horizontal or vertical space, something that has been very tricky to do with CSS. Chris Coyier has a great introduction to flexbox.
Flexbox has been around since 2009 and has great support on all the popular smartphones and tablets. We jumped at the chance to use flexbox when we found out how easily it could solve some of our complex layouts, and we started throwing it at every layout problem we faced. As the app began to grow, we found performance was getting worse and worse.
We spent a good few hours in Chrome Developers Tools’ timeline and found the culprit: Shock, horror! — it was our new best friend, flexbox. The timeline showed that some layouts were taking close to 100 milliseconds; reworking our layouts without flexbox reduced this to 10 milliseconds! This may not seem like a lot, but when swiping between sections, 90 milliseconds of unresponsiveness is very noticeable.
We had no other choice but to tear out flexbox wherever we could. We used 100% height, floats, negative margins, border-box sizing and padding to achieve the same layouts with much greater performance (albeit with more complex CSS). Flexbox is still used in some parts of the app. We found that its impact on performance was less expensive when used for small UI components.

Page layout time without flexbox
The content of a fixed-height layout will rarely fit its container; eventually it has to overflow. Traditionally in print, designers have used ellipses (three dots) to solve this problem; however, on the Web, this isn’t the simplest technique to implement.
You might be familiar with the text-overflow: ellipsis declaration in CSS. It works great, has awesome browser support, but has one shortfall: it can’t be used for text that spans multiple lines. We needed a solution that would insert an ellipsis at the point where the paragraph overflows its container. JavaScript had to step in.

Ellipsis truncation is used throughout.
After an in-depth research and exploration of several different approaches, we created our FTEllipsis library. In essence, it measures the available height of the container, then measures the height of each child element. When it finds the child element that overflows the container, it caps its height to a sensible number of lines. For WebKit-based browsers, we use the little-known -webkit-line-clamp property to truncate an element’s text by a set number of lines. For non-WebKit browsers, the library allows the developer to style the overflowing container however they wish using regular CSS.
Having tackled some of the low-level visual challenges, we needed to step back and decide on the best way to manage our application’s views. We wanted to be able to reuse small parts of our views in different contexts and find a way to architect rock-solid styling that wouldn’t leak between components.
One of the best decisions we made in implementing the new application was to modularize the views. This started when we were first looking over the designs. We scribbled over printouts, breaking the page down into chunks (or modules). Our plan was to identify all of the possible layouts and modules, and define each view (or page) as a combination of modules sitting inside the slots of a single layout.
Each module needed to be named, but we found it very hard to describe a module, especially when some modules could have multiple appearances depending on screen size or context. As a result, we abandoned semantic naming and decided to name each component after a type of fruit — no more time wasted thinking up sensible, unambiguous names!
An example of a module’s markup:
<div class="apple">
<h2 class="apple_headline">{{headline}}</h2>
<h3 class="apple_sub-head">{{subhead}}</h3>
<div class="apple_body">{{body}}</div>
</div>
An example of a module’s styling:
.apple {}
.apple_headline {
font-size: 40px;
}
.apple_sub-head {
font-size: 20px;
}
.apple_body {
font-size: 14px;
column-count: 2;
color: #333;
}
Notice how each class is prefixed with the module’s name. This ensures that the styling for one component will never affect another; every module’s styling is encapsulated. Also, notice how we use just one class in our CSS selectors; this makes our component transportable. Ridding selectors of any ancestral context means that modules may be dropped anywhere in our application and will look the same. This is all imperative if we want to be able to reuse components throughout the application (and even across applications).
Each module (or fruit) has its own markup and style, which we wrote in such a way that it can be reused. But what if we need a module to respond to interactions or events? We need a way to bring the component to life, but still ensure that it is unbound from context so that it can be reused in different places. This is a little trickier that just writing smart markup and styling. To solve this problem, we wrote FruitMachine.
FruitMachine is a lightweight library that assembles our layout’s components and enables us to declare interactions on a per-module basis. It was inspired by the simplicity of Backbone views, but with a little more structure to keep “boilerplate” code to a minimum. FruitMachine gives our team a consistent way to work with views, while at the same time remaining relatively unopinionated so that it can be used in almost any view.
Thinking about your application as a collection of standalone components changes the way you approach problems. Components need to be dumb; they can’t know anything of their context or of the consequences of any interactions that may occur within them. They can have a public API and should emit events when they are interacted with. An application-specific controller assembles each layout and is the brain behind everything. Its job is to create, control and listen to each component in the view.
For example, to show a popover when a component named “button” is clicked, we would not hardcode this logic into the button component. Instead “button” would emit a buttonclicked event on itself every time its button is clicked; the view controller would listen for this event and then show the popover. By working like this, we can create a large collection of components that can be reused in many different contexts. A view component may not have any application-specific dependencies if it is to be used across projects.
Working like this has simplified our architecture considerably. Breaking down our views into components and decoupling them from our application focuses our decision-making and moves us away from baking complex, heavily dependent modules into our application.
FruitMachine was our solution to achieve fully transportable view components. It enables us to quickly define and assemble views with minimal effort. We are currently using FruitMachine only on the client, but server-side (NodeJS) usage has been considered throughout development. In the coming months, we hope to move towards producing server-side-rendered websites that progressively enhance into a rich app experience.
You can find out more about FruitMachine and check out some more examples in the public GitHub repository.
The Financial Times’ first Web app was released before the age of “Retina” screens. We retrofitted some high-resolution solutions, but never went the whole hog. For our designers, 100% Retina support was a must-have in the new application. We developers were sick of maintaining multiple sizes and resolutions of each tiny image within the UI, so a single vector-based solution seemed like the best approach. We ended up choosing icon fonts to replace our old PNGs, and because they are implemented just like any other custom font, they are really well supported. SVG graphics were considered, but after finding a lack of support in Android 2.3 and below, this option was ruled out. Plus, there is something nice about having all of your icons bundled up in a single file, whilst not sacrificing the individuality of each graphic (like sprites).
Our first move was to replace the Financial Times’ logo image with a single glyph in our own custom icon font. A font glyph may be any color and size, and it always looks super-sharp and is usually lighter in weight than the original image. Once we had proved it could work, we began replacing every UI image and icon with an icon font alternative. Now, the only pixel-based image in our CSS is the full-color logo on the splash screen. We used the powerful but rather archaic-looking FontForge to achieve this.
Once past the installation phase, you can open any font file in FontForge and individually change the vector shape of any character. We imported SVG vector shapes (created in Adobe Illustrator) into suitable character slots of our font and exported as WOFF and TTF font types. A combination of WOFF and TTF file formats are required to support iOS, Android and Windows devices, although we hope to rely only on WOFFs once Android gains support (plus, WOFFs are around 25% smaller in file size than TTFs).
![]()
The Financial Times’ icon font in Font Forge
Article images are crucial for user engagement. Our images are delivered as double-resolution JPEGs so that they look sharp on Retina screens. Our image service (running ImageMagick) outputs JPEGs at the lowest possible quality level without causing noticeable degradation (we use 35 for Retina devices and 70 for non-Retina). Scaling down retina size images in the browser enables us to reduce JPEG quality to a lower level than would otherwise be possible without compression artifacts becoming noticeable. This article explains this technique in more detail.
It’s worth noting that this technique does require the browser to work a little harder. In old browsers, the work of scaling down many large images could have a noticeable impact on performance, but we haven’t encountered any serious problems.
Like almost any application, we require full-page and subcomponent scrolling in order to manage all of the content we want to show our users. On desktop, we can make use of the well-established overflow CSS property. When dealing with the mobile Web, this isn’t so straightforward. We require a single solution that provides a “momentum” scrolling experience across all of the devices we support.
The overflow: scroll declaration is becoming usable on the mobile Web. Android and iOS now support it, but only since Android 3.0 and iOS 5. IOS 5 came with the exciting new -webkit-overflow-scrolling: touch property, which allows for native momentum-like scrolling in the browser. Both of these options have their limitations.
Standard overflow: scroll and overflow: auto don’t display scroll bars as users might expect, and they don’t have the momentum touch-scrolling feel that users have become accustomed to from their native apps. The -webkit-overflow-scrolling: touch declaration does add momentum scrolling and scroll bars, but it doesn’t allow developers to style the scroll bars in any way, and has limited support (iOS 5+ and Chrome on Android).
Fragmented support and an inconsistent feel forced us to turn to JavaScript. Our first implementation used the TouchScroll library. This solution met our needs, but as our list of supported devices grew and as more complex scrolling interactions were required, working with it became trickier. TouchScroll lacks IE 10 support, and its API interface is difficult to work with. We also tried Scrollability and Zynga Scroller, neither of which have the features, performance or cross-browser capability we were looking for. Out of this problem, FTScroller was developed: a high-performance, momentum-scrolling library with support for iOS, Android, Playbook and IE 10.
FTScroller’s scrolling implementation is similar to TouchScroll’s, with a flexible API much like Zynga Scroller. We added some enhancements, such as CSS bezier curves for bouncing, requestAnimationFrame for smoother frame rates, and support for IE 10. The advantage of writing our own solution is that we could develop a product that exactly meets our requirements. When you know the code base inside out, fixing bugs and adding features is a lot simpler.
FTScroller is dead simple to use. Just pass in the element that will wrap the overflowing content, and FTScroller will implement horizontal or vertical scrolling as and when needed. Many other options may be declared in an object as the second argument, for more custom requirements. We use FTScroller throughout the Financial Times’ Web app for a consistent cross-platform scrolling experience.
A simple example:
var container = document.getElementById('scrollcontainer');
var scroller = new FTScroller(container);
The part of our application that holds and animates the page views is known as the “gallery.” It consists of three divisions: left, center and right. The page that is currently in view is located in the center pane. The previous page is positioned off screen in the left-hand pane, and the next page is positioned off screen in the right-hand pane. When the user swipes to the next page, we use CSS transitions to animate the three panes to the left, revealing the hidden right pane. When the transition has finished, the right pane becomes the center pane, and the far-left pane skips over to become the right pane. By using only three page containers, we keep the DOM light, while still creating the illusion of infinite pages.

Infinite scrolling made possible with a three-pane gallery
Not many Web apps currently offer an offline experience, and there’s a good reason for that: implementing it is a bloody pain! The application cache (AppCache) at first glance appears to be the answer to all offline problems, but dig a little deeper and stuff gets nasty. Talks by Andrew Betts and Jake Archibald explain really well the problems you will encounter. Unfortunately, AppCache is currently the only way to achieve offline support, so we have to work around its many deficiencies.
Our approach to offline is to store as little in the AppCache as possible. We use it for fonts, the favicon and one or two UI images — things that we know will rarely or never need updating. Our JavaScript, CSS and templates live in LocalStorage. This approach gives us complete control over serving and updating the most crucial parts of our application. When the application starts, the bare minimum required to get the app up and running is sent down the wire, embedded in a single HTML page; we call this the preload.
We show a splash screen, and behind the scenes we make a request for the application’s full resources. This request returns a big JSON object containing our JavaScript, CSS and Mustache templates. We eval the JavaScript and inject the CSS into the DOM, and then the application launches. This “bootstrap” JSON is then stored in LocalStorage, ready to be used when the app is next started up.
On subsequent startups, we always use the JSON from LocalStorage and then check for resource updates in the background. If an update is found, we download the latest JSON object and replace the existing one in LocalStorage. Then, the next time the app starts, it launches with the new assets. If the app is launched offline, the startup process is the same, except that we cannot make the request for resource updates.
Managing offline images is currently not as easy as it should be. Our image requests are run through a custom image loader and cached in the local database (IndexedDB or WebSQL) so that the images can be loaded when a network connection is not present. We never load images in the conventional way, otherwise they would break when users are offline.
Our image-loading process:
src attribute of each image placeholder found and requests the source from our JavaScript image-loader library.<img> element is created, and its src attribute is set to the Base64 data-URI string.I should also mention that we compress our Base64-encoded image strings in order to fit as many images in the database as possible. My colleague Andrew Betts goes into detail on how this can be achieved.
In some cases, we use this cool trick to handle images that fail to load:
<img src="image.jpg" onerror="this.style.display='none';" />
In order to stay competitive, a digital product needs to evolve, and as developers, we need to be prepared for this. When the request for a redesign landed at the Financial Times, we already had a fast, popular, feature-rich application, but it wasn’t built for change. At the time, we were able to implement small changes to features, but implementing anything big became a slow process and often introduced a lot of unrelated regressions.
Our application was drastically reworked to make the new requirements possible, and this took a lot of time. Having made this investment, we hope the new application not only meets (and even exceeds) the standard of the first product, but gives us a platform on which we can develop faster and more flexibly in the future.
(al)
© Wilson Page for Smashing Magazine, 2013.
Aaron Draplin is a graphic designer and founder of the Draplin Design Company. He’s done work for everyone from his friend’s hot dog company to President Obama himself. He’s also a speaker and co-creator of Field Notes, a popular notebook series among designers. He’s bold, outspoken, and unapologetic about being awesome.
He took a minute to talk with expert teacher, Mat Helme, and threw some knowledge bombs at him. Enjoy!
The full interview will be available tomorrow to all Treehouse Gold Members.
The post Tall Tales From A Large Man – Interview with Aaron Draplin appeared first on Treehouse Blog.
The process to understand API development is generally complicated but should become easier with practice. Social networks like Twitter and YouTube offer XML/RSS/JSON feeds without the requirement of an API key. However, other smaller networking websites like Instagram and Etsy will require developers to sign up for a new API key before allowing them to make requests from the server.
In this tutorial I want to demonstrate a really simple HTML/CSS/JS web application building over the YouTube API. This demo will list a number of YouTube channels which you may click and pull out all the latest videos, plus their related metadata such as views and comments. All of this dynamic page content will be handled via jQuery so you do not need to host anything on a web server. Check out my sample demo to get an idea of what we are building.
Live Demo – Download Source Code
I will skip a lot of the boring HTML so that we can focus more deeply on the YouTube response and how we handle this in JavaScript. The most important HTML section you should recognize is the navigation along with the inner videos content div. I have used specific IDs so that we can target each element and check whenever the user clicks a link, then display that content inside #videos.
<nav id="usersnav">
<ul>
<li><a href="#gotreehouse">gotreehouse</a></li>
<li><a href="#thenextweb">thenextweb</a></li>
<li><a href="#TEDxTalks">TEDxTalks</a></li>
<li><a href="#wearechange">wearechange</a></li>
<li><a href="#RTAmerica">RTAmerica</a></li>
<li><a href="#G4ZDTechTV2">G4ZDTechTV2</a></li>
<li><a href="#NovaCrystallisDotCom">NovaCrystallisDotCom</a></li>
</ul>
</nav>
<div id="videos">
<!-- vids go here -->
</div>
In order for the whole process to work we will need a copy of the latest jQuery library. My demo includes this file from within the ./js/ directory so you won’t need to re-download anything. Also I have kept my custom-written jQuery codes inside the index file instead of moving them to an external JS script. It would obviously be easier to do so when you are running this on a live website, but for my demo it is quicker to study these codes from within the same page.
The first step is to define a set of variables which we need in the script. Then we can handle a click event from the user which is interfacing with any of the navigation links. Each of the anchor elements is using an HREF value containing a hash symbol plus username we need. It is important that we stop this default href from loading by using e.preventDefault() and then pull the value out so we can get the YouTube feed results.
$(function(){
$('#usersnav ul li a').on('click', function(e){
e.preventDefault();
var htmlString = '<ul id="videoslisting">';
var channelname = $(this).attr('href').substring(1);
var ytapiurl = 'http://gdata.youtube.com/feeds/api/users/'+channelname+'/uploads?alt=json&max-results=10';
The handy JavaScript substring() method will create a new string variable starting from the character marker 1(marker 0 is the first character). This removes our hash symbol so that we can now place the username into a generic API call which looks like this: http://gdata.youtube.com/feeds/api/users/CHANNELNAME/uploads?alt=json&max-results=10
The user’s channel name can be accessed to query YouTube and pull out their latest uploads. I am referencing a max results value of 10 and since we are not using pagination. I have not included any other callback methods, either. JSON is the response type we need so that way it’ll be easier parsing all this content inside jQuery.
PHP and Rails and other programming languages often use logic loops to iterate through data patterns. While loops, for loops, do loops, and other common ideas are not as strict when you would compare them with JavaScript. However the methods for .parseJSON() and jQuery.each() offer the perfect system for looping through all of these results.
$.getJSON(ytapiurl, function(data) {
$.each(data.feed.entry, function(i, item) {
var title = item['title']['$t'];
var videoid = item['id']['$t'];
var pubdate = item['published']['$t'];
var fulldate = new Date(pubdate).toLocaleDateString();
var thumbimg = item['media$group']['media$thumbnail'][0]['url'];
var tinyimg1 = item['media$group']['media$thumbnail'][1]['url'];
var tinyimg2 = item['media$group']['media$thumbnail'][2]['url'];
var tinyimg3 = item['media$group']['media$thumbnail'][3]['url'];
var vlink = item['media$group']['media$content'][0]['url'];
var ytlink = item['media$group']['media$player'][0]['url'];
var numviews = item['yt$statistics']['viewCount'];
var numcomms = item['gd$comments']['gd$feedLink']['countHint'];
htmlString +='<li class="clearfix"><h2>' + title + '</h2>';
htmlString +='<div class="videothumb"><a href="' + ytlink + '" target="_blank"><img src="' + thumbimg + '" width="480" height="360"></a></div>';
htmlString +='<div class="meta"><p>Published on <strong>' + fulldate + '</strong></p><p>Total views: <strong>' + commafy(numviews) + '</strong></p><p>Total comments: <strong>'+ numcomms +'</strong></p><p><a href="'+ ytlink +'" class="external" target="_blank">View on YouTube</a></p><p><a href="'+ vlink +'" class="external" target="_blank">View in Fullscreen</a></p><p><strong>Alternate Thumbnails</strong>:<br><img src="'+ tinyimg1 +'"> <img src="' + tinyimg2 + '"> <img src="'+ tinyimg3 +'"></p></div></li>';
}); // end each loop
$('#videos').html(htmlString + "</ul>");
}); // end json parsing
This code block seems very large but the majority of the content is generating variable names. YouTube will return a lot more information than we need so it would be foolish to create an array containing all the keys. Instead we should make new variables strictly for the content which will be used inside the layout, and then we create a final HTML string to return to the browser.
Each variable block will contain an important section of the final display. We will need the video title, original publishing date, the full-size thumbnail along with each of the 3 mini-thumbs, direct video URL, view count, and also the comments count. The HTML is displayed using an unordered list of items which finishes by applying the HTML content into the #videos container. This is easily accomplished by using the jQuery .html() method.
One other final point I’d like to bring up is the ability to parse through each view counter. Return data for videos which have over 1000 views will not include the comma between each set of 3 numbers. I found an excellent solution on Stack Overflow written using pure JavaScript. The function name is commafy() which is wrapped around each of the view count numbers. This will check if the digits are higher than 4 and automatically place a comma where it should be.
These codes are wonderful to use in any number of JavaScript solutions. The questions and solutions on Stack Overflow are always helpful with these kinds of matters. I think it is worth noting that you could write a much simpler function using jQuery or handling this method inside the .each() loop. But if everything is kept inside a separate file then you may not worry as much about the syntax or number of lines.
Live Demo – Download Source Code
Many developers who are not familiar with JSON should hit Google and read a few articles on the subject. It is basically JavaScript code which is written in a certain way so that the syntax can be read as data-value pairs. YouTube can present JSON data from their server and using jQuery it is possible to organize this data into the page dynamically. I hope this tutorial may prove useful to anybody who has been interested in developing over YouTube’s API, or any API for that matter. Feel free to download a copy of my demo and see if you can implement a similar method elsewhere in your own projects.
The post Developing over the YouTube API with JSON appeared first on Treehouse Blog.
Flexible box layout (or flexbox) is a new box model optimized for UI layout. As one of the first CSS modules designed for actual layout (floats were really meant mostly for things such as wrapping text around images), it makes a lot of tasks much easier, or even possible at all. Flexbox’s repertoire includes the simple centering of elements (both horizontally and vertically), the expansion and contraction of elements to fill available space, and source-code independent layout, among others abilities.
Flexbox has lived a storied existence. It started as a feature of Mozilla’s XUL, where it was used to lay out application UI, such as the toolbars in Firefox, and it has since been rewritten multiple times. The specification has only recently reached stability, and we have fairly complete support across the latest versions of the leading browsers.
There are, however, some caveats. The specification changed between the implementation in Internet Explorer (IE) and the release of IE 10, so you will need to use a slightly different syntax. Chrome currently still requires the -webkit- prefix, and Firefox and Safari are still on the much older syntax. Firefox has updated to the latest specification, but that implementation is currently behind a runtime flag until it is considered stable and bug-free enough to be turned on by default. Until then, Firefox still requires the old syntax.
When you specify that an element will use the flexbox model, its children are laid out along either the horizontal or vertical axis, depending on the direction specified. The widths of these children expand or contract to fill the available space, based on the flexible length they are assigned.
Being able to center an element on the page is perhaps the number one wish among Web designers — yes, probably even higher than gaining the highly prized parent selector or putting IE 6 out of its misery (OK, maybe a close second then). With flexbox, this is trivially easy. Let’s start with a basic HTML template, with a heading that we want to center. Eventually, once we’ve added all the styling, it will end up looking like this vertically and horizontally centered demo.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Centering an Element on the Page</title>
</head>
<body>
<h1>OMG, I’m centered</h1>
</body>
</html>
Nothing special here, not even a wrapper div. The magic all happens in the CSS:
html {
height: 100%;
}
body {
display: -webkit-box; /* OLD: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* OLD: Firefox (buggy) */
display: -ms-flexbox; /* MID: IE 10 */
display: -webkit-flex; /* NEW, Chrome 21+ */
display: flex; /* NEW: Opera 12.1, Firefox 22+ */
-webkit-box-align: center; -moz-box-align: center; /* OLD… */
-ms-flex-align: center; /* You know the drill now… */
-webkit-align-items: center;
align-items: center;
-webkit-box-pack: center; -moz-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
margin: 0;
height: 100%;
width: 100% /* needed for Firefox */
}
h1 {
display: -webkit-box; display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-align: center; -moz-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
height: 10rem;
}
I’ve included all of the different prefixed versions in the CSS above, from the very oldest, which is still needed, to the modern and hopefully final syntax. This might look confusing, but the different syntaxes map fairly well to each other, and I’ve included tables at the end of this article to show the exact mappings.
This is not exactly all of the CSS needed for our example, because I’ve stripped out the extra styling that you probably already know how to use in order to save space.
Let’s look at the CSS that is needed to center the heading on the page. First, we set the html and body elements to have 100% height and remove any margins. This will make the container of our h1 take up the full height of the browser’s window. Firefox also needs a width specified on the body to force it to behave. Now, we just need to center everything.
Because the body element contains the heading that we want to center, we will set its display value to flex:
body {
display: flex;
}
This switches the body element to use the flexbox layout, rather than the regular block layout. All of its children in the flow of the document (i.e. not absolutely positioned elements) will now become flex items.
The syntax used by IE 10 is display: -ms-flexbox, while older Firefox and WebKit browsers use display: -prefix-box (where prefix is either moz or webkit). You can see the tables at the end of this article to see the mappings of the various versions.
What do we gain now that our elements have been to yoga class and become all flexible? They gain untold powers: they can flex their size and position relative to the available space; they can be laid out either horizontally or vertically; and they can even achieve source-order independence. (Two holy grails in one specification? We’re doing well.)
Next, we want to horizontally center our h1 element. No big deal, you might say; but it is somewhat easier than playing around with auto margins. We just need to tell the flexbox to center its flex items. By default, flex items are laid out horizontally, so setting the justify-content property will align the items along the main axis:
body {
display: flex;
justify-content: center;
}
For IE 10, the property is called flex-pack, while for older browsers it is box-pack (again, with the appropriate prefixes). The other possible values are flex-start, flex-end, space-between and space-around. These are start, end, justify and distribute, respectively, in IE 10 and the old specification (distribute is, however, not supported in the old specification). The flex-start value aligns to the left (or to the right with right-to-left text), flex-end aligns to the right, space-between evenly distributes the elements along the axis, and space-around evenly distributes along the axis, with half-sized spaces at the start and end of the line.
To explicitly set the axis that the element is aligned along, you can do this with the flex-flow property. The default is row, which will give us the same result that we’ve just achieved. To align along the vertical axis, we can use flex-flow: column. If we add this to our example, you will notice that the element is vertically centered but loses the horizontal centering. Reversing the order by appending -reverse to the row or column values is also possible (flex-flow: row-reverse or flex-flow: column-reverse), but that won’t do much in our example because we have only one item.
There are some differences here in the various versions of the specification, which are highlighted at the end of this article. Another caveat to bear in mind is that flex-flow directions are writing-mode sensitive. That is, when using writing-mode: vertical-rl to switch to vertical text layout (as used traditionally in China, Japan and Korea), flex-flow: row will align the items vertically, and column will align them horizontally.
Centering vertically is as easy as centering horizontally. We just need to use the appropriate property to align along the “cross-axis.” The what? The cross-axis is basically the axis perpendicular to the main one. So, if flex items are aligned horizontally, then the cross-axis would be vertical, and vice versa. We set this with the align-items property (flex-align in IE 10, and box-align for older browsers):
body {
/* Remember to use the other versions for IE 10 and older browsers! */
display: flex;
justify-content: center;
align-items: center;
}
This is all there is to centering elements with flexbox! We can also use the flex-start (start) and flex-end (end) values, as well as baseline and stretch. Let’s have another look at the finished example:

Simple horizontal and vertical centering using flexbox. Larger view.
You might notice that the text is also center-aligned vertically inside the h1 element. This could have been done with margins or a line height, but we used flexbox again to show that it works with anonymous boxes (in this case, the line of text inside the h1 element). No matter how high the h1 element gets, the text will always be in the center:
h1 {
/* Remember to use the other versions for IE 10 and older browsers! */
display: flex;
align-items: center;
height: 10rem;
}
If centering elements was all flexbox could do, it’d be pretty darn cool. But there is more. Let’s see how flex items can expand and contract to fit the available space within a flexbox element. Point your browser to this next example.

An interactive slideshow built using flexbox. Larger view.
The HTML and CSS for this example are similar to the previous one’s. We’re enabling flexbox and centering the elements on the page in the same way. In addition, we want to make the title (inside the header element) remain consistent in size, while the five boxes (the section elements) adjust in size to fill the width of the window. To do this, we use the new flex property:
section {
/* removed other styles to save space */
-prefix-box-flex: 1; /* old spec webkit, moz */
flex: 1;
height: 250px;
}
What we’ve just done here is to make each section element take up 1 flex unit. Because we haven’t set any explicit width, each of the five boxes will be the same width. The header element will take up a set width (277 pixels) because it is not flexible. We divide the remaining width inside the body element by 5 to calculate the width of each of the section elements. Now, if we resize the browser window, the section elements will grow or shrink.
In this example, we’ve set a consistent height, but this could be set to be flexible, too, in exactly the same way. We probably wouldn’t always want all elements to be the same size, so let’s make one bigger. On hover, we’ve set the element to take up 2 flex units:
section:hover {
-prefix-box-flex: 2;
flex: 2;
cursor: pointer;
}
Now the available space is divided by 6 rather than 5, and the hovered element gets twice the base amount. Note that an element with 2 flex units does not necessarily become twice as wide as one with 1 unit. It just gets twice the share of the available space added to its “preferred width.” In our examples, the “preferred width” is 0 (the default).
For our last party trick, we’ll study how to achieve source-order independence in our layouts. When clicking on a box, we will tell that element to move to the left of all the other boxes, directly after the title. All we have to do is set the order with the order property. By default, all flex items are in the 0 position. Because they’re in the same position, they follow the source order. Click on your favorite person in the updated example to see their order change.

An interactive slideshow with flex-order. Larger view.
To make our chosen element move to the first position, we just have to set a lower number. I chose -1. We also need to set the header to -1 so that the selected section element doesn’t get moved before it:
header {
-prefix-box-ordinal-group: 1; /* old spec; must be positive */
-ms-flex-order: -1; /* IE 10 syntax */
order: -1; /* new syntax */
}
section[aria-pressed="true"] {
/* Set order lower than 0 so it moves before other section elements,
except old spec, where it must be positive.
*/
-prefix-box-ordinal-group: 1;
-ms-flex-order: -1;
order: -1;
-prefix-box-flex: 3;
flex: 3;
max-width: 370px; /* Stops it from getting too wide. */
}
In the old specification, the property for setting the order (box-ordinal-group) accepts only a positive integer. Therefore, I’ve set the order to 2 for each section element (code not shown) and updated it to 1 for the active element. If you are wondering what aria-pressed="true" means in the example above, it is a WAI-ARIA attribute/value that I add via JavaScript when the user clicks on one of the sections.
This relays accessibility hints to the underlying system and to assistive technology to tell the user that that element is pressed and, thus, active. If you’d like more information on WAI-ARIA, check out “Introduction to WAI-ARIA” by Gez Lemon. Because I’m adding the attribute after the user clicks, this example requires a simple JavaScript file in order to work, but flexbox itself doesn’t require it; it’s just there to handle the user interaction.
Hopefully, this has given you some inspiration and enough introductory knowledge of flexbox to enable you to experiment with your own designs.
As you will have noticed throughout this article, the syntax has changed a number of times since it was first implemented. To aid backward- and forward-porting between the different versions, we’ve included tables below, which map the changes between the specifications.
| Specification | IE | Opera | Firefox | Chrome | Safari |
| Standard | 11? | 12.10+ * | Behind flag | 21+ (-webkit-) |
|
| Mid | 10 (-ms-) |
||||
| Old | 3+ (-moz-) |
<21 (-webkit-) |
3+ (-webkit-) |
* Opera will soon switch to WebKit. It will then require the -webkit- prefix if it has not been dropped by that time.
| Specification | Property name | Block-level flex | Inline-level flex |
| Standard | display |
flex |
inline-flex |
| Mid | display |
flexbox |
inline-flexbox |
| Old | display |
box |
inline-box |
| Specification | Property name | start | center | end | justify | distribute |
| Standard | justify-content |
flex-start |
center |
flex-end |
space-between |
space-around |
| Mid | flex-pack |
start |
center |
end |
justify |
distribute |
| Old | box-pack |
start |
center |
end |
justify |
N/A |
| Specification | Property name | start | center | end | baseline | stretch |
| Standard | align-items |
flex-start |
center |
flex-end |
baseline |
stretch |
| Mid | flex-align |
start |
center |
end |
baseline |
stretch |
| Old | box-align |
start |
center |
end |
baseline |
stretch |
| Specification | Property name | auto | start | center | end | baseline | stretch |
| Standard | align-self |
auto |
flex-start |
center |
flex-end |
baseline |
stretch |
| Mid | flex-item-align |
auto |
start |
center |
end |
baseline |
stretch |
| Old | N/A | ||||||
| Specification | Property name | start | center | end | justify | distribute | stretch |
| Standard | align-content |
flex-start |
center |
flex-end |
space-between |
space-around |
stretch |
| Mid | flex-line-pack |
start |
center |
end |
justify |
distribute |
stretch |
| Old | N/A | ||||||
This takes effect only when there are multiple flex lines, which is the case when flex items are allowed to wrap using the flex-wrap property and there isn’t enough space for all flex items to display on one line. This will align each line, rather than each item.
| Specification | Property name | Value |
| Standard | order |
|
| Mid | flex-order |
<number> |
| Old | box-ordinal-group |
<integer> |
| Specification | Property name | Value |
| Standard | flex |
none | [ <flex-grow> <flex-shrink>? || <flex-basis>] |
| Mid | flex |
none | [ [ <pos-flex> <neg-flex>? ] || <preferred-size> ] |
| Old | box-flex |
<number> |
The flex property is more or less unchanged between the new standard and the draft supported by Microsoft. The main difference is that it has been converted to a shorthand in the new version, with separate properties: flex-grow, flex-shrink and flex-basis. The values may be used in the same way in the shorthand. However, the default value for flex-shrink (previously called negative flex) is now 1. This means that items do not shrink by default. Previously, negative free space would be distributed using the flex-shrink ratio, but now it is distributed in proportion to flex-basis multiplied by the flex-shrink ratio.
| Specification | Property name | Horizontal | Reversed horizontal | Vertical | Reversed vertical |
| Standard | flex-direction |
row |
row-reverse |
column |
column-reverse |
| Mid | flex-direction |
row |
row-reverse |
column |
column-reverse |
| Old | box-orientbox-direction |
horizontalnormal |
horizontalreverse |
verticalnormal |
verticalreverse |
In the old version of the specification, the box-direction property needs to be set to reverse to get the same behavior as row-reverse or column-reverse in the later version of the specification. This can be omitted if you want the same behavior as row or column because normal is the initial value.
When setting the direction to reverse, the main flexbox axis is flipped. This means that when using a left-to-right writing system, the items will display from right to left when row-reverse is specified. Similarly, column-reverse will lay out flex items from bottom to top, instead of top to bottom.
The old version of the specification also has writing mode-independent values for box-orient. When using a left-to-write writing system, horizontal may be substituted for inline-axis, and vertical may be substituted for block-axis. If you are using a top-to-bottom writing system, such as those traditional in East Asia, then these values would be flipped.
| Specification | Property name | No wrapping | Wrapping | Reversed wrap |
| Standard | flex-wrap |
nowrap |
wrap |
wrap-reverse |
| Mid | flex-wrap |
nowrap |
wrap |
wrap-reverse |
| Old | box-lines |
single |
multiple |
N/A |
The wrap-reverse value flips the start and end of the cross-axis, so that if flex items are laid out horizontally, instead of items wrapping onto a new line below, they will wrap onto a new line above.
At the time of writing, Firefox does not support the flex-wrap or older box-lines property. It also doesn’t support the shorthand.
The current specification has a flex-flow shorthand, which controls both wrapping and direction. The behavior is the same as the one in the version of the specification implemented by IE 10. It is also currently not supported by Firefox, so I would recommend to avoid using it when specifying only the flex-direction value.
Well, that’s a (flex-)wrap. In this article, I’ve introduced some of the myriad of possibilities afforded by flexbox. Be it source-order independence, flexible sizing or just the humble centering of elements, I’m sure you can find ways to employ flexbox in your websites and applications. The syntax has settled down (finally!), and implementations are here. All major browsers now support flexbox in at least their latest versions.
While some browsers use an older syntax, Firefox looks like it is close to updating, and IE 11 uses the latest version in leaked Windows Blue builds. There is currently no word on Safari, but it is a no-brainer considering that Chrome had the latest syntax before the Blink-WebKit split. For the time being, use the tables above to map the various syntaxes, and get your flex on.
Layout in CSS is only getting more powerful, and flexbox is one of the first steps out of the quagmire we’ve found ourselves in over the years, first with table-based layouts, then float-based layouts. IE 10 already supports an early draft of the Grid layout specification, which is great for page layout, and Regions and Exclusions will revolutionize how we handle content flow and layout.
Flexbox can be used today if you only need to support relatively modern browsers or can provide a fallback, and in the not too distant future, all sorts of options will be available, so that we can use the best tool for the job. Flexbox is shaping up to be a mighty fine tool.
(al)
© David Storey for Smashing Magazine, 2013.
In case you haven’t heard, Mike Jeffries is a jerk. A big one. Robin Lewis was recently quoted claiming Jeffries, CEO of Abercrombie & Fitch, “doesn’t want larger people shopping in his store, he wants thin and beautiful people. He doesn’t want his core customers to see people who aren’t as hot as them wearing his clothing. People who wear his clothing should feel like they’re one of the â€cool kids’.”
So, Jeffries basically wants to hang a sign in front of every Abercrombie & Fitch store that reads: “No Fat Chicks”.
Twitter is still aflutter with girls and guys claiming they’ll never, ever, ever shop there. Here’s the thing though: Jeffries is a jerk, but it doesn’t matter. Like, at all.
In fact, here are some things that matter more than the fact that Jeffries is a jerk:
1. What you ate for breakfast this morning.
2. How long it will be before Lindsay Lohan gets locked up again.
3. Your high score on Fruit Ninja.
If anything, the fact that Jeffries is a jerk is going to do wonders for the brand.
Do I think what Jeffries has said in the past about plus size women is offensive? Yes. Do I think he’s overcompensating for some deep-seated high school insecurities? Definitely. Do I think he’s a fantastic marketer? Hell yes.
Here’s a universal truth: As a marketer, you need to know your audience. And Jeffries definitely knows his audience. He wants good looking, skinny, popular people wearing his clothes (in case you missed that the first time).
“In every school there are the cool and popular kids, and then there are the not-so-cool kids. Candidly, we go after the cool kids. We go after the attractive, all-American kid with a great attitude and a lot of friends. A lot of people don’t belong, and they can’t belong. Are we exclusionary? Absolutely.” ~Mike Jeffries
Tell me something I don’t know, Internet. Here are some equally shocking revelations:
1. Chanel is a fashion brand for rich people.
2. Addition Elle is for plus size women.
3. Axe markets primarily to men.
The only difference is Chanel, Addition Elle, and Axe don’t come right out and say it. Or, at least not in the polarizing way Jeffries has. What matters is that Jeffries has an opinion.
It’s not an opinion everyone agrees with, but it’s one those popular, attractive, skinny teenagers agree with. And that’s his audience. Wake up! He doesn’t care that people who have never shopped at Abercrombie & Fitch are vowing to never, ever, ever shop there.
He cares that he’s empowering those popular, attractive, skinny teenagers. He’s focused on the people who belong (and the people who want to belong). Everything else is just free press.
This is what all marketers need to be doing. We need to have real opinions (and we can’t apologize for them like Groupon). We need to make statements that will resonate with our audiences… even if they will alienate others (ahem, Chick-Fil-A). Don’t be afraid of the controversy that will arise from having an opinion – it’s worth it.
It’s hard to make a brand relatable. Big executives invest millions in marketing teams that can help make their brands relatable to as many audiences as possible. Jeffries is pulling us in a different direction, a better direction.
We need to be more like Mike Jeffries (Yeah, I said it). Stop trying to be relatable to everyone. Focus! Work on being relatable to one audience. Skinny people, overweight people, men, women, rich people, poor people, smart people, dumb people, black people, white people – whatever.
“Those companies that are in trouble are trying to target everybody: young, old, fat, skinny. But then you become totally vanilla. You don’t alienate anybody, but you don’t excite anybody, either.” ~Mike Jeffries
If you do it right, you’ll create some controversy. You’ll alienate people. You’ll even piss some people off. You might be slammed by Kirstie Alley. And that’s ok. In fact, it’s a good thing. Because if you’re alienating someone, you’re simultaneously telling someone else that they belong.
You have to alienate to create a sense of belonging. You have to alienate to excite your customers. It’s only when you risk being polarizing that you can be truly relatable.
“I don’t know the key to success, but the key to failure is trying to please everybody.” ~Bill Cosby
Looking for an SEO service that won’t get you banned?

A few weeks ago, I needed my post-lunch coffee. I made my way over to our fancy La Marzocco espresso machine and ran into my colleague, Cass, a data scientist and engineer at MailChimp.
While Cass and I have been in the same meetings before, we seldom cross paths. We’re on different teams, housed on different floors of the same building.
This was good timing: I was tasked with rethinking a user pathway through our application, and Cass could provide some influential data.
Running into him saved me from having to write a detailed email, or—worse—forgetting his input entirely.
Our interaction was not a happy accident so much as a desired outcome. The espresso machine is a magnet, parlaying an ingrained habit into a bit of social engineering. My chat with Cass was just...read more
By Gregg Bernstein
A vanity URL is a search engine optimized (SEO) URL. Instead of having a meaningless URL like http://storeofthefuture.com/products/2015 wouldn’t http://storeofthefuture.com/products/hoverboard be better and more meaningful?
It’s fairly straightforward to make URLs nicer in Rails. I’ll walk you through the process.
In Rails the models have a method called to_param. This method gets called when you pass a model into a URL helper like:
<%= link_to product.name, product %>
Or:
<%= link_to product.name, product_path(product) %>
By default the to_param returns the id as a String rather than a Fixnum. Under the hood Rails is calling to_s on the id attribute, which allows us to override this with our own string. To do this we define the to_param method.
class Product < ActiveRecord::Base
attr_accessible :description, :name
def to_param
end
end
Within the to_param method, let’s set a string with the id followed by the name separated with a dash.
class Product < ActiveRecord::Base
attr_accessible :description, :name
def to_param
"#{id}-#{name}"
end
end
This would generate a URL of /products/2015-Hoverboard for a product with the name of “Hoverboard”.
Now what happens in the show action in the ProductsController? The params[:id] is the String of “2015-Hoverboard” and when you do a Product.find(params[:id]) the find method calls to_i. In Ruby when you call to_i on a String it grabs the first part of the String that looks like an integer. So Product.find("2015-Hoverboard") is exactly the same as calling Product.find(2015).
However, there’s an issue with names that contain a space. For example, a product with the name of “Flux Capacitor” would generate /1955-Flux%20Capacitor/, which isn’t very friendly. We should format the names so that we get them all lowercase and replace the spaces with dashes.
We can do that by creating a method called slug. The word slug describes the part of a URL that is made up of human-readable keywords.
class Product < ActiveRecord::Base
attr_accessible :description, :name
def slug
name.downcase.gsub(" ", "-")
end
def to_param
"#{id}-#{slug}"
end
end
So as you can see we just downcase the name and then gsub out the spaces with a dash and then swap the name with slug in the to_param.
So now the URLs are /2015-hoverboard and /1955-flux-capacitor.
Much nicer.
Now we’ve done only a little bit of work and haven’t altered the database or the controller. Let’s say we wanted to ditch the ids completely from the URLs.
We’ll do this by generating a new attribute called slug, and then manually or programmatically update all the existing products to have a slug.
We’ll first need to create and run the migration.
rails g migration AddSlugToProducts slug:string
rake db:migrate
Then update your model to have :slug as an attr_accessible and validate its presence while ditching the slug method from the previous implementation. We can also just return the slug in the to_param method like this:
class Product < ActiveRecord::Base
attr_accessible :description, :name, :slug
validates_presence_of :slug
def to_param
slug
end
end
Next fire up your rails console and cycle through each product and update the slug in each existing product.
>> Product.all.each do |product|
?> product.slug = product.name.downcase.gsub(" ", "-")
>> product.save
>> end
Now that we’ve done that, we need to modify the controller. The find method looks up products by the id, so for all instances in your controller where you find(params[:id]) on the @product you’d want to find_by_slug(params[:id]). This is because the :id is defined in the routes.rb, not because it is the :id of the object.
$ rake routes
...
product GET /products/:id(.:format) products#show
...
So in the show action in the ProductsController is should look something like this:
def show
@product = Product.find_by_slug(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @product }
end
end
Depending on how you’re using the model in other actions in your controller, you may need update those too.
You’ll also want to update any forms to include a slug field as this is now required to generate a new model. It’s required because without it you won’t be able to generate a URL or find any existing models.
This implementation of creating clear, human-readable and friendly URLs will yield the urls /products/hoverboard and /products/flux-capacitor, which is exactly what we wanted!
The id column of databases are normally indexed, if not the first things to be checked and indexed when performance issues occur. Finding by id is a fast method for looking them up. However if you have lots of models it may be worth adding an index on the slug to improve performance.
Here’s what you’d add to a migration:
add_index :products, :slug
Depending on how clean you want your URLs, or how much effort you want to go in to cleaning up existing URLs, either one of these strategies will work for you.
The post Creating Vanity URLs in Rails appeared first on Treehouse Blog.
In this episode of The Treehouse Show, Nick Pettit (@nickrp) and Jason Seifer (@jseifer) talk about iTunes Scrolling and Mobile Shelving.
Quick ‘n dirty iTunes 11 style scroller – CodePen
http://codepen.io/vaskemaskine/pen/DrdJE
jQuery.Shapeshift
http://mcpants.github.io/jquery.shapeshift/
Packery
http://packery.metafizzy.co/
Pure CSS Peeling Sticky – CodePen
http://codepen.io/patrickkunka/pen/axEgL
Package Managers: An Introductory Guide For The Uninitiated Front-End Developer – Tech.Pro
http://tech.pro/tutorial/1190/package-managers-an-introductory-guide-for-the-uninitiated-front-end-developer
Niice. A search engine with taste.
http://www.niice.co/
jakiestfu/Snap.js · GitHub
http://github.com/jakiestfu/Snap.js/
The post iTunes Scrolling and Mobile Shelving – Treehouse Show Ep 40 appeared first on Treehouse Blog.
Everyone is talking about mobile. Some e-commerce websites are venturing into it. Mobile commerce (also known as “m-commerce”) has immense potential, exhibiting a 86% growth rate and hitting $25 billion in 2012 (set to reach $86 billion by 2016, according to eMarketer).
It’s also a whole new platform, with new interaction methods and usage contexts that introduce a host of limitations and pitfalls to watch out for when designing and running an m-commerce website. With few best practices yet established, m-commerce is, to a large degree, unchartered territory when it comes to actual implementation.
This is why we decided to invest the better part of a year at Baymard Institute to conduct a large-scale usability study focusing specifically on m-commerce (following the “think aloud” protocol). We set out to explore the entire mobile shopping experience, including users’ conceptual understanding of m-commerce websites and how users interact with form fields, category navigation, search, product pages, the checkout process, etc.
The 18 m-commerce websites that we tested were: 1-800-Flowers, Amazon, Avis, Best Buy, Buy.com, Coastal.com, Enterprise.com, Fandango, Foot Locker, FTD, GAP, H&M, Macy’s, REI, Southwest Airlines, Toys “R” Us, United Airlines, Walmart.
Despite testing the mobile websites of some of the largest e-commerce players in the world, our subjects encountered 1,000+ usability-related issues during the testing sessions. These usability issues have been analyzed and distilled into 147 design recommendations in a report titled “M-Commerce Usability.” In this article, we’ll share 10 recommendations from that report with you.
While following some of the guidelines would improve the usability of desktop websites, too, there is a major difference in the severity of breaking them. Whereas these guidelines are largely “nice improvements” on desktop, they are among the “vital basics” to get right on an m-commerce website. Thus, most of these usability guidelines are not exclusive to mobile, but they are much more critical to get right in the m-commerce context.
Issue: When users are not able to get an overview of the entire website by quickly scanning the home page, they will feel less confident with the website and often end up choosing the wrong path for their task.
70% of the test subjects scrolled up and down the entire page when first landing on a home page or a category list, in what most described as “getting an overview of my options.” These subjects wanted to see their options before deciding which to choose. Even when they knew how they wanted to find a given product, some subjects still chose to get an overview of the home page, presumably to get a better feel for the website on which they were going to shop. In some instances, when a subject found the category they were looking for, they continued to look through one or two other categories to get a better sense of the other options on the website.

Most subjects scanned the whole home page to get an overview of their options and to better understand what they could do on a particular website. Here, one subject continued to explore the home page options, even after having found his desired navigation path of “category” → “men.”
Therefore, making the home page easily scannable is important because this will be the first point of contact for a very large portion of your mobile visitors. This initial impression will have a significant impact on the types of products they expect your website to carry and, just as importantly, not carry. While “easily scannable” might sound a bit vague, three instances of “what not to do” became clear during testing.
Avoid the confusing eye path that results from placing multiple highly graphical elements that demand attention high up on the home page. This was the case on Macy’s, where approximately 60% of the first viewable part of the home page is plastered with highly graphical content, with at least eight different elements calling for attention:

Multiple subjects were overwhelmed by Macy’s home page because it was very difficult to scan. As one subject expressed it, “I’m desperately trying to get an overview here. There’s so much crap being shoved at my face.” The right-hand image shows typical eye fixations.
This is not to say you cannot have graphics — but limit their size if they are above the fold on the home page, and design them to have a clear eye path.
Another mistake is unnecessarily hiding the category navigation. Some websites have a single “browse categories” option, which takes the user to a new page with the first layer of category choices. If you have a website where the user cannot browse with any method other than category and search (i.e. not by “brand” or “store” directly from the home page) and the number of main category options is of a somewhat manageable size, then this is an oversimplification. Instead, show the first level of category options directly on the home page so that users can start scanning the list immediately upon landing on the home page.

On the left: On Coastal.com, all the category options are displayed directly on the home page, which not only allows direct access, but gives users an accurate idea of the types of products they can expect to find on the website. For stores with multiple ways of browsing the catalog (e.g. by both “category” and “brand”), displaying the category options directly on the home page might not be feasible. On the right: For stores with a very high number of first-layer categories (typically mass merchants), a curated list with the most popular options might prove to be a better option, because displaying all categories would impede scannability.
Moreover, do not present the categories in a drop-down dialog. Multiple subjects explicitly stated that they had to scroll through the entire list to choose the category in which they expected to find a particular product. The problem with a drop-down quickly became clear, then: because it takes up only 50% of the available screen, getting an overview of the available categories became needlessly difficult (see Best Buy below).
Because the gesture area is also only half the size, the subjects also had a much harder time accurately controlling the scrolling speed. Lastly, the drop-down interface element was confused with a filter selection by some subjects and not recognized as the main website category navigation.

Do not follow the example of Best Buy, which does not have a category option in the main body of its home page content. Instead, a “three bars” icon takes the place of a category option in the page’s header. This not only requires all users to understand the meaning of the three bars icon, but also makes it impossible to get an overview of the store by scanning the home page. And, of course, using a drop-down to actually select a category is not ideal either.
Finally, do not design your website to have perfect alignment or white space exactly at the fold. This happens on GAP’s website, where it is easy to doubt whether the home page contains more than a search field and a few graphics (i.e. no category navigation), because these home page elements align precisely with the viewport fold (on an iPhone at least).

One subject, a bit surprised, asked, “This is it? This is the entire page?” believing this was GAP’s entire home page. When elements are spaced with pixel-perfection alignment around the viewport fold, users are more likely to misinterpret the top part as being the entire home page (in this case, missing out on the category navigation below).
To indicate more content, simply align the elements so that some are only partly viewable within the viewport on the most popular mobile devices.
Therefore, when designing a scannable home page:
Issue: Typing on mobile devices is clumsy, so users are constantly worried about losing their inputted data.
“Argh, no! Do I have to start over? Now I’m getting angry. Doesn’t it have my shit already?,” a subject moaned, referring to his previously typed address and credit-card information, which suddenly disappeared. “Now I’m leaving. This isn’t a serious store.”
Data persistence is not something to take lightly. Your users certainly don’t. Of course, the recommendation is simple: always persist the user’s data, which requires investing in solid technology, testing thoroughly, and storing inputted data temporarily on the user’s device (most mobile browsers support localStorage). In practice, of course, this is easier said than done, and numerous websites have failed miserably, to the great frustration of users.
Because users have already suffered through many horrible experiences of lost data, they often exhibit extreme caution around certain types of elements and avoid certain interactions when possible. The following screenshot shows the types of actions and elements that particularly worry users. Either avoid these elements altogether or soothe users’ fear with the smart use of microcopy, icons and animations.
During checkout, the subjects consistently opened links in a new window because they were afraid their data would be lost if they opened links in the current window.
Subjects were almost always disturbed by unexpected page reloading (i.e. any page reloading that is not a direct consequence of clicking a link or button). In the image above, a subject selected a “Residence type,” which reloaded the page, causing the subject to immediately scroll up and down to ensure that none of their data was lost. We observed this type of unease with page reloading among subjects time and again throughout testing.
Many subjects were scared by system dialogs and often assumed that they would lose data by clicking “OK,” even though few of them actually read the message. The subject in the test shown above wanted to go backwards in the process to pick another ticket but was met with this dialog, which he cancelled — assuming that he would have to re-enter everything if he wanted to select another ticket.
A good number of the subjects believed that leaving the checkout process would destroy their data and so refused to go back and check for other products. The subject in the test above contemplated going back to find another bouquet of flowers, but decided against it because he did not want to re-enter all of his data. This happened despite many of the test websites actually remembering the users’ details, even if the users left the checkout process midway — the keyword, of course, being “many” websites, rather than “all.” Given this inconsistency, users have no way to know beforehand, so their only safe choice is to just assume the worst on all websites.
During checkout, the “back” button was generally perceived by the subjects to be dangerous, and subjects used it during checkout only when they felt they were out of all other options. In many cases, this perception was justified: numerous websites did indeed fail to persist the user’s data when they used the “back” button. However, equally important is that process step links and other “back” links and buttons that were part of the website’s UI were generally considered by the subjects to be “safe.”
Therefore, including either process steps or “back” links in the checkout is crucial so that users do not feel they have to gamble by using the browser’s “back” button and can instead use your website’s dedicated UI element(s) for the purpose. In the test shown above, the subject hunted up and down to find a link or button that would take him back to the previous step, but was unable to find one. Finally, he tried the browser’s “back” button.
These were the most significant insights relating to users’ fear of lost input. In general, the subjects were vastly more pessimistic about websites on which they had once lost data. For example, clicking the keyboard’s “next” button cleared one subject’s input on a website, which made her consistently avoid that button throughout the rest of the checkout. As she said, “Here, I don’t dare click â€Next’ anymore because I don’t want to start over again.” Not only that, the subject also became overly cautious when interacting with any fields on the website, fearing that even the slightest hiccup would destroy her data.
A single bad experience set low expectations for the rest of the website. So, how do we avoid bad experiences in cases where we are unable to persist the user’s data due to technical limitations? In these instances, clearly warn the user that they are about to do something destructive.

As the subject left the incomplete checkout, the website warned her that her data would be lost. “This is very good,” the subject remarked, “because if I did something wrong by accident, I would be extremely annoyed if they deleted everything. So, it’s good that they warn me like this if the data would otherwise be lost.”
Persisting data is always the ideal, of course, but warning the user and giving them the option to back out before destroying their data is a good secondary solution, and it sure beats simply destroying the user’s data without warning; moreover, it gives the user a chance to cancel the destructive action. This type of fallback solution could be especially useful for less common navigation paths, where persistent data is too time-consuming to implement, considering how few users it affects.
This could also entail something like persisting the user’s cart or checkout data when switching between the full website and mobile website. In these instances, it is acceptable to simply warn the user that they will lose their data if they proceed, and then give them the option to proceed (and lose their data) or stay (and keep their data).
Data persistence is clearly a complex matter, especially when one considers the user’s expectations towards data persistence. We observed subjects creating accounts merely to ensure persistence, and witnessed data lost due to accidental clicks, and we watched with as much surprise as the subject when an entire form was remembered perfectly by autofill, turning potentially horrible data loss into a small moment of joy. Data persistence is tricky, but getting it right is crucial.
Issue: Users are likely to misinterpret cart buttons in the page’s footer if there is no “Add to Cart” button at the bottom of every product page.
A wide range of the tested websites had multiple identical primary call-to-action (CTA) buttons on product pages (i.e. two “Add to Cart” buttons), one at either the top or middle of the product page and a second one at the bottom.

On Best Buy, one subject read this product’s entire specification sheet and was in the mindset of “Yes, this is the product I want to purchase.” He saw the website’s shopping-cart icon at the bottom of the page (second image above) and clicked it, believing it was an “Add to Cart” button. Logically, he assumed the product would be added to his cart and so continued browsing for more products, only to notice much later in the shopping session that the website had “deleted” his cart’s contents (the TV was never added in the first place).

The subject here on Amazon thought the shopping-cart icon was the button for adding the displayed product to her cart.
It turned out that on the websites with only one CTA button on a product page, subjects often ran into severe problems even with adding a product to their cart — which, in some cases, ultimately led to abandonments. Cart icons in the page’s header or footer were often mistaken for an “Add to Cart” button.
Both Best Buy and Amazon failed to make the primary buttons immediately obvious and generally available, which led subjects to start interpreting various icons on the page, including the cart icon, as shown in the two examples above. Subjects often scrolled to the bottom of a product’s page when looking for the “Add to Cart” button (a behavior confirmed in another study).

This subject started looking for the “Add to cart” button by scrolling to the bottom of the page, then scrolling back to the top of the page, thinking she might have missed it, and finally scrolling down again patiently, until finding the “Add to bag” button in the middle of the page.
To accommodate this behavior and reduce misinterpretation of any cart icons, add a second “Add to Cart” button to the bottom of all of your product pages. A second button there will also support a more natural interaction flow, as the user first reads the product description, then the specification sheet, then the reviews and so on, and then, at the end of the page, decides whether to buy or not. Only if the product page is extremely short (one to two mobile viewports tall) would a single button suffice.
Issue:Â Users fail to discover vital features that appear only in a carousel, and they have a hard time interacting with carousels themselves.
Animated carousels caused interaction problems for half of the test’s subjects. The carousels simply changed too quickly for some subjects to both read and select an option.

A subject was about to click the “Mega Sale” slide (left image), but the carousel animated to the next slide at the very same moment, forcing the subject to wait for that slide to reappear.
In multiple instances, a subject found a carousel slide interesting and attempted to tap it. However, the carousel changed to the next slide at the very same moment, causing the wrong slide to load. Sometimes the subjects noted this, but sometimes they did not and left the landing page immediately because they did not find it relevant to what they were looking for.
Interestingly, the “Prev” and “Next” buttons in the Toys “R” Us carousel were not used by a single subject during testing, despite these issues:

The carousel changed the very second this subject tapped it, registering a click for “Bike Blast” instead of the “Mega Sale” she wanted. The subject never noticed and assumed that “Bike Blast” was the sale.
Both of these interaction issues were also encountered (and still exist) in the early versions of carousels on full websites, but as carousels have become increasingly popular on e-commerce home pages over the last several of years, they have evolved, so most now stop animating when the user hovers over an option with the mouse.
And most also have an indicator that enables the user to see how many slides a carousel has and, just as importantly, to jump to a particular slide (such as back to the one that piqued their interest but changed too quickly). These interaction issues cannot be easily solved on mobile because there is no hover state and much less screen real estate.

On Toys “R” Us’ home page, the subjects pored over the menus to find a “Gift Guide” wizard but could not find one (image on left). It turns out there is a wizard but is accessible only via a particular slide in the rotating carousel at the top of the page.
Perhaps an even more critical usability issue is that most test subjects simply ignored the carousel after quickly glancing at the first slide. Some waited and looked at two to three slides before focusing elsewhere. This proved critical on some websites, such as Toys “R” Us’, because the majority of subjects were desperately looking in the traditional navigation for certain features (such as the “Gift Finder”) that were accessible only via the carousel. Some subjects spoke at length about how the website really should have some sort of “gift guide,” ultimately abandoning the website because they could not find one.
Users ignore animated carousels for multiple reasons. First, a carousel’s content might look like advertising, depending on how it is styled, greatly increasing the chance of banner blindness (a subgroup of subjects tended to focus much more closely on text-based navigation than on graphics-based navigation). Secondly, when using a large laptop or desktop monitor to browse a full website, the user is able to check out other options on the home page while still glancing at the carousel slides as they change.
On mobile devices, however, the screen is so small that a carousel would take up a significant portion of the viewport, making it practically impossible to scan any navigation or category options while monitoring the carousel slides (one of them will always be partly or completely out of sight). Therefore, if users are to see all options in a carousel on a mobile device, they will have to watch the carousel for its full duration (like a video clip).
Regardless of the cause(s), what is really important is that the vast majority of subjects ignored the animated carousels completely and, on the home page, focused instead on the category navigation and search features. For this reason, be very cautious about relying on carousels for important content, and never have it as the only path to a particular feature.
Issue: Users have incredible difficulty understanding the scope of product subpages.
On a mobile device, understanding the scope of the current page is vastly more difficult for users, due to the very small display. Mobile pages often lack the subtle yet vital page-scope cues that are present on full-size pages, such as a full set of breadcrumbs, an overview of the current page, and full URL paths viewable throughout the browsing session.
This lack of scope on mobile makes having any kind of substeps or subpages that refer to a main page very risky, because the user would have to fully understand the scope of the current page in order to appreciate the difference between the subpage and main page.

When users want to see larger versions of images of an Amazon product (left), they are taken to a subpage (middle). Our test subjects clearly noticed that they were still within a product’s particular scope (because of the large product image), but they did not understand where the rest of the product page went (right).
This became immediately apparent when testing websites that offer a “larger view” option of their images, taking users to a separate product subpage, as seen on Amazon above. Because of the apparent lack of access to vital content, such as “Product Description,” “Product Specs” and “User Reviews” (which are available only on the main product page), the subjects who did not notice this change in scope assumed that such content simply did not exist for the given product and continued looking for other products with such information, discarding perfectly matching ones.

Amazon also uses subpages to show full specification lists, causing the exact same issue, except that this time subjects were unable to locate something as vital as the “Add to Cart” button.
On a mobile device, and especially on subpages, understanding the current scope is simply much more difficult. Instead, display your “larger views,” image galleries, detailed specification sheets and the like (i.e. all relevant content) directly on the product’s main page. You could also use progressive disclosure by collapsing each content section by default, to avoid overly long pages; but then be sure to have clear trigger indicators. A strategy such as this minimizes the need to display additional information and images on subpages and the resulting scope issues.
Especially with image galleries, you also have the option of an overlay, as shown above on Foot Locker. With an overlay, the user can still see the product page beneath and have a simple way to get back to it.
Issue: Users had difficulty figuring out how to initiate “Guest Checkout” and understanding field relationships, selection options and buttons in the account-selection steps.
On mobile, the user’s selection of a checkout type — “create an account,” “sign into account” or “guest checkout” — will be a separate step (unlike on full websites, where it could be integrated into the first step). More than half of the test subjects (60%) had serious trouble identifying, seeing and selecting the guest-checkout option at the account selection step during checkout.
Multiple times, the misunderstandings led subjects to believe that registration was required, despite it being optional, and carried all of the downsides of forced account registration (including abandonments). Therefore, the design of your account-selection screen for mobile is just as important as having a guest-checkout option at all.
Several different design schemes led to these serious misunderstandings, as the following screenshots illustrate.
On Macy’s, subjects saw the account-selection step (above left) after selecting the cart. Some clicked “Express Checkout,” believing they would have a fast checkout (as a guest), only to get form-field validation errors for the two fields because “Express Checkout” requires a Macy’s account (above center). Some only discovered the “Checkout as a Guest” option further down the page (right), after getting this validation error, while others never noticed the guest-checkout option and registered for an account, believing it was required.
On multiple websites (Amazon, Toys “R” Us, REI, GAP, Best Buy), subjects started to interact with the fields, such as by providing their email address (above). On REI, every single subject interacted with the email field before looking for, or figuring out that there was, a guest-checkout option.
In most cases, the subjects spotted the error before submitting the form (typically upon reaching the password field and deducing that they were on an account sign-in or creation form). In such cases, not even detailed analysis of your Web statistics and error logs would reveal these issues because no validation error ever occurs.
On Buy.com, things are even worse. The vast majority of subjects simply could not figure out the relationship between the four checkout methods (sign-in, create account, guest checkout and PayPal checkout), the two form fields, the three radio buttons and the two primary buttons. All tapped the “Checkout as a Guest” option after spending some time trying to understand the page.
Then, the naming of the “Sign in Using Our Secure Server” button utterly confused subjects because they were trying to check out as a guest (and, therefore, actively opted not to sign into anything). This particular naming has been used by Amazon for years and has even been highlighted as a best practice to indicate a secure checkout, so how could it lead to such major misinterpretation?
The reason is that it indicates the user will sign in, which makes sense only if they have an account or will create one, but not if they are checking out as a guest. (Amazon does not offer a guest-checkout option, so the wording makes sense in that context.) Given the button’s name, one subject assumed that the only other prominent button on the page, “Checkout with PayPal,” must be the one to pick to initiate the “Checkout as a guest” selection.
Others finally clicked the oddly named button — but nothing seemed to happen. It turns out that inline text reading “Required” appeared next to the “Enter your eMail Address” label (seen above), but no one noticed it initially. The subjects typically waited for a little while just in case the website did not load, and then clicked again, at which point most realized that they needed to fill in more data. By this point, some, especially those who did not notice the validation error, concluded that they were not allowed to check out as a guest and proceeded to create an account instead.
One explained his experience thusly, “Normally I would think â€guest checkout’ would let me through without having to create an account. But here I have to fill in my mail, so I have no idea what that option is for, then. To be on the safe side, I’ll then pick the â€No, I’m a new customer,’ because if I’m forced to create an account, I might as well just do it properly anyways.”
Making the account-selection process clear is as important as offering a guest checkout option. Following two main design principles will help to prevent these serious problems:
Below, we have created a simple mockup to illustrate how account selection can be clarified by combining these two principles:

All three account-selection options are displayed in collapsed state (with guest checkout at the top), so that the user can instantly see all available options. The options can either expand inline (image on right) or redirect to the next step in the checkout process. Progressive disclosure also makes the relationship between an option and its fields much clearer.
Issue:Â Poor autocorrection is frustrating when users notice it, and can be detrimental when they do not.
Autocorrection usually works poorly for abbreviations, street names, email addresses and similar words that are not in the dictionary. This caused significant problems throughout testing and resulted in a great deal of erroneous data being submitted as subjects completed their purchases.

When this subject typed in his street name, “westheimer,” the phone incorrectly autocorrected this to “weathermen” (left). However, the subject did not notice this, submitted the form and received a validation error (right).
One of the major issues of autocorrection was that the subjects often failed to notice the correction (because they were often focused on what they were typing, instead of what they had typed). This is fine if the “correction” is correct, but it can be detrimental if it is wrong. For example, in multiple instances, a valid address was autocorrected to an invalid one and submitted because the subject failed to notice it.
On websites without address validators, this resulted in wrong addresses being submitted, unless the subject was particularly attentive on the order review page. After all, the user’s address will often be replaced with something that looks very similar, although incorrect. In addition to the “weathermen” example, official address abbreviations, such as “Rd,” were autocorrected, to “Ed.”
That being said, autocorrection did prove very helpful when it worked. So, don’t disable it in all fields. Use it discreetly, and disable it on fields for which autocorrection dictionaries are weak. This typically includes names of various sorts (street, city, user) and other identifiers (such as email address).
You can disable autocorrection by adding an autocorrect attribute to the input tag and setting it to off, like so:
<input type="text" autocorrect="off" />
Issue:Â Users cannot easily spot errors, let alone correct them, when the field is too short to display the entire inputted data.
Due to the small size of mobile screens, form fields often get so short that users cannot self-validate before submitting their data, and users have a very difficult time correcting any validation errors because they cannot see the inputted data in its entirety.

“I can’t see what I’ve typed. Argh. Then I’ll delete everything and retype it.” On REI, a validation error for an email field that was too short to be displayed in its entirety made it impossible for the subject to see what the actual error was. In trying to pan the inputted text, the subject accidentally enabled both the iOS text-selection tool and the text-replacement tool.
Form fields that are too short presented problems for many subjects who tried to confirm the validity of their data before submitting it. They often made complaints such as, “I can’t see if the emails are the same when the email field isn’t long enough.” Some examples are seen below.

On the left: Amazon’s email field is too short, despite the abundance of white space. In the middle: United’s credit-card field shows only 15 characters, even though most card numbers are 16 digits. On the right: Macy’s email fields are too short for users to verify whether the two addresses they’ve inputted match.
Given how easy it is to make a typing mistake on a mobile device, fields that are not long enough to allow users to validate their data before submission are very harmful to the typing experience. Even worse, they make correcting any validation errors unnecessarily difficult.
Note that in the case of Amazon and the earlier example from REI, the white space is sufficient to make the field much longer, while the other two examples have no additional space to make the fields longer because the labels are all left-aligned. For this very reason, labels should be placed above form fields to allow full use of the space and to display all of the user’s data (at a decent font size). Displaying labels to the left of the fields would be acceptable only when the device is in landscape mode (as explained in detail in “Mobile Form Usability: Place Labels Above the Field”).
An adequate width for email and address lines is the full screen. Then, adjust the font size of the fields to allow for the full display of reasonably long data, such as first.lastname@my-company.com. (The character-length distribution of our own newsletter list shows that 96% of email addresses are 30 characters or fewer.)
Issue:Â Using text fields for dates requires unnecessary mental processing of the user and can cause serious selection errors.
During testing, websites that had only a simple text field or drop-down dialog for date selection presented problems for 80% of the subjects.

This subject was among the 80% who were unsure which date “this Friday” was. So, she decided to count the days on her hand, wanting to make sure she picked the right one.
This happened with both Southwest (which uses drop-downs for the month and day) and United (which shows a text field for writing MM/DD/YYYY). On both of these websites, the following scenarios occurred:
Half of the subjects went off-site and opened the phone’s native calendar app to double-check the date for their weekend trip (to confirm “this Friday”). In the instance seen above, this calendar verification goes completely awry because the subject checked the day of June 15th, instead of July 15th, and ended up purchasing a flight ticket for his “weekend” trip that left on a Sunday and returned on a Tuesday.
Lastly, a few struggled with typing and using the text-selection tool to enter the correct date on a website that uses a text field for date selection.
By contrast, on the three test websites that provided a graphical interface for inputting dates in the form of a calendar view (namely, Enterprise, Avis and 1-800-Flowers, seen above), not a single one of these issues arose, and the subjects generally liked being able to verify the day and date they were selecting. This could potentially save customers from incorrectly counting or “verifying” the wrong weekday (as mentioned earlier) and thus booking the wrong date.
While this is an annoyance on desktop as well (since the user would be no better equipped to spot the errors there), the severity and impact on the user’s experience is much greater in mobile when it comes to correcting the erroneous data, because panning and editing truncated data on a three- or four-inch touchscreen is much more cumbersome than using a mouse or keyboard arrows on a desktop. Furthermore, ordering tickets on the wrong day is much less likely on the desktop because the booking form and a separate calendar application can be displayed next to each other — whereas on mobile, only one can be viewed at a time.
Therefore, always provide an interface that enables users to verify the day of their selected date. One option is to display a calendar interface in which the user explicitly selects the date they want. That would simplify the actual selection interface and, more importantly, gives users a chance to verify the day. If you already use a drop-down for date inputs and do not want to replace it, you could instead append the day after each date option (for example, “March 15 – Monday”); although that would require the month to be included in each drop-down day value or, in case a separate drop-down is used to select the month, you would need to dynamically update the day names depending on the currently selected month.
Issue:Â With some lists, users simply have no idea where to tap in order to select an item.
Can the entire “element” be tapped? Or only the product title? And what about the thumbnail? During testing, multiple issues arose as subjects were unsure of where to tap in order to select an item in a list. This was by far the worst on websites where list items were above the recommended half-screen height. In fact, one subject got completely stuck and was unable to complete her purchase.
The problem was by no means limited to websites with list items that were too tall; it was just worse on those websites. The issue also extended to websites whose list items were normal in size but whose hit areas were unclear, which severely limited the subjects and even resulted in abandonments.

It simply was not clear to subjects what can and cannot be clicked on this page. Note the very inconsistent link styles. Orange is sometimes used for the header, other times for a list item. Separators are sometimes used to set off list items, other times to set off elements of text. Some text is one shade of blue, which sometimes indicates a link, while other links are styled in a darker blue and underlined. Confused yet? The subjects were, too.

Note how the subject was trying to click the “Lowest Fare” label, believing this was the button to choose the displayed flight. Besides the primary button being unclear, the list item is also very long. Combined, these two design choices are a surefire way to leave some users in doubt on how to even proceed.

On the left: This subject did not know what to click in order to proceed on United’s website. Presumably, this was caused by the single result. With no options to compare and choose between, it was not clear to the subject what to select. On the right: Many subjects did not pick up on the ticket icon and its meaning on Fandango’s website. Instead, they assumed that the movie was playing only in theaters where a “Buy” button was shown (which was not the case).
The images above show only some of the many instances where it was unclear to subjects what elements are clickable, what the differences are between the different hit areas and, most importantly, where to click in order to select an item in a list. The websites with the far fewest problems with hit areas embraced multiple of the following recommendations:
Aside from their practical use, these 10 recommendations have hopefully given you a glimpse of just how complex designing an m-commerce website really can be. It’s not simply a matter scaling and adding media queries; it’s an entirely new platform, and the balancing act is particularly difficult to get right due to the complex tasks involved, such as product finding and product comparison and multi-step processes such as checking out. In many ways, designing and optimizing an m-commerce website is much more difficult and often requires more “intelligent” website features than a traditional desktop e-commerce website. It comes as no surprise that IBM reports average m-commerce conversion rates that are roughly half of its desktop e-commerce conversion rates.
In general, the more complex a mobile website’s features, the more likely the experience should be significantly different from the desktop experience. The greater the difference between the two, the stronger the argument for having a standalone mobile website. Of course, maintaining two versions of the same website comes with many issues, especially with maintenance (of content, code and design). A responsive design is a better solution in some cases, but it depends very much on the size and complexity of the website, as well as on your organization’s strengths and weaknesses. It’s a nuanced issue, with many gray areas and with good arguments both for and against having a standalone mobile website.
If you can achieve this by designing for mobile first, then a responsive design could be truly great — not just in its maintainability, but also its user experience. Be clear, however, that if your existing website is complex, merely scaling it down to different devices won’t be enough to offer a great mobile experience. And if messing with the full website’s existing structure and content isn’t an option, then you might be forced to create a standalone mobile website in order to provide a decent experience — although maintaining content and code on the two separate platforms in parallel could turn out to be both expensive and messy.
Thus, getting an m-commerce website right tends to be very resource-demanding, as you account for all of the nuances. But the opportunities are great. This is a new world, and it will take time before best practices stabilize. Spending time and money on a mediocre m-commerce website is wasteful. Yes, making the website great will require significant investment, but the potential payoff is high, too. M-commerce is a window of opportunity; it enables you to distinguish yourself from competitors and to position yourself well to grab a share of this market, which is expected to reach $86 billion by 2016.
Note: Find out more about m-commerce usability guidelines in the (paid) report “M-Commerce Usability.”
(al) (il)
© Christian Holst for Smashing Magazine, 2013.
Not that anyone shops at Barnes and Nobles anymore but I just saw on my create space account that they have picked up a large amount of inventory to stock at select locations around the country.
This is really interesting news cause 2 months ago when we hit the 30,000 Â copies sold mark I was approached by a publisher who told me the only way to get into traditional book stores was to invest $40,000.00 for renting the “shelf space”. Â He said that these traditional book stores take zero risk now days unless they know they can make money on a book.
So lol… Â Not sure if they think they can make money on it or if that was just total BS.
Looking for an SEO service that won’t get you banned?
Great design is a product of care and attention applied to areas that matter, resulting in a useful, understandable, and hopefully beautiful user interface. But don’t be fooled into thinking that design is left only for designers.
There is a lot of design in code, and I don’t mean code that builds the user interface—I mean the design of code.
Well-designed code is much easier to maintain, optimize, and extend, making for more efficient developers. That means more focus and energy can be spent on building great things, which makes everyone happy—users, developers, and stakeholders.
There are three high-level, language-agnostic aspects to code design that are particularly important.
In looser languages, specifically JavaScript, it takes a bit of discipline to write well-designed code. The JavaScript environment is so forgiving that it’s easy to throw bits and pieces everywhere and still have things work. Establishing system architecture early (and sticking to it!) provides constraints to your codebase, ensuring consistency throughout.
One approach I’m fond of consists of a tried-and-true software design pattern, the module pattern, whose extensible structure lends itself to a solid system architecture and a maintainable codebase. I like building modules within a jQuery plugin, which makes for beautiful reusability, provides robust options, and exposes a well-crafted API.
Below, I’ll walk through how to craft your code into well-organized components that can be reused in projects to come.
There are a lot of design patterns out there, and equally as many resources on them. Addy Osmani wrote an amazing (free!) book on design patterns in JavaScript, which I highly recommend to developers of all levels.
The module pattern is a simple structural foundation that can help keep your code clean and organized. A “module” is just a standard object literal containing methods and properties, and that simplicity is the best thing about this pattern: even someone unfamiliar with traditional software design patterns would be able to look at the code and instantly understand how it works.
In applications that use this pattern, each component gets its own distinct module. For example, to build autocomplete functionality, you’d create a module for the textfield and a module for the results list. These two modules would work together, but the textfield code wouldn’t touch the results list code, and vice versa.
That decoupling of components is why the module pattern is great for building solid system architecture. Relationships within the application are well-defined; anything related to the textfield is managed by the textfield module, not strewn throughout the codebase—resulting in clear code.
Another benefit of module-based organization is that it is inherently maintainable. Modules can be improved and optimized independently without affecting any other part of the application.
I used the module pattern for the basic structure of jPanelMenu, the jQuery plugin I built for off-canvas menu systems. I’ll use that as an example to illustrate the process of building a module.
To begin, I define three methods and a property that are used to manage the interactions of the menu system.
var jpm = {
animated: true,
openMenu: function( ) {
…
this.setMenuStyle( );
},
closeMenu: function( ) {
…
this.setMenuStyle( );
},
setMenuStyle: function( ) { … }
};
The idea is to break down code into the smallest, most reusable bits possible. I could have written just one toggleMenu( ) method, but creating distinct openMenu( ) and closeMenu( ) methods provides more control and reusability within the module.
Notice that calls to module methods and properties from within the module itself (such as the calls to setMenuStyle( )) are prefixed with the this keyword—that’s how modules access their own members.
That’s the basic structure of a module. You can continue to add methods and properties as needed, but it doesn’t get any more complex than that. After the structural foundations are in place, the reusability layer—options and an exposed API—can be built on top.
The third aspect of well-designed code is probably the most crucial: reusability. This section comes with a caveat. While there are obviously ways to build and implement reusable components in raw JavaScript (we’re about 90 percent of the way there with our module above), I prefer to build jQuery plugins for more complex things, for a few reasons.
Most importantly, it’s a form of unobtrusive communication. If you used jQuery to build a component, you should make that obvious to those implementing it. Building the component as a jQuery plugin is a great way to say that jQuery is required.
In addition, the implementation code will be consistent with the rest of the jQuery-based project code. That’s good for aesthetic reasons, but it also means (to an extent) that developers can predict how to interact with the plugin without too much research. Just one more way to build a better developer interface.
Before you begin building a jQuery plugin, ensure that the plugin does not conflict with other JavaScript libraries using the $ notation. That’s a lot simpler than it sounds—just wrap your plugin code like so:
(function($) {
// jQuery plugin code here
})(jQuery);
Next, we set up our plugin and drop our previously built module code inside. A plugin is just a method defined on the jQuery ($) object.
(function($) {
$.jPanelMenu = function( ) {
var jpm = {
animated: true,
openMenu: function( ) {
…
this.setMenuStyle( );
},
closeMenu: function( ) {
…
this.setMenuStyle( );
},
setMenuStyle: function( ) { … }
};
};
})(jQuery);
All it takes to use the plugin is a call to the function you just created.
var jpm = $.jPanelMenu( );
Options are essential to any truly reusable plugin because they allow for customizations to each implementation. Every project brings with it a slew of design styles, interaction types, and content structures. Customizable options help ensure that you can adapt the plugin to fit within those project constraints.
It’s best practice to provide good default values for your options. The easiest way to do that is to use jQuery’s $.extend( ) method, which accepts (at least) two arguments.
As the first argument of $.extend( ), define an object with all available options and their default values. As the second argument, pass through the passed-in options. This will merge the two objects, overriding the defaults with any passed-in options.
(function($) {
$.jPanelMenu = function(options) {
var jpm = {
options: $.extend({
'animated': true,
'duration': 500,
'direction': 'left'
}, options),
openMenu: function( ) {
…
this.setMenuStyle( );
},
closeMenu: function( ) {
…
this.setMenuStyle( );
},
setMenuStyle: function( ) { … }
};
};
})(jQuery);
Beyond providing good defaults, options become almost self-documenting—someone can look at the code and see all of the available options immediately.
Expose as many options as is feasible. The customization will help in future implementations, and flexibility never hurts.
Options are terrific ways to customize how a plugin works. An API, on the other hand, enables extensions to the plugin’s functionality by exposing methods and properties for the implementation code to take advantage of.
While it’s great to expose as much as possible through an API, the outside world shouldn’t have access to all internal methods and properties. Ideally, you should expose only the elements that will be used.
In our example, the exposed API should include calls to open and close the menu, but nothing else. The internal setMenuStyle( ) method runs when the menu opens and closes, but the public doesn’t need access to it.
To expose an API, return an object with any desired methods and properties at the end of the plugin code. You can even map returned methods and properties to those within the module code—this is where the beautiful organization of the module pattern really shines.
(function($) {
$.jPanelMenu = function(options) {
var jpm = {
options: $.extend({
'animated': true,
'duration': 500,
'direction': 'left'
}, options),
openMenu: function( ) {
…
this.setMenuStyle( );
},
closeMenu: function( ) {
…
this.setMenuStyle( );
},
setMenuStyle: function( ) { … }
};
return {
open: jpm.openMenu,
close: jpm.closeMenu,
someComplexMethod: function( ) { … }
};
};
})(jQuery);
API methods and properties will be available through the object returned from the plugin initialization.
var jpm = $.jPanelMenu({
duration: 1000,
…
});
jpm.open( );
With just a few simple constructs and guidelines, we’ve built ourselves a reusable, extensible plugin that will help make our lives easier. Like any part of what we do, experiment with this structure to see if it works for you, your team, and your workflow.
Whenever I find myself building something with a potential for reuse, I break it out into a module-based jQuery plugin. The best part about this approach is that it forces you to use—and test—the code you write. By using something as you build it, you’ll quickly identify strengths, discover shortcomings, and plan changes.
This process leads to battle-tested code ready for open-source contributions, or to be sold and distributed. I’ve released my (mostly) polished plugins as open-source projects on GitHub.
Even if you aren’t building something to be released in the wild, it’s still important to think about the design of your code. Your future self will thank you.
We’ve all been there: that bit of JavaScript functionality that started out as just a handful of lines grows to a dozen, then two dozen, then more. Along the way, a function picks up a few more arguments; a conditional picks up a few more conditions. And then one day, the bug report comes in: something’s broken, and it’s up to us to untangle the mess.
As we ask our client-side code to take on more and more responsibilities—indeed, whole applications are living largely in the browser these days—two things are becoming clear. One, we can’t just point and click our way through testing that things are working as we expect; automated tests are key to having confidence in our code. Two, we’re probably going to have to change how we write our code in order to make it possible to write tests.
Really, we need to change how we code? Yes—because even if we know that automated tests are a good thing, most of us are probably only able to write integration tests right now. Integration tests are valuable because they focus on how the pieces of an application work together, but what they don’t do is tell us whether individual units of functionality are behaving as expected.
That’s where unit testing comes in. And we’ll have a very hard time writing unit tests until we start writing testable JavaScript.
Writing integration tests is usually fairly straightforward: we simply write code that describes how a user interacts with our app, and what the user should expect to see as she does. Selenium is a popular tool for automating browsers. Capybara for Ruby makes it easy to talk to Selenium, and there are plenty of tools for other languages, too.
Here’s an integration test for a portion of a search app:
def test_search
fill_in('q', :with => 'cat')
find('.btn').click
assert( find('#results li').has_content?('cat'), 'Search results are shown' )
assert( page.has_no_selector?('#results li.no-results'), 'No results is not shown' )
end
Whereas an integration test is interested in a user’s interaction with an app, a unit test is narrowly focused on a small piece of code:
When I call a function with a certain input, do I receive the expected output?
Apps that are written in a traditional procedural style can be very difficult to unit test—and difficult to maintain, debug, and extend, too. But if we write our code with our future unit testing needs in mind, we will not only find that writing the tests becomes more straightforward than we might have expected, but also that we’ll simply write better code, too.
To see what I’m talking about, let’s take a look at a simple search app:

When a user enters a search term, the app sends an XHR to the server for the corresponding data. When the server responds with the data, formatted as JSON, the app takes that data and displays it on the page, using client-side templating. A user can click on a search result to indicate that he “likes” it; when this happens, the name of the person he liked is added to the “Liked” list on the right-hand side.
A “traditional” JavaScript implementation of this app might look like this:
var tmplCache = {};
function loadTemplate (name) {
if (!tmplCache[name]) {
tmplCache[name] = $.get('/templates/' + name);
}
return tmplCache[name];
}
$(function () {
var resultsList = $('#results');
var liked = $('#liked');
var pending = false;
$('#searchForm').on('submit', function (e) {
e.preventDefault();
if (pending) { return; }
var form = $(this);
var query = $.trim( form.find('input[name="q"]').val() );
if (!query) { return; }
pending = true;
$.ajax('/data/search.json', {
data : { q: query },
dataType : 'json',
success : function (data) {
loadTemplate('people-detailed.tmpl').then(function (t) {
var tmpl = _.template(t);
resultsList.html( tmpl({ people : data.results }) );
pending = false;
});
}
});
$('<li>', {
'class' : 'pending',
html : 'Searching …'
}).appendTo( resultsList.empty() );
});
resultsList.on('click', '.like', function (e) {
e.preventDefault();
var name = $(this).closest('li').find('h2').text();
liked.find('.no-results').remove();
$('<li>', { text: name }).appendTo(liked);
});
});
My friend Adam Sontag calls this Choose Your Own Adventure code—on any given line, we might be dealing with presentation, or data, or user interaction, or application state. Who knows! It’s easy enough to write integration tests for this kind of code, but it’s hard to test individual units of functionality.
What makes it hard? Four things:
$(document).ready() callback, and then in anonymous functions that can’t be tested because they aren’t exposed.pending is in a closure, there’s no way to test whether the pending state is set correctly.$.ajax success handler shouldn’t need direct access to the DOM.The first step toward solving this is to take a less tangled approach to our code, breaking it up into a few different areas of responsibility:
In the “traditional” implementation shown above, these four categories are intermingled—on one line we’re dealing with presentation, and two lines later we might be communicating with the server.

While we can absolutely write integration tests for this code—and we should!—writing unit tests for it is pretty difficult. In our functional tests, we can make assertions such as “when a user searches for something, she should see the appropriate results,” but we can’t get much more specific. If something goes wrong, we’ll have to track down exactly where it went wrong, and our functional tests won’t help much with that.
If we rethink how we write our code, though, we can write unit tests that will give us better insight into where things went wrong, and also help us end up with code that’s easier to reuse, maintain, and extend.
Our new code will follow a few guiding principles:
To start with, we need to figure out how we’ll break our application into different pieces. We’ll have three pieces dedicated to presentation and interaction: the Search Form, the Search Results, and the Likes Box.

We’ll also have a piece dedicated to fetching data from the server and a piece dedicated to gluing everything together.
Let’s start by looking at one of the simplest pieces of our application: the Likes Box. In the original version of the app, this code was responsible for updating the Likes Box:
var liked = $('#liked');

var resultsList = $('#results');



// ...



resultsList.on('click', '.like', function (e) {
e.preventDefault();

var name = $(this).closest('li').find('h2').text();

liked.find( '.no-results' ).remove();

$('<li>', { text: name }).appendTo(liked);

});
The Search Results piece is completely intertwined with the Likes Box piece and needs to know a lot about its markup. A much better and more testable approach would be to create a Likes Box object that’s responsible for manipulating the DOM related to the Likes Box:
var Likes = function (el) {
this.el = $(el);
return this;
};
Likes.prototype.add = function (name) {
this.el.find('.no-results').remove();
$('<li>', { text: name }).appendTo(this.el);
};
This code provides a constructor function that creates a new instance of a Likes Box. The instance that’s created has an .add() method, which we can use to add new results. We can write a couple of tests to prove that it works:
var ul;
setup(function(){
ul = $('<ul><li class="no-results"></li></ul>');
});
test('constructor', function () {
var l = new Likes(ul);
assert(l);
});
test('adding a name', function () {
var l = new Likes(ul);
l.add('Brendan Eich');
assert.equal(ul.find('li').length, 1);
assert.equal(ul.find('li').first().html(), 'Brendan Eich');
assert.equal(ul.find('li.no-results').length, 0);
});
Not so hard, is it? Here we’re using Mocha as the test framework, and Chai as the assertion library. Mocha provides the test and setup functions; Chai provides assert. There are plenty of other test frameworks and assertion libraries to choose from, but for the sake of an introduction, I find these two work well. You should find the one that works best for you and your project—aside from Mocha, QUnit is popular, and Intern is a new framework that shows a lot of promise.
Our test code starts out by creating an element that we’ll use as the container for our Likes Box. Then, it runs two tests: one is a sanity check to make sure we can make a Likes Box; the other is a test to ensure that our .add() method has the desired effect. With these tests in place, we can safely refactor the code for our Likes Box, and be confident that we’ll know if we break anything.
Our new application code can now look like this:
var liked = new Likes('#liked');
var resultsList = $('#results');



// ...



resultsList.on('click', '.like', function (e) {
e.preventDefault();

var name = $(this).closest('li').find('h2').text();

liked.add(name);
});
The Search Results piece is more complex than the Likes Box, but let’s take a stab at refactoring that, too. Just as we created an .add() method on the Likes Box, we also want to create methods for interacting with the Search Results. We’ll want a way to add new results, as well as a way to “broadcast” to the rest of the app when things happen within the Search Results—for example, when someone likes a result.
var SearchResults = function (el) {
this.el = $(el);
this.el.on( 'click', '.btn.like', _.bind(this._handleClick, this) );
};
SearchResults.prototype.setResults = function (results) {
var templateRequest = $.get('people-detailed.tmpl');
templateRequest.then( _.bind(this._populate, this, results) );
};
SearchResults.prototype._handleClick = function (evt) {
var name = $(evt.target).closest('li.result').attr('data-name');
$(document).trigger('like', [ name ]);
};
SearchResults.prototype._populate = function (results, tmpl) {
var html = _.template(tmpl, { people: results });
this.el.html(html);
};
Now, our old app code for managing the interaction between Search Results and the Likes Box could look like this:
var liked = new Likes('#liked');
var resultsList = new SearchResults('#results');



// ...



$(document).on('like', function (evt, name) {
liked.add(name);
})
It’s much simpler and less entangled, because we’re using the document as a global message bus, and passing messages through it so individual components don’t need to know about each other. (Note that in a real app, we’d use something like Backbone or the RSVP library to manage events. We’re just triggering on document to keep things simple here.) We’re also hiding all the dirty work—such as finding the name of the person who was liked—inside the Search Results object, rather than having it muddy up our application code. The best part: we can now write tests to prove that our Search Results object works as we expect:
var ul;
var data = [ /* fake data here */ ];
setup(function () {
ul = $('<ul><li class="no-results"></li></ul>');
});
test('constructor', function () {
var sr = new SearchResults(ul);
assert(sr);
});
test('display received results', function () {
var sr = new SearchResults(ul);
sr.setResults(data);
assert.equal(ul.find('.no-results').length, 0);
assert.equal(ul.find('li.result').length, data.length);
assert.equal(
ul.find('li.result').first().attr('data-name'),
data[0].name
);
});
test('announce likes', function() {
var sr = new SearchResults(ul);
var flag;
var spy = function () {
flag = [].slice.call(arguments);
};
sr.setResults(data);
$(document).on('like', spy);
ul.find('li').first().find('.like.btn').click();
assert(flag, 'event handler called');
assert.equal(flag[1], data[0].name, 'event handler receives data' );
});
The interaction with the server is another interesting piece to consider. The original code included a direct $.ajax() request, and the callback interacted directly with the DOM:
$.ajax('/data/search.json', {
data : { q: query },
dataType : 'json',
success : function( data ) {
loadTemplate('people-detailed.tmpl').then(function(t) {
var tmpl = _.template( t );
resultsList.html( tmpl({ people : data.results }) );
pending = false;
});
}
});
Again, this is difficult to write a unit test for, because so many different things are happening in just a few lines of code. We can restructure the data portion of our application as an object of its own:
var SearchData = function () { };
SearchData.prototype.fetch = function (query) {
var dfd;
if (!query) {
dfd = $.Deferred();
dfd.resolve([]);
return dfd.promise();
}
return $.ajax( '/data/search.json', {
data : { q: query },
dataType : 'json'
}).pipe(function( resp ) {
return resp.results;
});
};
Now, we can change our code for getting the results onto the page:
var resultsList = new SearchResults('#results');

var searchData = new SearchData();
// ...
searchData.fetch(query).then(resultsList.setResults);
Again, we’ve dramatically simplified our application code, and isolated the complexity within the Search Data object, rather than having it live in our main application code. We’ve also made our search interface testable, though there are a couple caveats to bear in mind when testing code that interacts with the server.
The first is that we don’t want to actually interact with the server—to do so would be to reenter the world of integration tests, and because we’re responsible developers, we already have tests that ensure the server does the right thing, right? Instead, we want to “mock” the interaction with the server, which we can do using the Sinon library. The second caveat is that we should also test non-ideal paths, such as an empty query.
test('constructor', function () {
var sd = new SearchData();
assert(sd);
});
suite('fetch', function () {
var xhr, requests;
setup(function () {
requests = [];
xhr = sinon.useFakeXMLHttpRequest();
xhr.onCreate = function (req) {
requests.push(req);
};
});
teardown(function () {
xhr.restore();
});
test('fetches from correct URL', function () {
var sd = new SearchData();
sd.fetch('cat');
assert.equal(requests[0].url, '/data/search.json?q=cat');
});
test('returns a promise', function () {
var sd = new SearchData();
var req = sd.fetch('cat');
assert.isFunction(req.then);
});
test('no request if no query', function () {
var sd = new SearchData();
var req = sd.fetch();
assert.equal(requests.length, 0);
});
test('return a promise even if no query', function () {
var sd = new SearchData();
var req = sd.fetch();
assert.isFunction( req.then );
});
test('no query promise resolves with empty array', function () {
var sd = new SearchData();
var req = sd.fetch();
var spy = sinon.spy();
req.then(spy);
assert.deepEqual(spy.args[0][0], []);
});
test('returns contents of results property of the response', function () {
var sd = new SearchData();
var req = sd.fetch('cat');
var spy = sinon.spy();
requests[0].respond(
200, { 'Content-type': 'text/json' },
JSON.stringify({ results: [ 1, 2, 3 ] })
);
req.then(spy);
assert.deepEqual(spy.args[0][0], [ 1, 2, 3 ]);
});
});
For the sake of brevity, I’ve left out the refactoring of the Search Form, and also simplified some of the other refactorings and tests, but you can see a finished version of the app here if you’re interested.
When we’re done rewriting our application using testable JavaScript patterns, we end up with something much cleaner than what we started with:
$(function() {
var pending = false;
var searchForm = new SearchForm('#searchForm');
var searchResults = new SearchResults('#results');
var likes = new Likes('#liked');
var searchData = new SearchData();
$(document).on('search', function (event, query) {
if (pending) { return; }
pending = true;
searchData.fetch(query).then(function (results) {
searchResults.setResults(results);
pending = false;
});
searchResults.pending();
});
$(document).on('like', function (evt, name) {
likes.add(name);
});
});
Even more important than our much cleaner application code, though, is the fact that we end up with a codebase that is thoroughly tested. That means we can safely refactor it and add to it without the fear of breaking things. We can even write new tests as we find new issues, and then write the code that makes those tests pass.
It’s easy to look at all of this and say, “Wait, you want me to write more code to do the same job?”
The thing is, there are a few inescapable facts of life about Making Things On The Internet. You will spend time designing an approach to a problem. You will test your solution, whether by clicking around in a browser, writing automated tests, or—shudder—letting your users do your testing for you in production. You will make changes to your code, and other people will use your code. Finally: there will be bugs, no matter how many tests you write.
The thing about testing is that while it might require a bit more time at the outset, it really does save time in the long run. You’ll be patting yourself on the back the first time a test you wrote catches a bug before it finds its way into production. You’ll be grateful, too, when you have a system in place that can prove that your bug fix really does fix a bug that slips through.
This article just scratches the surface of JavaScript testing, but if you’d like to learn more, check out:
Tools
|
|
|
|
|
|
|
|
|
|
More »
| Home | Create a Website | About Us | Premium | Browse | News | Store | Contact Us | Terms of Service | Privacy Policy | ||
![]() |
© 2006-2013 DynamicDevelop LLC
|
|

