The influence of design is expanding beyond the realms of typography and objects and into healthcare, public policy, education, financial services, and more. Designers working in these emerging design fields are responsible for projects that have significant and fundamental impact on the quality of people’s lives with clear ethical implications.
In healthcare, for example, designers are responsible for creating everything from the industrial designer’s medical device that keeps a heart beating to the service designer’s physical layout of an operating room. Clinicians, with similar levels of influence, initiate their professional practice by swearing to follow the Hippocratic Oath. This sets specific boundaries that guide the ethics of their behavior. Designers, on the other hand, are given no guidance for ethical decision-making even as they continue to expand their influence into newer and riskier fields with long-standing moral implications.
Are designers talking about ethics in their practices? Do designers need or want ethical guidelines? Who should be involved in creating ethical guidelines for a design practice or project? Is there one code of ethics for all types of design and designers?
This article explores multiple interactive methods to create ethical guidelines with interdisciplinary teams using design.
Designing Healthcare Apps
As designers, we have the power to help millions of people live longer, healthier and happier lives. But a truly delightful and meaningful app doesn’t happen by magic.Read a related article →
Ethics In Design History
Small design groups have been exploring ethics in design through manifestos like First Things First in 1964 where Ken Garland focused on the responsibilities of designers working in advertising. In 2007, Valerie Casey’s Designer’s Accord project brought designers, educators, and business leaders together to define guidelines around environmental sustainability in design.
Later, in 2009, David Berman wrote the Do Good Pledge to encourage graphic designers to pledge ten percent of their professional time to “doing good” while simultaneously adhering to moral codes in their work. Unlike these existing manifestos, pledges and projects, we were interested in how designers might collaboratively create ethical guidelines for specific project engagements and teams.
With this rich history in mind, we set out to understand how designers thought about and used ethics in contemporary design. We spent a year asking interaction designers, service designers, game designers, graphic designers, industrial designers, and designers in the healthcare space if they were talking about ethics in their practices, trying to understand if designers felt the need for ethical guidelines and if so, how we could help designers develop them. We connected and engaged with 50 designers through an effort with the Service Design Network publication, BarnRaise (a design hackathon event in Chicago), and an IxDA conference workshop.
We had a few hypotheses about how ethics would work and about the ethical guidelines that we hoped to create:
Ethics were the personal responsibility of individuals
If we talked to enough people, we would be able to create a single code of ethics that would be applicable across design and
We would be able to create a replicable process to guide people in the creation of these ethical codes.
We conducted our exploration in three stages:
First stage: “Shifting Ethical Responsibilities From Individuals To Communities”
Second stage: “Creating Project-Specific Ethics”
Third stage: “Breaking Down Barriers Through Conversation”
Shifting Ethical Responsibilities From Individuals To Communities
As the year progressed, we learned that not all of these hypotheses were correct. We began our work by collaborating with Mad*Pow and the Service Design Network by inviting 15 designers from across the nation to each remotely rewrite one piece of the Modern Hippocratic Oath, the ethical guideline for medical doctors, to make it applicable to design.
We selected designers from different backgrounds (game design, graphic design, healthcare, and industrial design) to see if the essence of ethical responsibility was different across design disciplines. Each designer received a fill-in-the-blank template to express their individual ethical guidelines.
We stitched these 15 templates together to create three Designer’s Oaths. Each designer had been assigned one of five sections of the MHO to rewrite, so we placed the pieces back in the order of the original MHO. We had invited 15 designers to take part, so we were able to form three distinct Oaths. This process allowed us to showcase individual design voices as well as highlight their collective representation of a broader community. We formalized these templates and published them online to make the Designer’s Oath an open-sourced tool that anyone can use to document their individual or communal ethical guidelines.
It is important to stress the remote work that was done at this stage. None of these designers ever met face-to-face or had the opportunity to influence each other’s Oaths. We would learn the importance of in-person collaboration when we began to work with specific project groups. By nature, design is collaborative, so we needed to begin to think about how ethics could be created through collaboration rather than individual reflection.
Creating Project-Specific Ethics
The SDN experience helped us realize that we were asking the wrong questions about ethics in design. Ethics are not something one person decides for everyone in a community. In fact, different groups might require different types of ethics specific to their situation. How could we create a tool that teams could use to define the ethical guidelines of their collaboration?
Moving forward with this idea, we experimented with more open-ended tools and conversation prompts. We wanted to give teams of people coming from different backgrounds the flexibility to create their ethical guidelines without a template. We were able to explore this concept at BarnRaise, an interactive conference/hackathon for social impact design. We led a multidisciplinary team through the entire design process from research to prototyping in one weekend. We kicked off the experience by facilitating and documenting a conversation with our team to define their ethical guidelines as a collective. The conversation focused on how the team would work together and which responsibilities they collectively had for the people they were designing for.
We began by sharing the Hippocratic Oath to spark our team thinking about what a code of ethics might look like. The conversation followed about the community that we would be working with and how we, a design team, should understand our relationship with them. We then focused on answering questions like, “What approach do we want to adapt to address this problem? What is the spirit with which we want to address this problem? What role does the community play in understanding and addressing the problem?”
Through these conversations we crafted an oath that outlined their ethical guidelines as a team specific to their project work over the next few days (see below). This document framed the space they were working in, the methodologies they would use, and the mindset they needed to accomplish this task.
The team, called “Team Neuron Sparks”, referenced their oath throughout the design process. They had been tasked with answering the question, “How might we support stroke prevention by empowering community leaders to educate community members on the South side of Chicago?” The team’s oath heavily influenced their design process, guiding the manner in which they conducted interviews with community leaders and leading them to perform a participatory design exercise.
The oath also kept the team focused on understanding the community members holistically in the context of their lives. It helped them maintain their commitment to conducting interviews with humility and with respect for the dignity of the community. In the end, they created a prototype of an orientation kit for community leaders considering spearheading stroke prevention and a digital app that allowed them to coordinate their efforts. These prototypes have been adopted by the team’s clinician lead who is continuing to iterate on them with support from IIT + ID, the graduate school of design at Illinois Institute of Technology.
Ethics are not something that you decide on once and never revisit. Working with “Team Neuron Sparks” helped us realize how important it was to continue to talk about ethics throughout a project, not just at the beginning. Ethics are alive and must be iterative as our knowledge and position about a project grows and changes. With this in mind, we decided to focus the next effort of our journey on facilitating conversations around ethics.
Breaking Down Barriers Through Conversation
Conversation facilitation led us in an unexpected direction: game design. Our final ethical inquisition led us to create a role-playing game, Ethics Quest, which we play-tested at IxD16, in Helsinki. Ethics Quest encourages members of a multidisciplinary project team to role play through several ethical situations, each taking on a new role in the process. This empathy-building exercise removes the self from ethical conversations, lowering the barrier to entry and making participants more comfortable talking about difficult subjects.
The game gives players the opportunity to take on a role in a project team that they do not play in real life. We provide backstory, skills, and experience to help players get into character and understand how their role might perceive a situation. Players go through 3 different situations: solo, head to head, and cooperative so the player can ease into their character before taking on ethical situations (or “combat”) against another team member.
With Ethics Quest, we discovered that conversations between team members were the most powerful tool for changing the way people thought about ethics. Conversations about ethics are often difficult and awkward, but by framing these conversations within the “safe space” of a game, we were able to make things easy and even enjoyable. Ethics Quest also helped people empathize with the goals and perspectives of others which is an essential ingredient for a productive conversation. These realizations helped us shift our focus from creating tools that document ethical guidelines to focusing on the importance of ethical conversations. With this in mind, we are continuing to iterate on Ethics Quest, exploring new ways to incorporate it with project teams and design education.
What We Learned
At the end of our year of asking questions, we realized that our initial assumptions about ethics in contemporary design had not been correct.
General ethics for design cannot be created by a single entity.
Ethics are dynamic, a living breathing thing, unique to each team.
Ethics require care and attention from every member of a team to stay alive and relevant.
The only way that each team member can feel the personal ownership necessary to maintain a collective code is by taking part in thoughtful, reflective, and co-creative conversations designed to create and regularly breathe life into the team’s ethical guidelines.
This evolution in our understanding of ethics changed how we understood our role as designers. We shifted from seeing ourselves as creators of static ethical documentation to being the facilitators of conversations that would change the practice of design ethics. If we hope to change the function of ethics in our profession, then we must first change how we view our role in that process. We must become designers of conversations and find new ways for people to relate to and communicate with each other.
This shift is necessary not only to change the view of ethics within our profession but also to position designers to be catalysts for ethical change within our larger organizations. As designers, we have the opportunity to design conversations about ethics with every team we are a part of, influencing the perception of ethics in any organization wielding the power of design. Through these conversations, design can become a powerful tool for doing good.
Taking The Next Step
Take action by facilitating these conversations and empowering your teams to design ethically.
Start small and think about your own ethical guidelines first.
Consider any duties you believe you have as a designer. What or who do you stand for in your design work?
Write, draw, or find some other way you feel comfortable expressing and documenting your ethical guidelines.
Engage with your project team and invite them to think about their individual ethical guidelines.
Ask each individual team member to express and document their ethical guidelines. Consider how you might make this easier for people by co-opting an existing guideline by turning it into a fill-in-the-blank outline, prompting alternative ways of thinking by asking people to express themselves visually instead of verbally, or creating a safe space to talk about ethics by using gameful design.
Share and discuss with each other to understand and empathize with each team member’s ethical beliefs.
Facilitate a team discussion about how you might combine your individual ethical documents into one collective statement that is specific to your team’s problem space or current engagement.
Consider answering the following questions: what roles are represented by the group assembled? What roles are missing? Who are you designing for? What are the specific concerns and ethical ramifications of the problem space? How do you ensure ethical alignment and integrity of the project throughout the engagement? How might you invite “end users” to collaborate on these guidelines? How does your statement interact with other relevant professional codes?
Document your discussion by collectively crafting an ethical statement to guide your team’s decisions throughout your engagement.
What happens when we take the web browser out of web browsing? Google’s new “Add to Homescreen” feature delivers fast, focused web experiences that are indistinguishable from those of a native app. What can designers learn from the successes of early adopters such as Twitter, and how can we leverage app-like design patterns to tackle this brand new set of user experience challenges?
We’ve seen debates on the topic of native versus web experiences. Both have their pros and cons, but very often the biggest downside of the in-browser experience is that it doesn’t feel as reliable, fast and immersive as the native app experience.
In this article, we will cover tips and tricks for designing and developing progressive web applications (PWAs), specifically the ones that are added to the home screen on Android devices. But first, let’s see a couple of examples and make a case for PWAs.
From Web Apps To Desktop Apps
Did you know that you can add “desktop app developer” to your resumé with just a little more effort? All you need to do is look over some API documentation and create your first modern desktop app. Read a related article →
The Rise Of The App-Like Experience
PWAs are, simply put, websites that look and feel like native applications. In his talk at the Google I/O developer conference, Google’s VP of Product, Rahul Roy-Chowdhury, describes them as “a radically better web experience… which users love and are more engaged with.”
The numbers back up Rahul’s claims. Forbes has seen its user engagement double since the launch of its PWA. The numbers also continue to show growth in the e-commerce sector, with Lancôme seeing a large increase in conversion rates following the launch of its new PWA.
These kinds of fast, fluid, app-like mobile experiences are what users want and will come to expect as more PWAs emerge in the mainstream market. One feature that will seem to accelerate this wave is “Add to Homescreen,” which is basically a PWA installation process. For the end user, adding a PWA to the home screen kicks off that app-like experience.
What Is “Add To Homescreen,” And Is It Worth It?
“Add to Homescreen” is a feature that installs a PWA to Android’s home screen, making the PWA instantly accessible without the user needing to open a browser and type the URL or use a search engine. (Side note: Even though a similar feature has been available on iOS Safari since the earliest iPhones, users were not offered much to simulate the behavior of an app. For this reason, Safari’s version is not a part of this article.)
As reflected in Google’s Lighthouse checklist, PWAs with this capability score higher and, as a result, are likely to rank better in search results.
Take Twitter Lite, a PWA. Traditionally, Twitter has found it difficult to re-engage its millions of users on the mobile web. Since introducing the “Add to Homescreen” prompt to its Twitter Lite PWA, it is seeing 250,000 unique daily users launch the web app from the home screen at an average of four times a day.
The retail sector is also seeing success. Alibaba has reported a four-times higher interaction rate after users added the PWA to their device’s home screen, and Flipkart has seen a 70% increase in conversion rate among shoppers who arrived via the home-screen icon.
Although “Add to Homescreen”’s user base is limited to Android Chrome, the feature rewards this highly engaged minority with an immersive, more exclusive experience — a role traditionally played by native apps.
Aren’t Progressive Web Applications Just Websites Wrapped Up As Apps?
These are the kind of statistics that would lead any retailer down the path of native app development. However, with the average cost of a native app sitting at around $270,000, “Add to Homescreen” offers an attractive financial alternative.
Users couldn’t care less about whether a technology is native, an installed web app or a website. What makes users engage and makes shoppers convert is the experience itself:
Does it load quickly?
Does it work offline?
Is navigation instant?
Does it integrate seamlessly with the device?
These are the characteristics of app-like design that must be incorporated if “Add to Homescreen” is to deliver the kind of high engagement statistics commonly associated with native apps.
What Makes An Experience App-Like?
“Add to Homescreen” creates an experience focused solely on the app in question. The website is launched via an app icon, without the browser’s URL bar or any navigation toolbar that would otherwise offer links to external websites.
It’s a good starting point, but we must also recognize and meet certain expectations of native app users if the experience is to feel truly app-like, including:
instant page transitions;
high perceived performance;
offline accessibility;
full device integration;
app-style navigation;
back button;
sharing action;
copy URL, print, and go forward.
Ready to dive in? Let’s look at each one.
Instant Page Transitions
Users expect to be able to get in and around an app quickly, without waiting for new content to load after each interaction.
Solved With PWA
For a PWA to pass the Lighthouse checklist, it must follow certain performance-enhancing guidelines. Content must be cached behind the scenes, and new pages must load so quickly that it feels like there was no loading event.
Perceived Performance
Amazingly, the level of stress caused by mobile delays is comparable to that of watching a horror movie! Users who download an app do not expect to have to wait for their content. Nor are they willing to suffer a disjointed experience caused by elements appearing asynchronously as they load.
Solved With PWA
The “Add to Homescreen” PWA launch transition (see Flipkart example below) provides a visual bridge between loading and loaded content. This is an example of how “preloaded states” can enhance the perception of speed and seamlessness. A well-designed PWA will build on this idea by using placeholders (skeletons) that mimic the end state of the page and by using lazy-loading to deprioritize elements that are out of view, making the initial loading seem faster.
Works Offline
Users who download native apps do not expect to have to rely on an Internet connection in order for the apps to function properly.
Solved With PWA
Service workers (a technology that improves the offline experience) can be used to instantly display online content in areas of low or no connectivity. Page content is cached behind the scenes, allowing it to be accessed where there would otherwise be a lag in the browsing experience, such as when entering a tunnel on a train.
Full Device Integration
There are certain locations on a device where users expect to find and manage their apps.
PWA Solution
PWAs added to the home screen now show up anywhere you’d expect an Android app to show up. This includes the app launcher, task switcher and system settings. This also ensures that any other app that links to a page on the PWA, such as a Google search or social media link, will open the app and not the browser. Push notifications even appear as if they come from a native app.
App-Style Navigation
Apps share a common approach to navigation. The header bar typically shows the title of the current section in the center; the back button is in the top left; and any contextual actions (favoriting, sharing, etc.) are in the top right.
No PWA Solution, Yet
This pattern is not common on the mobile web. Instead, these actions are found in the browser’s built-in functionality (for example, the browser’s back button). The web works this way for a reason. An app will typically start from the same screen each time, whereas mobile web users are often referred from search or social media — any page can be their landing page. For this reason, the logo and other global actions take center stage in the header bar and remain there throughout the experience.
This expectation must be addressed if PWAs with “Add to Homescreen” are to really feel like apps. In order to do this, designers must figure out how to recover key navigation patterns now lost with the browser.
Back Button
Some might argue that because Android provides a back button through the device itself, then there is no need to replace the browser’s back functionality. In fact, the two interactions do different things. Most apps continue to offer a back button in the header as an “up” action, to navigate within the hierarchical relationship between pages. The system’s back functionality might close a modal window or navigate to a different app entirely.
Solution
One possible solution is to replace the menu button in the top left with a back button once the user progresses past the initial page. This was validated when we put this pattern in front of users. Once participants had progressed through the initial home page (and a menu icon was no longer visible), we asked them to navigate to a new section. Six out of six intuitively used the back button to navigate to the home page, where they could open the menu.
Sharing Action
Built into the user interface of any web browser is the ability to share a page on social media and through other apps installed on the device.
Solution
Designers should provide more prompts to share commonly shared content within the page. We found during testing that users will typically look for sharing buttons around the page’s head or product image before opening any menus. If the functionality was not found, participants expected to find a sharing icon in the header bar.
The “More” icon is an Android-esque pattern used to indicate an overflow of options. Try adding the sharing action behind a menu like this. It is even possible to trigger Android’s native sharing dialog using the Web Share API (which, at the time of writing, is a Chrome-only feature and still not standards-tracked).
Copy URL, Print, Go Forward
Less common actions, such as copying the URL and printing, are basic functions of a browser and should not be overlooked.
Solution
An easy way to offer copy-URL and print functionality is by using the Web Share API (again, at the time of writing, supported only in Google Chrome). Alternatively, they can be presented as separate options in the overflow menu. This menu can then be extended to include the forward action or anything else that would benefit from a persistent location in the header bar (logging in and out, for example).
How To Make It Work In The Real World
It will take time for “Add to Homescreen” to develop into an accepted group of patterns. Below are some best practices that could help in this development.
Sticky Headers, Persistent Actions
“Add to Homescreen” early adopters Flipkart and AliExpress both recognize the importance of learnability when introducing new patterns. They ensure that users always know where to find crucial global actions (back, cart, search): in a header bar that sticks to the top of the screen.
Prompt Intelligently
Since the Google Chrome team announced that it would be giving PWAs full control of when to prompt users, “Add to Homescreen” installations have increased. Flipkart saw a threefold increase in engagement when prompting users after they had made a purchase.
Stress and Test
Part of the validation process for any new pattern is to stress test it in multiple applications. We found that the pattern stood up well to the edgiest of edge cases. The header bar in Lancome’s PWA contains many calls to action. Lancome identified the overflow menu as a great opportunity to simplify its user interface, while offering exclusives to power users whom it expected to use “Add to Homescreen,” exclusives such as a link to its loyalty program.
Where Is “Add To Homescreen” Supported?
Apple has announced it will support service workers, but it has also made a commitment to making the App Store an attractive place for native app developers to spend their time and money. This could be the reason why iOS’ Safari browser has been slow to adopt PWAs and browserless web browsing, despite advances from competitors.
Samsung Internet browser has developed a persistent “Add to Homescreen” prompt within the browser bar, so that users always know where to find it.
Windows takes “Add to Homescreen” one step further. Any PWA with this ability will now be listed in the Windows Store as a downloadable app. These apps are light and can be installed on desktop and tablet devices quickly, running the websites as convenient, browserless experiences.
Conclusion
“Add to Homescreen” offers an immersive, exclusive experience to the highly engaged, converting user. While adoption grows, both in user base and the devices that support the feature, validation can be found in early success stories, such as Twitter Lite. These stories show how a more modern, app-like web can have a positive effect on engagement when it meets user expectations of performance and design.
These expectations are met by combining PWA performance enhancements with intuitive design patterns in navigation and app-like user experiences. With this, we can pave the way for a new era of browserless web browsing.
Editor’s Note: This article originally appeared on Inclusive Components. If you’d like to know more about similar inclusive component articles, follow @inclusicomps on Twitter or subscribe to the RSS feed. By supporting inclusive-components.design on Patreon, you can help to make it the most comprehensive database of robust interface components available.
Classification is hard. Take crabs, for example. Hermit crabs, porcelain crabs, and horseshoe crabs are not — taxonomically speaking — true crabs. But that doesn’t stop us using the “crab” suffix. It gets more confusing when, over time and thanks to a process called carcinisation, untrue crabs evolve to resemble true crabs more closely. This is the case with king crabs, which are believed to have been hermit crabs in the past. Imagine the size of their shells!
In design, we often make the same mistake of giving different things the same name. They appear similar, but appearances can be deceptive. This can have an unfortunate effect on the clarity of your component library. In terms of inclusion, it may also lead you to repurpose a semantically and behaviorally inappropriate component. Users will expect one thing and get another.
The term “dropdown” names a classic example. Lots of things “drop down” in interfaces, including the set of <option>s from a <select> element, and the JavaScript-revealed list of links that constitute a navigation submenu. Same name; quite different things. (Some people call these “pulldowns”, of course, but let’s not get into that.)
Dropdowns which constitute a set of options are often called “menus”, and I want to talk about these here. We shall be devising a true menu, but there’s plenty to be said about not-really-true menus along the way.
Let’s start with a quiz. Is the box of links hanging down from the navigation bar in the illustration a menu?
The answer is no, not a true menu.
It’s a longstanding convention that navigation schemas are composed of lists of links. A convention nearly as longstanding dictates that sub-navigation should be provided as nested lists of links. If I were to remove the CSS for the component illustrated above, I should see something like the following, except colored blue and in Times New Roman.
Semantically speaking, nested lists of links are correct in this context. Navigation systems are really tables of content and this is how tables of content are structured. The only thing that really makes us think “menu” is the styling of the nested lists and the way they are revealed on hover or focus.
That’s where some go wrong and start adding WAI-ARIA semantics: aria-haspopup="true", role="menu", role="menuitem" etc. There is a place for these, as we’ll cover, but not here. Here are two reasons why:
ARIA menus are not designated for navigation but for application behavior. Imagine the menu system for a desktop application.
The top-level link should be usable as a link, meaning it does not behave like a menu button.
Regarding (2): When traversing a navigation region with submenus, one would expect each submenu to appear upon hovering or focusing the “top level” link (“Shop” in the illustration). This both reveals the submenu and places its own links in focus order. With a little help from JavaScript capturing focus and blur events to persist the appearance of the submenus while needed, someone using the keyboard should be able to tab through each link of each tier, in turn.
Menu buttons which take the aria-haspopup="true" property do not behave like this. They are activated on click and have no other purpose than to reveal a secreted menu.
As pictured, whether that menu is open or closed should be communicated with aria-expanded. You should only change this state on click, not on focus. Users do not usually expect an explicit change of state on a mere focus event. In our navigation system, state doesn’t really change; it’s just a styling trick. Behaviorally, we can Tab through the navigation as if no such show/hide trickery were occurring.
The Problem With Navigation Submenus
Navigation submenus (or “dropdowns” to some) work well with a mouse or by keyboard, but they’re not so hot when it comes to touch. When you press the top-level “Shop” link in our example for the first time, you are telling it to both open the submenu and follow the link.
There are two possible resolutions here:
Prevent the default behavior of top-level links (e.preventDefault()) and script in full WAI-ARIA menu semantics and behavior.
Make sure each top-level destination page has a table of contents as an alternative to the submenu.
(1) is unsatisfactory because, as I noted previously, these kinds of semantics and behaviors are not expected in this context, where links are the subject controls. Plus users could no longer navigate to a top-level page, if it exists.
Sidenote: Which devices are touch devices?
It’s tempting to think, “this isn’t a great solution, but I’ll only add it for touch interfaces”. The problem is: how does one detect if a device has a touch screen?
You certainly shouldn’t equate “small screen” with “touch activated”. Having worked in the same office as folks making touch displays for museums, I can assure you that some of the largest screens around are touch screens. Dual keyboard and touch input laptops are becoming increasingly prolific too.
By the same token, many but not all smaller devices are touch devices. In inclusive design, you cannot afford to make assumptions.
Resolution (2) is more inclusive and robust in that it provides a “fallback” for users of all inputs. But the scare quotes around the fallback term here are quite deliberate because I actually think in-page tables of content are a superior way of providing navigation.
Tables of content are navigation for related pages or page sections and should be semantically similar to main site navigation regions, using a <nav> element, a list, and a group labeling mechanism.
<nav aria-labelledby="sections-heading"> <h2>Products</h2> <ul> <li><a href="http://www.smashingmagazine.com/products/dog-costumes">Dog costumes</a></li> <li><a href="http://www.smashingmagazine.com/products/waffle-irons">Waffle irons</a></li> <li><a href="http://www.smashingmagazine.com/products/magical-orbs">Magical orbs</a></li> </ul></nav><!-- each section, in order, here -->
Notes
In this example, we’re imagining that each section is its own page, as it would have been in the dropdown submenu.
It’s important that each of these “Shop” pages has the same structure, with this “Products” table of content present in the same place. Consistency supports understanding.
The list groups the items and enumerates them in assistive technology output, such as a screen reader’s synthetic voice.
The <nav> is recursively labeled by the heading using aria-labelledby. This means “products navigation” will be announced in most screen readers upon entering the region by Tab. It also means that “products navigation” will be itemized in screen reader element interfaces, from which users can navigate to regions directly.
All on one page
If you can fit all the sections onto one page without it becoming too long and arduous to scroll, even better. Just link to each section’s hash identifier. For example, href="#waffle-irons" should point to id="waffle-irons".
<nav aria-labelledby="sections-heading"> <h2>Products</h2> <ul> <li><a href="#dog-costumes">Dog costumes</a></li> <li><a href="#waffle-irons">Waffle irons</a></li> <li><a href="#magical-orbs">Magical orbs</a></li> </ul></nav><!-- dog costumes section here --><section tabindex="-1"><h2>Waffle Irons</h2></section><!-- magical orbs section here -->
(Note: Some browsers are poor at actually sending focus to linked page fragments. Placing tabindex="-1" on the target fragment fixes this.)
Where a site has a lot of content, a carefully constructed information architecture, expressed through the liberal use of tables of content “menus” is infinitely preferable to a precarious and unwieldy dropdown system. Not only is it easier to make responsive, and requires less code to do so, but it makes things clearer: where dropdown systems hide structure away, tables of content lay it bare.
Some sites, including the Government Digital Service’s gov.uk, include index (or “topic”) pages that are just tables of content. It’s such a powerful concept that the popular static site generator Hugo generates such pages by default.
Information architecture is a big part of inclusion. A badly organized site can be as technically compliant as you like, but will still alienate lots of users — especially those with cognitive impairments or those who are pressed for time.
Navigation Menu Buttons
While we’re on the subject of faux navigation-related menus, it’d be remiss of me not to talk about navigation menu buttons. You’ve almost certainly seen these denoted by a three-line “hamburger” or “navicon” icon.
Even with a pared down information architecture and only one tier of navigation links, space on small screens is at a premium. Hiding navigation behind a button means there’s more room for the main content in the viewport.
A navigation button is the closest thing we’ve studied so far to a true menu button. Since it has the purpose of toggling the availability of a menu on click, it should:
Identify itself as a button, not a link;
Identify the expanded or collapsed state of its corresponding menu (which, in strict terms, is just a list of links).
Progressive enhancement
But let’s not get ahead of ourselves. We ought to be mindful of progressive enhancement and consider how this would work without JavaScript.
In an unenhanced HTML document there’s not a lot you can do with buttons (except submit buttons but that’s not even closely related to what we want to achieve here). Instead, perhaps we should start with just a link which takes us to the navigation?
<a href="#navigation">navigation</a><!-- some content here perhaps --><nav> <ul> <li><a href="http://www.smashingmagazine.com/">Home</a></li> <li><a href="http://www.smashingmagazine.com/about">About</a></li> <li><a href="http://www.smashingmagazine.com/shop">Shop</a></li> <li><a href="http://www.smashingmagazine.com/content">Content</a></li> </ul></nav>
There’s not a lot of point in having the link unless there’s a lot of content between the link and the navigation. Since site navigation should almost always appear near the top of the source order, there’s no need. So, really, a navigation menu in the absence of JavaScript should just be… some navigation.
Some older browsers — you know which ones — don’t support hidden, so remember to put the following in your CSS. It fixes the problem because display: none has the same affect of hiding the menu from assistive technologies and removing the links from focus order.
[hidden] { display: none; }
Doing one’s best to support older software is, of course, an act of inclusive design. Some are unable or unwilling to upgrade.
Placement
Where a lot of people go wrong is by placing the button outside the region. This would mean screen reader users who move to the <nav> using a shortcut would find it to be empty, which isn’t very helpful. With the list hidden from screen readers, they’d just encounter this:
<nav></nav>
Here’s how we might toggle state:
var navButton = document.querySelector('nav button');navButton.addEventListener('click', function() { let expanded = this.getAttribute('aria-expanded') === 'true' || false; this.setAttribute('aria-expanded', !expanded); let menu = this.nextElementSibling; menu.hidden = !menu.hidden; });
aria-controls
As I wrote in Aria-controls Is Poop, the aria-controls attribute, intended to help screen reader users navigate from a controlling element to a controlled element, is only supported in the JAWS screen reader. So you simply can’t rely on it.
Without a good method for directing users between elements, you should instead make sure one of the following is true:
The expanded list’s first link is next in focus order after the button (as in the previous code example).
The first link is focused programmatically upon revealing the list.
In this case, I would recommend (1). It’s a lot simpler since you don’t have to worry about moving focus back to the button and on which event(s) to do so. Also, there’s currently nothing in place to warn users that their focus will be moved to somewhere different. In the true menus we’ll be discussing shortly, this is the job of aria-haspopup="true".
Employing aria-controls doesn’t really do much harm, except that it makes readout in screen readers more verbose. However, some JAWS users may expect it. Here is how it would be applied, using the list’s id as the cipher:
A true menu (in the WAI-ARIA sense) should identify itself as such using the menu role (for the container) and, typically, menuitem children (other child roles may apply). These parent and child roles work together to provide information to assistive technologies. Here’s how a list might be augmented to have menu semantics:
We could, of course, suppress the list semantics of the <li>s using role="presentation" or role="none" (which are equivalent) and place the menuitem role on each link. However, this would suppress the implicit link role. In other words, the example to follow would be announced as “Home, menu item”, not “Home, link” or “Home, menu item, link”. ARIA roles simply override HTML roles.
<!-- will be read as "Home, menu item" --><li role="presentation"><a href="http://www.smashingmagazine.com/" role="menuitem">Home</a></li>
We want the user to know that they are using a link and can expect link behavior, so this is no good. Like I said, true menus are for (JavaScript driven) application behavior.
What we’re left with is a kind of hybrid component, which isn’t quite a true menu but at least tells users whether the list of links is open, thanks to the aria-expanded state. This is a perfectly satisfactory pattern for navigation menus.
Sidenote: The <select> element
If you’ve been involved in responsive design from the beginning, you may remember a pattern whereby navigation was condensed into a <select> element for narrow viewports.
As with the checkbox-based toggle buttons we discussed, using a native element that behaves somewhat as intended without additional scripting is a good choice for efficiency and — especially on mobile — performance. And <select> elements are menus of sorts, with similar semantics to the button-triggered menu we shall soon be constructing.
However, just as with the checkbox toggle button, we’re using an element associated with entering input, not simply making a choice. This is likely to cause confusion for many users — especially since this pattern uses JavaScript to make the selected <option> behave like a link. The unexpected change of context this elicits is considered a failure according to WCAG’s 3.2.2 On Input (Level A) criterion.
True Menus
Now that we’ve had the discussion about false menus and quasi-menus, the time has arrived to create a true menu, as opened and closed by a true menu button. From here on in I will refer to the button and menu together as simply a “menu button”.
But in what respects will our menu button be true? Well, it’ll be a menu component intended for choosing options in the subject application, which implements all the expected semantics and corresponding behaviors to be considered conventional for such a tool.
As mentioned already, these conventions come from desktop application design. ARIA attribution and JavaScript governed focus management are needed to imitate them fully. Part of the purpose of ARIA is to help web developers create rich web experiences without breaking with usability conventions forged in the native world.
In this example, we’ll imagine our application is some sort of game or quiz. Our menu button will let the user choose a difficulty level. With all the semantics in place, the menu looks like this:
The aria-haspopup property simply indicates that the button secretes a menu. It acts as warning that, when pressed, the user will be moved to the “popup” menu (we’ll cover focus behavior shortly). Its value does not change — it remains as true at all times.
The <span> inside the button contains the unicode point for a black down-pointing small triangle. This convention indicates visually what aria-haspopup does non-visually — that pressing the button will reveal something below it. The aria-hidden="true" attribution prevents screen readers from announcing “down pointing triangle” or similar. Thanks to aria-haspopup, it’s not needed in the non-visual context.
The aria-haspopup property is complemented by aria-expanded. This tells the user whether the menu is currently in an open (expanded) or closed (collapsed) state by toggling between true and false values.
The menu itself takes the (aptly named) menu role. It takes descendants with the menuitem role. They do not need to be direct children of the menu element, but they are in this case — for simplicity.
Keyboard And Focus Behavior
When it comes to making interactive controls keyboard accessible, the best thing you can do is use the right elements. Because we’re using <button> elements here, we can be assured that click events will fire on Enter and Space keystrokes, as specified in the HTMLButtonElement interface. It also means that we can disable the menu items using the button-associated disabled property.
There’s a lot more to menu button keyboard interaction, though. Here’s a summary of all the focus and keyboard behavior we’re going to implement, based on WAI-ARIA Authoring Practices 1.1:
Enter, Space or ↓ on the menu button
Opens the menu
↓ on a menu item
Moves focus to the next menu item, or the first menu item if you’re on the last one
↑ on a menu item
Moves focus to the previous menu item, or the last menu item if you’re on the first one
↑ on the menu button
Closes the menu if open
Esc on a menu item
Closes the menu and focuses the menu button
The advantage of moving focus between menu items using the arrow keys is that Tab is preserved for moving out of the menu. In practice, this means users don’t have to move through every menu item to exit the menu — a huge improvement for usability, especially where there are many menu items.
The application of tabindex="-1" makes the menu items unfocusable by Tab but preserves the ability to focus the elements programmatically, upon capturing key strokes on the arrow keys.
As part of a sound API design, we can construct methods for handling the various events.
For example, the open method needs to switch the aria-expanded value to “true”, change the menu’s hidden property to false, and focus the first menuitem in the menu that isn’t disabled:
We can execute this method where the user presses the down key on a focused menu button instance:
this.button.addEventListener('keydown', function (e) { if (e.keyCode === 40) { this.open(); }}.bind(this));
In addition, a developer using this script will now be able to open the menu programmatically:
exampleMenuButton = new MenuButton(document.querySelector('[aria-haspopup]'));exampleMenuButton.open();
Sidenote: The checkbox hack
As much as possible, it’s better not to use JavaScript unless you need to. Involving a third technology on top of HTML and CSS is necessarily an increase in systemic complexity and fragility. However, not all components can be satisfactorily built without JavaScript in the mix.
In the case of menu buttons, an enthusiasm for making them “work without JavaScript” has led to something called the checkbox hack. This is where the checked (or unchecked) state of a hidden checkbox is used to toggle the visibility of a menu element using CSS.
/* menu closed */[type="checkbox"] + [role="menu"] { display: none;}/* menu open */[type="checkbox"]:checked + [role="menu"] { display: block;}
To screen reader users, the checkbox role and checked state are nonsensical in this context. This can be partly overcome by adding role="button" to the checkbox.
Unfortunately, this suppresses the implicit checked state communication, depriving us of JavaScript-free state feedback (poor though it would have been as “checked” in this context).
But it is possible to spoof aria-expanded. We just need to supply our label with two spans as below.
These are both visually hidden using the visually-hidden class, but — depending on which state we’re in — only one is hidden to screen readers as well. That is, only one has display: none, and this is determined by the extant (but not communicated) checked state:
/* class to hide spans visually */.vh { position: absolute !important; clip: rect(1px, 1px, 1px, 1px); padding: 0 !important; border: 0 !important; height: 1px !important; width: 1px !important; overflow: hidden;}/* reveal the correct state wording to screen readers based on state */[type="checkbox"]:checked + label .expanded-text { display: inline;}[type="checkbox"]:checked + label .collapsed-text { display: none;}[type="checkbox"]:not(:checked) + label .expanded-text { display: none;}[type="checkbox"]:not(:checked) + label .collapsed-text { display: inline;}
This is clever and all, but our menu button is still incomplete since the expected focus behaviors we’ve been discussing simply cannot be implemented without JavaScript.
These behaviors are conventional and expected, making the button more usable. However, if you really need to implement a menu button without JavaScript, this is about as close as you can get. Considering the cut-down navigation menu button I covered previously offers menu content that is not JavaScript dependent itself (i.e. links), this approach may be a suitable option.
Executing some methods should emit events so that we can set up listeners. For example, we can emit a choose event when a user clicks a menu item. We can set this up using CustomEvent, which lets us pass an argument to the event’s detail property. In this case, the argument (“choice”) would be the chosen menu item’s DOM node.
MenuButton.prototype.choose = function (choice) { // Define the 'choose' event var chooseEvent = new CustomEvent('choose', { detail: { choice: choice } }); // Dispatch the event this.button.dispatchEvent(chooseEvent); return this; }
There are all sorts of things we can do with this mechanism. Perhaps we have a live region set up with an id of menuFeedback:
<div role="alert"></div>
Now we can set up a listener and populate the live region with the information secreted inside the event:
exampleMenuButton.addEventListener('choose', function (e) { // Get the node's text content (label) var choiceLabel = e.details.choice.textContent; // Get the live region node var liveRegion = document.getElementById('menuFeedback'); // Populate the live region liveRegion.textContent = 'Your difficulty level is ${choiceLabel}';});
When a menu item is selected, the screen reader user will hear, “You chose [menu item’s label]”. A live region (defined here with the role="alert" attribution) announces its content in screen readers whenever that content changes. The live region isn’t mandatory, but it is an example of what might happen in the interface as a response to the user making a menu choice.
Persisting Choices
Not all menu items are for choosing persistent settings. Many just act like standard buttons which make something in the interface happen when pressed. However, in the case of our difficulty menu button, we’d like to indicate which is the current difficulty setting — the one chosen last.
The aria-checked="true" attribute works for items that, instead of menuitem, take the menuitemradio role. The enhanced markup, with the second item checked (set) looks like this:
While traversing the menu with a screen reader running, focusing this checked item will prompt an announcement like “check mark, Medium menu item, checked”.
The behavior on opening a menu with a checked menuitemradio differs slightly. Instead of focusing the first (enabled) item in the menu, the checked item is focused instead.
What’s the benefit of this behavior? The user (any user) is reminded of their previously selected option. In menus with numerous incremental options (for example, a set of zoom levels), people operating by keyboard are placed in the optimal position to make their adjustment.
Using The Menu Button With A Screen Reader
In this video, I’ll show you what it’s like to use the menu button with the Voiceover screen reader and Chrome. The example uses items with menuitemradio, aria-checked and the focus behavior discussed. Similar experiences can be expected across the gamut of popular screen reader software.
Inclusive Menu Button On Github
Hugo Giraudel and I have worked together on creating a menu button component with the API features I have described, and more. You have Hugo to thank for many of these features, since they were based on the work they did on a11y-dialog — an accessible modal dialog. It is available on Github and NPM.
npm i inclusive-menu-button --save
In addition, Hugo has created a React version for your delectation.
Checklist
Don’t use ARIA menu semantics in navigation menu systems.
On content heavy sites, don’t hide structure away in nested dropdown-powered navigation menus.
Use aria-expanded to indicate the open/closed state of a button-activated navigation menu.
Make sure said navigation menu is next in focus order after the button that opens/closes it.
Never sacrifice usability in the pursuit of JavaScript-free solutions. It’s vanity.
We can’t believe it’s actually happening. After 18 months of hard work on the big bang relaunch of this little website, today is the day when everything changes. New design and new technical stack. New personality and new ambitious goals. But most importantly, a new focus on our wonderful web community, with the brand new Smashing Membership.
Rewarding Great People Doing Great Work
In times when we fight all the craziness and narrow-mindedness around us, we need to remind ourselves how wonderful a vast majority of the web community actually is. There are thousands of active, hard-working folks who contribute to open-source projects, who share, blog, speak, teach and learn from each other — and for each other.
There are people who deeply care about diversity and respect. People who care about accessibility and performance. People who care about quality. People who change things for the better. People who help and share. Truly smashing people like you.
Unfortunately, these people usually remain unnoticed, sometimes making huge contributions in their little spare time, and as time passes by, too often so does their motivation. We want to reward and highlight these people, and support their contributions.
Over the last 18 months, we’ve been cooking something new. It’s about time to give you a taste of what we have in mind!
That is why today we are proud to launch Smashing Membership. A community effort dedicated to support and highlight new and old voices of the community side by side.
A safe, friendly place where together we can share, learn and decide on the future of the web. But also an effort to move away from an ad-ridden, noisy, clicks-driven web to a friendlier, cleaner and calmer place.
Web community lies in the very heart of the Membership; but it’s much more than that. We’re building a place with features worth using daily — webinars, books, eBooks, printed magazine, hefty discounts for books, video courses, tools and Smashing TV.
Bonus: 68 enchantingly beautiful cats and UX gems scattered across the site. Smash it up alright: that’s Smashing Membership for y’all!
What’s In It For You?
We don’t believe in donations, but we do believe in value of good products. We want your Smashing Membership to be worth every penny. It should provide you with tangible benefits, day after day. Here’s what you should be expecting.
Smashing TV and Webinars
Every community grows slowly, but its value shines through slow, mindful discussions. We want to encourage this kind of discussions with Smashing TV, our regular live sessions with you and other smart people from the industry.
Unlike in regular webinars, you’ll be the central part of the events, having discussions with us and other people from the industry. Format: 60 mins talk + 45 mins Q&A, taking place every second Thursday. Can’t watch it live? You can download recordings of webinars, too. That’s how you stay on the cutting edge of digital.
Suggest Topics For Articles and Webinars
We’re listening to you. You’d like us to cover a particular topic in the magazine or run a webinar, or even in-house training on it? Suggest your ideas in the open channel with our editors, and we will do our best to make it happen.
Hefty Discounts to Books and Videos
We also want to build up a place worth coming back to. Be it due to hefty discounts for tools or video courses, or books and eBooks for your personal growth. We’ve teamed up with Rachel Andrew, Chris Coyier, Remy Sharp, Wes Bos and others to provide you with discounts for their video courses and tools.
Ideally, you should learn something new every day. Also, you get access to Smashing eBooks, the old ones and the new ones, so you can start reading a book before it officially gets released.
Home, Where You Meet Friends
But we also want it to be a fireplace where you meet new and old friends. Everybody around here is called by their real name. We’ve set up a discussion place over at Spectrum, kind-of-a-community-forum thing for threaded, lengthy discussions. That’s where you hopefully meet friends and make genuine, authentic connections. Perhaps it could become a place you might call home one day.
Super-Early-Bird Tickets
You should feel like home around people you know and trust. This goes not just for digital gatherings — we’d love to see you at Smashing conferences and meet-ups, too. To make it a bit easier for you to come, we’ve set up discounts for Smashing workshops and conferences. With a Membership, you save the money spent with one conference ticket already.
A New Printed Magazine
Print is dead? Think again! With Smashing Magazine Print, we’re rediscovering what a printed magazine looks like. Not just a recycling of online content; no ads or fill content — long-form articles written for the magazine and designed to stay relevant long-term. Now in print, every 4 months, and delivered to your doorsteps worldwide. Designed by one-and-only Veerle Pieters.
Transparency and Public Reporting
By the end of every month, we’ll be reporting the earnings and how we spent the money. You’ll see where the money goes, the projects we supported and initiated, and what you made possible.
Support New Voices in The Industry
We search and support new voices in the industry: people who write, or code, or design, people who want to learn but can’t afford it, and people who are disadvantaged in any way.
One thing is certain: with our community, you’re in for a wonderful, diverse, respectful group of people who share values and have versatile experiences. Most importantly, they are willing to share them with you. We do not tolerate any disrespect around here.
Bonus: Ditching Display Ads
The web is polluted with cranky, malicious and painfully slow ad scripts, creating a culture of exaggerated, click-baiting titles that generate ad impressions. It’s about time to take a stand against it.
Let’s be honest: display ads are just out-of-date. They don’t serve anybody, and nobody really likes them. They slow us down and they distract from what we are here to do; and advertisers don’t fancy them either because they communicate next to nothing about their offering.
However, we all need to pay the bills at the end of the day. In the new design, you won’t find that many ad spots any longer, and we’ll remove them entirely once we reach 5.000 members.
We want to help our industry transition away from display ads to more effective ways of spreading the word that benefits everybody. After all, we still believe that the companies who have supported us over the years bring so much to the web community. Without them many events wouldn’t happen, many open source projects would close their doors, and much of the content you read wouldn’t exist.
The Day When Everything Changes
We couldn’t be more excited about getting Membership finally out there. We’ve put a lot of effort and consideration into shaping it and designing it and building it, and to us, it feels like the beginning of something very special. We’d love you to be a part of it, too. Welcome to the brand new Smashing Magazine.
Ah, by the way, as it always is with a relaunch, please be patient: not everything on the new site might work as expected, and we still have a few issues to fix. If you find a errors, please report a bug, or help us squash it, the smashing way. So long, and good luck finding all those 68 hidden cats!
Articles In The Series
This article is a part of the series about how we work and design and build and play. We’ll be publishing a case study on the work we did, both from the design perspective and the technical perspective, soon. Stay tuned!
(This is a sponsored post). Web design is tricky. Designers and developers have to take a lot of things into account when designing a website, from visual appearance (how the website looks) to functional design (how the website works). To simplify the task, we’ve prepared this little guide.
In this article, I’ll focus on the main principles, heuristics, and approaches that will help you to create a great user experience for your website. I’ll start with global things like the user journey (how to define the “skeleton” of the website) and work down to the individual page (what should be considered during web page design). We’ll also cover other essential aspects of design, such as mobile considerations and testing.
Designing The User Journey
Information Architecture
People often use the term “information architecture” (IA) to mean the menus on a website. But that’s not correct. While menus are a part of IA, they are only one aspect of it.
IA is all about the organization of information in a clear and logical way. Such organization follows a clear purpose: helping users to navigate a complex set of information. Good IA creates a hierarchy that aligns with user’s expectations. But good hierarchy and intuitive navigation don’t happen by chance. They are a result of proper user research and testing.
There are a number of ways to research user needs. Often, an information architect will take an active part in user interviews or card sorting, where they would hear of user expectations directly or see how prospective users would categorize a variety of information groups. Information architects also need access to the results of usability tests to see whether users are able to navigate efficiently.
A menu structure would be created based on the results of user interviews, and card sorting would be tested for whether it satisfies the user’s mental model. UX researchers use a technique called “tree testing” to prove that it will work. This happens before designing the actual interface.
Global Navigation
Navigation is a cornerstone of usability. It doesn’t matter how good your website is if users can’t find their way around it. That’s why navigation on your website should adhere to a few principles:
SimplicityNavigation should be designed in a way that gets visitors where they want to go with the fewest clicks possible.
ClarityThere shouldn’t be any guessing about what each navigation option means. Every navigation option should be self-evident to visitors.
ConsistencyThe navigation system should be the same for all pages on the website.
Consider a few things when designing navigation:
Select a navigation pattern based on the user’s needs.Navigation should accommodate the needs of the majority of your app’s users. A given target group expects a particular type of interaction with your website, so make these expectations work in your favor. For example, avoid hamburger-menu navigation if the majority of your users aren’t familiar with the meaning of the icon itself.
Prioritize navigation options.One simple way to prioritize navigation options is to assign different priority levels (high, medium, low) to common user tasks, and then give prominence in the layout to paths and destinations with high priority levels and frequent use.
Make it visible.As Jakob Nielsen says, recognizing something is easier than remembering it. Minimize the user’s memory load by making all important navigation options permanently visible. The most important navigation options should be available at all times, not just when we anticipate that the user will need them.
Communicate the current location.“Where am I?” is a fundamental question to which users need an answer in order to effectively navigate. Failing to indicate the current location is a common problem on many websites. Think about location indicators.
Links and Navigation Options
Links and navigation options are key factors in the navigation process and have a direct effect on the user journey. Follow a few rules with these interactive elements:
Recognize the difference between internal and external links.Users expect different behavior for internal and external links. All internal links should open in the same tab (this way, you’ll allow users to use the “back” button). If you decide to open external links in a new window, you should provide an advanced warning before automatically opening a new window or tab. This might take the form of text added to the link text stating “(opens in a new window)”.
Change the color of visited links.When visited links don’t change color, users could unintentionally revisit the same pages.
Double-check all links.A user can easily get frustrated by clicking a link and getting a 404 error page in response. When a visitor is searching for content, they expect every link to take them where it says it will, not to a 404 error page or another place they weren’t expecting.
“Back” Button in Browser
The “back” button is perhaps the second-most popular UI control in the browser (after the URL input field). Make sure the “back” button works according to user expectations. When a user follows a link on a page and then clicks the “back” button, they expect to return to the same spot on the original page. Avoid situations in which clicking “back” brings the user to the top of the initial page, instead of where they left off, especially on pages. Losing their spot forces the user to scroll through content they have already seen. It’s no surprise that users get frustrated quickly with no proper “back to position” functionality.
Breadcrumbs
Breadcrumbs are a set of contextual links that function as a navigation aid on websites. It’s a secondary navigation scheme that usually shows the user’s location on a website.
While this element doesn’t require a lot of explanation, a few things are worth mentioning:
Don’t use breadcrumbs as a substitute for primary navigation.The main navigation should be the element that leads the user, whereas breadcrumbs should only support the user. Relying on breadcrumbs as a primary method of navigation, rather than an extra feature, is usually an indication of poor navigation design.
Use arrowheads, not slashes, as separators. Separate each level clearly.A more-than sign (>) or right-pointing arrow (→) is recommended, because these symbols signal direction. A forward slash (/) isn’t recommended as a separator for e-commerce websites. If you’re going to use it, be certain that no product category will ever use a slash:
Search
Some users come to a website looking for one particular item. They don’t want to use the navigation options. They want to type text in a search box, submit their search query and find the page they’re looking for.
Take these few basic rules into account when designing the search box:
Put the search box where users expect to find it.The chart below was created based on a study by A. Dawn Shaikh and Keisi Lenz. It shows the expected location of the search field, according to a survey of 142 participants. The study found that the most convenient spot is the top left or top right of every page on a website. Users can easily find it using the common F-shaped scanning pattern.
Display search prominently on content-rich websites.
If search is an important function on your website, display it prominently, because it can be the fastest route to discovery for users.
Size the input box appropriately.
Making the input field too short is a common mistake among designers. Of course, users can type a long query into a short field, but only a portion of the text will be visible at a time, which is bad for usability because seeing the entire query at once won’t be possible. In fact, when a search box is too short, users are forced to use short, imprecise queries, because longer queries would be hard and inconvenient to read. Nielsen Norman Group recommends a 27-character input field, which would accommodate 90% of queries.
Put the search box on every page.
Show the search box on every page, because if users cannot navigate to the content they are looking for, they will try to use search regardless of where they are on the website.
Designing Individual Pages
Content Strategy
Perhaps the most important thing about content strategy is to focus the design on page objectives. Understand the goal of the page, and write content according to the goal.
Here are a few practical tips to improve content comprehension:
Prevent information overload.Information overload is a serious problem. It prevents users from making decisions or taking action because they feel they have too much information to consume. There are some simple ways to minimize information overload. One common technique is chunking — breaking content into smaller chunks to help users understand and process it better. A checkout form is a perfect example. Display at most five to seven input fields at a time, and break down the checkout into pages, progressively disclosing fields as necessary.
Avoid jargon and industry-specific terms.Each unknown term or phrase that appears on the page will increase the cognitive load on users. A safe bet is to write for all levels of readers, and pick words that are clearly and easily understandable to all groups of users.
Minimize long content sections with a lot of detail.In line with the point about information overload, try to avoid long blocks of text if the website isn’t geared to major information consumption. For example, if you need to provide details about a service or product, try to reveal details step by step. Write in small, scannable segments to facilitate discovery. According to Robert Gunning’s book “How to Take the Fog Out of Business Writing”, for comfortable reading, most sentences should be 20 words or less.
Avoid capitalizing all letters.All-caps text — that is, text with all letters capitalized — is fine in tiny doses, such as for acronyms and logos. However, avoid all caps for anything longer (such as paragraphs, form labels, errors, notifications). As mentioned by Miles Tinker in his book Legibility of Print, all caps dramatically reduces the speed of reading. Also, most readers find all capitals to be less legible.
Page Structure
A properly structured page makes it clear where each user interface element is located in the layout. While there are no one-size-fits-all rules, there are a few guidelines that will help you create a solid structure:
Make the structure predictable.Align your design to user expectations. Consider websites from a similar category to find out which elements to use on the page and where. Use patterns that your target audience is familiar with.
Use a layout grid.A layout grid divides a page into major regions, and defines the relationships between elements in terms of size and position. With the help of a grid, combining different parts of a page together in a cohesive layout becomes much easier.
Use a low-fidelity wireframe to cut out clutter.Clutter overloads an interface and reduces comprehension. Every added button, image and line of text makes the screen more complicated. Before building the page with real elements, create a wireframe, analyze it, and get rid of anything that isn’t absolutely necessary.
Visual Hierarchy
People are more likely to quickly scan a web page than to read everything there. Therefore, if a visitor wants to find content or complete a task, they are going to scan until they find where they need to go. You, as a designer, can help them with that by designing good visual hierarchy. Visual hierarchy refers to the arrangement or presentation of elements in a way that indicates importance (that is, where their eyes should focus first, second, etc.). A proper visual hierarchy makes it easy to scan the page.
Use natural scanning patterns.As designers, we have a lot of control over where people look when they’re viewing a page. To set the right path for the visitor’s eyes to follow, we can use two natural scanning patterns: the F-shaped pattern and the Z-shaped pattern. For text-heavy pages, such as articles and search results, the F pattern is better, whereas the Z pattern is good for pages that aren’t text-oriented.
Visually prioritize important elements.Make screen titles, log-in forms, navigation options and other important content focal points, so that visitors see them right away.
Create mockups to clarify the visual hierarchy.Mockups enable designers to see what a layout will look like when it’ll have a real data. Rearranging elements in a mockup is much easier than doing it when the developer is building the web page.
Scrolling Behavior
A persistent myth among web designers is that people don’t scroll. To be clear: Today, everybody scrolls!
Improving scrolling behavior is possible with a few tips:
Encourage users to scroll.Despite the fact that people usually start scrolling as soon as the page loads, content at the top of the page is still very important. What appears at the top sets the impression and expectation of quality for visitors. People do scroll, but only if what’s above the fold is promising enough. Thus, put your most compelling content at the top of the page:
Offer a good introduction.An excellent introduction sets the context for the content and answers the user’s question, “What’s this page about?”
Use engaging imagery.Users pay close attention to images that contain relevant information.
Persist navigation options.When you create lengthy pages, keep in mind that users still require a sense of orientation (of their current location) and a sense of navigation (other possible paths). Long pages can make navigation problematic for users; if the top navigation bar loses visibility when the user scrolls down, they will have to scroll all the way back up when they’re deep within the page. The obvious solution to this is a sticky menu that shows the current location and that remains on screen in a consistent area at all times.
Provide visual feedback when loading new content.This is especially important for web pages where content loads dynamically (such as news feeds). Because content-loading during scrolling is supposed to be fast (it shouldn’t take longer than 2 to 10 seconds), you can use looped animation to indicate that the system is working.
Don’t hijack scrolling.Hijacked scrolling is one of the most annoying things because it takes control away from the user and makes the scrolling behavior completely unpredictable. When you design a website, let the user control their browsing and movement through the website.
Content Loading
Content loading is worth additional clarification. While an instant response is best, there are occasions when your website will need more time to deliver content to visitors. A bad Internet connection could cause a slow reaction, or an operation could take a bit more time to complete. But no matter the cause of such behavior, your website should appear fast and responsive.
Make sure regular loading doesn’t take long.The attention span and patience of web users is very low. According to Nielsen Norman Group research, 10 seconds is about the limit for keeping the user’s attention on a task. When visitors have to wait for a website to load, they will become frustrated and likely leave if the website doesn’t load quickly enough for them. Even with the most beautifully designed loading indicator, users will still leave if loading takes too long.
Use skeleton screens during loading.Many websites use progress indicators to show that data is loading. While the intention behind a progress indicator is good (providing visual feedback), the result can be negative. As Luke Wroblewski mentions, “Progress indicators by definition call attention to the fact that someone needs to wait. It’s like watching the clock tick down — when you do, time seems to go slower.” There is an excellent alternative to progress indicators: skeleton screens. These containers are essentially a temporarily blank version of the page, into which information is gradually loaded. Rather than showing a loading indicator, designers can use a skeleton screen to focus users’ attention on actual progress and create anticipation for what’s to come. This creates a sense that things are happening immediately, as information is incrementally displayed on the screen and people see that the website is acting while they wait.
Buttons
Buttons are vital to creating a smooth conversational flow. It’s worth paying attention to these basic best practices for buttons:
Ensure that clickable elements look like ones.With buttons and other interactive elements, think about how the design communicates affordance. How do users understand the element as a button? Form should follow the function: the way an object looks tells users how to use it. Visual elements that look like links or buttons but aren’t clickable (such as underlined words that aren’t links or elements that have a rectangular background but aren’t buttons) can easily confuse users.
Label buttons according to what they do.The label on any actionable interface element should always tie back to what it will do for the user. Users will feel more comfortable if they understand what action a button does. Vague labels such as “Submit” and abstract labels like in the example below don’t provide enough information about the action.
Design buttons consistently.Users remember details, whether consciously or not. When browsing a website, they’ll associate a particular element’s shape with button functionality. Therefore, consistency will not only contribute to a great-looking design, but will also make the experience more familiar to users. The image below illustrates this point perfectly. Using three different shapes in one part of an app (such as the system toolbar) is not only confusing, but sloppy.
Imagery
As the saying goes, a picture is worth a thousand words. Human beings are highly visual creatures, able to process visual information almost instantly; 90% of all information that we perceive and that gets transmitted to our brains is visual. Images are a powerful way to capture the user’s attention and to differentiate a product. A single image can convey more to the viewer than an elaborately designed block of text. Furthermore, images cross language barriers in a way that text simply can’t.
The following principles will help you integrate imagery in your web design:
Make sure images are relevant.One of the biggest dangers in design is imagery that conveys the wrong message. Select images that strongly support your product goals, and ensure that they are relevant to the context.
Avoid generic photos of people.Using human faces in design is an effective way to engage users. Seeing faces of other humans makes viewers feel like they are connecting with them, and not just being sold a product. However, many corporate websites are notorious for using generic stock photos to build a sense of trust. Usability tests show that such photos rarely add value to the design and more often impair rather than improve the user experience.
Use high-quality assets with no distortion.The quality of assets of your website will have a tremendous impact on the user’s impression and expectations of your service. Make sure images are appropriately sized for displays across all platforms. Images shouldn’t appear pixelated, so test resolution sizes for various ratios and devices. Display photos and graphics in their original aspect ratio.
Video
With increasing Internet speeds, videos are becoming more popular, especially considering that they extend time spent on site. Today, video is everywhere. We’re watching it on our desktops, tablets and phones. When used effectively, video is one of the most powerful tools available for engaging an audience — it conveys more emotion and really gives people a feel for a product or service.
Set audio to off by default, with the option to turn it on.When users arrive on a page, they don’t expect that it will play any sound. Most users don’t use headphones and will be stressed because they’ll need to figure out how to turn the sound off. In most cases, users will leave the website as soon as it plays.
Keep promo video as short as possible.According to the research by D-Mak Productions, short videos are more appealing to the majority of users. Thus, keep business videos in the range of two to three minutes.
Provide an alternative way to access content.If a video is the only way to consume content, this can limit access to the information for anyone who cannot see or hear the content. For accessibility, include captions and a full transcript of the video.
Call-to-Action Buttons
Calls to action (CTA) are buttons that guide users towards your conversion goal. The whole point of a CTA is to direct visitors to a desired course of action. Some common examples of CTAs are:
“Start a trial”
“Download the book”
“Sign up for updates”
“Get a consultation”
Take a few things into account when designing CTA buttons:
SizeThe CTA should be large enough to see from a distance, but not so large as to detract attention from other content on the page. To confirm that your CTA is the most prominent element on the page, try the five-second test: View a web page for five seconds and then write down what you remember. If the CTA is on your list, then congrats! It’s sized appropriately.
Visual prominenceThe color you choose for CTAs has a tremendous impact on whether it will be noticeable. With color, you can make certain buttons stand out more than others by giving them more visual prominence. Contrasting colors work best for CTAs and make for striking buttons.
Negative spaceThe amount of space around a CTA is important, too. White (or negative) space creates essential breathing room and separates a button from other elements in the interface.
Action-oriented textWrite text for the button that will compel visitors to take action. Begin with a verb like “Start,” “Get” or “Join.”
Tip: You can quickly test a CTA using a blur effect. A blur test is a quick technique to determine whether the user’s eye will go where you want it to go. Take a screenshot of your page and apply a blur effect in Adobe XD (see the example on Charity Water below). Looking at the blurred version of your page, which elements stand out? If you don’t like what’s being projected, revise.
Web Forms
Filling a form remains one of the most important types of interaction for users on the web. In fact, a form is often considered the final step in the completion of a goal. Users should be able to complete forms quickly and without confusion. A form is like a conversation, and like any conversation, there should be logical communication between two parties: the user and the website.
Ask only what’s required.Ask for only what you really need. Every extra field you add to a form will affect its conversion rate. Always think about why you’re requesting certain information from users and how you will be using it.
Order the form logically.Questions should be asked logically from the user’s perspective, not from the application or database’s perspective. For example, asking for someone’s address before their name would be incorrect.
Group related fields together.Group related information into logical blocks or sets. The flow from one set of questions to the next will better resemble a conversation. Grouping related fields together also helps the user make sense of the information.
Animation
More and more designers are incorporating animation as a functional element to enhance the user experience. Animation is no longer just for delight; it is one of the most important tools for effective interaction. However, animation in design can enhance the user experience only if it’s incorporated at the right time and place. Good UI animation has a purpose; it is meaningful and functional.
Here are a few cases in which animation can enhance the experience:
Visual feedback on user actionGood interaction design provides feedback. Visual feedback is helpful when you need to inform users about the result of an operation. In case an operation isn’t performed successfully, functional animation can provide information about the problem in a fast and easy way. For example, a shake animation can be used when a wrong password is entered. It’s easy to understand why the shake is a fairly universal gesture to communicate “no,” because a simple head shake is so prevalent in interpersonal communication.
Visibility of system statusOne of Jakob Nielsen’s 10 heuristics for usability, visibility of system status remains among the most important principles in user interface design. Users want to know their current context in a system at any given time, and an app shouldn’t keep them guessing — it should tell the user what’s happening via appropriate visual feedback. Data uploading and downloading operations are great opportunities for functional animation. For example, an animated loading bar shows how fast a process is going and sets an expectation for how fast the action will be processed.
Navigational transitionsNavigational transitions are movements between states on a website — for example, from a high-level view to a detailed view. State changes often involve hard cuts by default, which can make them difficult to follow. Functional animation eases users through these moments of change, smoothly transporting users between navigational contexts and explaining changes on the screen by creating visual connections between states.
BrandingSuppose you have dozens of websites that have the same exact features and help users to accomplish the same tasks. They might all offer a good user experience, but the one that people really love offers something more than just a good user experience. It establishes an emotional connection with users. Branding animation plays a key role in engaging users. It can support a company’s brand values, highlight a product’s strengths and make the user experience truly delightful and memorable.
Mobile Considerations
Today, almost 50% of users access the web from mobile devices. What does this mean for us web designers? It means that we must have a mobile strategy for every website we design.
Practice Responsive Web Design
It’s essential to optimize your website for the vast landscape of desktop and mobile browsers, each of which has a different screen resolution, supported technologies and user base.
Aim for a single-column layout.Single-column layouts usually work best on mobile screens. Not only does a single column help with managing the limited space on a small screen, but it also easily scales between different device resolutions and between portrait and landscape mode.
Use the Priority+ pattern to prioritize navigation across breakpoints.Priority+ is a term coined by Michael Scharnagl to describe navigation that exposes what’s deemed to be the most important elements and hides away less important items behind a “more” button. It makes use of available screen space. As space increases, the number of exposed navigation options increases as well, which can result in better visibility and more engagement. This pattern is especially good for content-heavy websites with a lot of different sections and pages (such as a news website or a large retailer’s store). The Guardian makes use of the Priority+ pattern for its section navigation. Less important items are revealed when the user hits the “All” button.
Make sure images are sized appropriately for displays and platforms.A website must adapt to look perfect on all of the different devices and in all of the various resolutions, pixel densities and orientations. Managing, manipulating and delivering images is one of the main challenges web designers face when building responsive websites. To simplify this task, you can use tools such as Responsive Image Breakpoints Generator to generate breakpoints for images interactively.
Going From Clickable to Tappable
On the mobile web, interaction is done via finger taps, not mouse clicks. This means that different rules apply when you’re designing touch targets and interactions.
Properly sized touch targets.All interactive element (such as links, buttons and menus) should be tappable. While the desktop web lends itself well to links whose active (i.e. clickable) area is small and precise, the mobile web requires larger, chunkier buttons that can be easily pressed with a thumb. When a tap is used as a primary input method for your website, refer to the MIT Touch Lab’s study to choose a proper size for your buttons. The study found that the average size of finger pads are between 10 and 14 millimeters and that fingertips range from 8 to 10, making 10 × 10 millimeters a good minimum touch target size.
Stronger visual signifiers of interactivity.On the mobile web, there is no hover state. While on a desktop, it’s possible to provide additional visual feedback when a user hovers the mouse over an element (for example, revealing a dropdown menu), a mobile user would have to tap to see that response. Thus, users should be able to correctly predict how an interface element will behave just by looking at it.
Accessibility
Today’s products must be accessible to everyone, regardless of a person’s abilities. Designing for users with impairments is one way that designers can practice empathy and learn to experience the world from someone else’s perspective.
Users With Poor Eyesight
A lot of websites use low contrast for text copy. While low-contrast text may be trendy, it’s also illegible and inaccessible. Low contrast is especially problematic for users with low vision and who struggle with contrast sensitivity.
Low-contrast text is hard to read on a desktop, but it becomes even more difficult on mobile. Imagine trying to read low-contrast text on a mobile device while walking in bright sunlight. This is a good reminder that accessible visual design is better visual design for all users.
Never sacrifice usability for beauty. The most important characteristic of text and other vital elements on a website is readability. Readability requires sufficient contrast between text and background. To ensure that text is readable by people with visual impairments, the W3C’s Web Content Accessibility Guidelines (WCAG) has a contrast-ratio recommendation. The following contrast ratios are recommended for body text and image text:
Small text should have a contrast ratio of at least 4.5:1 against its background. A ratio of 7:1 is preferable.
Large text (at 14-point bold and 18-point regular and up) should have a contrast ratio of at least 3:1 against its background.
You can use WebAIM’s Color Contrast Checker to quickly find out whether you’re within the optimal range.
Color Blind Users
It’s estimated that 4.5% of the global population experience color blindness (that’s 1 in 12 men and 1 in 200 women), 4% suffer from low vision (1 in 30 people), and 0.6% are blind (1 in 188 people). It’s easy to forget that we design for this group of users because most designers don’t experience such problems.
To make design accessible for these users, avoid using color alone to convey meaning. As the W3C states, color shouldn’t be used “as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.”
One common example where color is used as the sole means of conveying information is alerts in forms. Success and error messages are often colored green and red, respectively. But red and green are the colors most affected by color-vision deficiency — these colors can be difficult to distinguish for people with deuteranopia or protanopia. Most probably, you’ve seen error messages like, “The fields marked in red are required.” While it might not seem like a big deal, this error message appearing in a form like the one below can be extremely frustrating for people with a color-vision deficiency. Designers should use color to highlight or complement what is already visible.
In the form above, the designer should give more specific instruction, like, “The email address you entered is not valid.” Or at least display an icon near the field that requires attention.
Blind Users
Images and illustrations are a significant part of the web experience. Blind people use assistive technologies such as screen readers to interpret websites. Screen readers “read” images by relying on alternative text attributed to the image. If that text is not present or is not descriptive enough, they won’t be able to get the information as intended.
Consider two examples — first, Threadless, a popular t-shirt store. This page doesn’t say much about the item being sold. The only text information available is a combination of price and size.
The second example is from ASOS. This page, selling a similar shirt, provides accurate alternative text for the item. This helps people who use screen readers to envision what the item looks like.
When creating text alternatives for images, follow this guideline:
All “meaningful” images require descriptive alternative text. (A “meaningful” photo adds context to the information being conveyed.)
A text alternative isn’t needed if an image is purely decorative and provides no useful information to the user to aid them in understanding the content of the page.
Keyboard-Friendly Experience
Certain users navigate the Internet using their keyboard, rather than a mouse. For example, people with motor impairments have difficulty with the fine motor movements required for using a mouse. Make interactive and navigation elements easily accessible to this group of users by enabling interactive elements to be focused with the Tab key and by displaying a keyboard-focus indicator.
Here are the most basic rules for keyboard navigation:
Check that keyboard focus is visible and obvious.Some web designers remove the keyboard focus indicator because they think it’s an eyesore. This hinders keyboard users from properly interacting with the website. If you don’t like the default indicator provided by the browser, don’t remove it altogether; instead, design it to satisfy your taste.
All interactive elements should be accessible.Keyboard users must be able to access all interactive elements, not just the main navigation options or primary calls to action.
You can find detailed requirements for keyboard interaction in the “Design Patterns and Widgets” section of the W3C’s “WAI-ARIA Authoring Practices” document.
Testing
Iterative Testing
Testing is an essential part of the UX design process. And like any other part of the design cycle, it is an iterative process. Gather feedback early on in the design process, and iterate throughout.
Test Page-Loading Time
Users hate slow-loading web pages. That’s why response time is a critical factor on modern websites. According to Nielsen Norman Group, there are three response-time limits:
0.1 secondThis feels instant for users.
1 secondThis keeps the user’s flow of thought seamless, but the user will sense a slight delay.
10 secondsThis is about the limit for keeping the user’s attention focused on the operation. A 10-second delay will often make users leave the website immediately.
Obviously, we shouldn’t make users wait 10 seconds for anything on our websites. But even a few seconds of delay, which happens regularly, makes an experience unpleasant. Users will be annoyed with having to wait for the operation.
What usually causes slow loading time?
Heavy content objects (such as embedded video and slideshow widgets),
Unoptimized back-end code,
Hardware-related issues (infrastructure that doesn’t allow for fast operations).
Tools like PageSpeed Insights will help you to find the causes of slow times.
A/B Testing
An A/B test is ideal when you’re struggling to choose between two versions of a design (such as an existing version and a redesigned version of a page). This testing method consists of showing one of two versions randomly to an equal number of users and then reviewing analytics to see which version accomplished your goal more effectively.
Developer Handoff
A UX design process has two important steps: prototyping the design and developing a working solution. The step that connects the two is called a handoff. As soon as the design is finalized and ready to be moved to development, designers prepare a specification, which is a document that describes how the design should be coded. A specification ensures that the design will be implemented according to the original intention.
Precision in the specification is critical because, with an inaccurate specification, the developers will have to either rely on guesswork when building the website or go back to the designer to get answers to their questions. But assembling a specification manually can be a headache and usually takes significant time, depending on the complexity of the design.
With Adobe XD’s design specs feature (in beta), designers can publish a public URL for developers to inspect flows, grab measurements and copy styles. Designers no longer have to spend time authoring specifications to communicate positioning, text styles or fonts to the developer.
Conclusion
As with any aspect of design, the tips shared here are just a start. Mix and match these ideas with your own for best results. Treat your website as a continually evolving project, and use analytics and user feedback to constantly improve the experience. And remember that design isn’t just for designers — it’s for users.
This article is part of the UX design series sponsored by Adobe. Adobe XD tool is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app.You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.
Editor’s Note: Our dear friend Anselm Hannemann summarizes what happened in the web community in the past few weeks in one handy list, so that you can catch up on everything new and important. Enjoy!
Welcome back to our monthly reading list. Before we dive right into all the amazing content I stumbled upon — admittedly, this one is going to be quite a long update — I want to make a personal announcement. This week I launched a personal project called Colloq, a new conference and event service for users and organizers. If you’re going to events or are organizing one or if you’re interested in the recorded content of conferences, this could be for you. So if you like, go ahead and check it out.
In this issue, we’ll focus on some usually rather underaddressed things, such as numerals in web typography, variable fonts, or the image async attribute that’s coming to Chrome soon. So without further ado, let’s get started.
News
WebKit just got support for the Touch Bar Web API that will make use of the menuitem. It’s still in WebKit trunk currently and likely to land in Safari next year at the earliest.
Chrome 62 was released this week with some important updates to the Network Information API that now reflects the actual connection type even when tethering. Support for OpenType Variable Fonts and Media Capture from DOM elements also landed in the new version. Notably, Chrome 62 on iOS got support for the Payment Request API which is interesting because the iOS WebKit doesn’t support it yet in stable channel. It seems that they used a custom extension to support this feature. Might get interesting to see what else could be supported this way.
With the new Windows 10 fall update, Edge 16 is pushed to customers — with full CSS Grid support, object-fit and object-position, the Payment Request API, Service Worker preview behind flags, and Motion Controllers in WebVR.
David Yates’ plea for “RSS: there’s nothing better” is a thoughtful column that praises the idea of the good old RSS over the siloed, algorithm-driven feeds of social media services.
Inter UI is a nice, completely free to use open-source font family optimized for screen readability.
Adobe announced the first stable version of their screen design tool XD at this year’s MAX conference. Besides a lot of smaller improvements, XD now supports sharing, as well as first-class integrations of third-party tools like Zeplin and Sympli. Apart from that, Adobe provided major updates for nearly all their software products during the event.
InVision had a big announcement to make this week: They are going to bring a new screen design tool called “Studio” to the market in January and now invite beta testers to preview it.
Web Performance
Vlad Krasnov got the chance to compare the newest server processors at Cloudflare. The results are pretty interesting: Qualcomm achieves a similar performance as the fastest Intel processors, but it needs about 30% less power, sometimes even less. So while newer Qualcomm chips might have some issues with software incompatibilities, it’s going to be interesting what will happen on the server market. Especially with large data centers in mind where saving energy is quite important — not only because our planet benefits from less power consumption but also because it’s cheaper.
Chrome is implementing an async attribute for HTMLImageElement and SVGImageElement. It’ll have two states: “On” will indicate that the developer prefers responsiveness and performance over the atomic presentation of image and non-image content, while “off” will indicate that the developer prefers atomic presentation of content over responsiveness.
Alexey Ivanov shares how to optimize web servers for high throughput and low latency. But please note: These are small, fine-tuning methods that can be very useful but we should apply them one after another, measure them and then decide if they are useful for the project or not. A thoughtful post that gives us insights into how the Dropbox team improves their edge network servers.
Tooling
Webpack Monitor is a nice dashboard for your JavaScript toolchain. It gives insights into bundle size, the individual parts of the bundle and how the bundle and its size change over time. With tips for optimizing the output, the dashboard is quite useful if you care about reducing the payload for users on your website.
Security
This week, the “KRACK”-attack was widely discussed. It’s effectively breaking WPA2 encryption on most WiFi hardware. But vendors aren’t sleeping, some already updated their systems and offer software updates for the devices which you should patch as soon as possible. One thing to note here is that websites that use HSTS preloading aren’t affected by the issue, which reminds us that we should consider adding this header to our websites.
Vincent De Oliveira wrote about the amazing CSS element() function which is only available in Firefox currently (but that might change). Actually, it’s not even a new function, but it allows us to use images from the HTML DOM in our CSS, e.g. for a background-image.
Richard Rutter wrote a guide about how to use old-style numerals on the web with the font-variant-numeric CSS property, if available. Proper sub- and superscripts are explained, too, and we can learn when to use which feature for a specific purpose.
Jake Archibald wrote about Netflix removing client-side React and why this step makes the site more robust while still benefiting from the advantages of React.
GitHub open-sourced their own client-side accessibility error scanner. It’s basically a JavaScript module that you import into your codebase, and that then reports back basic issues such as images without alt attribute, links without labels and similar accessibility errors.
Work & Life
200 universities just launched 560 free online courses. Here’s the full list.
Going Beyond…
The Guardian recently published an interesting article called “Ashamed to work in Silicon Valley: how techies became the new bankers”. Seeing that working at tech giants like Facebook is considered negatively by a growing number of people is something I didn’t expect. The article also shares that employees at such companies are even ashamed of their jobs — an interesting change when you remember how most people craved to land a job at one of these companies only until this year.
A chatbot called DoNotPay has saved motorists millions in parking fines — without charging a cent. Its next target: divorce law. And airlines, landlords, and telemarketers will follow, too, in the future.
We hope you enjoyed this Web Development Update. The next one is scheduled for December 15th. Stay tuned!
When using any new CSS, the question of browser support has to be addressed. This is even more of a consideration when new CSS is used for layout as with Flexbox and CSS Grid, rather than things we might consider an enhancement.
In this article, I explore approaches to dealing with browser support today. What are the practical things we can do to allow us to use new CSS now and still give a great experience to the browsers that don’t support it?
What Do We Mean By Support?
Before deciding how you are going to support browsers without grid support, it is worth working out what you mean by support. Support might mean that the site has to look absolutely identical in all the browsers on your list. It might mean that you are happy for some finishing touches not to be available in all browsers. It might mean that you are testing these browsers but are completely happy for them to receive a much simplified experience.
A linked question is how do you come up with your list of supported browsers? Even for a brand new website, this shouldn’t need to be a guess. For most businesses today, a new website won’t be the first site they have ever built. You probably have some analytics you can look at to see the browsers in use, although you need to take care that they are not skewed by a site that is entirely mobile unfriendly for example. People won’t be visiting the site on mobile if it is impossible to use on a small screen!
If you don’t have any relevant analytics you can look at data on Can I Use, where you can import the data for your location.
It is also worth keeping the site goals in mind here too. For example, a site hoping to attract visitors who live in emerging markets such as India will want to ensure the site works well in browsers used in those countries.
Is It Just Old Browsers I Should Worry About?
A the time of writing Edge, Chrome, Firefox, Opera, Safari, iOS Safari all support Grid Layout.
IE10 and IE11 have support for the original spec with an -ms prefix. In terms of old browsers you are looking at:
Internet Explorer 9 (or IE 11 and below if only considering the new spec)
Edge 15 and below
Firefox older than version 52
Safari and iOS Safari older than version 10.1
Chrome older than version 57
Samsung Internet older than version 6.2
However, as mentioned in the last section, these popular desktops and mobile browsers are joined by browsers more commonly used in emerging markets. These browsers haven’t yet adopted grid. For example, if we take a worldwide view UC Browser comes in at 8.1% of traffic — the third most popular browser in the world. If you happen to live in the USA or Europe, it’s possible that you may have never heard of it.
UC Browser does not support Grid Layout. It is also a browser optimized for lower powered devices, but also for users in areas with expensive, often metered data. This is an important thing to consider as we begin to plan a strategy for support.
Is There A CSS Grid Polyfill?
When first encountering CSS Grid, an obvious question is, “Can I use a polyfill?” Unfortunately, a magic polyfill for your entire layout is unlikely to be forthcoming or a great idea to use even if there were such a thing.
Grid does things that are pretty much impossible with older layout methods. So, in order to replicate Grid in browsers that don’t have support, you would need to do a lot of work in JavaScript. Even on a well-resourced computer, with a fast rendering engine that is likely to give you something of a janky experience as heights are calculated and items positioned. As we already know, the browsers that don’t support grid are older, slower browsers or browsers most often found on lower powered devices in emerging markets. Why would you force a bunch of JavaScript onto those devices?
Instead of searching for a polyfill, consider how using Grid Layout can actually provide a better experience to those browsers that don’t support it. Grid will allow you to create complex layout experiences for supporting browsers with minimal CSS, while still offering a good experience to those browsers without support. Yes, it will be a little more work than just throwing a polyfill at the problem, but by doing so, you are ensuring that support means providing a good experience, rather than making the site looking the same the most important goal.
Providing Support For Browsers That Don’t Understand Grid Layout
So, how do we provide support that is tailored to the device and browser in use? It turns out that CSS has the answers for you.
Browsers Ignore CSS They Don’t understand
The first part of the picture is the fact that browsers ignore CSS they don’t understand. If a browser that doesn’t support CSS Grid, comes across the grid-template-columns property, it doesn’t know what it is and so throws that line away and continues.
This means that you can use some old CSS, for example, floats or display: table-cell to provide a grid type layout for older browsers, just as you would in the past. The browsers that do not support Grid Layout will use this layout and ignore all the grid instructions. Browsers that do support Grid Layout will continue and discover the grid instructions and apply those. At which point we need to consider what happens if an item using another layout method becomes a grid item.
New Layout Knows About Old Layout
Defined in the specification is exactly how Grid behaves if you have elements in your page positioned by other layout methods.
Items that are floated or that use the clear property, which then become a grid item, no longer exhibit any floating or clearing behavior. As if this was never applied. Remove all of the properties applied to the class .grid in this next CodePen, and you can see how we have floated all of the items and cleared the third one. However, once we are in Grid Layout this is ignored.
The same is true for inline-block. The value inline-block can be applied to the child item, but as soon as the parent has display: grid the inline-block behaviour will no longer be applied.
I often use CSS display: table-cell when I need to create a column layout and also align items in non-supporting browsers, as the vertical-align property works when you use display: table-cell.
If this is new to you, read The Anti-hero of CSS Layout — “display:table”. I wouldn’t suggest you use this today as your main layout method, but it can be very helpful as a fallback.
When you use display: table-cell to create columns, CSS will create what is known as anonymous boxes. These are the missing parts of the table — a table cell in a real HTML table will be inside a tr element, and that will be inside a table element. The anonymous boxes essentially fix up these missing parents. If your table-cell item becomes a Grid Item however, this happens before the boxes are generated and so once again the item will act as if the CSS tables display had never happened.
The vertical-align property does not apply once in Grid Layout either and so if you use it in a CSS tables layout or with inline-block you can safely ignore that and use Box Alignment for Grid Layout. You can see a layout that uses display: table-cell and vertical-align overwritten by Grid Layout in this next CodePen.
You can also use Flexbox as a fallback, if you have used the flex property or individual flex-grow, flex-shrink or flex-basis properties on the item these will be ignored once it becomes a Grid Item.
Finally, don’t forget that Multi-column layout can be used in some cases as a fallback. For example, when laying out a list of card components or images. It will display items in columns rather than across the row but in some circumstances can be useful. You apply column-count or column-width on the container to make it a multicolumn container, if you then apply display:grid the column-* behaviour will be ignored.
Feature Queries
In the majority of other layout methods, we target the individual items rather than their container. For example in a floated layout, we have a set of items that we have given a percentage width and then set to float: left. This causes them to line up next to each other. As long as we don’t end up with more than a total of 100%, we can make something that looks like a grid.
.grid > * { float: left; width: 33%;}
If we then turn that layout into a CSS Grid Layout, we create a grid on the parent. The only thing we apply to the items is an instruction as to how many columns to span.
In our old layout we have floated items with a size applied, in our new layout those items become Grid Items, and typically we don’t want to give those items a size, as they will get that information from the grid tracks that they span.
It is here that we come to an issue with simply being able to override one layout method with another. In the example of a floated layout where the items have been given a percentage size, once that item becomes a Grid Item the size becomes a percentage of the Grid Area it is in and not a percentage of the overall container width. You can see this by using the Firefox Grid Inspector to highlight the lines — the items are now squashed to one side of the Grid Cell.
This is where Feature Queries can help. Feature Queries act much like a Media Query, instead of checking for the width or orientation of a device, we check to see if the browser supports a CSS feature.
In our example of a floated layout that we want to turn into a grid layout, we only need to override one thing inside the Feature Query — we want to set the width back to auto.
How much overwriting of CSS used for nonsupporting browsers you need to do depends on how much you have decided to create a different layout for those older browsers.
The IE10 And 11 Version Of Grid Layout
While Edge has now updated to the modern grid layout, IE10 and 11 only have support for the early version first shipped with a -ms prefix in those browsers. The Grid specification that we know of today came originally from Microsoft. So far from being unhappy about this old implementation, we should be glad they kickstarted the process and gave us Grid in the first place. You can read more about the story in the article The Story of CSS Grid, from Its Creators.
You might decide to offer IE10 and 11 a fallback experience based on a floated or other layout type as described above. This will work well, as will using Feature Queries, which are not supported in IE10 and 11. As long as you use these to overwrite your older methods checking for support, then creating the version for supporting browsers, IE10 and 11 will continue to use the older method.
You could however make use of the -ms-grid version to create a fallback method. However this prefixed version is not the same as modern Grid Layout, it was the first version and experimental version. Things have changed in the five years or so since it shipped. This means you can’t just use autoprefixer to add the prefixes, that approach will probably leave IE10 and 11 users with a worse experience than if you do nothing at all. Instead, you need to create a layout using this different and more limited spec.
The key points to note are as follows:
There is no auto-placement. You need to place each item on the grid using line-based positioning.
The grid-template-areas ascii-art method of positioning is not part of the implementation.
There are no grid gap properties.
Instead of specifying start and end lines, you specify a start line and the number of tracks to span.
If you have a large number of users with these browsers then you may find that this old spec is helpful. It is definitely worth knowing it exists even if you only use it to solve a couple of small issues that are real showstoppers for you.
Why Bother Using Grid If I Have To Support These Browsers?
If you have non-supporting browsers in your list, and you have to offer them an identical experience to supporting browsers then I would indeed question whether to use Grid Layout, or any new CSS. Use the methods that work. That approach is still perfectly valid.
You might still consider using Grid Layout with a high level of fallback if you know that within the short-term it is likely that you will be dropping a bunch of those browsers from the “must be identical” list. Especially if you know the development you are doing now will have a long shelf-life. You could then lose the fallbacks at a later date and only use the Grid version.
However, support for you may mean that it is possible for non-supporting browsers to get some level of simplified experience, and there are things you want to do with Grid Layout that are essentially impossible without it. That’s the time to use Grid Layout and design a good non-grid experience for those browsers.
Testing Fallbacks
A final note on testing these fallbacks. The only real way to test your fallbacks is to have access to browsers that do not support CSS Grid. One way to do this, without buying a stack of extra computers, is to download the Virtual Machines offered by Microsoft. You could then test using a version of Internet Explorer without support.
You could download UC Browser onto a phone, or use the desktop version on Windows or in a Virtual Machine.
There are also tools such as BrowserStack which give you access to remote Virtual Machines running a whole range of browsers. These services aren’t free, but they can save you a lot of time setting up VMs for testing.
I have seen people recommend switching your Feature Query to test for something that doesn’t exist — such as testing for support of display: gridx. This will work reasonably well. However, you do then need to put all of your Grid code inside the Feature Query Block, rather than relying on the fact it is ignored by browsers that don’t support it. You could easily end up with a false positive result by not realizing that some Grid code had wound up outside of a Feature Query. Even if you are using this method for quick checks, I would highly recommend doing some testing on actual browsers too.
Further Reading
I’ve rounded up the URLs referenced in this article and also some additional resources to help you navigate your own path to supporting browsers while still taking advantage of new layout. If you have come across any good resources, or particularly tricky issues, add them to the questions. Grid Layout is still new to all of us as something we can use in production, so there are bound to be some unanswered questions we can take a look at.
If anything’s clear in 2017, it’s that lying is back in fashion (if it ever left us at all). From the heated fake news debate to the false data provided by Facebook, lying is all the rage these days. A white lie here and there is no big deal. We’re all guilty of it. The problem arises when lies turn into full-grown myths, then become accepted as truths.
In an era of digital chaos, we understandably gravitate to our trusted sources of information. For us designers, this usually means guidelines as defined by juggernauts such as Google and Apple.
With the impending switch to a mobile-first search engine world, myths about mobile interfaces are on the rapid rise. As we transition to a mobile-first world, I’d like to remind designers to see guidelines for what they are: guidelines. Somehow, many mobile concepts have evolved into biblical truths, when their intent might rather be case by case.
Having white-labeled design and marketing work for ad agencies for a few years, I’ve heard the following statements boldly proclaimed as unquestionable truths more times than I can count. From my experience with ad teams and client meetings, these are the most frequent myths I think we need to put to bed, or at least remember to evaluate case by case.
Let’s take some time to cover five mobile interface myths you’ve probably been sold on (and why that might be a bad thing).
To Use Or Not To Use
Many criticize gestural controls as being unintuitive and unnecessary. Despite this, widespread adoption is underway already. Read a related article →
Myth 1: Mobile Users Are Always In A Hurry
The prevailing wisdom about mobile users is that they’re always in a rush.
They’re easily distracted, they hate tapping, they have bad taste, and they’re overwhelmingly suspicious of anything laid out in front of them.
While these ideas are rooted deep and might have pieces of truth, they’re not the full picture. Furthermore, one-size-fits-all statements don’t make much sense in an increasingly niche-audience Internet. What works for some webmasters doesn’t necessarily hold true for others.
The Truth: Get to Know Your Real Users
There’s no question that mobile speed is key, and Google’s AMP project serves as a strong reminder of the importance of website-loading time.
What’s less discussed is that you’ll never know which (if any) of these stereotypes apply to your website unless you get to know your target audience.
Take the following company. We could argue over this screenshot all day, but let’s not dive too deep into the analytics. Just compare the website’s “Device Category” column with the “Average Session Duration” column on the far right:
You’ll notice almost no difference in time spent on site when comparing desktop and mobile session durations. In this company’s case, most website visitors come from organic search, so this screenshot is fairly representative of the website’s overall traffic.
In this case, mobile users don’t seem to be in a hurry. Should we assume that all websites have analytics like these? Of course not. Should we assume that session duration is the perfect and only indicator of conversions? No.
Take a longer look at this screenshot and you could accurately find that the bounce rate is higher on mobile and that the percentage of sessions skews heavily towards desktop, as well as a number of other interesting discrepancies. My point is not that session duration means everything, but that each website’s audience behaves differently and that you need to understand your unique audience. Then, optimize accordingly.
Here’s what you should do to better understand your audience:
Know the goals of your website. Do you plan on using the website or app as a new revenue stream? Do you want to outdo your competitors by showing how innovative you are?
Find out who your target audience is. A buyer persona might come in handy for this. Get inside their heads. What do they need? What are they looking for? What problems are they trying to solve? Are they ready to sit and read long posts? Do they prefer a quick video?
Test your ideas. Before rolling out any changes, make it a point to gain customer feedback. Do not hesitate to test. Knowing what works and what doesn’t ahead of time will facilitate your design and development process.
Spend time reviewing your own website’s analytics, and work to understand your audience’s intent, which is hiding behind the raw numbers.
Myth 2: Mobile Websites Require Fewer Features
I’m sure we all remember how we typically used the Internet nearly 10 years ago — we were primarily looking for time-sensitive content. Back then, our needs were rather immediate and specific.
People on mobile websites had little to no intent to explore or purchase anything. Data connections were slow and expensive. It made sense to design mobile websites for pared-down tasks, offering the bare minimum. Publishers adopted an “if in doubt, leave it out” mentality, and if users wanted to view the full website, they’d need to hop onto their PC or Macintosh.
This just isn’t the case anymore.
The Truth: Prioritize and Maximize Mobile Capabilities
Nowadays, when someone visits a website on their mobile device, they expect to see everything that the desktop version offers. The practical way to accomplish this is to prioritize and maximize the capabilities of mobile features, including:
taking advantage of mobile sensors’ superpowers, something that desktops don’t have;
adding more content and features to a mobile website — depending on your user’s goals, this could mean adding share buttons pinned to the bottom of the screen or quick-tap functionality to return to the top of the page;
building your website or blog to adapt to the particular needs of each device type.
The idea is to get rid of the thought that a smaller screen indicates less intent among users to explore. Instead of eliminating features on mobile, prioritize them.
Layout
Offer users the same useful features that you would on your desktop website, while keeping in mind the screen-size limitations.
Interstitials
Common wisdom (and probably your experience) tells you that popups are annoying and that you should delete them immediately. Here’s the problem with this advice: You still need to encourage signups, downloads and so on for mobile visitors.
The key is to prioritize this content, not eliminate its purpose.
Myth 3: Simplicity Is Good, Complexity Is Bad
Closely related to myth 2, the next myth is one of the most widely held beliefs in the industry. When it comes to websites and apps, “less is more,” right?
This myth states that mobile applications should be the “light version” of a desktop website. This comes from the principle that the organic interface has to be as close to zero as possible.
Marissa Mayer famously discussed the two-tap rule: The fewer the clicks needed to achieve a goal, the better.
A ton of designers tend to treat mobile and desktop as two different creatures, with opposing needs. Yes, there are significant limitations to a mobile device’s capabilities (namely, screen size). However, the intent of a user doesn’t drastically change, whether they’re using their mobile device or a desktop computer.
So, why should the mobile interface be simpler?
The Truth: Embrace Complexity
Depending on your website or app’s users, this myth could ring true.
Could you imagine needing eight taps to send snaps on Snapchat? Me neither.
The point is more that mobile users don’t want a dumbed-down version of a website. People simply need complexity presented in a way that’s uncomplicated. It all boils down to giving a good user experience. Consider the following:
Have one big idea per screen.
Instead of sending elements to secondary pages, you could put more content under properly labeled display elements.
Requiring more taps on a screen isn’t necessarily a bad thing. The idea is to make the website’s screen clear and easily digestible, rather than cluttered and dense. If a click has a goal to it, it can stay.
Take Circlebox Creative:
A lot is involved in creating a profile. Is this a personal user? Is it a business profile? Will you choose social login? Email login? This signup process incorporates a lot of information but doesn’t feel overwhelming because it’s easily digestible.
Complexity is not the bane of mobile design. When you build your website, you just need to make it enticing and user-friendly.
Myth 4: Guidelines Cannot Be Broken
Most designers treat guidelines as gospel, and for a decent reason.
Many times, guidelines are incredible resources, to be followed as instructed. Google’s material design is a great resource for understanding how to craft digital experiences using a consistent set of principles.
Designers often hold that applications created for iOS should follow Apple’s guidelines and that apps made for Android should follow Google’s guidelines, and that if an app needs to be accessible on both operating systems, then the designs should be entirely different from each other.
The problem arises when designers find themselves stuck between a rock and a hard place, where they envision a design that conflicts with the guidelines.
Should they follow guidelines? Or can they trust their design instincts for each unique case?
The Truth: Treat Guidelines as Recommendations
The dictionary defines a guideline as a “general rule, principle, or piece of advice.” A guideline is intended to serve as a loose guide or as helpful suggestions, not a strict mandate to obey.
Design is an exploration to discover what works best.
– Google Design
If your intended design severely clashes with conventional guidelines, you’ll need to weigh whether this is an indicator to rethink your layout approach or whether you’re simply designing with your unique users’ needs and intentions in mind.
To put this myth to bed, Google even ignores its own material design guidelines (on occasion). Take its icons:
To paraphrase Android Authority, Google’s icons fly in the face of product-icon anatomy. The guideline states that you shouldn’t crop elevated material elements within another shape, meaning that the uppermost layer shouldn’t have its boundaries defined by the lower layer.
The icons for Movies, Music, Games, Books and Newsstand all are beautifully designed, while defying this straightforward guideline. These icons have also done away with the 45-degree light source that is commonly encouraged for all icons.
On the whole, Apple and Android guidelines are a tremendous gift. However, don’t treat them as hard and fast rules. Always design with your users in mind, even if that means bending some of the guidelines.
Myth 5: The Designer And The User Think The Same
This myth is more of a commonly held belief carried out in practice, rather than an actual myth. Of course, the first rule of user-centered design is that you are not the user. But, so often, clients and designers fall for the “we know what’s best” approach.
It’s tempting to think that everybody thinks just like you.
Often, designers fall into the trap of thinking like their client or thinking of themselves when approaching design. “Would I like this feature if I implemented it?” or “Would my client tap on this button if I placed it here?” are questions that fall under this umbrella.
The problem with this is that you lose sight of who you’re designing for: the user.
The Truth: Users Have Experiences Unique From Yours
It’s possible that the demographics of your users include yours or your client’s. However, you’ll need to look at design from the perspective of your visitors, not of your client.
This is true for a couple of reasons:
Users only want what’s beneficial for them. You, as a designer, are able to come up with ideas to present a product in a way that you think would engage the user. However, these ideas will only matter as long as they are beneficial to the user. If the user doesn’t find value in it, they won’t enjoy engaging with the content you produce.
Users only want their problems to be solved. The client knows more about the business than the user. They immerse themselves in the industry, studying it, learning its ins and outs. This data isn’t of interest to the user, who only wants their problems to be solved. The client is all about gaining profit; the user is all about finding solutions. Sometimes these interests overlap, but keep your eye on user needs first and foremost.
I’m hardly a usability testing expert, but I’ve been thinking about how my team could use a significantly simplified version of user testing for an upcoming website redesign. Here’s the basic outline of user testing I have in mind:
Gather an unbiased group of individuals.
Do not disclose which website is being tested, to avoid bias. Instead, show several websites sequentially, including our website and competitor websites.
For each website, walk individuals through each page, discussing the intended user flow, mission, etc.
Let each individual test how they would achieve the tasks, while providing no indication of how you think the goals should be completed.
Test on various devices and connections, to compare between devices.
Ask each individual to write down any issues they run up against, while trying to achieve the stated purpose for each page.
Ask each participant to grade each website, asking for their feedback on accessibility, speed, UX, navigation, readability, the overall score, etc.
Repeat these observations over time to identify new recommendations.
This is not a perfect scenario, but it enables us to define a preliminary report of usability issues and observations, and to pinpoint key recommendations for our work moving forward.
Summary
If I had to encapsulate the sections above, along with what I’ve learned at my web design and marketing agency, it would be this: Test, test, test. And then test again.
Takeaways
Understand your audience and purpose. Determine the goals of your website, find out who your target audience is, and test your ideas to gain useful data about your visitors.
Maximize mobile capabilities. Take advantage of the superpowers of mobile sensors, add mobile-specific features, and adapt to the specific needs of each device and mobile operating system.
Embrace complexity. Have one big idea per screen. Put content under properly labeled display elements, instead of on secondary pages. And make sure the screen is clear and easily digestible, rather than cluttered and dense.
Treat guidelines as useful recommendations, not mandates. Guidelines can serve as helpful suggestions. But, ultimately, design is an exploration to discover what works best.
Work to understand your audience’s unique points of view. Try employing mobile usability testing to better understand your visitors’ needs.
Make time to track and analyze the analytics for how your audience responds to your company’s split-testing efforts. Don’t take anybody’s word for it (including mine).
Observe what your visitors are doing, anticipate their needs, and design for their approval and convenience. Over time, you’ll gain a deeper understanding of your unique audience and will naturally attract a growing number of visitors eager to engage with you and your business.
When a user of your application has forgotten their password, it can and should be reset securely. To accomplish a secure password reset, I will demonstrate how to use JSON Web Tokens (JWT) to generate a URL-safe token. The JWT contains encoded information about the user and a signature that, when decoded, is validated to ensure that the token has not been tampered with.
Once the JWT is validated, your application can securely allow the user to generate a new password, instead of sending them their forgotten one.
“Why Can’t I Just Send The User Their Password?”
There was a time when your password was stored in your favorite website’s database just as you typed it. In fact, it still seems to occur far too often. An entire website is dedicated to telling people whether their email address or username has been exposed.
In those days (and I use the past tense loosely), when a user forgot their password, they would arrive on a page that asked for their username or email address. The website would then send them an email “reminding” them of their password. This should be a red flag to you, as both a user of the website and as a developer. Either your password is stored in plain text or it can be decrypted, instead of having the much stronger, more secure one-way encryption.
Because (secure) passwords cannot be decrypted, that leaves us with one of two common choices when a user forgets their password:
Generate a new, temporary password and send it via email.
Generate an email that contains a one-time-use link within the contents of the email, which will take the user to a page where they can enter a new secure password.
Both options send out an email, which in the long term should not be considered a secure storage medium. With the first option, the password is shown in plain text. If the user were to leave this email in their inbox as their method of remembering their password (especially because they didn’t choose it), it would be almost as insecure as writing down their password on a sticky note and leaving it beside their computer. OK, not that bad, but you get the idea.
Another concern with option one is that a malicious user who knows their email address could easily lock out a user from the website by resetting their password. If the malicious user repeated this over and over again, it would make it almost impossible for the user to ever log in again because their password would never remain the same.
Password-Reset Process Overview
The goal of this tutorial isn’t to learn how to secure your users’ passwords in your database; you’ve already done that! This tutorial will show you how to reset the password of a user who has forgotten theirs by generating a special link that enables them to securely reset their password. The link will look similar to the following example:
Contained within this link is a special JWT that is used to securely validate the user who is trying to reset their password.
By the end of this tutorial, I will have walked you through creating an application that contains the following functionality:
We’ll have a form that accepts the email address of a user who has forgotten their password.
We’ll create a link with a JWT token embedded in the URL. The user will click this link and be allowed to reset their password.
We’ll create a page for resetting the password. This page will require the token and will decode it to ensure it is valid.
When the token has been successfully validated, a form will be displayed allowing the user to reset their password.
The following is an application diagram that demonstrates what the user does and how the server processes and responds to each action initiated by the user.
I mentioned earlier that email should not be considered secure for long-term storage. To help prevent this issue with option two, the link contained in the email is to be used once. Once the user has clicked the link and changed their password, if they (or a malicious person) were to click the link again, it would not be valid and the user would be unable to change their password. The user would, thus, be forced through option two again: generating a new email with a new one-time-use link.
This solution also prevents the secondary negative side effect of option one. If a malicious user were to attempt to constantly reset the user’s password, the original password would be unaffected and the user would never be locked out.
Before creating the application, let’s better understand what JWTs are and learn how to create, encode and decode them.
What Are JSON Web Tokens?
A JSON Web Token (JWT), in its simplest form, is a URL-safe string that contains an encoded JSON object. JWTs are an open industry standard that are fully described in RFC 7519, which contains an immense amount of detail, specifically regarding how JWT claims function to ensure the security of a generated token. Feel free to peruse the full RFC specifications at your leisure.
Notice that the token contains two periods (.) separating the three pieces of the outputted token, those three pieces being the following:
header
The header contains information that identifies what the hashing algorithm is, so that it can be used to properly decrypt and validate the signature.
payload
This contains the information you wish to send with your JWT. Note that the payload is not secure and can be decoded without a secret key. JWTs are not meant to send sensitive information, such as passwords or credit card numbers.
signature
The signature combines the encoded header and the payload with a secret key and securely encodes it using the hashing algorithm defined in the header — for example, HMAC with SHA-256.
To summarize, each time you generate a token:
the header will remain constant (assuming you do not change the hashing algorithm);
the payload will remain constant when the payload to encode is the same;
the signature will encrypt these two pieces of information based on the hashing algorithm with a secret key. This means that if you do not generate a unique secret key or change the payload, then the signature will also remain the same.
Encoding And Decoding JWTs
We are going to create a new application to demonstrate the basics of encoding and decoding tokens. Once we have a solid understanding of JWTs, we are going to recreate the application and I’ll demonstrate how to securely reset a user’s password.
To begin, please ensure you have Node.js installed. If you do not have it installed, I suggest visiting the download page and selecting the appropriate installer for you.
Our new application will be named “passwordreset.” In a command prompt, I ran the following commands to create a basic application. Ensure that you start in the current working directory of where you wish to host your Node.js application.
mkdir passwordresetcd passwordresetnpm init
The npm init process asks a lot of questions to help you customize your final package.json file. In my case, I have left everything as their defaults.
Creating Our First JWT
To make generating JWTs easy, we are going to use an existing npm package named JWT Simple, which will obfuscate a lot of the complexities of encrypting and decrypting a token.
To install the package, in your command prompt where your application resides, enter the following command:
npm install jwt-simple --save
In this first code example, I have created a new index.js file, which creates a JavaScript object that I encrypted into a JWT:
Let’s look at what is happening. The application begins by including the JWT Simple module. We then create a payload object. This object is what we will be encoding inside the token. We have created an object that contains a single property, named userId. I’ve used a hardcoded value of 1.
A token needs to be encrypted (and decrypted) with a secret key. I’ve generated a random string that will be used each time (in this sample application).
With the prerequisites set, we are finally able to create our token. This is done by calling the encode function from the JWT Simple module. This function accepts our payload and the secret key. The result of this function is our URL-friendly token, which contains our encoded header, payload and signature. The final line outputs our token to the console.
Running our application will output the following:
As you might have observed, this is the same token from earlier that I broke apart and whose three parts I described (header, payload and signature). Let’s now update our index.js file to decode the token and log it to the console:
var decode = jwt.decode(token, secret);console.log(decode);
Now, when we run the application, we receive the following output:
Yep, our token was successfully decoded and contains our userId property, with the correct value of 1!
If the token was tampered with and any of the three parts were not able to be decoded and decrypted, then the JWT Simple module would throw exceptions.
Resetting The User’s Password
Let’s put our JWT knowledge to good use and create the final application, allowing the user to reset their password. To focus on the one-time-use password-reset link, we will not implement a database or an email. Nevertheless, our application will contain the following functionality, with several comments about where the application could be enhanced to integrate those features:
The application will display a form that accepts the user’s email address.
It will handle the form’s POST with the user’s email address.
This will create a link, with a JWT token embedded in the URL. The user will click this link and be allowed to reset their password.
The application will create a password-reset page. This page will require the token and will decode it to ensure it is valid.
If successful, a form will be displayed allowing the user to reset their password.
The application will handle the form’s POST with the user’s new password.
This page will also decode and validate the token before saving the new password.
It’s now time to create the application to reset the user’s password, leveraging JWTs to validate the user throughout the process.
To handle the HTTP communication, we are going to use the Express module. We will also be using the BodyParser module to parse the content from our form’s POSTs.
These can be installed by running the following commands in your project’s working directory:
We will be pseudo-coding the spots where we would be leveraging a database and sending emails, in order to keep this article focused on how JWTs are used throughout the password-reset process. I am going to repurpose my previously created index.js file for the final application.
The following code examples will all be subsets of my full index.js file, allowing me to incrementally demonstrate the process that I am building.
The first thing we need to do is include the required modules and create a web server that allows the user to reset their password:
const express = require('express');const bodyParser = require('body-parser');const jwt = require('jwt-simple');const app = express();app.use(bodyParser.urlencoded({ extended: false }));app.listen(3000, function () { console.log('Node started on port 3000!')});
The first three lines include the modules required to serve the web pages, parse our forms and encode and decode our JWTs.
The next set of lines set up Express to listen on port 3000 for HTTP requests, and they initialize the BodyParser module to decode standard form data.
With our web server set up, the next set of code will display a form that asks the user for their email address. This will begin the password-reset process:
This page can be accessed via http://localhost:3000/forgotpassword. The form it creates will POST to passwordreset with the user’s email address. Our basic form looks as follows. Once the user has entered their email address and submitted the form, our application needs to handle it:
app.post('/passwordreset', function (req, res) { if (req.body.email !== undefined) { var emailAddress = req.body.email; // TODO: Using email, find user from your database. var payload = { id: 1, // User ID from database email: emailAddress }; // TODO: Make this a one-time-use token by using the user's // current password hash from the database, and combine it // with the user's created date to make a very unique secret key! // For example: // var secret = user.password + ‘-' + user.created.getTime(); var secret = 'fe1a1915a379f3be5394b64d14794932-1506868106675'; var token = jwt.encode(payload, secret); // TODO: Send email containing link to reset password. // In our case, will just return a link to click. res.send('<a href="http://www.smashingmagazine.com/resetpassword/' + payload.id + '/' + token + '">Reset password</a>'); } else { res.send('Email address is missing.'); }});
Quite a bit is going on here, so let’s break it down:
We ensure that the POST’s body contains the email property. If it doesn’t, then a basic error message is returned to the user.
Store the email from the POST’s body in a local variable, emailAddress.
Now our first pseudo-code occurs. I’ve placed a TODO message that says you should search your user database for a valid user with the email address supplied.
Next, we generate the payload for the token. My payload consists of the user’s ID and email address.
To make this token a one-time-use token, I encourage you to use the user’s current password hash in conjunction with the user’s created date (in ticks) as the secret key to generate the JWT. This helps to ensure that if the user’s password was the target of a previous attack (on an unrelated website), then the user’s created date will make the secret key unique from the potentially leaked password.
With the combination of the user’s password hash and created date, the JWT will become a one-time-use token, because once the user has changed their password, it will generate a new password hash invalidating the secret key that references the old password.
Because we don’t have a database, we are simply using a static string.
The token is then generated using our payload and secret key.
The final bit of pseudo-code occurs, to send the password-reset link to the user’s email address in an email.
To continue focusing on how tokens are being used, let’s return the link to the browser. This can be clicked to finish the password-reset process. This link would be the same link that the user clicks in the email they received.
In all cases where you send an email to the user, the response should indicate that an email has been sent to the user and instruct them to click the link in the email.
When the user receives the email, they will click the link that takes them to the password-reset page. This page accepts the user’s ID and token as URL parameters (which were set in the link generated in the previous code example). The following code will handle this page. Upon successful decoding and validation of the token, a form is displayed allowing the user to set their new password:
app.get('/resetpassword/:id/:token', function(req, res) { // TODO: Fetch user from database using // req.params.id // TODO: Decrypt one-time-use token using the user's // current password hash from the database and combine it // with the user's created date to make a very unique secret key! // For example, // var secret = user.password + ‘-' + user.created.getTime(); var secret = 'fe1a1915a379f3be5394b64d14794932-1506868106675'; var payload = jwt.decode(req.params.token, secret); // TODO: Gracefully handle decoding issues. // Create form to reset password. res.send('<form action="/resetpassword" method="POST">' + '<input type="hidden" name="id" value="' + payload.id + '" />' + '<input type="hidden" name="token" value="' + req.params.token + '" />' + '<input type="password" name="password" value="" placeholder="Enter your new password..." />' + '<input type="submit" value="Reset Password" />' + '</form>');});
Similar pseudo-code from the previous example has been included in this example to help secure the application:
Using the ID from the URL parameters, we fetch and validate that the user exists in our database.
We decode the token from the URL parameters. To ensure it is a one-time-use token, I encouraged you in the previous example to encode it with the user’s current password hash in combination with the user’s created date (represented in ticks); thus, it should be decoded with that same hash.
This is how it becomes a one-time-use token. Once the user has successfully changed their password, if they attempt to use the same token again, the token would not decode properly because the password hash would be different for that user.
It would be a good idea to gracefully handle any errors that occur while decoding the token.
Finally, a new form is returned that places the ID and token as hidden form fields and that includes a form field to accept the new password.
This is an example of our basic form for the user to reset their password.
The final part now is to handle the form’s POST with the user’s new password:
app.post('/resetpassword', function(req, res) { // TODO: Fetch user from database using // req.body.id // TODO: Decrypt one-time-use token using the user's // current password hash from the database and combining it // with the user's created date to make a very unique secret key! // For example, // var secret = user.password + ‘-' + user.created.getTime(); var secret = 'fe1a1915a379f3be5394b64d14794932-1506868106675'; var payload = jwt.decode(req.body.token, secret); // TODO: Gracefully handle decoding issues. // TODO: Hash password from // req.body.password res.send('Your password has been successfully changed.');});
The first part of this code is nearly identical to the previous example where the pseudo-code fetches the user and decodes the token with their current password hash, and the user’s created date is converted to ticks.
Notice the minor change in accessing the user’s ID and token. In the previous example, we used req.params. In this example, we are using req.body. The difference is that the first example was a GET request with the variables in the URL. This example is a POST request in which the variables are in the form.
The final TODO is for you to hash the user’s new password once the token has been validated.
This completes our sample application, which uses a single JWT to allow the user to change their password if they have forgotten it.
Additional Password-Reset Security Measures
Our application focuses specifically on securing the password-reset form by generating and validating a special link embedded with a JWT.
This is just the tip of the iceberg to ensure that the entire password process is more secure. Below is a list of several other enhancements that could further secure your website:
Limit the number of password-reset attempts to prevent a malicious user from giving your end user a negative experience of flooding their inbox with password-reset emails.
Always indicate success when the user enters their email address in the forgotten-password page.
Ensure that your website uses HTTPS to prevent any plain-text communication between the user and server when they are entering or resetting their password.
Ensure that the user’s new password is secure and is not the same as their last password.
Implement a CAPTCHA — the “Are you a human?” test — on both the forgotten-password and password-reset pages. Some websites even implement the CAPTCHA test on the log-in screen.
Implement forgotten-password security questions, where the user must answer a security question (that they’ve previously created) before an email is ever sent to reset their password.
“How Else Can I Use JWTs?”
By now, I’ll bet you are addicted to creating and consuming JWTs! Now you want to use them more. Here are a few examples of how else I have used them:
Single sign-on
A friendly third-party website would generate a JWT with information that your website would require to authenticate the user in your application. You and the friendly website would privately share the secret key used to encode and decode the token.
Information exchange
Similar to single sign-on, you or the friendly website would generate a token with a privately shared secret key that contains the information you wish to send or receive. Be sure not to share sensitive data!
Note that, because a generated JWT is a string, it can be decoded by a server other than the one that generated it. For example, you might generate a token with your Node.js server, and I could consume it with my PHP application as long as we use the same secret key and hashing algorithm!
Conclusion
Almost every day, we hear about a new security leak. And, let’s be honest, locks only keep out honest people. This means that, as developers, we need to try harder to make better locks. A JWT provides a URL-safe token that, when generated securely, makes for a more secure password-reset process by ensuring that a malicious user cannot easily generate their own token.
This article focused on the password-reset process by securing the password-reset flow with a URL-safe token that is validated with a signature. If you haven’t already done so, I suggest enhancing your processes further by reviewing the additional password-reset security measures and adding the ones that work for you.
If you have any further security processes, be sure to leave a comment below to help your fellow developers ensure that their password policies are more secure.
(This is a sponsored post). Testing is a fundamental part of the UX designer’s job and a core part of the overall UX design process. Testing provides the inspiration, guidance and validation that product teams need in order to design great products. That’s why the most effective teams make testing a habit.
Usability testing involves observing users as they use a product. It helps you find where users struggle and what they like. There are two ways to run a usability test:
Moderated, in which a moderator works with a test participant.
Unmoderated, in which the test participant completes the test alone.
We’ll focus on the first, but some of the tips mentioned can be applied to both types of testing.
1. Test As Early As Possible
The earlier you test, the easier it is to make changes and, thus, the greater impact the testing will have on the quality of the product. A lot of design teams use the excuse, “The product isn’t done yet. We’ll test it later,” to postpone testing. Of course, we all want our work to be perfect, which is why we try to avoid showing a half-baked design. But if you work too long without a feedback loop, the chances are higher that you’ll need to make a significant change after releasing the product to the market. It’s the classic mistake: thinking you’re the user and designing for yourself. If you can invest energy to learn early and prevent problems from happening in the first place, you will save a tremendous amount of time later.
The good news is that you don’t need to wait for a high-fidelity prototype or fully formed product to start testing. In fact, you should start testing ideas as soon as possible. You can test design mockups and low-fidelity prototypes. You’ll need to set the context for the test and explain to test participants what’s required of them.
2. Outline Your Objectives
Before starting usability testing, be crystal clear on your goals. Think of the reason you want to test the product. What are you trying to learn? Ask yourself, “What do I need to know from this session?” Then, once you understand that, identify exactly which features and areas you want feedback on.
Here are a few common objectives:
Find out whether users are able to complete specified tasks successfully (e.g. purchase a product, find information),
Identify how long it takes to complete specific tasks,
Find out whether users are satisfied with a product and identify changes required to improve satisfaction.
3. Carefully Prepare Questions And Tasks
Once you have an objective, you can define which tasks you’ll need to test in order to answer your questions or validate your hypothesis and assumptions. The objective is not to test the functionality itself (that should be a goal of the quality assurance team), but to test the experience with that functionality.
Actionable Tasks
When designing tasks, make them realistic and actionable. These could be specific parts of the product or prototype that you want users to test — for example:
Getting started with the product,
Completing a checkout,
Configuring the product.
Prioritize Tasks
Don’t squeeze in many subjects in your usability testing checklist. Conducting the tests and analyzing the results will take a lot of time. Instead, list the important tasks in your product, and order them by priority.
Clearly Describe Tasks
Testers need to know what to do. Make it easy. Users tend to become discouraged when tasks are unclear.
Have a Goal For Each Task
As a moderator, you should be very clear about the goal of a task (for example, “I expect that users will be able to complete the checkout within two minutes”). However, you don’t need to share that goal with participants.
Limit The Number Of Tasks
Patrick Neeman of Usability Counts recommends assigning five tasks per participant. Considering the time of the session (usually 60 minutes), leave time for your questions, too.
Provide a Scenario, Not Instruction
People tend to perform more naturally if you provide them with a scenario, rather than dry instruction. Instead of asking them something like, “Download a book with recipes,” you could phrase it as a scenario, like, “You’re looking for some new ways to cook beans. Download an ebook with recipes.” A scenario provides some context and makes the task more natural for the user. The more naturally participants perform the task, the better the data you will get as a result.
Test The Set Of Tasks Yourself
Go through the task several times yourself, and work out appropriate questions to ask. It’s hard work but will definitely pay off.
4. Recruit Representative Users
Finding the questions you want to ask is important, but also, the people who participate in your test should be representative of your target audience (user persona). There’s no point in watching people use your product if they don’t match your target audience. Therefore, as soon as you have some idea of what to test, start recruiting. Carefully recruit people based on your goals. Be advised: Finding people for usability tests is not easy. In fact, recruiting is one of the biggest reasons why many companies don’t regularly talk to their users. Thus, put in the extra effort to find people who represent your target audience.
Analyze Existing User Data
If your product already has a customer base, then a quick analysis of available information (for example, analytics data, customer support tickets, surveys, previous usability sessions) will help you assess what you already know or don’t know about your users.
Test With Users Who Aren’t Only Friends or Family
Of course, feedback from friends and family is better than nothing, but for better results, you’ll need independent and unbiased users, ones who haven’t used your product before. Your friends and family are too close to the product to know how real people would perceive it for the first time.
Define Your Criteria
Before recruiting users, you’ll need to decide on the type of people to test your product. Define criteria and select testers according to it. For example, if you are testing a mobile app for ordering food, most probably you’ll need feedback from people who order food regularly. Translate this requirement into precise, measurable criteria, so that you can use it to screen prospective participants: people who order food at least once a week from different delivery services (participants should have experience with at least three services).
In addition to specifying the users you want to talk to, think about people you don’t want to see in any of your sessions. As a rule of thumb, avoid testing with tech-savvy users and early adopters, because such testing might not be as revealing as you’d like. Also, avoid participants who have conflicts of interest (such as ones who work for competitors).
Create Screener Questions
Next, create a screener questionnaire to identify people for your testing sessions. As with any good survey or questionnaire, avoid leading questions. An example of a question that would reveal the “right” answer is, “Do you like ordering food using a smartphone?” Most people who want to join a testing session would surely answer yes to that question.
You can prepare a list of questions in the format of a survey and ask potential testers to fill it out. Google Forms is a great tool for creating screeners and collecting the responses in a spreadsheet. Because responses go right into a Google spreadsheet, you can sort and filter them.
Get People to Fill Out the Screener
Next, you’ll need to get people to fill out the screener. One way to achieve this is to create a job description with a link to your survey. In the description, explain your expectations, and offer an incentive to motivate people to show up (such as a $100 Amazon gift card for a 60-minute interview).
Craigslist, Twitter and Facebook are the most obvious places to post the job description.
Things will be a bit harder when you need to recruit very specific and hard-to-find types of users. But even in this case, it’s totally solvable:
Talk with your sales or marketing team to see if they have lists of contacts they can share.
Find contacts in relevant community groups and professional associations.
Tip: If your product is on the market, you could show a message — “Want to give us more feedback?” — somewhere in the user flow, which leads to your screener form. Also, if you use a service such as Intercom, you could automatically email new users after they have used the product five times, inviting participation in testing.
Think Quality, Not Quantity
Some product teams think they need a lot of participants for usability testing. In fact, testing with five users generally unveils 85% of core usability problems. The most important problems are easy to spot for people who are new to your product, and difficult for you to spot because you no longer have fresh eyes. It turns out that you’ll learn a lot from the first person you talk to, a little less from the next, and so forth.
Once you collect the responses and filter the list of potential participants based on your criteria, select the five candidates who fit your criteria the best.
Clearly Instruct on How to Join the Session
When you schedule a test session, provide all details in a confirmation email to participants:
The time (if you do remote testing, provide the time in the relevant time zone),
The location (including building, parking information, etc.),
What test participants need to bring with them (for example, personal ID, a mobile device with iOS or Android, etc.),
Your phone number (in case they have questions or need to reschedule).
To minimize frustrating no-shows, you could ask users to reply to confirm. For example, your subject line in the confirmation email could be something like, “Usability session scheduled on May 14 at 3 pm. (Please reply to confirm).” You could also call participants to remind them about their appointment on the day before the session.
5. Get The Most Out Of In-Person Testing
Hearing directly from users is one of the fastest ways to learn about and improve your product. By watching someone use your product, you can quickly identify areas where the product isn’t clear enough.
Building a Good Rapport
When a session begins, the participant might be nervous and unsure about what to expect. The quality of a usability session is directly related to the rapport you build with the participant. The deeper the participant’s trust in the moderator, the more frank their feedback will be. Conduct the test in a way that participants will feel comfortable giving you honest feedback.
A few things to remember:
In case of failure, people tend to blame themselves, rather than a flaw in the design. Thus, make sure they don’t feel like they’re being tested. (For example, “We’re not testing you; we’re testing our design. So, nothing you say or do is wrong.”)
You want participants to be as candid as possible. If they don’t like something or they think it’s silly, make sure they say so. Some participants don’t like to share such thoughts because they are afraid of hurting your feelings. Just tell them something such as, “You won’t be hurting our feelings. We haven’t been involved in designing these screens at all.”
Start with easy tasks or questions. They won’t yield any juicy insights, but they will get people talking and will help relax them. Learn a bit about the person. Try to find out what the person likes or doesn’t like, their hobbies, as well as tech habits. This information will help you better evaluate the results of the test.
Listen, Don’t Lead
Once you have presented the task, everything should be led by the participant. Your goal in this session is to understand how users will use the product. For example, if the participant takes an unplanned route through your app, don’t correct them! Wait to see what happens. This is valuable learning.
Don’t Judge Participants
Your participants are there to teach you something, not the other way around! Judging users or trying to educate them during the test would be counterproductive. Your goal is to get as much information as possible in the time available and to understand it all from their perspective.
Thus, avoid phrases like, “That was obvious, right?” and “Do you really think so?” while raising your eyebrows, even if something seems obvious. Instead, ask something like, “How easy or difficult was it for you to complete this task?” or “Why do you think that?” There should never be any judgement or surprise in either your tone or body language.
Don’t Explain
When you explain how the product you’re testing functions, you’ll almost certainly be introducing bias to the test. In the real world, your product will live on its own. You won’t be there to guide users along and tell them exactly what to do and how to use it. Participants should have to figure things out based on the task’s description and what they see in the interface.
Don’t Interrupt
When participants start a task, try your best not to interrupt them. The more you interrupt, the less likely they’ll have the confidence to complete the task. They’ll lose their flow, and you won’t see anything resembling natural behavior.
Don’t Draw Attention to Specific Issues
Drawing attention to specific issues that you care about could cause people to change their behavior and focus their answers on the issues you’re emphasizing. This problem is particularly common in discussions on user interface design: If you were to ask people about a particular design element (such as the color of the primary call-to-action button), they’ll notice it thereafter much more than they would have otherwise. This could lead participants to change their behavior and focus on something that doesn’t matter.
Use the Think-Aloud Technique
The think-aloud method is critical to getting inside the participant’s head. In fact, Jakob Nielsen argues that it’s the best usability tool. Using the think-aloud technique, the moderator asks test participants to use the product while continuously thinking out loud — simply verbalizing their thoughts as they move through the user interface. Using this technique for the food-ordering app, most probably you’d get responses like, “Hm, this looks like a food-ordering app. I’m wondering how to order food. Maybe if I tap here, I’ll see a form to request a meal.” The technique enables you to discover what users really think about your design and will help you turn the usability session into actionable redesign recommendations. Responses like, “Oh, it loads too slowly”, “Why am I seeing this?” and “I expected to see B after A” can be translated into actionable design changes.
Tip: Because most users don’t talk while using a product, the test facilitator will have to prompt them to keep talking. Ask something like, “What’s going on here?” when test participants interact with the product.
Observe Behavior
Mind the distinction between listening and observing. While both methods will provide UX designers with valuable information, many UX designers focus too heavily on listening. Observing users can uncover a lot more in a lot less time. You can learn a lot by listening to people, but you can learn way more by seeing how they react to a product.
Most people want to look smart, which is why during testing sessions, you’ll notice participants struggle through a task but then tell you that it was easy for them. Thus, focus on their behavior, not their opinion.
When in Doubt, Clarify
When you’re not quite sure what a participant is talking about, ask for clarification. A simple question like “When you said… did you mean…?” will make things clear. Don’t leave it to the end of the session. The end of a session is too late to go back and figure out what someone was talking about.
Follow Up With Questions
Be eager and curious to learn as much as you can about the user’s experiences and perspectives. Don’t settle for the first answer you get. Always dig deeper by asking follow-up questions. Follow-up questions will give you a lot of insight into what has really happened. People often can’t clearly state their motivations without being prompted. A simple well-timed follow-up question will usually yield a more thorough explanation or valuable example.
Answer Questions With Questions
During the session, participants will certainly ask you some questions. Here are some of the most common ones:
“Should I use it?”
“What do you think?”
“What did others think about this?”
Resist the temptation to tell them all about it! Ask them a question right back. It’ll reveal a lot.
6. Treat Design As An Iterative Process
A lot of product teams think about the design process as a linear process that starts with user research, has a phase for prototyping and ends with testing. However, treat it as an iterative process.
Testing, as much as coding, designing and gathering requirements, has a place in the iterative loop of product design and development. It’s important to test at each interval of this process, if resources are available.
Feedback Loop
The best way to avoid having to rework a product is to inject feedback into the process. Regular user feedback (not necessarily in the form of usability testing, but also in online surveys or analysis of customer support tickets) should be at the heart of the UX design process.
7. Don’t Limit Yourself To In-Person Sessions
Testing in-person is a great way to understand user behavior; unfortunately, it’s not always possible. What if you need to test only one small feature, or your test participants are dispersed (for example, if your product targets international customers), or you need results fast (ideally, today)? In this case, focus on remote testing. But how do you handle remote sessions?
Use Tools for Unmoderated Tests
Nowadays, a ton of tools are available for you to run remote unmoderated tests. Here are some:
This tool allows for both remote live moderated testing and unmoderated testing. Live sessions are automatically recorded in the cloud — no uploading, waiting or managing files.
With Validately, choose either unmoderated or moderated testing. To test a product, add a link to your website or prototype. Testers will receive a URL to take the test or join an moderated session. After the session, you’ll receive a qualitative report and sharable videos. Pricing starts from $49 per month.
Collect both qualitative and quantitative insights from users to make the right design decisions. Among testing deliverables, you’ll receive nice heat maps.
Conduct Moderated Remote Testing
You could conduct remote moderated sessions using Google Hangouts or Skype. Simply ask users to share their screen, and then see how they interact with your product. Don’t forget to record the session for further analysis. (Record both video and audio; without audio, it might be hard to tell why certain behavior occurred.)
Avoid “Professional” Testers
The downside of remote testing is that many participants get tested so frequently that they’ve learned to focus on certain aspects of a design. To compensate for possible “professional” testers, you’ll need to analyze the test sessions (for example, by watching the video recordings), and exclude results from people who don’t seem to provide genuine feedback.
8. Engage The Whole Team In The Process
Involve the whole product team in the testing process. Having an opportunity to observe users will help the whole team understand the problems with usability and to empathize with users. Testing enables you to build shared understanding, even before the team starts designing.
Discuss the Testing Strategy With the Team
Product design is a team sport. And because testing is an essential part of the design process, it should be discussed with all team players. Direct involvement in preparing the test will make team members more interested in the activity. As the person responsible for UX research, you should make it clear how your team will use the findings from the usability tests.
Ask Everyone to Watch the Sessions
You can’t expect the entire team to join the testing sessions. In most cases, it isn’t necessary for everyone to observe all usability testing first-hand (although it might be desirable). But you can record the testing sessions on video and share it with colleagues. Video can be extremely helpful during design discussions.
Ask Team to Help With Analysis
One thing that slows down many forms of usability testing is analysis. Extracting findings from the data collected during testing sessions could take days or even weeks. But if the entire team watches the sessions and takes notes, they will be better able to summarize the findings and decide on next steps.
9. Test Before, During And After The Redesign
A common question among many product teams is, “When should we test?” The answer is simple: Test before a design or redesign, test during the design, and then test afterwards, too.
Before a design or redesign
Testing would be conducted during the discovery phase of the UX design process. If you plan to redesign an existing product, usability testing could help you identify the biggest pain points in the current version. Consider testing competitors’ products, to compare results.
During a redesign
If resources exist, do this at every milestone of the project. In the time it takes to build and launch a new product or feature, you could run several testing sessions and improve the prototype after each one.
After a redesign
Knowledge of how real users use the product will help you make it better.
10. Don’t Try To Solve Everything At Once
Trying to solve everything at once is simply impossible. Instead, prioritize your findings. Fix the most important problems first, and then test again. However, if that’s impossible (for example, if the problems are too big to tackle), then prioritize problems according to their impact on revenue.
Conclusion
You can’t afford to skip testing, because even a simple round of testing could make or break your product. Investment in user testing is just about the only way to consistently generate a rich stream of data on user behavior. Thus, test early, test often.
This article is part of the UX design series sponsored by Adobe. Adobe XD tool is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.
Following a summer of Wonder Woman, Spiderman, and other superhero blockbusters, it’s natural to fantasize about having a superpower of your own. Luckily for designers, innovators, and customer-centric thinkers, a design sprint allows you to see into the future to learn in just five days what customers think about your finished product.
As a UX consultant and in-house design strategist, I have facilitated dozens upon dozens of design workshops (ranging from rapid prototyping sessions to, of course, sprints). The sprint is by far the most effective process I’ve seen to drive customer-first decision making in a design thinky way.
What Is A Sprint?
Because ‘sprint’ is used to refer to a variety of processes, I’ve given a brief description of a few different types of sprints to clarify:
Development sprint: a set period of time for software development work and review. (This is not what I’m writing about.)
(Regular) design sprint: set period of time for the design team to create functional designs ahead of the development sprint. (This is still not what I’m writing about, but check out a previous Smashing article, Getting Started with Design Sprints.)
(Google) design sprints: a 5-day process to understand if an idea maps to a customer need or opportunity without having to launch a minimal product. (Finally, this is what I’m writing about.)
Now that we are all on the same page about different kinds of sprints, let’s take a look at an example:
Recently, I participated in a sprint that had the big goal to use our pre-built kit to build an app (coincidentally) in five days or less. Given that this process normally takes months, we assumed the faster, the better, right? We wanted to make sure this assumption was correct and sprinted this idea.
We more or less followed the process suggested on the Google Venture’s website. If you are completely unfamiliar with the design sprint, here’s a handy 90 second intro.
(We are aware that there’s a call to action to buy the book at the end of this video, but if you are not at all familiar with the design sprint, it will provide you with a quick introduction. We are not in any way affiliated with Google Ventures nor are trying to promote the book.)
This is what our process looked like:
Monday, we set our goals, targets, and learning about potential users from customer experts.
Tuesday consisted of drawing from inspirations and sketching a solution.
Wednesday involved choosing a winning sketch and turning it into a storyboard.
Thursday, we prototyped.
Friday, we tested the prototype with customers.
By Friday, our prototype reflected the flow of a customer learning about our kit, viewing examples of the types of apps they could build, and launching their own app in a short span of time. We thought we did a great job, as the prototype illustrated our main value propositions:
The features that would be available through our kit.
The speed with which they could have a fully functional app of their own using our kit.
However, we tested our prototype with customers and learned that our value proposition didn’t really resonate. While it would be great to have speedy deployment, our kit did not allow for the level of customization developers required to meet the needs of their own customers.
Was it a waste of time? Of course, not. If we hadn’t explored and validated the idea with a design sprint, can you imagine the time and effort that would have gone into implementing the wrong thing? Avoiding wrong turns is the superpower of the sprint.
This superpower allows us to make major decisions and sidestep business paralysis. But with so much to pack into so little time, every minute — from prep to during to after — is critical. I’ll share what I’ve learned to maximize the sprint experience and help us flex our new superpower.
Before the sprint: setting yourself up for success.
During the sprint: maximizing your sprint week.
After the sprint: how to keep the momentum.
Before The Sprint: Setting Yourself Up For Success
Successful sprints start with good preparation. First, know that it’s a lot of logistical work. Even with the Sprint book’s explicit guidance, securing the right space, time, and people is a big undertaking, so give yourself 3 weeks. Consider a schedule that looks something like this:
Week 1: Confirm the sprint with stakeholders and send out an email getting people to book travel if necessary. Tell them now about the NO DEVICES rule — one of the design sprint’s key ideas, which basically says that the electronic devices shouldn’t be used during the sprint activities. Start scheduling users and customer experts to interview. Book your meeting space. If you can’t get a room for the full week at an office space, consider meeting at a hotel or nearby rental facility. If you haven’t already, start customer research (more on that later).
Week 2: Continue to follow up on your interviews.
Week 3: Gather supplies (recommend buying sprint kit), schedule interviews, and send a reminder email to participants (remind them about the NO DEVICES rule).
Notice that all three weeks involve scheduling participants. This is worth emphasizing because securing quality customer interviews can take time.
Quality interviews are with people who match your target customer. Getting the right people ensures that your feedback at the end of the week will be meaningful and adequate to drive decisions and next steps.
In the sprint example above (the development kit), we were testing an idea aimed at developers. The prototype we created wouldn’t make sense to non-developers, so we would have had difficulty recruiting the right testers on Craigslist or at a local Starbucks (unless we got really lucky!). Instead, we took weeks tracking down the right participants and finding interview times that worked for them. In this particular sprint, we drew from a pool of existing customers.
Other ways to find good participants is to leverage people in your network, or use sites like usertesting.com to screen potential participants. If your value proposition applies to a more general audience, you will not need as much lead time to secure the right people, but making sure you have the right testers is essential for a successful sprint.
If there’s opportunity to do so, I recommend conducting at least some kind of customer research. Get a sense of the day-to-day tasks and goals of your customers through actives such as interviews and ethnographic studies (you will most likely need to start these activities more than 3 weeks in advance). Waiting until the end of the week to hear from customers in your sprint makes you less likely to have a value proposition that meets actual needs or opportunities. Without customer research, you are still relying on your best guess to understand what customers want or what would add value. Even though the sprint process takes into consideration input from customer experts, this is never as effective as hearing from customers directly. Instead, infuse the voice of the customer into your sprint from the start.
Now that you’ve set yourself up for success, let’s look at how you can maximize your sprint week.
During The Sprint: Maximizing Your Sprint Week
Like any good design thinking process, start with your customer. Right after you introduce the sprint and set expectations for the week, present the findings of the customer research. Do this at the very beginning on Monday so that your knowledge of the customer will influence the goal, target, and types of questions you ask your customer experts.
The discussion does not have to be exhaustive, but make sure the team knows enough to begin the sprint by building empathy for your customer. This will be the foundation for the rest of the week’s activities, including sketching on Tuesday and prototyping on Thursday.
When creating a prototype, consider the appropriate scope and fidelity. The Sprint book recommends a high-fidelity prototype for a more realistic testing experience but only allows for prototyping to occur from 10am–3pm on one day.
We’ve found it quite difficult to build a high-fidelity prototype within the suggested five hours. For example, I’ve participated in a sprint that had three makers (makers in a design sprint are participants who create the prototype). Even with three makers, the prototype was not completed until well into the night. This prevented the team from doing a test run through prior to customer interviews, and the output of the sprint suffered.
Is there any way we can avoid this kind of stress and optimize the process? Allow me to share a few tips for maximizing the possibility of producing a viable prototype, as well as how to get the most out of the customer interview on Friday.
The Prototype Maker Should Be Comfortable With The Scope
The maker (again, the person who will build the prototype) has the most realistic view on how long it will take to create the prototype — since they only have one day (Thursday) to do so. The maker should firmly remind the decider (the term the Sprint book uses for the person who will make the major decisions during the design sprint) to focus on validating the value proposition.
People, myself included, get excited about the opportunity to get real feedback from potential customers and try to include non-essential things to test.
For example, we once prototyped a chat feature that was unrelated to our value proposition because our decider wanted to know if people would use it for support. That kind of insight would be interesting, but creating and testing these nice-to-haves can happen later.
When these situations happen, the (prototype) maker should be able to overrule the decider.
Be Realistic About The Level Of Fidelity
The correct level of fidelity is the one you can create in the given time that illustrates your value proposition.
Use realistic content and data.
Illustrate the essential components of your value proposition in a way that is functional (i.e. for a website, critical path for a task is clickable).
Do not build out features that do not illustrate the value proposition (unless you have the time!).
Consider Plant Stops, a fictitious company that sells trees and planting services. Plant Stops has always been a brick and mortar business but wants to expand. They want to sprint to see if customers would be interested in buying trees online. Let’s look at an example page from their prototype in varying levels of fidelity from too low to too much to just about right.
Too low. The fidelity of this page is too low. It is not clear what task the customer is trying to accomplish and does not illustrate the idea that Plant Stops is testing.
Too much. This example illustrates the idea at a high fidelity level. In order to be realistic, it contains features that are not necessary to validate the value proposition and should only be designed once all other critical components are created.
Just about right. While not realistic, this example also conveys the idea and is sufficient to test with customers. Omitting additional features will free up time for more effective flow design.
More Than A Usability Test
After you’ve created a prototype on Thursday, it is time to test your value proposition on Friday. In my experience it is easy to turn customer interviews into usability tests (you don’t want to do that). This is especially easy if your tester is a UX person with experience giving usability tests (do I sound guilty yet?)
It took me a few sprints to un-train myself from asking only usability questions. For example, instead of asking, “where would you expect so and so to be?” I should have been asking, “what did you like or dislike about so and so?” Even more so, the best approach is to avoid specific questions and encourage the customer to think out loud.
Similarly, you might also need to walk users through the concept more than would be needed for a usability test. For instance, rather than watching customers fumble around trying to navigate the menu you created in 3 minutes the day before, get them to the key features as soon as possible to start getting feedback on your value proposition.
Usability feedback is definitely a plus, but you really want to make sure you are getting customer input on your idea. At the end of your interview, ask meaningful wrap-up questions. The answers that you receive will inform your decision whether or not to move forward with the project. For example, ask questions like:
What were your overall impressions of X?
On a scale from 1-10 (1 being the least useful and 10 being the most useful), how useful is X?
Use five adjectives to describe X.
Next steps
At the end of the sprint week, your team needs to decide if you will move forward with your value proposition. If not, you’ll need to discuss if there’s anything that can be salvaged from the project or if it’s better just to cut your losses and move on. The latter rarely happens, though.
Assuming you are moving forward with the validated concept, it’s important to stay focused. After such a successful and insightful sprint week, you wouldn’t want to lose the momentum, would you?
After The Sprint: How To Keep The Momentum
You’ve just had a week jam-packed with making decisions and progressing an idea. At the end of the week, people part ways and return to their day jobs. How do you keep the momentum? Here are some practical next steps and tips:
Someone needs to be in charge. This could be the decider or someone the decider assigns to the role, such as a product owner or project manager. Ideally, this person was also a participant in the sprint.
Decide what’s the minimum marketable product (MMP). What are the essential features and functions needed to deliver your value proposition? The customer feedback gathered during the sprint should drive this decision. All non-critical features (the nice-to-haves) should be saved for later.
Make sure the prototype reflects the critical features of the MMP with UX design best practices applied.
Test your prototype for usability. Now is the time to ask, “where would you expect so and so to be?”
Get to work! Development can start using the customer-validated prototype. Your design team can start incorporating those nice-to-haves into the prototype, starting with the features that the product owner has prioritized based on customer feedback.
Run more sprints. The design team would ideally conduct a few sprints ahead of the development team’s sprints. For example, if the development team is working in two-week sprints, then designers should schedule their sprints accordingly every two weeks, regardless of what type of design sprint they use. At the very least, the design sprints should consist of iterating on the prototype, testing with users, and passing off to the developers, ensuring that only customer-validated features are developed.
Using this process, you have established a continuous customer feedback loop, starting with your sprint.
Test Your New Superpower!
Since embracing the sprint, I have seen ideas — that have had no traction for years — gain new momentum and interest. Months and months of meetings and discussions bypassed by one week of collaboration, design thinking, and customer-centric decision making.
The tips gained from practical experience that I have outlined in the article will only make this effort more successful. So as you plan your next design sprint, remember how you can maximize your experience:
The Middle Eastern market is growing at a rapid pace, and, as a result, demand for various IT products is also booming in the region. What is peculiar, though, is that Middle Eastern countries require design that is not only compatible with their needs and comfortable for their users, but that is also suitable to their language standards, making a serious adaptation process very important. Given that most languages spoken in the Middle East are written and read from right to left (such as Arabic, Hebrew and Urdu), developers often face a range of problems when creating products in those languages.
Although this might seem like not that big of a deal, IT development for right-to-left (RTL) languages entails paying attention to a number of peculiarities. This is only further complicated by the fact that the RTL market is relatively new, and not many resources are available to help developers.
Our experience with RTL development has enabled us to compile a thorough list of tips that are useful for anyone developing an RTL product (such as a website or mobile app). By following the tips closely, you should be able to navigate the challenging waters of RTL development and deliver a functional, user-friendly result.
Flipping The Interface
First and foremost, the interface must be flipped from right to left. You might think this is rather “D’uh” advice, but we simply could not disregard it, because it is in fact the very first thing to do.
Here’s an example of Facebook’s left-to-right (LTR) design:
And here is the RTL version of Facebook:
There are several ways to achieve this.
1. Using the dir Attribute or CSS
If the basic markup is built with floating blocks, it will look something like the example below.
For LTR design, pay attention to the styles. In this case, the link with logo will be fixed to the left, with the login-container to the right.
For RTL design, once you’ve assigned the body tag to the dir="rtl attribute, the whole markup will be mirrored, placing the logo to the right and login-container to the left. The opposite properties will be then applied to blocks with the float-left or float-right class.
<body dir="ltr">
The dir attribute specifies the text’s direction and display (either left to right or right to left). Normally, browsers recognize the direction because it’s assigned in the Unicode character set, but with the dir attribute, you can set whatever direction you want.
The possible variants are dir="ltr", dir="rtl" and dir="auto". This attribute can also be rewritten with the CSS direction property.
Because text direction is semantically tied to content and not to presentation, we recommend that, whenever possible, web developers use the dir attribute and not the CSS properties related to it. That way, the text will be displayed properly even in browsers that don’t support CSS (or in those where CSS support is turned off).
With this attribute, you can horizontally mirror images, reassign fonts, align text to either side of the page, etc. However, the manual way is fairly labor-intensive. There are tools to automate the assembly of RTL styles, which we’ll get to a bit later in this post. In the meantime, we’ll describe another way of dealing with markup directional changes.
2. Using Flexbox
Flexbox is popular among developers for a couple of good reasons. Not only does it provide flexibility when adjusting the alignment of page elements and other bits, but it also eliminates the need to reassign styles for RTL development. See the code snippets below for more details.
The grid layout is also useful here. We set grid-template-areas in the containing block with {display: grid;} property (imagine it as a table with two columns and three rows). From the top: The header occupies the entire width of the screen, the sidebar is on the left, while the main content and the footer are on the right, one under another.
For RTL, by changing the dir attribute, the horizontal axis with the grid class and the {display: grid;} property will adjust to the specified direction. The layout matrix is then inverted:
Even though using tables to build layouts hasn’t been popular for a while now, they would still build flow direction as a component, just like in the previous examples, meaning that when you add the dir="rtl" tag, columns will start from the right and move from right to left. All table elements will follow this, unless the direction is clearly predefined beforehand.
Character Encoding
Save your file using a character encoding that includes the characters you need (UTF-8 is a good bet). Declare that you are going to use such characters in the head tag of your HTML page with:
<meta charset="utf-8"/>
UTF-8 is a character encoding capable of encoding all possible Unicode code points, and it covers almost all languages, characters and punctuation symbols. Using UTF-8 also removes the need for server-side logic when individually determining each page’s character encoding or each incoming form submission. Coding helps to convert everything into binary numbers. For instance, “hello” in UTF-8 would be stored like this (in binary): 01101000 01100101 01101100 01101100 01101111.
Formatted Text
Try as hard as you can to avoid using bold and italics. Bold text would make readability extremely difficult in most RTL languages (especially Arabic), and italics is simply never used. As well, capital letters are almost always disregarded in RTL languages.
If you need to highlight a certain part of text in Arabic, overline it instead of underlining, interspacing or italicizing. Here is how we do it:
<h1>مثال</h1> h1 { text-decoration: overline; }
Make sure that all text is aligned to the right, and that font and font size are adjusted properly (better yet, customize them), because Latin fonts tend to affect Arabic readability rather poorly.
Actually, the best way to deal with fonts is to speak to your client (assuming, of course, they speak the language). The thing is that languages such as Arabic tend to have a great number of spoken and written variations, and if you’re making a product catered specifically to some region, it should really display the language version used there. If you find this matter interesting, information about the history of Arabic writing systems is available here.
In case your client isn’t a native speaker of the product’s language or isn’t able to help you, there is always the simple option of using one of the Google Noto fonts (there is one for every language, and all of them are free). Alternatively, Arabnet recommends 10 Arabic fonts (the list is from 2014, but things haven’t changed much in this area over the last three years). However, do keep in mind that your client always knows best which language variant is used most in their particular region, and if you have a chance to consult with them about it, do so right away.
Also, remember that words in RTL languages are often much shorter than words in English. So, adjust to keep a balance in how text is displayed on the page.
Icons
Using icons in RTL development can be tricky. Keep in mind that some of them might have to be mirrored, and some could be considered offensive to people of some nationalities, so double-check that the icons you’re using make sense.
Icons that are symmetrical and that don’t point in a particular direction should not be flipped.
On the other hand, icons that clearly point in a particular direction should be mirrored.
The scale (x, y) CSS function used in the example above modifies the size of an element. If set to 1, it does nothing, but when negative, it performs as a “point reflection” and can modify size.
Icons that have characters or words from non-RTL languages don’t need to be mirrored. You should, however, localize them if necessary.
Ensure that the icons you’re using are appropriate. For example, using a wine glass as a symbol for a restaurant or bar could be misunderstood because alcohol consumption is prohibited in Islam. Cultural peculiarities need to be taken into account, and developers should double-check that the symbols and icons they’re using are appropriate for the target market.
Navigation Menus
Logos, navigation buttons and menus should be located in the upper-right corner for RTL design. The two latter elements also need to be displayed in reverse order. You don’t, however, need to mirror all of the stuff related to controlling media content (such as play and pause buttons).
Digit Ordering
The order of digits in numbers should not be changed for RTL. Note the phone number below. The digits are displayed in the same order in both LTR and RTL, but the telephone icon changes position. The same rule applies to other digits (such as addresses and other numeric strings).
Position Of Control Buttons
Even though people speaking RTL languages perceive and process information from right to left, many of them are right-handed. Thus, it would be a good idea not to mirror control buttons, so that users can interact with them comfortably. Instead, center them to resolve any issues. For instance, if the orange button shown below was located to the left, it’d be extremely difficult for people to reach it with their right thumb while holding their device in one hand:
In this case, it would be much more convenient for users if such important elements of interaction were large and located in the middle of the screen.
The elements in the bottom tab bar below should be positioned from right to left. RTL also exists in the Persian language — see example below:
Navigation drawers should appear from the right side.
Position Of Other Symbols
The position of symbols that can be used for both RTL and LTR (such as punctuation marks) will depend on the direction of the text as a whole. This is because browsers process RTL words in the RTL direction, even though the data format starts from the beginning. Punctuation is converted only towards the specified direction.
The following example should illustrate the issue better:
To fix this problem, you can convert RTL and LTR strings (or text fragments) into separate elements. Then, specify their direction with either the dir attribute or the CSS direction property. In the first case, you would do this:
<p dir="rtl">?سوف أعطي مثالا على ذلك. لا تمانع</p> <p dir="ltr">I will give an example. Don’t you mind?</p>
Alternatively, you could also use the bdi tag to avoid this type of issue. However, it is only supported in Chrome (16) and Firefox (10).
Separate RTL CSS File
For basic CSS styles, you should create a separate RTL file and set the horizontal properties there (floating left and right, padding left and right, margins and so on), while also redefining them appropriately:
If you need to eliminate some other LTR-directed features, you can always create and attach another separate rtl.css file.
In case this approach doesn’t meet your needs well enough, you can create two separate style files for LTR and RTL. Various utilities can be applied to automate their assembly. One such program is css-flip (created by Twitter). With its help, you can easily compile a file with properties redefined for RTL from an existing source file.
In input.css:
p { padding-left: 1em;}
And in output.rtl.css:
p { padding-right: 1em;}
You can also use replacements and exceptions, based on directives in the source file. For example, in input.css:
p { background-position: -32px -32px; content: ">"; float: left;}
RTLCSS is another tool that supports replacements (exceptions) and makes it possible for developers to rename selectors, add local configurations of exception, and delete or add properties.
You could also use plugins for assembly instruments, including for Gulp, Grunt and Webpack.
Calendars are probably one of the most important and complicated aspects of RTL design, because calendar years are different between LTR and RTL geographic regions.
Hijri
Hijri, the Islamic calendar, is lunar-based, which means that a year in the Gregorian calendar is longer than in the Islamic calendar. As a result, Hijri always has to shift according to the Gregorian calendar.
Hebrew Calendar
The Hebrew calendar, which has 12 lunar months, with an extra month added every few years, also differs from the Gregorian calendar. These differences make it hard to find an adequate tool for working with both Gregorian calendars in LTR scripts and non-Gregorian calendars in RTL scripts.
Tools for Displaying Calendars
One popular tool is FullCalendar, because it calculates time based on Moment.js. However, it cannot convert between different types of calendars and is only useful for localizing dates and displaying RTL content.
dijit/Calendar is able to display non-Gregorian calendars but has a rather limited range of tasks.
The DateTimeFormat constructor is an invaluable property for international objects. It makes it possible to pass additional options to the argument string when specifying the exact formatting for time and date.
Below, you can see how a date should be converted from the Gregorian calendar to the Islamic one:
var sampleDate = new Intl.DateTimeFormat("ru-RU-u-ca-islamicc").format(new Date()); // => "26.03.2017" console.log(sampleDate); // => "27.06.1438 AH"
Abbreviations (Days Of Week)
Although abbreviating the names of the days of the week is standard in many languages, this isn’t possible in Arabic because all of them start with the same letter. Instead, simply display their whole names and reduce the font size.
Internationalization
If your product requires internationalization, consider the ECMAScript Internationalization API. It comes with a language-sensitive string comparison and relevant formatting for numbers, dates and time.
Another important point is that ECMAScript supports not only Arabic, but also a wide range of other combinations, such as Arabic-Arabic and Arabic-Tunisian.
Also, keep in mind that the use of Eastern and Western Arabic numerals might depend on the language variant. Some regions might use Eastern Arabic numerals (123), while others use Western ones (١٢٣).
Formatting Arabic-Egyptian Numerals
var sampleNumber = new Intl.NumberFormat(‘ar-EG’).format(12345); console.log(sampleNumber); // => ١٢٬٣٤٥
In Tunisia, for instance, Eastern Arabic numerals are usually used:
var sampleNumber = new Intl.NumberFormat(‘ar-TN’).format(12345); console.log(sampleNumber); // => 12345
Examples Of Native Arabic Websites
Share Your Experience!
Cultural and linguistic peculiarities can be a hassle when you’re developing for different regions and markets. When it comes to the RTL market, developers must use their knowledge to adhere to a completely different set of rules, making the whole process more challenging and potentially frustrating. Using the 12 tips above, we hope you’re able to overcome some of the most common problems with RTL development.
If you have encountered any obstacles related to RTL development, please describe them (along with the solutions you’ve found) in the comments section below. The more that developers share their knowledge and experience, the easier it will be for all of us to deal with the peculiarities of RTL development.
I became a huge fan of customer journey mapping (CJM) the first time I was introduced to it. And after a few years of mapping, tweaking and presenting maps, my team and I started looking for other more exotic uses of this technique. The law of the instrument at its best, I suppose. Well, seek and ye shall find.
Customer journey mapping is a visualization technique that helps marketing specialists, user experience designers, and product and business owners see the journey people take when interacting with products and services. It is a great way to put on your customer’s shoes and see where your business fails to deliver a great user experience.
The way CJM works is pretty straightforward: You collect user research data, break down the entire funnel into steps (i.e. stages) and describe each stage from multiple points of view, such as your business goal, the customer’s goals, touchpoints (the very moments of interaction), customers expectations and pain points, their thoughts and feelings, etc. In the end, you have a table that looks something like this:
From this table, you can tell at which points customers are not happy, and you can come up with some ideas to improve the situation.
Сustomer journey mapping is mainly used to find flaws in the entire path of the user, but I was curious if there was some unconventional way to use this technique. Turns out there is, and here the story of how it found me.
It’s Not A Journey Map… Or Is It?
After reading Baremetrics CEO Josh Pigford’s brilliant article about an email campaign that Baremetrics created to reduce churn and convert customers, our team at UXPressia decided that we needed something similar for our app.
Fast-forward a few weeks, and we had a sequence of emails ready to fly to our users’ mailboxes. They looked somewhat like this:
These printed emails stuck around on our whiteboard for a while. Then, one day, while we were having coffee after a long and tedious CJM workshop, one of the participants glanced at the emails still hanging on the board and asked, “What’s this journey map for, guys?”
“Oh no, that’s not a journey…” — I was about to say that this was not a journey map, but I suddenly stopped. Our guys looked at each other. “Are you thinking what I am thinking?” Yes, our email campaign had stages and our business goals, so it could be. After all, we made a tool for mapping customer journeys, so it was a great opportunity for us to put it to the test. The question was: Is it OK to just cut out one channel from the entire user journey and focus on it solely?
On the one hand, customer journey mapping is all about a holistic approach, so it isn’t entirely right to focus on just one channel. On the other hand, we want to follow the “individuals and interactions over processes and tools” principle from the agile manifesto.
Besides, we tried our best to make our emails as personal as possible. Today, email campaigns are no longer carpet-bombing monologues. They are more of ongoing conversations in which we try to bond with our users. And customer journey mapping is all about finding a better and more personal approach.
So, why not try?
Everyone in the room started pitching ideas. Someone noticed that we had our goals linked to every email. “If we could add our user goals and see if both goals match…” he said.
At this point, it was clear that this was going to become a map. But two CJM sessions on the same day? You have got to be kidding. We took a break and agreed to sleep on this idea.
Doubts, The First Draft
The next day, after rebooting our brains, we gathered in the same room and asked ourselves, “What is the problem we are trying to solve here?” And is there any problem in the first place?
Well, have you ever seen how email campaigns are stored, organized and manipulated? We had a Google Doc with text and pictures, and it was kind of fine, although it was not easy to get a bird’s-eye view of the whole campaign all at once.
Our campaign was not very long and complex. It was a sequence of about 12 emails in which we welcome our users, give them tips and do some upselling.
Now, imagine if you had a longer campaign consisting of 50 emails triggered at different moments. I remembered my friend telling me how his company had an enormous spreadsheet file linking to different sources with multiple emails.
And there is no way to evaluate each letter out of the context. Setting up your campaign in some tool like MailChimp or Intercom would make your campaign a lot less messy, but you would still have to open each email to see the details.
Turns out that hundreds of people working on email campaigns have terrible experiences themselves while crafting a better experience for others. Trying to unweave webs of interrelated email letters scattered over a spreadsheet would drive anyone crazy. This had to stop.
So, we rolled up our sleeves and drafted the first map using emails from our campaign.
By mapping out the whole chain of emails on a single canvas, we could finally see everything in one place. Timing, email texts, business goals at each stage, as well as goals of each letter — it was all there. Having it all aligned in such a way instantly raised (and even answered) questions like:
“Are we bombarding our users with a number of emails from the same person? Would it be more appropriate to introduce someone new?”
“Is the timing correct and in line with the overall experience?”
And these questions were way easier to answer once we saw the whole picture. This alone was valuable enough because this clarity turned out to be a huge time-saver.
For example, shortly after the launch of our campaign, we noticed a pretty high unsubscribe rate from our emails. We tried to understand why this was happening and what we could do to fix it. Then, we looked at our email map and realized that the time gap between the first two emails was quite short, so we increased it. Guess what? The unsubscribe rate slowed down. This would have been more difficult to troubleshoot without the clear picture we had from customer journey mapping.
But we decided to take it up a few notches.
Leveraging Personas
Remember I said we were trying to find a better and more personal approach? That’s what personas are best at. And having a well-researched persona when creating this email campaign was a game-changer for us.
By that time, we had already defined our customer personas, so it was no biggie to take each email and read it as if the reader was our persona.
A Brief Example
In one of our letters, we asked our users to tell us about themselves, so that we could make some suggestions and offer personalized help just in case. We expected them to drop us emails with some really short stories. So we “read” this email to our personas. Hey, picture a bunch of fellows reading to a poster on a wall. Bonkers!
We tried to understand why this or that persona wouldn’t answer, and we realized that what we had in mind was not the way to go. What if our business-owner persona didn’t have time to sit there and compose emails? What could we offer to eliminate this objection? A quick call? Meh. Maybe. An online poll with predefined answers? Better!
So, using personas certainly had a great impact on our email campaign in the end.
Campaigns For Different Personas And A/B Tests
By the way, what if you have multiple personas in your email campaign? That poor spreadsheet! Unless, again, you use customer journey mapping. In this case, we’d be able to easily map different letters to corresponding personas — and even find where these emails intersect!
Example
In her case study, one of our customers told us an interesting story. She was working on a complicated email campaign for multiple personas. The tricky part was to bring together all possible scenarios and see which email she should write for each specific case.
And she was quite amazed by how customer journey mapping saved her a lot of time and effort. Once all emails had been mapped out, it became apparent which letters repeated, so she could merge them into one.
This applies not only to scenarios like this one, but also to A/B tests. Imagine doing the same without customer journey mapping. Ugh! But wait, the best part is yet to come.
Email Campaign On CJM Steroids
And here is it. Once we started putting our campaign on CJM steroids, there was no going back. Customer journey mapping offers a ton of sections that we could use to take our email campaign to a whole new level. We tried some of them, and the results were quite surprising.
User Expectations and Goals
Adding user goals and expectations to our map cocktail changed the way we saw our email campaign for the better. When sending an upsell email, is this what our user expects from us at that very moment? Does the goal of this letter match the goal of our customers?
By that moment, we had already rolled out our campaign, so we had some stats on hand. And adding these sections and answering these questions made us realize why the unsubscribe rate for some of our emails was so high. Speaking of which…
Key Performance Indicators and Other Metrics
Now, what if we had real statistics under each email? Seeing how this or that letter performed enabled us to instantly find where our campaign hit the dirt. It did require some maintenance, but in the end, it was totally worth all the effort.
Quote or User Response
Because we believe that email campaigns are conversations rather than monologues, we expect our users to say something back. Why not add some of their responses to our map? They could be from a single quote or an entire response. And based on their reactions, we were able to draw an…
Experience Graph
The experience graph made it so easy for us to see the whole flow of our email campaign. Tracking performance enabled us to see which emails failed most and which did the best job. For us, this was priceless.
Problems and Ideas
Finally, once we had identified problematic emails in our campaign, it was time to think about what caused fails and how we could improve their performance. We pitched some ideas and started testing them ASAP!
Wrapping Up
When we finally called it a day (or, rather, a night), everyone was so inspired. Using customer journey mapping to map our email campaign turned out to be not just a huge timesaver, but a well of insights, too. Not to mention that we were able to achieve a 40% open rate! Not a bad result in today’s world, where users develop email-blindness syndrome.
Of course, using CJM for mapping email campaigns will not work for all cases, but it was a lifesaver — and not just for us.
One of our customers transformed their existing email campaign the same way shortly after our debut. What they did was compare the email journey they created with the customer journey map they already had. Once they saw all emails on a single CJM canvas right next to the customer journey map, they got quite a few insights, like:
The first email in the campaign promoted the web application heavily right after a user downloaded the mobile app. The business goal at this stage was to decrease the number of users leaving the mobile app, but they were encouraging people to do just that!
The second email was pushing people towards providing more personal data. But from looking at the CJM as a whole, it was obvious that the timing was completely wrong: It happened at the stage when the majority of users were not yet ready to share anything — they simply hadn’t yet perceived any value from using the app.
The third email promoted the blog, which indeed had some great content. But the content was focused on just two personas, whereas the email campaign was sent to everyone. The majority of users were obviously not interested, so they kept unsubscribing.
These were not all of the insights they had, but even with these, it was pretty clear that the campaign needed some rethinking. Even more importantly, they already knew what had to be changed.
Anyway, here are some ideas about when transforming an email campaign into an email journey map will work for you as well:
You are working on a massive email campaign that you want to be consistent and well crafted as much as sympathetic and humane.
You believe that your team should try CJM, but people hesitate to engage because of the time commitment and unclear value. Seeing how it works for one channel would be less time-consuming and might help to convince your team to try a full-blown customer journey map after all.
You want to present campaign content to clients or stakeholders (which would be way more attractive than the bunch of separate files mentioned before).
The worst-case scenario here is that you would put your emails in order and save a lot of time in the long run.
Plus, you can do the same thing not just with emails but with virtually anything, be it call scripts for support or sales, alongside postal or face-to-face interactions.
Oh, and one more thing. We created a free template you can use to start mapping your email journey now! It has a predefined persona and all the sections we used in our own journey map.
But what about you? Have you tried using CJM for email campaigns? What insights can you share? Do you know of any unusual uses of CJM? Share your ideas in comments!
The Vary HTTP header is sent in billions of HTTP responses every day. But its use has never fulfilled its original vision, and many developers misunderstand what it does or don’t even realize that their web server is sending it. With the coming of the Client Hints, Variants and Key specifications, varied responses are getting a fresh start.
What’s Vary?
The story of Vary starts with a beautiful idea of how the web should work. In principle, a URL represents not a web page, but a conceptual resource, like your bank statement. Imagine that you want to see your bank statement: You go to bank.com and send a GET request for /statement. So far so good, but you didn’t say what format you want the statement in. This is why your browser will also include something like Accept: text/html in your request. In theory, at least, this means you could say Accept: text/csv instead and get the same resource in a different format.
Because the same URL now produces different responses based on the value of the Accept header, any cache that stores this response needs to know that that header is important. The server tells us that the Accept header is important like this:
Vary: Accept
You could read this as, “This response varies based on the value of the Accept header of your request.”
This basically doesn’t work on today’s web. So-called “content negotiation” was a great idea, but it failed. This doesn’t mean that Vary is useless, though. A decent portion of the pages you visit on the web carry a Vary header in the response — maybe your websites have them, too, and you don’t know it. So, if the header doesn’t work for content negotiation, why is it still so popular, and how do browsers deal with it? Let’s take a look.
I’ve previously written about Vary in relation to content delivery networks (CDNs), those intermediary caches (such as Fastly, CloudFront and Akamai) that you can put between your servers and the user. Browsers also need to understand and respond to Vary rules, and the way they do this is different from the way Vary is treated by CDNs. In this post, I’ll explore the murky world of cache variation in the browser.
Today’s Use Cases For Varying In The Browser
As we saw earlier, the traditional use of Vary is to perform content negotiation using the Accept, Accept-Language and Accept-Encoding headers, and, historically, the first two of these have failed miserably. Varying on Accept-Encoding to deliver Gzip- or Brotli-compressed responses, where supported, mostly works reasonably well, but all browsers support Gzip these days, so that isn’t very exciting.
How about some of these scenarios?
We want to serve images that are the exact width of the user’s screen. If the user resizes their browser, we would download new images (varying on Client Hints).
If the user logs out, we want to avoid using any pages that were cached while they were logged in (using a cookie as a Key).
Users of browsers that support the WebP image format should get WebP images; otherwise, they should get JPEGs.
When using a browser on a high-density screen, the user should get 2x images. If they move the browser window onto a standard-density screen and refresh, they should get 1x images.
Caches All The Way Down
Unlike edge caches, which act as one gigantic cache shared by all users, the browser is just for one user, but it has a lot of different caches for distinct, specific uses:
Some of these are quite new, and understanding exactly which cache the content is being loaded from is a complex calculation that is not well supported by developer tools. Here’s what these caches do:
image cache
This is a page-scoped cache that stores decoded image data, so that, for example, if you include the same image on a page multiple times, the browser only needs to download and decode it once.
This is also page-scoped and stores anything that has been preloaded in a Link header or a <link rel="preload"> tag, even if the resource is ordinarily uncacheable. Like the image cache, the preload cache is destroyed when the user navigates away from the page.
This provides a cache back end with a programmable interface; so, nothing is stored here unless you specifically put it there via JavaScript code in a service worker. It will also only be checked if you explicitly do so in a service worker fetch handler. The service worker cache is origin-scoped, and, while not guaranteed to be persistent, it’s more persistent than the browser’s HTTP cache.
This is the main cache that people are most familiar with. It is the only cache that pays attention to HTTP-level cache headers such as Cache-Control, and it combines these with the browser’s own heuristic rules to determine whether to cache something and for how long. It has the broadest scope, being shared by all websites; so, if two unrelated websites load the same asset (for example, Google Analytics), they might share the same cache hit.
This sits with the connection, and it stores objects that have been pushed from the server but have not yet been requested by any page that is using the connection. It is scoped to pages using a particular connection, which is essentially the same as being scoped to a single origin, but it is also destroyed when the connection closes.
Of these, the HTTP cache and service worker cache are best defined. As for the image and preload caches, some browsers might implement them as a single “memory cache” tied to the render of a particular navigation, but the mental model I’m describing here is still the right way to think about the process. See the specification note on preload if you’re interested. In the case of the H2 server push, discussion over the fate of this cache remains active.
The order in which a request checks these caches before venturing out onto the network is important, because requesting something might pull it from an outer layer of caching into an inner one. For example, if your HTTP/2 server pushes a style sheet along with a page that needs it, and that page also preloads the style sheet with a <link rel="preload"> tag, then the style sheet will end up touching three caches in the browser. First, it will sit in the H2 push cache, waiting to be requested. When the browser is rendering the page and gets to the preload tag, it will pull the style sheet out of the push cache, through the HTTP cache (which might store it, depending on the style sheet’s Cache-Control header), and will save it in the preload cache.
Introducing Vary As A Validator
OK, so what happens when we take this situation and add Vary to the mix?
Unlike intermediary caches (such as CDNs), browsers typically do not implement the capability to store multiple variations per URL. The rationale for this is that the things we typically use Vary for (mainly Accept-Encoding and Accept-Language) do not change frequently within the context of a single user. Accept-Encoding might (but probably doesn’t) change upon a browser upgrade, and Accept-Language would most likely only change if you edit your operating system’s language locale settings. It also happens to be a lot easier to implement Vary in this way, although some specification authors believe this was a mistake.
It’s no great loss most of the time for a browser to store only one variation, but it is important that we don’t accidentally use a variation that isn’t valid anymore if the “varied on” data does happen to change.
The compromise is to treat Vary as a validator, not a key. Browsers compute cache keys in the normal way (essentially, using the URL), and then if they score a hit, they check that the request satisfies any Vary rules that are baked into the cached response. If it doesn’t, then the browser treats the request as a miss on the cache, and it moves on to the next layer of cache or out to the network. When a fresh response is received, it will then overwrite the cached version, even though it’s technically a different variation.
Demonstrating Vary Behavior
To demonstrate the way Vary is handled, I’ve made a little test suite. The test loads a range of different URLs, varying on different headers, and detects whether the request has hit the cache or not. I was originally using ResourceTiming for this, but for greater compatibility, I ended up switching to just measuring how long the request takes to complete (and intentionally added a 1-second delay to server-side responses to make the difference really clear).
Let’s look at each of the cache types and how Vary should work and whether it actually works like that. For each test, I show here whether we should expect to see a result from the cache (“HIT” versus “MISS”) and what actually happened.
Preload
Preload is currently supported only in Chrome, where preloaded responses are stored in a memory cache until they are needed by the page. The responses also populate the HTTP cache on their way to the preload cache, if they are HTTP-cacheable. Because specifying request headers with a preload is impossible, and the preload cache lasts only as long as the page, testing this is hard, but we can at least see that objects with a Vary header do get preloaded successfully:
Service Worker Cache API
Chrome and Firefox support service workers, and in developing the service worker specification, the authors wanted to fix what they saw as broken implementations in browsers, to make Vary in the browser work more like CDNs. This means that while the browser should store only one variation in the HTTP cache, it is supposed to hold onto multiple variations in the Cache API. Firefox (54) does this correctly, whereas Chrome uses the same vary-as-validator logic that it uses for the HTTP cache (the bug is being tracked).
Vary should be observed, but in practice no browser actually respects it, and browsers will happily match and consume pushed responses with requests that carry random values in headers that the responses are varying on.
The “304 (Not Modified)” Wrinkle
The HTTP “304 (Not Modified)” response status is fascinating. Our “dear leader,” Artur Bergman, pointed out to me this gem in the HTTP caching specification (emphasis mine):
The server generating a 304 response must generate any of the following header fields that would have been sent in a 200 (OK) response to the same request: Cache-Control, Content-Location, Date, ETag, Expires, and Vary.
Why would a 304 response return a Vary header? The plot thickens when you read about what you’re supposed to do upon receiving a 304 response that contains those headers:
If a stored response is selected for update, the cache must […] use other header fields provided in the 304 (Not Modified) response to replace all instances of the corresponding header fields in the stored response.
Wait, what? So, if the 304’s Vary header is different from the one in the existing cached object, we’re supposed to update the cached object? But that might mean it no longer matches the request we made!
In that scenario, at first glance, the 304 seems to be telling you simultaneously that you can and cannot use the cached version. Of course, if the server really didn’t want you to use the cached version, it would have sent a 200, not a 304; so, the cached version should definitely be used — but after applying the updates to it, it might not be used again for a future request identical to the one that actually populated the cache in the first place.
(Side note: At Fastly, we do not respect this quirk of the specification. So, if we receive a 304 from your origin server, we will continue to use the cached object unmodified, other than resetting the TTL.)
Browsers do seem to respect this, but with a quirk. They update not just the response headers but the request headers that pair with them, in order to guarantee that, post-update, the cached response is a match for the current request. This seems to make sense. The specification doesn’t mention this, so the browser vendors are free to do what they like; luckily, all browsers exhibit this same behavior.
Client Hints
Google’s Client Hints feature is one of the most significant new things to happen to Vary in the browser in a long time. Unlike Accept-Encoding and Accept-Language, Client Hints describe values that might well change regularly as a user moves around your website, specifically the following:
DPR
Device pixel ratio, the pixel density of the screen (might vary if the user has multiple screens)
Save-Data
Whether the user has enabled data-saving mode
Viewport-Width
Pixel width of the current viewport
Width
Desired resource width in physical pixels
Not only might these values change for a single user, but the range of values for the width-related ones is large. So, we can totally use Vary with these headers, but we risk reducing our cache efficiency or even rendering caching ineffective.
The Key Header Proposal
Client Hints and other highly granular headers lend themselves to a proposal that Mark has been working on, named Key. Let’s look at a couple of examples:
Key: Viewport-Width;div=50
This says that the response varies based on the value of the Viewport-Width request header, but rounded down to the nearest multiple of 50 pixels!
Key: cookie;param=sessionAuth;param=flags
Adding this header into a response means that we’re varying on two specific cookies: sessionAuth and flags. If they haven’t changed, we can reuse this response for a future request.
So, the main differences between Key and Vary are:
Key allows varying on subfields within headers, which suddenly makes it feasible to vary on cookies, because you can vary on just one cookie — this would be huge;
individual values can be bucketed into ranges, to increase the chance of a cache hit, particularly useful for varying on things such as viewport width.
all variations with the same URL must have the same key. So, if a cache receives a new response for a URL for which it already has some existing variants, and the new response’s Key header value doesn’t match the values on those existing variants, then all the variants must be evicted from the cache.
At time of writing, no browser or CDN supports Key, although in some CDNs you might be able to get the same effect by splitting incoming headers into multiple private headers and varying on those (see our post, “Getting the Most Out of Vary With Fastly”), so browsers are the main area where Key can make an impact.
The requirement for all variations to have the same key recipe is somewhat limiting, and I’d like to see some kind of “early exit” option in the specification. This would enable you to do things like, “Vary on authentication state, and if logged in, also vary on preferences.”
The Variants Proposal
Key is a nice generic mechanism, but some headers have more complex rules for their values, and understanding those values’ semantics can help us to find automated ways of reducing cache variation. For example, imagine that two requests come in with different Accept-Language values, en-gb and en-us, but although your website does have support for language variation, you only have one “English.” If we answer the request for US English and that response is cached on a CDN, then it can’t be reused for the UK English request, because the Accept-Language value would be different and the cache isn’t smart enough to know better.
Enter, with considerable fanfare, the Variants proposal. This would enable servers to describe which variants they support, allowing caches to make smarter decisions about which variations are actually distinct and which are effectively the same.
Right now, Variants is a very early draft, and because it is designed to help with Accept-Encoding and Accept-Language, its usefulness is rather limited to shared caches, such as CDNs, rather than browser caches. But it nicely pairs up with Key and completes the picture for better control of cache variation.
Conclusion
There’s a lot to take in here, and while it can be interesting to understand how the browser works under the hood, there are also some simple things you can distil from it:
Most browsers treat Vary as a validator. If you want multiple separate variations to be cached, find a way to use different URLs instead.
Browsers ignore Vary for resources pushed using HTTP/2 server push, so don’t vary on anything you push.
Browsers have a ton of caches, and they work in different ways. It’s worth trying to understand how your caching decisions impact performance in each one, especially in the context of Vary.
Vary is not as useful as it could be, and Key paired with Client Hints is starting to change that. Follow along with browser support to find out when you can start using them.
Great conferences are all about learning new skills and making new connections. That’s why we’ve set up a couple of new adventures for SmashingConf 2018 — just practical sessions, new formats, new lightning talks, evening sessions and genuine, interesting conversations — with a dash of friendly networking! Taking place in London, San Francisco, Toronto. Tickets? Glad you asked!
Performance matters. Next year, we’re thrilled to venture to London for our brand new conference fully dedicated to everything front-end performance. Dealing with ads, third-party scripts, A/B testing, HTTP/2, debugging, JAM stack, PWA, web fonts loading, memory/CPU perf, service workers. Plus lightning community talks. Schedule and details.
Over the two days, we’ll cover pretty much every aspect of front-end performance: from rendering to debugging. Two days, one track, 16 speakers and 7 hands-on workshops. 50 early-bird-tickets now on sale.
The classic. With our third annual conference in San Francisco, we want to explore ways and strategies for breaking out: leaving behind generic designs and understanding the new techniques and capabilities available today. We care about the solutions we come up with, and the approaches that failed along the way. In San Francisco, we want to find out the why, and how, and what we all — as designers and developers — need to know today to be more productive and make smarter decisions tomorrow. Schedule and details.
A wide range of everything web-related, covered in 2 days, with a single track, 16 speakers and 8 hands-on workshops. CSS Grid, Design systems, new frontiers of CSS and JavaScript, accessibility, performance, lettering, graphic design, UX, multi-cultural design, among other things. 100 super early-bird-tickets now on sale.
What’s the best way to learn? By observing designers and developers working live. For our new conference in Toronto, all speakers aren’t allowed to use any slides at all. Welcome SmashingConf #noslides, a brand new conference, full of interactive live sessions, showing how web designers design and how web developers build — including setup, workflow, design thinking, naming conventions and everything in-between. Schedule and details.
Interactive live sessions on everything from organizing layers in Photoshop to naming conventions in CSS. Live workflow in Sketch and Photoshop, design systems setup, lettering, new frontiers of CSS and JavaScript, CSS Grid Layout, live debugging, performance audits, accessibility audits, sketching, graphic design, data visualization and creative coding. 100 super early-bird-tickets now on sale.
To give everybody a chance to buy ticket in time, we are releasing all tickets in batches this time. The first batch of super early-birds are available right away: fetch them before they fly out!
Ah, and just in case you’re wondering: we’re planning on running a conference in our hometown Freiburg, Germany on September 10–11, and we will be coming back to New York, USA on October 23–24 — with a slightly different format, too. We can’t wait to see you there! 😉
November is a rather gray month in many parts of the world, so what could be better as some colorful inspiration to start it off with the right foot? To tickle your creativity, artists and designers from across the globe once again challenged their artistic abilities and designed desktop wallpapers for you to indulge in. Wallpapers that are a bit more distinctive as the usual crowd, bound to breathe some fresh life into your routine.
All artworks in this collection come in versions with and without a calendar for November 2017, so it’s up to you to decide if you want to have the month always in sight or just some distraction-free inspiration. A big thank-you to everyone who shared their wallpapers this time around! Enjoy!
Please note that:
All images can be clicked on and lead to the preview of the wallpaper,
You can feature your work in our magazine by taking part in our Desktop Wallpaper Calendars series. We are regularly looking for creative designers and artists to be featured on Smashing Magazine. Are you one of them?
Colorful Autumn
“Autumn can be dreary, especially in November, when rain starts pouring every day. We wanted to summon better days, so that’s how this colourful November calendar was created. Open your umbrella and let’s roll!” — Designed by PopArt Studio from Serbia.
“Kindness drives humanity. Be kind. Be humble. Be humane. Be the best of yourself! Here is presenting to you an inspiration in form of a calendar for November.” — Designed by Color Mean Creative Studio from Dubai.
“‘When autumn darkness falls, what we will remember are the small acts of kindness: a cake, a hug, an invitation to talk, and every single rose. These are all expressions of a nation coming together and caring about its people.’ (Jens Stoltenberg)” — Designed by Dipanjan Karmakar from India.
“By the end of autumn, ferocious Poseidon will part from tinted clouds and timid breeze. After this uneven clash, the sky once more becomes pellucid just in time for imminent luminous snow.” — Designed by Ana Masnikosa from Belgrade, Serbia.
“The colorful leaves and cool breeze that make you want to snuggle in your couch at home inspired me to create this fall design.” — Designed by Allison Coyle from the United States.
“November is the Peanut Butter Month so I decided to make a wallpaper around that. As everyone knows peanut butter goes really well with some jelly so I made two sandwiches, one with peanut butter and one with jelly. Together they make the best combination. I also think peanut butter tastes pretty good so that’s why I chose this for my wallpaper.” — Designed by Senne Mommens from Belgium.
“Movember is an annual event involving the growing of mustaches during the month of November to raise awareness of men’s health issues, such as prostate cancer, testicular cancer and men’s suicide. This wallpaper is to support men’s health.” — Designed by Hemangi Rane from Gainesville, FL.
“No dream is too big. No challenge is too great. The whole universe is friendly to us and conspires only to give the best to those who dream and work.” — Designed by BootstrapDash from India.
“‘Feeling gratitude and not expressing it is like wrapping a present and not giving it.’ (William Arthur Ward)” — Designed by TemplateWatch from India.
“It’s C.S. Lewis’s birthday on the 29th November, so I decided to create this ‘Chronicles of Narnia’ inspired wallpaper to honour this day.” — Designed by Safia Begum from the United Kingdom.
“The short days of the autumn and the early nights of winter. The image gives you the feeling of a cold night in autumn.” — Designed by Lars Pauwels from Belgium.
“November is great for having a walk in the park, being out of your house, watching the few colored leaves that are still hanging on the trees. Enjoy the fresh but cold air from a blue sky on a nice November day.” — Designed by Arne Ameye from Belgium.
“November brings us deeper into Autumn, when all leaves are brown and yellow, and Summer is just a distant memory to which we look back with a sweet melancholy.” — Designed by Pedro Vaz from Portugal.
“In Belgium we have Armistice Day on November the 11th. This is a Bank Holiday. We remember the end of the War and all the weapons were put down.” — Designed by Ruben Annaert from Belgium.
“Since I was a kid I’ve always been extremely inspired by astronomy. Starting this project I found out that many meteor showers occur during November. I had never made a proper space-related illustration before and I definitely took my chance now.” — Designed by Yannis Wellemans from Belgium.
“A single hammer headed person around can simply ruin your entire peace and pleasure when you are working on something great. As it’s an empty vessel, nothing much to expect but loud noise. It’s easy to identify those from outside and being hammer headed is a choice. So, consider people around, stop hitting yourself into others and let them do whatever they feel like.” — Designed by Sweans from London.
“When it’s cold outside, bring out the warmth and love in your hearts; to enjoy what the season has kept in store for you. Let’s welcome the onset of winter this November with open arms.” — Designed by Acodez from India.
Please note that we respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us, but rather designed from scratch by the artists themselves.
A big thank you to all designers for their participation. Join in next month!
What’s Your Favorite?
What’s your favorite theme or wallpaper for this month? Please let us know in the comment section below.