A List Apart

Subscribe to A List Apart feed
Articles for people who make web sites.
Updated: 36 min 20 sec ago

Discovery on a Budget: Part II

Tue, 02/13/2018 - 08:00

Welcome to the second installment of the “Discovery on a Budget” series, in which we explore how to conduct effective discovery research when there is no existing data to comb through, no stakeholders to interview, and no slush fund to draw upon. In part 1 of this series, we discussed how it is helpful to articulate what you know (and what you assume) in the form of a problem hypothesis. We also covered strategies for conducting one of the most affordable and effective research methods: user interviews. In part 2 we will discuss when it’s beneficial to introduce a second, competing problem hypothesis to test against the first. We will also discuss the benefits of launching a “fake-door” and how to conduct an A/B test when you have little to no traffic.

A quick recap

In part 1 I conducted the first round of discovery research for my budget-conscious (and fictitious!) startup, Candor Network. The original goal for Candor Network was to provide a non-addictive social media platform that users would pay for directly. I articulated that goal in the form of a problem hypothesis:

Because their business model relies on advertising, social media tools like Facebook are deliberately designed to “hook” users and make them addicted to the service. Users are unhappy with this and would rather have a healthier relationship with social media tools. They would be willing to pay for a social media service that was designed with mental health in mind.

Also in part 1, I took extra care to document the assumptions that went into creating this hypothesis. They were:

  • Users feel that social media sites like Facebook are addictive.
  • Users don’t like to be addicted to social media.
  • Users would be willing to pay for a non-addictive Facebook replacement.

For the first round of research, I chose to conduct user interviews because it is a research method that is adaptable, effective, and—above all—affordable. I recruited participants from Facebook, taking care to document the bias of using a convenience sampling method. I carefully crafted my interview protocol, and used a number of strategies to keep my participants talking. Now it is time to review the data and analyze the results.

Analyze the data

When we conduct discovery research, we look for data that can help us either affirm or reject the assumptions we made in our problem hypothesis. Regardless of what research method you choose, it’s critical that you set aside the time to objectively review and analyze the results.

In practice, analyzing interview data involves creating transcriptions of the interviews and then reading them many, many times. Each time you read through the transcripts, you highlight and label sentences or sections that seem relevant or important to your research question. You can use products like NVivo, HyperRESEARCH, or any other qualitative analysis tool to help facilitate this process. Or, if you are on a pretty strict budget, you can simply use Google Sheets to keep track of relevant sections in one column and labels in another.

Screenshot of my interview analysis in Google Sheets

For my project, I specifically looked for data that would show whether my participants felt Facebook was addicting and whether that was a bad thing, and if they’d be willing to pay for an alternative. Here’s how that analysis played out:

Assumption 1: Users feel that social media sites like Facebook are addictive

Facebook has a weird, hypnotizing effect on my brain. I keep scrolling and scrolling and then I like wake up and think, ‘where have I been? why am I spending my time on this?’ interview participant

Overwhelmingly, my data affirms this assumption. All of my participants (eleven out of eleven) mentioned Facebook being addictive in some way.

Assumption 2: Users don’t like to be addicted to social media

I know a lot of people who spend a lot of time on Facebook, but I think I manage it pretty well. interview participant

This assumption turned out to be a little more tricky to affirm or reject. While all of my participants described Facebook as addictive, many of them (eight out of eleven) expressed that “it wasn’t so bad” or that they felt like they were less addicted than the average Facebook user.

Assumption 3: Users would be willing to pay for a non-addictive Facebook replacement

No, I wouldn’t pay for that. I mean, why would I pay for something I don’t think I should use so much anyway? interview participant

Unfortunately for my project, I can’t readily affirm this assumption. Four participants told me they would flat-out never pay for a social media service, four participants said they would be interested in trying a paid-for “non-addictive Facebook,” and three participants said they would only try it if it became really popular and everyone else was using it.

One unexpected result: “It’s super creepy”

I don’t like that they are really targeting me with those ads. It’s super creepy. interview participant

In reviewing the interview transcripts, I came across one unexpected theme. More than 80% of the interviewees (nine out of eleven) said they found Facebook “creepy” because of the targeted advertising and the collection of personal data. Also, most of those participants (seven out of nine) went on to say that they would pay for a “non-creepy Facebook.” This is particularly remarkable because I never asked the participants how they felt about targeted advertising or the use of personal data. It always came up in the conversation organically.

Whenever we start a new project, our initial ideas revolve around our own personal experiences and discomforts. I started Candor Network because I personally feel that social media is designed to be addicting, and that this is a major flaw with many of the most popular services. However, while I can affirm my first assumption, I had unclear results on the second and have to consider rejecting the third. Also, I encountered a new user experience that I previously didn’t think of or account for: that the way social media tools collect and use personal data for advertising can be disconcerting and “creepy.” As is so often the case, the data analysis showed that there are a variety of other experiences, expectations, and needs that must be accounted for if the project is to be successful.

Refining the hypothesis Discovery research cycle: Create Hypothesis, Test, Analyze, and repeat

Each time we go through the discovery research process, we start with a hypothesis, test it by gathering data, analyze the data, and arrive at a new understanding of the problem. In theory, it may be possible to take one trip through the cycle and either completely affirm or completely reject our hypothesis and assumptions. However, like with Candor Network, it is more often the case that we get a mixture of results: some assumptions can be affirmed while others are rejected, and some completely new insights come to light.

One option is to continue working with a single hypothesis, and simply refine it to account for the results of each round of research. This is especially helpful when the research mostly affirms your assumptions, but there is additional context and nuance you need to account for. However, if you find that your research results are pulling you in a new direction entirely, it can be useful to create a second, competing hypothesis.

In my example, the interview research brought to light a new concern about social media I previously hadn’t considered: the “creepy” collection of personal data. I am left wondering, Would potential customers be more attracted to the idea of a social media platform built to prevent addiction, or one built for data privacy? To answer this question, I articulated a new, competing hypothesis:

Because their business model relies on advertising, social media tools like Facebook are designed to gather lots of behavior data. They then utilize this behavior data to create super-targeted ads. Users are unhappy with this, and would rather use a social media tool that does not rely on the commodification of their data to make money. They would be willing to pay for a social media service that did not track their use and behavior.

I now have two hypotheses to test against one another: one focused on social media addiction, the other focused on behavior tracking and data collection.

At this point, it would be perfectly acceptable to conduct another round of interviews. We would need to change our interview protocol and find more participants, but it would still be an effective (and cheap) method to use. However, for this article I wanted to introduce a new method for you to consider, and to illustrate that a technique like A/B testing is not just for the “big guys” on the web. So I chose to conduct an A/B test utilizing two “fake-doors.”

A low-cost comparative test: fake-door A/B testing

A “fake-door” test is simply a marketing page, ad, button, or other asset that promotes a product that has yet to be made. Fake-door testing (or “ghetto testing”) is Zynga’s go-to method for testing ideas. They create a five-word summary of any new game they are considering, make a few ads, and put it up on various high-trafficked websites. Data is then collected to track how often users click on each of the fake-door “probes,” and only those games that attract a certain number of “conversions” on the fake-door are built.

One of the many benefits of conducting a fake-door test is that it allows you to measure interest in a product before you begin to develop it. This makes it a great method for low-budget projects, because it can help you decide whether a project is worth investing in before you spend anything.

However, for my project, I wasn’t just interested in measuring potential customer interest in a single product idea. I wanted to continue evaluating my original hypothesis on non-addictive social media as well as start investigating the second hypothesis on a social media platform that doesn’t record behavior data. Specifically, I wanted to see which theoretical social media platform is more attractive. So I created two fake-door landing pages—one for each hypothesis—and used Google Optimize to conduct an A/B test.

Versions A (right) and B (left) of the Candor Network landing page

Version A of the Candor Network landing page advertises the product I originally envisioned and described in my first problem hypothesis. It advertises a social network “built with mental health in mind.” Version B reflects the second problem hypothesis and my interview participants’ concerns around the “creepy” commodification of user data. It advertises a social network that “doesn’t track, use, solicit, or sell your data.” In all other respects, the landing pages are identical, and both will receive 50% of the traffic.

Running an A/B test with little to no site traffic

One of the major caveats when running an A/B test is that you need to have a certain number of people participate to achieve any kind of statistically significant result. This wouldn’t be a problem if we worked at a large company with an existing customer base, as it would be relatively straightforward to find ways to direct some of the existing traffic to the test. If you’re working on a new or low-trafficked site, however, conducting an A/B test can be tricky. Here are a few strategies I recommend:

Figuring out how much traffic you need to achieve statistical significance in a quantitative study is an inexact science. If we were conducting a high-stakes experiment at a more established business, we would conduct multiple rounds of pre-tests to calculate the effect size of the experiment. Then we would use a calculation like Cohen’s d to estimate the number of people we need to participate in the actual test. This approach is rigorous and helps avoid sample pollution or sampling bias, but it requires a lot of resources upfront (like time, money, and lots of potential participants) that we may not have access to.

In general, however, you can use this rule of thumb: the bigger the difference between the variations, the fewer participants you need to see a significant result. In other words, if your A and B are very different from each other, you will need fewer participants.

Tip 2: Run the test for a longer amount of time

When I worked at Weather Underground, we would always start an A/B test on a Sunday and end it a full week later on the following Sunday. That way we could be sure we captured both weekday and weekend users. Because Weather Underground is a high-trafficked site, this always resulted in having more than enough participants to see a statistically significant result.

If you’re working on a new or low-trafficked site, however, you’ll need to run your test for longer than a week to achieve the number of test participants required. I recommend budgeting enough time so that your study can run a full six weeks. Six weeks will provide enough time to not only capture results from all your usual website traffic, but also any newcomers you can recruit through other means.

Tip 3: Beg and borrow traffic from someone else

I’ve got a pretty low number of followers on social media, so if I tweet or post about Candor Network, only a few people will see it. However, I know a few people and organizations that have a huge number of followers. For example, @alistapart has roughly 148k followers on Twitter, and A List Apart’s publisher, Jeffrey Zeldman (@zeldman), has 358k followers. I have asked them both to share the link for Candor Network with their followers.

A helpful tweet from @zeldman

Of course, this method of advertising doesn’t cost any money, but it does cost social capital. I’m sure A List Apart and Mr. Zeldman wouldn’t appreciate it if I asked them to tweet things on my behalf on a regular basis. I recommend you use this method sparingly.

Tip 4: Beware! There is always a risk of no results.

Before you create an A/B test for your new product idea, there is one major risk you need to assess: there is a chance that your experiment won’t produce any statistically significant results at all. Even if you use all of the tips I’ve outlined above and manage to get a large number of participants in your test, there is a chance that you won’t be able to “declare a winner.” This isn’t just a risk for companies that have low traffic, it is an inherent risk when running any kind of quantitative study. Sometimes there simply isn’t a clear effect on participant behavior.

Tune in next time for the last installment

In the third and final installment of the “Discovery on a Budget” series, I’ll describe how I designed the incredibly short survey on the Candor Network landing page and discuss the results of my fake-door A/B test. I will also make another revision to my problem hypothesis and will discuss how to know when you’re ready to leave the discovery process (at least for now) and embark on the next phase of design: ideating over possible solutions.

My Accessibility Journey: What I’ve Learned So Far

Tue, 02/06/2018 - 08:00

Last year I gave a talk about CSS and accessibility at the stahlstadt.js meetup in Linz, Austria. Afterward, an attendee asked why I was interested in accessibility: Did I or someone in my life have a disability?

I’m used to answering this question—to which the answer is no—because I get it all the time. A lot of people seem to assume that a personal connection is the only reason someone would care about accessibility.

This is a problem. For the web to be truly accessible, everyone who makes websites needs to care about accessibility. We tend to use our own abilities as a baseline when we’re designing and building websites. Instead, we need to keep in mind our diverse users and their diverse abilities to make sure we’re creating inclusive products that aren’t just designed for a specific range of people.

Another reason we all should think about accessibility is that it makes us better at our jobs. In 2016 I took part in 10k Apart, a competition held by Microsoft and An Event Apart. The objective was to build a compelling web experience that worked without JavaScript and could be delivered in 10 kB. On top of that, the site had to be accessible. At the time, I knew about some accessibility basics like using semantic HTML, providing descriptions for images, and hiding content visually. But there was still a lot to learn.

As I dug deeper, I realized that there was far more to accessibility than I had ever imagined, and that making accessible sites basically means doing a great job as a developer (or as a designer, project manager, or writer).

Accessibility is exciting

Web accessibility is not about a certain technology. It’s not about writing the most sophisticated code or finding the most clever solution to a problem; it’s about users and whether they’re able to use our products.

The focus on users is the main reason why I’m specializing in accessibility rather than solely in animation, performance, JavaScript frameworks, or WebVR. Focusing on users means I have to keep up with pretty much every web discipline, because users will load a page, deal with markup in some way, use a design, read text, control a JavaScript component, see animation, walk through a process, and navigate. What all those things have in common is that they’re performed by someone in front of a device. What makes them exciting is that we don’t know which device it will be, or which operating system or browser. We also don’t know how our app or site will be used, who will use it, how fast their internet connection will be, or how powerful their device will be.

Making accessible sites forces you to engage with all of these variables—and pushes you, in the process, to do a great job as a developer. For me, making accessible sites means making fast, resilient sites with great UX that are fun and easy to use even in conditions that aren’t ideal.

I know, that sounds daunting. The good news, though, is that I’ve spent the last year focusing on some of those things, and I’ve learned several important lessons that I’m happy to share.

1. Accessibility is a broad concept

Many people, like me pre-2016, think making your site accessible is synonymous with making it accessible to people who use screen readers. That’s certainly hugely important, but it’s only one part of the puzzle. Accessibility means access for everyone:

  • If your site takes ten seconds to load on a mobile connection, it’s not accessible.
  • If your site is only optimized for one browser, it’s not accessible.
  • If the content on your site is difficult to understand, your site isn’t accessible.

It doesn’t matter who’s using your website or when, where, and how they’re doing it. What matters is that they’re able to do it.

The belief that you have to learn new software or maybe even hardware to get started with accessibility is a barrier for many developers. At some point you will have to learn how to use a screen reader if you really want to get everything right, but there’s a lot more to do before that. We can make a lot of improvements that help everyone, including people with visual impairments, by simply following best practices.

2. There are permanent, temporary, and situational impairments

Who benefits from a keyboard-accessible site? Only a small percentage of users, some might argue. Aaron Gustafson pointed me to the Microsoft design toolkit, which helped me broaden my perspective. People with permanent impairments are not the only ones who benefit from accessibility. There are also people with temporary and situational impairments who’d be happy to have an alternative way of navigating. For example, someone with a broken arm, someone who recently got their forearm tattooed, or a parent who’s holding their kid in one arm while having to check something online. When you watch a developer operate their editor, it sometimes feels like they don’t even know they have a mouse. Why not give users the opportunity to use your website in a similar way?

As you think about the range of people who could benefit from accessibility improvements, the group of beneficiaries tends to grow much bigger. As Derek Featherstone has said, “When something works for everyone, it works better for everyone.

3. The first step is to make accessibility a requirement

I’ve been asked many times whether it’s worth the effort to fix accessibility, how much it costs, and how to convince bosses and colleagues. My answer to those questions is that you can improve things significantly without even having to use new tools, spend extra money, or ask anyone’s permission.

The first step is to make accessibility a requirement—if not on paper, then at least in your head. For example, if you’re looking for a slider component, pick one that’s accessible. If you’re working on a design, make sure color contrasts are high enough. If you’re writing copy, use language that is easy to understand.

We ask ourselves many questions when we make design and development decisions: Is the code clean? Does the site look nice? Is the UX great? Is it fast enough? Is it well-documented?

As a first step, add one more question to your list: Is it accessible?

4. Making accessible sites is a team sport

Another reason why making websites accessible sounds scary to some developers is that there is a belief that we’re the only ones responsible for getting it right.

In fact, as Dennis Lembree reminds us, “Nearly everyone in the organization is responsible for accessibility at some level.

It’s a developer’s job to create an accessible site from a coding perspective, but there are many things that have to be taken care of both before and after that. Designs must be intuitive, interactions clear and helpful, copy understandable and readable. Relevant personas and use cases have to be defined, and tests must be carried out accordingly. Most importantly, leadership and teams have to see accessibility as a core principle and requirement, which brings me to the next point: communication.

5. Communication is key

After talking to a variety of people at meetups and conferences, I think one of the reasons accessibility often doesn’t get the place it deserves is that not everyone knows what it means. Many times you don’t even have to convince your team, but rather just explain what accessibility is. If you want to get people on board, it matters how you approach them.

The first step here is to listen. Talk to your colleagues and ask why they make certain design, development, or management decisions. Try to find out if they don’t approach things in an accessible way because they don’t want to, they’re not allowed to, or they just never thought of it. You’ll have better results if they don’t feel bad, so don’t try to guilt anyone into anything. Just listen. As soon as you know why they do things the way they do, you’ll know how to address your concerns.

Highlight the benefits beyond accessibility

You can talk about accessibility without mentioning it. For example, talk about typography and ideal character counts per line and how beautiful text is with the perfect combination of font size and line height. Demonstrate how better performance impacts conversion rates and how focusing on accessibility can promote out-of-the-box thinking that improves usability in general.

Challenge your colleagues

Some people like challenges. At a meetup, a designer who specializes in accessibility once said that one of the main reasons she loves designing with constraints in mind is that it demands a lot more of her than going the easy way. Ask your colleagues, Can we hit a speed index below 1000? Do you think you can design that component in such a way that it’s keyboard-accessible? My Nokia 3310 has a browser—wouldn’t it be cool if we could make our next website work on that thing as well?

Help people empathize

In his talk “Every Day Website Accessibility,” Scott O’Hara points out that it can be hard for someone to empathize if they are unaware of what they should be empathizing with. Sometimes people just don’t know that certain implementations might be problematic for others. You can help them by explaining how people who are blind or who can’t use a mouse, use the web. Even better, show videos of how people navigate the web without a mouse. Empathy prompts are also a great of way of illustrating different circumstances under which people are surfing the web.

6. Talk about accessibility before a projects kicks off

It’s of course a good thing if you’re fixing accessibility issues on a site that’s already in production, but that has its limitations. At some point, changes may be so complicated and costly that someone will argue that it’s not worth the effort. If your whole team cares about accessibility from the very beginning, before a box is drawn or a line of code is written, it’s much easier, effective, and cost-efficient to make an accessible product.

7. A solid knowledge of HTML solves a lot of problems

It’s impressive to see how JavaScript and the way we use it has changed in recent years. It has become incredibly powerful and more important than ever for web development. At the same time, it seems HTML has become less important. There is an ongoing discussion about CSS in JavaScript and whether it’s more efficient and cleaner than normal CSS from a development perspective. What we should talk about instead is the excessive use of <div> and <span> elements at the expense of other elements. It makes a huge difference whether we use a link or a <div> with an onclick handler. There’s also a difference between links and buttons when it comes to accessibility. Form items need <label> elements, and a sound document outline is essential. Those are just a few examples of absolute basics that some of us forgot or never learned. Semantic HTML is one of the cornerstones of accessible web development. Even if we write everything in JavaScript, HTML is what is finally rendered in the user’s browser.

(Re)learning HTML and using it consciously prevents and fixes many accessibility issues.

8. JavaScript is not the enemy, and sometimes JavaScript even improves accessibility

I’m one of those people who believes that most websites should be accessible even when JavaScript fails to execute. That doesn’t mean that I hate JavaScript; of course not—it pays part of my rent. JavaScript is not the enemy, but it’s important that we use it carefully because it’s very easy to change the user experience for the worse otherwise.

Not that long ago, I didn’t know that JavaScript could improve accessibility. We can leverage its power to make our websites more accessible for keyboard users. We can do things like trapping focus in a modal window, adding key controls to custom components, or showing and hiding content in an accessible manner.

There are many impressive and creative CSS-only implementations of common widgets, but they’re often less accessible and provide worse UX than their JavaScript equivalents. In a post about building a fully accessible help tooltip, Sara Soueidan explains why JavaScript is important for accessibility. “Every single no-JS solution came with a very bad downside that negatively affected the user experience,” she writes.

9. It’s a good time to know vanilla CSS and JavaScript

For a long time, we’ve been reliant on libraries, frameworks, grid systems, and polyfills because we demanded more of browsers than they were able to give us. Naturally, we got used to many of those tools, but from time to time we should take a step back and question if we really still need them. There were many problems that Bootstrap and jQuery solved for us, but do those problems still exist, or is it just easier for us to write $() instead of document.querySelector()?

jQuery is still relevant, but browser inconsistencies aren’t as bad as they used to be. CSS Grid Layout is supported in all major desktop browsers, and thanks to progressive enhancement we can still provide experiences for legacy browsers. We can do feature detection natively with feature queries, testing has gotten much easier, and caniuse and MDN help us understand what browsers are capable of. Many people use frameworks and libraries without knowing what problems those tools are solving. To decide whether it makes sense to add the extra weight to your site, you need a solid understanding of HTML, CSS, and JavaScript. Instead of increasing the page weight for older browsers, it’s often better to progressively enhance an experience. Progressively enhancing our websites—and reducing the number of requests, kilobytes, and dependencies—makes them faster and more robust, and thus more accessible.

10. Keep learning about accessibility and share your knowledge

I’m really thankful that I’ve learned all this in the past few months. Previously, I was a very passive part of the web community for a very long time. Ever since I started to participate online, attend and organize events, and write about web-related topics, especially accessibility, things have changed significantly for me and I’ve grown both personally and professionally.

Understanding the importance of access and inclusion, viewing things from different perspectives, and challenging my decisions has helped me become a better developer.

Knowing how things should be done is great, but it’s just the first step. Truly caring, implementing, and most importantly sharing your knowledge is what makes an impact.

Share your knowledge

Don’t be afraid to share what you’ve learned. Write articles, talk at meetups, and give in-house workshops. The distinct culture of sharing knowledge is one of the most important and beautiful things about our industry.

Go to conferences and meetups

Attending conferences and meetups is very valuable because you get to meet many different people from whom you can learn. There are several dedicated accessibility events and many conferences that feature at least one accessibility talk.

Organize meetups

Dennis Deacon describes his decision to start and run an accessibility meetup as a life-changing experience. Meetups are very important and valuable for the community, but organizing a meetup doesn’t just bring value to attendees and speakers. As an organizer, you get to meet all these people and learn from them. By listening and by understanding how they see and approach things, and what’s important to them, you are able to broaden your horizons. You grow as a person, but you also get to meet other professionals, agencies, and companies from which you may also benefit professionally.

Invite experts to your meetup or conference

If you’re a meetup or conference organizer, you can have a massive impact on the role accessibility plays in our community. Invite accessibility experts to your event and give the topic a forum for discussion.

Follow accessibility experts on Twitter

Follow experts on Twitter to learn what they’re working on, what bothers them, and what they think about recent developments in inclusive web development and design in general. I’ve learned a lot from the following people: Aaron Gustafson, Adrian Roselli, Carie Fisher, Deborah Edwards-Onoro, Heydon Pickering, Hugo Giraudel, Jo Spelbrink, Karl Groves, Léonie Watson, Marco Zehe, Marcy Sutton, Rob Dodson, Scott O’Hara, Scott Vinkle, and Steve Faulkner.

11. Simply get started

You don’t have to go all-in from the very beginning. If you improve just one thing, you’re already doing a great job in bringing us closer to a better web. Just get started and keep working.

There are a lot of resources out there, and trying to find out how and where to start can get quite overwhelming. I’ve gathered a few sites and books that helped me; hopefully they will help you as well. The following lists are by no means exhaustive.

Video series
  • This free Udacity course is a great way to get started.
  • Rob Dodson covers many different accessibility topics in his video series A11ycasts (a11y is short for accessibility—the number eleven stands for the number of letters omitted).
Books Blogs Newsletters Accessible JavaScript components Resources and further reading

Design Like a Teacher

Thu, 02/01/2018 - 08:00

In 2014, the clinic where I served as head of communications and digital strategy switched to a new online patient portal, a change that was mandated by the electronic health record (EHR) system we used. The company that provides the EHR system held several meetings for the COO and me to learn the new tool and provided materials to give to patients to help them register for and use the new portal.

As the sole person at my clinic working on any aspect of user experience, I knew the importance of knowing the audience when implementing an initiative like the patient portal. So I was skeptical of the materials provided to the patients, which assumed a lot of knowledge on their part and focused on the cool features of the portal rather than on why patients would actually want to use it.

By the time the phone rang for the fifth time on the first day of the transition, I knew my suspicion that the patient portal had gone wrong in the user experience stage was warranted. Patients were getting stuck during every phase of the process—from wondering why they should use the portal to registering for and using it. My response was to ask patients what they had tried so far and where they were getting stuck. Then I would try to explain why they might want to use the portal.

Sometimes I lost patients completely; they just refused to sign up. They had a bad user experience trying to understand how a portal fit into their mental model of receiving healthcare, and I had a terrible user experience trying to learn what I needed to do to guide patients through the migration. To borrow a phrase from Dave Platt, the lead instructor of the UX Engineering course I currently help teach, the “hassle budget” was extremely high.

I realized three important things in leading this migration:

  • When people get stuck, their frustration prevents them from providing information up front. They start off with “I’m stuck” and don’t offer additional feedback until you pull it out of them. (If you felt a tremor just then, that was every IT support desk employee in the universe nodding emphatically.)
  • In trying to get them unstuck, I had to employ skills that drew on my work outside of UX. There was no choice; I had a mandate to reach an adoption rate of at least 60%.
  • The overarching goal was really to help these patients learn to do something different than what they were used to, whether that was deal with a new interface or deal with an interface for the first time at all.

Considering these three realizations led me to a single, urgent conclusion that has transformed my UX practice: user experience is really a way of defining and planning what we want a user to learn, so we also need to think about our own work as how to teach.

It follows, then, that user experience toolkits need to include developing a teaching mindset. But what does that mean? And what’s the benefit? Let’s use this patient portal story and the three realizations above as a framework for considering this.

Helping users get unstuck

Research on teaching and learning has produced two concepts that can help explain why people struggle to get unstuck and what to do about it: 1) cognitive load and 2) the zone of proximal development.

Much like you work your muscles through weight resistance to develop physical strength, you work your brain through cognitive load to develop mental strength—to learn. There are three kinds of cognitive load: intrinsic, germane, and extraneous.


.cognitive-load td:first-child{width: 33.33%;} .cognitive-load td:last-child{width: 66.67%} This type of cognitive load ... is responsible for ... Intrinsic Actual learning of the material Germane Building that new information into a more permanent memory store Extraneous Everything else about the experience of encountering the material (e.g., who’s teaching it, how they teach, your comfort level with the material, what the room is like, the temperature, the season, your physical health, energy levels, and so on)

In the case of the patient portal, intrinsic cognitive load was responsible for a user actually signing up for the portal and using it for the first time. Germane cognitive load was devoted to a user making sense of this experience and storing it so that it can be repeated in the future with increasing fluency. My job in salvaging the user experience was to figure out what was extraneous in the process of using the portal so that I could help users focus on what they needed to know to use it effectively.

Additionally, we all have a threshold for comfortably exploring and figuring something out with minimal guidance. This threshold moves around depending on the task and is called your zone of proximal development. It lays between the spaces where you can easily do a task on your own and where you cannot do a task at all without help. Effective learning happens in this zone by offering the right support, at the right time, in the right amount.

When you’re confronted with an extremely frustrated person because of a user experience you have helped create (or ideally, before that scenario happens), ask yourself a couple questions:

  • Did I put too much burden on their learning experience at the expense of the material?
  • Did I do my best to support their movement from something completely familiar to something new and/or unknown?

Think about your creation in terms of the immediate task and everything else. Consider (or reconsider) all the feelings, thoughts, contexts, and everything else that could make up the space around that task. What proportion of effort goes to the task versus to everything in the space around it? After that, think about how easy or difficult it is to achieve that task. Are you offering the right support, at the right time, in the right amount? What new questions might you need to ask to figure that out?

Making use of “unrelated” skill sets

When you were hired, you responded to a job description that included specific bullet points detailing the skills you should have and duties you would be responsible for fulfilling. You highlighted everything about your work that showed you fit that description. You prepared your portfolio, and demonstrated awareness of the recent writings from UX professionals in the field to show you can hold a conversation about how to “do” this work. You looked incredibly knowledgeable.

In research on teaching and learning, we also explore the idea of how we know in addition to what we know. Some people believe that knowledge is universally true and is out there to be uncovered and explored. Others believe that knowledge is subjective because it is uncovered and explored through the filter of the individual’s experiences, reflections, and general perception of reality. This is called constructivism. If we accept constructivism, it means that we open ourselves to learning from each other in how we conceptualize and practice UX based on what else we know besides what job descriptions ask. How do we methodically figure out the what else? By asking better questions.

Part of teaching and learning in a constructivist framework is understanding that the name of the game is facilitation, not lecturing (you might have heard the cute phrase, “Guide on the side, not sage on the stage”). Sharing knowledge is actually about asking questions to evoke reflection and then conversation to connect the dots. Making time to do this can help you recall and highlight the “unrelated” skills that you may have buried that would actually serve you well in your UX work. For example:

  • That was an incredibly difficult stakeholder meeting. What feels like the most surprising thing about how it turned out?
  • It seemed like we got nothing done in that wireframing session. Everyone wanted to see their own stuff included instead of keeping their eye on who we’re solving for. What is another time in my life when I had this kind of situation? How did it turn out?

All of this is in service to helping ourselves unlock more productive communication with our clients. In the patient portal case, I relied very heavily on my master’s degree in international relations, which taught me about how to ask questions to methodically untangle a problem into more manageable chunks, and listen for what a speaker is really saying between the lines. When you don’t speak the same language, your emotional intelligence and empathy begin to heighten as you try to relate on a broader human level. This helped me manage patient expectations to navigate them to the outcome I needed, even though this degree was meant to prepare me to be a diplomat.

As you consider how you’re feeling in your current role, preparing for a performance review, or plotting your next step, think about your whole body of experience. What are the themes in your work that you can recall dealing with in other parts of your life (at any point)? What skills are you relying on that, until you’ve now observed them, you didn’t think very much about but that have a heavy influence on your style of practice or that help make you effective when you work with your intended audiences?

Unlearn first, then learn

When Apple wanted to win over consumers in their bid to make computers a household item, they had to help them embrace what a machine with a screen and some keys could accomplish. In other words, to convince consumers it was worth it to learn how to use a computer, they first had to help consumers unlearn their reliance on a desk, paper, file folders, and pencils.

Apple integrated this unlearning and learning into one seamless experience by creating a graphical user interface that used digital representations of objects people were already familiar with—desks, paper, file folders, and pencils. But the solution may not always be that literal. There are two concepts that can help you support your intended audiences as they transition from one system or experience to another.

The first concept, called a growth mindset, relates to the belief that people are capable of constructing and developing intelligence in any given area, as opposed to a fixed mindset, which holds that each of us is born with a finite capacity for some level of skill. It’s easy to tell if someone has a fixed mindset if they say things like, “I’m too old to understand new technology,” or “This is too complicated. I’ll never get it.”

The second is self-determination theory, which divides motivation into two types: intrinsic and extrinsic. Self-determination theory states that in learning, your desire to persevere is not just about having motivation at all, but about what kind of motivation you have. Intrinsic motivation comes from within yourself; extrinsic comes from the world around you. Thanks to this research and subsequent studies, we know that intrinsic motivation is vital to meaningful learning and skill development (think about the last time you did an HR training and liked it).

This appears in our professional practice as the ever-favored endeavor to generate “buy-in.” What we’re really saying is, “How do I get someone to feel motivated on their own to be part of this or do this thing, instead of me having to reward them or somehow provide an incentive?” Many resources on getting buy-in are about the end goal of getting someone to do what you want. While this is important, conducting this as a teaching process allows you to step back and make space for the other person’s active contribution to a dialogue where you also learn something, even if you don’t end up getting buy-in:

  • “I’m curious about your feeling that this is complicated. Walk me through what you’ve done so far and tell me more about that feeling.”
  • “What’s the most important part of this for you? What excites you or resonates with you?”

For the majority of patients I worked with, transitioning to a new portal was almost fully an extrinsically motivated endeavor—if they didn’t switch, they didn’t get to access their health information, such as lab results, which is vital for people with chronic diseases. They did it because they had to. And many patients ran into a fixed-mindset wall as they confronted bad design: “I can’t understand this. I’m not very good at the computer. I don’t understand technology. Why do I have to get my information this way?” I especially spent a lot of time on exploring why some users felt the portal was complicated (i.e., the first bullet point above), because not only did I want them to switch to it, but I wanted them to switch and then keep using the portal with increasing fluency. First I had to help them unlearn some beliefs about their capabilities and what it means to access information online, and then I could help them successfully set up and use this tool.

While you’re researching the experience you’re going to create around a product, service, or program, ask questions not just about the thing itself but about the circumstances or context. What are the habits or actions someone might need to stop doing, or unlearn, before they adopt what you’re creating? What are the possible motivators in learning to do the something different? Among those, what is the ratio of extrinsic to intrinsic? Do you inadvertently cause an inflammation of fixed mindset? How do you instead encourage a growth mindset?

Where we go from here

Ultimately, I hit the target: about 70% of patients who had been using the old portal migrated to the new tool. It took some time for me to realize I needed to create a process rather than react to individual situations, but gradually things started to smooth out as I knew what bumps in the road to expect. I also walked back even further and adjusted our communications and website content to speak to the fears and concerns I now knew patients experienced. Eventually, we finished migrating existing patients, and the majority of patients signing onto this portal for the first time were new to the clinic overall (so they would not have used the previous portal). To my knowledge the interface design never improved in any profound way, but we certainly lodged a lot of technical tickets to contribute to a push for feature changes and improvements.

Although this piece contains a lot of information, it essentially boils down to asking questions as you always do, but from a different angle to uncover more blind spots. The benefit is a more thorough understanding of who you intend to serve and a more empathetic process for acquiring that understanding. Each section is specifically written to give you a direct idea of a question or prompt you can use the next time you have an opportunity in your own work. I would love to hear how deepening your practice in this way works for you—please comment or feel free to find me on Twitter!

CSS: The Definitive Guide, 4th Edition

Tue, 01/30/2018 - 06:48

A note from the editors: We’re pleased to share an excerpt from Chapter 19 (“Filters, Blending, Clipping, and Masking”) of CSS: The Definitive Guide, 4th Edition by Eric Meyer and Estelle Weyl, available now from O’Reilly.

In addition to filtering, CSS offers the ability to determine how elements are composited together. Take, for example, two elements that partially overlap due to positioning. We’re used to the one in front obscuring the one behind. This is sometimes called simple alpha compositing, in that you can see whatever is behind the element as long as some (or all) of it has alpha channel values less than 1. Think of, for example, how you can see the background through an element with opacity: 0.5, or in the areas of a PNG or GIF87a that are set to be transparent.

But if you’re familiar with image-editing programs like Photoshop or GIMP, you know that image layers which overlap can be blended together in a variety of ways. CSS has gained the same ability. There are two blending strategies in CSS (at least as of late 2017): blending entire elements with whatever is behind them, and blending together the background layers of a single element.

Blending Elements

In situations where elements overlap, it’s possible to change how they blend together with the property mix-blend-mode.


Values: normal | multiply | screen | overlay | darken | lighten | colordodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity
Initial value: normal
Applies to: All elements
Computed value: As declared
Inherited: No
Animatable: No

The way the CSS specification puts this is: “defines the formula that must be used to mix the colors with the backdrop.” That is to say, the element is blended with whatever is behind it (the “backdrop”), whether that’s pieces of another element, or just the background of its parent element.

The default, normal, means that the element’s pixels are shown as is, without any mixing with the backdrop, except where the alpha channel is less than 1. This is the “simple alpha compositing” mentioned previously. It’s what we’re all used to, which is why it’s the default value. A few examples are shown in Figure 19-6.

Figure 19-6. Simple alpha channel blending

For the rest of the mix-blend-mode keywords, I’ve grouped them into a few categories. Let’s also nail down a few definitions:

  • The foreground is the element that has mix-blend-mode applied to it.
  • The backdrop is whatever is behind that element. This can be other elements, the background of the parent element, and so on.
  • A pixel component is the color component of a given pixel: R, G, and B

If it helps, think of the foreground and backdrop as images that are layered atop one another in an image-editing program. With mix-blend-mode, you can change the blend mode applied to the top image (the foreground).

Darken, Lighten, Difference, and Exclusion

These blend modes might be called simple-math modes—they achieve their effect by directly comparing values in some way, or using simple addition and subtraction to modify pixels:

darken: Each pixel in the foreground is compared with the corresponding pixel in the backdrop, and for each of the R, G, and B values (the pixel components), the smaller of the two is kept. Thus, if the foreground pixel has a value corresponding to rgb(91,164,22) and the backdrop pixel is rgb(102,104,255), the resulting pixel will be rgb(91,104,22).

lighten: This blend is the inverse of darken: when comparing the R, G, and B components of a foreground pixel and its corresponding backdrop pixel, the larger of the two values is kept. Thus, if the foreground pixel has a value corresponding to rgb(91,164,22) and the backdrop pixel is rgb(102,104,255), the resulting pixel will be rgb(102,164,255).

difference: The R, G, and B components of each pixel in the foreground are compared to the corresponding pixel in the backdrop, and the absolute value of subtracting one from the other is the final result. Thus, if the foreground pixel has a value corresponding to rgb(91,164,22) and the backdrop pixel is rgb(102,104,255), the resulting pixel will be rgb(11,60,233). If one of the pixels is white, the resulting pixel will be the inverse of the non-white pixel. If one of the pixels is black, the result will be exactly the same as the non-black pixel.

exclusion: This blend is a milder version of difference. Rather than being | back - fore |, the formula is back + fore - (2 × back × fore), where back and fore are values in the range from 0-1. For example, an exclusion calculation of an orange (rgb(100%,50%,0%)) and medium gray (rgb(50%,50%,50%)) will yield rgb(50%,50%,50%). For the red component, the math is 1 + 0.5 - (2 × 1 × 0.5), which reduces to 0.5, corresponding to 50%. For the blue and green components, the math is 0 + 0.5 - (2 × 0 × 0.5), which again reduces to 0.5. Compare this to difference, where the result would be rgb(50%,0%,50%), since each component is the absolute value of subtracting one from the other.

This last definition highlights the fact that for all blend modes, the actual values being operated on are in the range 0-1. The previous examples showing values like rgb(11,60,233) are normalized from the 0-1 range. In other words, given the example of applying the difference blend mode to rgb(91,164,22) and rgb(102,104,255), the actual operation is as follows:

  • rgb(91,164,22) is R = 91 ÷ 255 = 0.357; G = 164 ÷ 255 = 0.643; B = 22 ÷ 255 = 0.086. Similarly, rgb(102,104,255) corresponds to R = 0.4; G = 0.408; B = 1.
  • Each component is subtracted from the corresponding component, and the absolute value taken. Thus, R = | 0.357 - 0.4 | = 0.043; G = | 0.643 - 0.408 | = 0.235; B = | 1 - 0.086 | = 0.914. This could be expressed as rgba(4.3%,23.5%,91.4%), or (by multiplying each component by 255) as rgb(11,60,233).

From all this, you can perhaps understand why the full formulas are not written out for every blend mode we cover. If you’re interested in the fine details, each blend mode’s formula is provided in the “Compositing and Blending Level 1” specification.

Examples of the blend modes in this section are depicted in Figure 19-7.

Figure 19-7. Darken, lighten, difference, and exclusion blending Multiply, Screen, and Overlay

These blend modes might be called the multiplication modes—they achieve their effect by multiplying values together:

multiply: Each pixel component in the foreground is multiplied by the corresponding pixel component in the backdrop. This yields a darker version of the foreground, modified by what is underneath. This blend mode is symmetric, in that the result will be exactly the same even if you were to swap the foreground with the back‐drop.

screen: Each pixel component in the foreground is inverted (see invert in the earlier section “Color Filtering” on page 948), multiplied by the inverse of the corresponding pixel component in the backdrop, and the result inverted again. This yields a lighter version of the foreground, modified by what is underneath. Like multiply, screen is symmetric.

overlay: This blend is a combination of multiply and screen. For foreground pixel components darker than 0.5 (50%), the multiply operation is carried out; for foreground pixel components whose values are above 0.5, screen is used. This makes the dark areas darker, and the light areas lighter. This blend mode is not symmetric, because swapping the foreground for the backdrop would mean a different pattern of light and dark, and thus a different pattern of multiplying versus screening.

Examples of these blend modes are depicted in Figure 19-8.

Figure 19-8. Multiply, screen, and overlay blending Hard and Soft Light

There blend modes are covered here because the first is closely related to a previous blend mode, and the other is just a muted version of the first:

hard-light: This blend is the inverse of overlay blending. Like overlay, it’s a combination of multiply and screen, but the determining layer is the backdrop. Thus, for back‐drop pixel components darker than 0.5 (50%), the multiply operation is carried out; for backdrop pixel components lighter than 0.5, screen is used. This makes it appear somewhat as if the foreground is being projected onto the backdrop with a projector that employs a harsh light.

soft-light: This blend is a softer version of hard-light. That is to say, it uses the same operation, but is muted in its effects. The intended appearance is as if the foreground is being projected onto the backdrop with a projector that employs a diffuse light.

Examples of these blend modes are depicted in Figure 19-9.

Figure 19-9. Hard- and soft-light blending Color Dodge and Burn

Color dodging and burning are interesting modes, in that they’re meant to lighten or darken a picture with a minimum of change to the colors themselves. The terms come from old darkroom techniques performed on chemical film stock:

color-dodge: Each pixel component in the foreground is inverted, and the component of the corresponding backdrop pixel component is divided by the inverted foreground value. This yields a brightened backdrop unless the foreground value is 0, in which case the backdrop value is unchanged.

color-burn: This blend is a reverse of color-dodge: each pixel component in the backdrop is inverted, the inverted backdrop value is divided by the unchanged value of the corresponding foreground pixel component, and the result is then inverted. This yields a result where the darker the backdrop pixel, the more its color will burn through the foreground pixel.

Examples of these blend modes are depicted in Figure 19-10.

Figure 19-10. Color dodge and burn blending Hue, Saturation, Luminosity, and Color

The final four blend modes are different than those we’ve seen before, because they do not perform operations on the R/G/B pixel components. Instead, they perform operations to combine the hue, saturation, luminosity, and color of the foreground and backdrop in different ways:

hue: For each pixel, combines the luminosity and saturation levels of the backdrop with the hue angle of the foreground.

saturation: For each pixel, combines the hue angle and luminosity level of the backdrop with the saturation level of the foreground.

color: For each pixel, combines the luminosity level of the backdrop with the hue angle and saturation level of the foreground.

luminosity: For each pixel, combines the hue angle and saturation level of the backdrop with the luminosity level of the foreground.

Examples of these blend modes are depicted in Figure 19-11.

Figure 19-11. Hue, saturation, luminosity, and color blending

These blend modes can be a lot harder to grasp without busting out raw formulas, and even those can be confusing if you aren’t familiar with how things like saturation and luminosity levels are determined. If you don’t feel like you quite have a handle on how they work, the best thing is to practice with a bunch of different images and simple color patterns.

Two things to note:

  • Remember that an element always blends with its backdrop. If there are other elements behind it, it will blend with them; if there’s a patterned background on the parent element, the blending will be done against that pattern.
  • Changing the opacity of a blended element will change the outcome, though not always in the way you might expect. For example, if an element with mix-blend-mode: difference is also given opacity: 0.8, then the difference calculations will be scaled by 80%. More precisely, a scaling factor of 0.8 will be applied to the color-value calculations. This can cause some operations to trend toward flat middle gray, and others to shift the color changes.

The King vs. Pawn Game of UI Design

Tue, 01/23/2018 - 06:33

If you want to improve your UI design skills, have you tried looking at chess? I know it sounds contrived, but hear me out. I’m going to take a concept from chess and use it to build a toolkit of UI design strategies. By the end, we’ll have covered color, typography, lighting and shadows, and more.

But it all starts with rooks and pawns.

I want you to think back to the first time you ever played chess (if you’ve never played chess, humor me for a second—and no biggie; you will still understand this article). If your experience was anything like mine, your friend set up the board like this:

And you got your explanation of all the pieces. This one’s a pawn and it moves like this, and this one is a rook and it moves like this, but the knight goes like this or this—still with me?—and the bishop moves diagonally, and the king can only do this, but the queen is your best piece, like a combo of the rook and the bishop. OK, want to play?

This is probably the most common way of explaining chess, and it’s enough to make me hate board games forever. I don’t want to sit through an arbitrary lecture. I want to play.

One particular chess player happens to agree with me. His name is Josh Waitzkin, and he’s actually pretty good. Not only at chess (where he’s a grandmaster), but also at Tai Chi Push Hands (he’s a world champion) and Brazilian Jiu Jitsu (he’s the first black belt under 5x world champion Marcelo Garcia). Now he trains financiers to go from the top 1% to the top .01% in their profession.

Point is: this dude knows a lot about getting good at stuff.

Now here’s the crazy part. When Josh teaches you chess, the board looks like this:

King vs. King and Pawn


Compared to what we saw above, this is stupidly simple.

And, if you know how to play chess, it’s even more mind-blowing that someone would start teaching with this board. In the actual game of chess, you never see a board like this. Someone would have won long ago. This is the chess equivalent of a street fight where both guys break every bone in their body, dislocate both their arms, can hardly see out of their swollen eyes, yet continue to fight for another half-hour.

What gives?

Here’s Josh’s thinking: when you strip the game down to its core, everything you learn is a universal principle.

That sounds pretty lofty, but I think it makes sense when you consider it. There are lots of things to distract a beginning chess player by a fully-loaded board, but everything you start learning in a king-pawn situation is fundamentally important to chess:

  • using two pieces to apply pressure together;
  • which spaces are “hot”;
  • and the difference between driving for a checkmate and a draw.

Are you wondering if I’m ever going to start talking about design? Glad you asked.

The simplest possible scenario

What if, instead of trying to design an entire page with dozens of elements (nav, text, input controls, a logo, etc.), we consciously started by designing the simplest thing possible? We deliberately limit the playing field to one, tiny thing and see what we learn? Let’s try.

What is the simplest possible element? I vote that it’s a button.

This is the most basic, default button I could muster. It’s Helvetica (default font) with a 16px font size (pretty default) on a plain, Sketch-default-blue rectangle. It’s 40px tall (nice, round number) and has 20px of horizontal padding on each side.

So yeah, I’ve already made a bunch of design decisions, but can we agree I basically just used default values instead of making decisions for principled, design-related reasons?

Now let’s start playing with this button. What properties are modifiable here?

  • the font (and text styling)
  • the color
  • the border radius
  • the border
  • the shadows

These are just the first things that come to my mind. There are even more, of course.


Playing with the font is a pretty easy place to start.

Blown up to show font detail.

Now I’ve changed the font to Moon (available for free on Behance for personal use). It’s rounded and soft, unlike Helvetica, which felt a little more squared-off—or at least not as overtly friendly.

The funny thing is: do you see how the perfectly square edges now look a tad awkward with the rounded font?

Let’s round the corners a bit.

Bam. Nice. That’s a 3px border radius.

But that’s kind of weird, isn’t it? We adjusted the border radius of a button because of the shape of the letterforms in our font. I wouldn’t want you thinking fonts are just loosey-goosey works of art that only work when you say the right incantations.

No, fonts are shapes. Shapes have connotations. It’s not rocket science.

Here’s another popular font, DIN.

With its squared edges, DIN is a clean and solid workhorse font.

Specifically, this is a version called DIN 2014 (available for cheap on Typekit). It’s the epitome of a squared-off-but-still-readable font. A bit harsh and no-nonsense, but in a bureaucratic way.

It’s the official font of the German government, and it looks the part.

So let’s test our working hypothesis with DIN.

How does DIN look with those rounded corners?

Well, we need to compare it to square corners now, don’t we?

Ahhh, the squared-off corners are better here. It’s a much more consistent feel.

Now look at our two buttons with their separate fonts. Which is more readable? I think Moon has a slight advantage here. DIN’s letters just look too cramped by comparison. Let’s add a bit of letter-spacing.

When we add some letter-spacing, it’s far more relaxed.

This is a key law of typography: always letter-space your uppercase text. Why? Because unless a font doesn’t have lowercase characters, it was designed for sentence-case reading, and characters in uppercase words will ALWAYS appear too cramped. (Moon is the special exception here—it only has uppercase characters, and notice how the letter-spacing is built into the font.)

We’ll review later, but so far we’ve noticed two things that apply not just to buttons, but to all elements:

  • Rounded fonts go better with rounded shapes; squared-off fonts with squared-off shapes.
  • Fonts designed for sentence case should be letter-spaced when used in words that are all uppercase.

Let’s keep moving for now.


Seeing the plain default Sketch blue is annoying me. It’s begging to be changed into something that matches the typefaces we’re using.

How can a color match a font? Well, I’ll hand it to you. This one is a bit more loosey-goosey.

For our Moon button, we want something a bit more friendly. To me, a staid blue says default, unstyled, trustworthy, takes-no-risks, design-by-committee. How do you inject some fun into it?

Well, like all problems of modifying color, it helps to think in the HSB color system (hue, saturation, and brightness). When we boil color down to three intuitive numbers, we give ourselves levers to pull.

For instance, let’s look at hue. We have two directions we can push hue: down to aqua or up to indigo. Which sounds more in line with Moon? To me, aqua does. A bit less staid, a bit more Caribbean sea. Let’s try it. We’ll move the hue to 180° or so.

Ah, Moon Button, now you’ve got a beach vibe going on. You’re a vibrant sea foam!

This is a critical lesson about color. “Blue” is not a monolith; it’s a starting point. I’ve taught hundreds of students UI design, and this comes up again and again: just because blue was one color in kindergarten doesn’t mean that we can’t find interesting variations around it as designers.

“Blue” is not a monolith. Variations are listed in HSB, with CSS color names given below each swatch.

Aqua is a great variation with a much cooler feel, but it’s also much harder to read that white text. So now we have another problem to fix.

“Hard to read” is actually a numerically-specific property. The World Wide Web Consortium has published guidelines for contrast between text and background, and if we use a tool to test those, we find we’re lacking in a couple departments.

White text on an aqua button doesn’t provide enough contrast, failing to pass either AA or AAA WCAG recommendations.

According to Stark (which is my preferred Sketch plugin for checking contrast—check out Lea Verou’s Contrast Ratio for a similar web-based tool), we’ve failed our contrast guidelines across the board!

How do you make the white text more legible against the aqua button? Let’s think of our HSB properties again.

  • Brightness. Let’s decrease it. That much should be obvious.
  • Saturation. We’re going to increase it. Why? Because we’re contrasting with white text, and white has a saturation of zero. So a higher saturation will naturally stand out more.
  • Hue. We’ll leave this alone since we like its vibe. But if the contrast continued to be too low, you could lower the aqua’s luminosity by shifting its hue up toward blue.

So now, we’ve got a teal button:

Much better?

Much better.

For what it’s worth, I’m not particularly concerned about missing the AAA standard here. WCAG developed the levels as relative descriptors of how much contrast there is, not as an absolute benchmark of, say, some particular percentage of people to being able to read the text. The gold standard is—as always—to test with real people. AAA is best to hit, but at times, AA may be as good as you’re going to get with the colors you have to work with.

Some of the ideas we’ve used to make a button’s blue a bit more fun and legible against white are actually deeper lessons about color that apply to almost everything else you design:

  • Think in HSB, as it gives you intuitive levers to pull when modifying color.
  • If you like the general feel of a color, shifting the hue in either direction can be a baseline for getting interesting variations on it (e.g., we wanted to spice up the default blue, but not by, say, changing it to red).
  • Modify saturation and brightness at the same time (but always in opposite directions) to increase or decrease contrast.

OK, now let’s switch over to our DIN button. What color goes with its harsh edges and squared-off feel?

The first thing that comes to mind is black.

But let’s keep brainstorming. Maybe a stark red would also work.

Or even a construction-grade orange.

(But not the red and orange together. Yikes! In general, two adjacent hues with high saturations will not look great next to each other.)

Now, ignoring that the text of this is “Learn More” and a button like this probably doesn’t need to be blaze orange, I want you to pay attention to the colors I’m picking. We’re trying to maintain consistency with the official-y, squared-off DIN. So the colors we go to naturally have some of the same connotations: engineered, decisive, no funny business.

Sure, this match-a-color-and-a-font business is more subjective, but there’s something solid to it: note that the words I used to describe the colors (“stark” and “construction-grade”) apply equally well to DIN—a fact I am only noticing now, not something done intentionally.

Want to match a color with a font? This is another lesson applicable to all of branding. It’s best to start with adjectives/emotions, then match everything to those. Practically by accident, we’ve uncovered something fundamental in the branding design process.


Let’s shift gears to work with shadows for a bit.

There are a couple directions we could go with shadows, but the two main categories are (for lack of better terms):

  • realistic shadows;
  • and cartoon-y shadows.

Here’s an example of each:

The top button’s shadow is more photorealistic. It behaves like a shadow in the real world.

The bottom button’s shadow is a bit lower-fidelity. It shows that the button is raised up, but it’s a cartoon version, with a slightly unrealistic, idealized bottom edge—and without a normal shadow, which would be present in the real world.

The bottom works better for the button we’re crafting. The smoothness, the friendliness, the cartoon fidelity—it all goes together.

As for our DIN button?

I’m more ambivalent here. Maybe the shadow is for a hover state, à la Material Design?

In any case, with a black background, a darkened bottom edge is impossible—you can’t get any darker than black.

By the way, you may not have noticed it above, but the black button has a much stronger shadow. Compare:

The teal button’s shadow is 30%-opacity black, shifted 1 pixel down on the y-axis, with a 2-pixel blur (0 1px 2px). The black button’s is 50%-opacity black, shifted 2 pixels down on the y-axis, with a 4-pixel blur (0 2px 4px). What’s more, the stronger shadow looks awful on the teal button.

Why is that? The answer, like so many questions that involve color, is in luminosity. When we put the button’s background in luminosity blend mode, converting it to a gray of equal natural lightness, we see something interesting.

The shadow, at its darkest, is basically as dark as the button itself. Or, at least, the rate of change of luminosity is steady between each row of pixels.

The top row is the button itself, not shadow.

Shadows that are too close to the luminosity of their element’s backgrounds will appear too strong. And while this may sound like an overly specific lesson, it’s actually broadly applicable across elements. You know where else you see it?


Let’s put a border on our teal button.

Now the way I’ve added this border is something that a bunch of people have thought of: make the border translucent black so that it works on any background color. In this case, I’ve used a single-pixel-wide border of 20%-opacity black.

However, if I switch the background color to a more standard blue, which is naturally a lot less luminous, that border all but disappears.

In fact, to see it on blue just as much as you can see it on teal, you’ve got to crank up black’s opacity to something like 50%.

This is a generalizable rule: when you want to layer black on another color, it needs to be a more opaque black to show up the same amount on less luminous background colors. Where else would you apply this idea?

Spoiler alert: shadows!

Each of these buttons has the same shadow (0 2px 3px) except for different opacities. The top two buttons’ shadows have opacity 20%, and the bottom two have opacity 40%. Note how what’s fine on a white background (top left) is hardly noticeable on a dark background (top right). And what’s too dark on a white background (lower left) works fine on a dark background (lower right).


I want to change gears one more time and talk about icons.

Here’s the download icon from Font Awesome, my least favorite icon set of all time.

I dislike it, not only because it’s completely overused, but also because the icons are really bubbly and soft. Yet most of the time, they’re used in clean, crisp websites. They just don’t fit.

You can see it works better with a soft, rounded font. I’m less opposed to this sort of thing.

But there’s still a problem: the icon has these insanely small details! The dots are never going to show up at size, and even the space between the arrow and the disk is a fraction of a pixel in practice. Compared to the letterforms, it doesn’t look like quite the same style.

But what good is my complaining if I don’t offer a solution?

Let’s create a new take on the “download” icon, but with some different guiding principles:

  • We’ll use a stroke weight that’s equivalent (or basically equivalent) to the text weight.
  • We’ll use corner radii that are similar to the corner radii of our font: squared off for DIN, rounded for Moon.
  • We’ll use a simpler icon shape so the differences are easy to see.

Let’s see how it looks:

I call this “drawing with the same pen.” Each of these icons looks like it could basically be a character in the font used in the button. And that’s the point here. I’m not saying all icons will appear this way, but for an icon that appears inline with text like this, it’s a fantastic rule of thumb.

Wrapping it up

Now this is just the beginning. Buttons can take all kinds of styles.

But we’ve got a good start here considering we designed just two buttons. In doing so, we covered a bunch of the things that are focal points of my day-to-day work as a UI designer:

  • lighting and shadows;
  • color;
  • typography;
  • consistency;
  • and brand.

And the lessons we’ve learned in those areas are fundamental to the entirety of UI design, not just one element. Recall:

  • Letterforms are shapes. You can analyze fonts as sets of shapes, not simply as works of art.
  • You should letter-space uppercase text, since most fonts were designed for sentence case.
  • Think in HSB to modify colors.
  • You can find more interesting variations on a “basic” color (like a CSS default shade of blue or red) by tweaking the hue in either direction.
  • Saturation and brightness are levers that you can move in opposite directions to control luminosity.
  • Find colors that match the same descriptors that you would give your typeface and your overall brand.
  • Use darker shadows or black borders on darker backgrounds—and vice versa.
  • For inline icons, choose or design them to appear as though they were drawn with the same pen as the font you’re using.

You can thank Josh Waitzkin for making me a pedant. I know, you just read an entire essay on buttons. But next time you’re struggling with a redesign or even something you’re designing from scratch, try stripping out all the elements that you think you should be including already, and just mess around with the simplest players on the board. Get a feel for the fundamentals, and go from there.

Weird? Sure. But if it’s good enough for a grandmaster, I’ll take it.

Mental Illness in the Web Industry

Thu, 01/18/2018 - 06:57

The picture of the tortured artist has endured for centuries: creative geniuses who struggle with their metaphorical demons and don’t relate to life the same way as most people. Today, we know some of this can be attributed to mental illness: depression, anxiety, bipolar disorder, and many others. We have modern stories about this and plenty of anecdotal information that fuels the popular belief in a link between creativity and mental illness.

But science has also started asking questions about the link between mental illness and creativity. A recent study has suggested that creative professionals may be more genetically predisposed to mental illness. In the web industry, whether designer, dev, copywriter, or anything else, we’re often creative professionals. The numbers suggest that mental illness hits the web industry especially hard.

Our industry has made great strides in compassionate discussion of disability, with a focus on accessibility and events like Blue Beanie Day. But even though we’re having meaningful conversations and we’re seeing progress, issues related to diversity, inclusion, and sexual harassment are still a major problem for our industry. Understanding and acceptance of mental health issues is an area that needs growth and attention just like many others.

When it comes to mental health, we aren’t quite as understanding as we think we are. According to a study published by the Center of Disease Control, 57% of the general population believes that society at large is caring and sympathetic toward people with mental illness; but only 25% of people with mental health symptoms believed the same thing. Society is less understanding and sympathetic regarding mental illness than it thinks it is.

Where’s the disconnect?  What does it look like in our industry? It’s usually not negligence or ill will on anybody’s part. It has a lot more to do with people just not understanding the prevalence and reality of mental illness in the workplace. We need to begin discussing mental illness as we do any other personal challenge that people face.

This article is no substitute for a well-designed scientific study or a doctor’s advice, and it’s not trying to declare truths about mental illness in the industry. And it certainly does not intend to lump together or equalize any and all mental health issues, illnesses, or conditions. But it does suspect that plenty of people in the industry struggle with their mental health at some point or another, and we just don’t seem to talk about it. This doesn’t seem to make sense in light of the sense of community that web professionals have been proud of for decades.

We reached out to a few people in our industry who were willing to share their unique stories to bring light to what mental health looks like for them in the workplace. Whether you have your own struggles with mental health issues or just want to understand those who do, these stories are a great place to start the conversation.

Meet the contributors

Gerry: I’ve been designing websites since the late ‘90s, starting out in UI design, evolving into an IA, and now in a UX leadership role. Over my career, I’ve contributed to many high-profile projects, organized local UX events, and done so in spite of my personal roadblocks.

Brandon Gregory: I’ve been working in the web industry since 2006, first as a designer, then as a developer, then as a manager/technical leader. I’m also a staff member and regular contributor at A List Apart. I was diagnosed with bipolar disorder in 2002 and almost failed out of college because of it, although I now live a mostly normal life with a solid career and great family. I’ve been very open about my condition and have done some writing on it on Medium to help spread awareness and destigmatize mental illnesses.

Stephen Keable: I’ve been building and running websites since 1999, both professionally and for fun. Worked for newspapers, software companies, and design agencies, in both permanent and freelance roles, almost always creating front-end solutions, concentrating on a user-centered approach.

Bri Piccari: I’ve been messing around with the web since MySpace was a thing, figuring out how to customize themes and make random animations fall down from the top of my profile. Professionally, I’ve been in the field since 2010, freelancing while in college before transitioning to work at small agencies and in-house for a spell after graduation. I focus on creating solid digital experiences, employing my love for design with [a] knack for front-end development. Most recently, I started a small design studio, but decided to jump back into more steady contract and full-time work, after the stress of owning a small business took a toll on my mental health. It was a tough decision, but I had to do what was best for me. I also lead my local AIGA chapter and recently got my 200-hour-yoga-teacher certification.

X: I also started tinkering with the web on Myspace, and started working on websites to help pay my way through college. I just always assumed I would do something else to make a living. Then, I was diagnosed with bipolar disorder. My [original non-web] field was not a welcoming and supportive place for that, so I had to start over, in more ways than one. The web industry hadn’t gone anywhere, and it’s always been welcoming to people with random educational histories, so I felt good about being able to make a living and staying healthy here. But because of my experience when I first tried to be open about my illness, I now keep it a secret. I’m not ashamed of it; in fact, it’s made me live life more authentically. For example, in my heart, I knew I wanted to work on the web the entire time.

The struggle is real

Mental health issues are as numerous and unique as the people who struggle with them. We asked the contributors what their struggles look like, particularly at work in the web industry.

G: I have an interesting mix of ADD, dyslexia, and complex PTSD. As a result, I’m an incomplete person, in a perpetual state of self-doubt, toxic shame, and paralyzing anxiety. I’ve had a few episodes in my past where a requirement didn’t register or a criticism was taken the wrong way and I’ve acted less than appropriately (either through panic, avoidance, or anger). When things go wrong, I deal with emotional flashbacks for weeks.

Presenting or reading before an audience is a surreal experience as well. I go into a zone where I’m never sure if I’m speaking coherently or making any sense at all until I’ve spoken with friends in the audience afterward. This has had a negative effect on my career, making even the most simple tasks anxiety-driven.

BG: I actually manage to at least look like I have everything together, so most people don’t know I have bipolar until I tell them. On the inside, I struggle—a lot. There are bouts of depression where I’m exhausted all day and deal with physical pain, and bursts of mania where I take unnecessary risks and make inappropriate outbursts, and I can switch between these states with little or no notice. It’s a balancing act to be sure, and I work very hard to keep it together for the people in my life.

SK: After the sudden death of my mother, I started suffering from panic attacks. One of which came on about 30 mins after getting to work, I couldn’t deal with the attack at work, so suddenly went home without telling anyone. Only phoning my boss from a lay-by after I’d been in tears at the side of the road for a while. The attacks also triggered depression, which has made motivation when I’m working from home so hard that I actually want to spend more time at the office. Luckily my employer is very understanding and has been really flexible.

BP: Depending upon the time of year, I struggle greatly, with the worst making it nearly impossible to leave my apartment. As most folks often say, I’ve gotten rather good at appearing as though I’ve got my shit together—typically, most people I interact with have no idea what I’m going through unless I let them in. It wasn’t until recently that my mental health began to make a public appearance, as the stress of starting my own business and attempting to “have it all” made it tough to continue hiding it. There are definitely spans of time where depression severely affects my ability to create and interface with others, and “fake it till ya make it” doesn’t even cut it. I’m currently struggling with severe anxiety brought on by stress. Learning to manage that has been a process.

X: I have been fortunate to be a high-functioning bipolar person for about 5 years now, so there really isn’t a struggle you can really see. The struggle is the stress and anxiety of losing that stability, and especially of people finding out. I take medication, have a routine, a support system, and a self-care regimen that is the reason why I am stable, but if work starts [to] erode my work-life balance, I can’t protect that time and energy anymore. In the past, this has started to happen when I’ve been asked to routinely pull all-nighters, work over the weekend, travel often, or be surrounded by a partying and drinking culture at work. Many people burn out under those conditions, but for me, it could be dangerous and send me into a manic episode, or even [make me] feel suicidal. I struggle with not knowing how far I can grow in my career, because a lot of the things you do to prove yourself and to demonstrate that you’re ready for more responsibility involves putting more on your plate. What’s the point of going after a big role if it’ll mean that I won’t be able to take care of myself? The FOMO [(fear of missing out)] gets bad.

Making it work

There are different ways that people can choose to—or choose not to—address the mental problems they struggle with. We’re ultimately responsible for making our own mental health decisions, and they are different for everyone. In the meantime, the rent has to get paid. Here’s how our contributors cope with their situations at work to make it happen.

G: I started seeing a therapist, which has been an amazing help. I’ve also worked to change my attitude about criticism—I ask more clarifying questions, looking to define the problem, rather than get mad, defensive, or sarcastic. I’ve learned to be more honest with my very close coworkers, making them aware of my irrational shortcomings and asking for help. Also, because I’ve experienced trauma in personal and professional life, I’m hypersensitive to the emotions of others. Just being around a heated argument or otherwise heightened situation could put my body into a panic. I have to take extra special care in managing personalities, making sure everyone in a particular situation feels confident that they’re set up for success.

BG: Medicine has worked very well for me, and I’m very lucky in that regard. That keeps most of my symptoms at a manageable level. Keeping my regular schedule and maintaining some degree of normalcy is a huge factor in remaining stable. Going to work, sleeping when I should, and keeping some social appointments, while not always easy, keep me from slipping too far in either direction. Also, writing has been a huge outlet for me and has helped others to better understand my condition as well. Finding some way to express what you’re going through is huge.

SK: I had several sessions of bereavement counseling to help with the grief. I also made efforts to try and be more physically active each day, even if just going for a short walk on my lunch break. Working had become a way of escaping everything else that was going on at the time. Before the depression I used to work from home two days a week, however found these days very hard being on my own. So I started working from the office every weekday. Thankfully, through all of this, my employer was incredibly supportive and simply told me to do what I need to do. And it’s made me want to stay where I work more than before, as I realize how lucky I am to have their support.

BP: Last winter I enrolled in a leadership/yoga teacher training [program] with a goal of cultivating a personal practice to better manage my depression and anxiety. Making the jump to be in an uncomfortable situation and learn the value of mindfulness has made a huge difference in my ability to cope with stress. Self-care is really big for me, and being aware of when I need to take a break. I’ve heard it called high-functioning depression and anxiety. I often take on too much and learning to say no has been huge. Therapy and a daily routine have been incredibly beneficial as well.

X: The biggest one is medicine, it’s something I will take for the rest of my life and it’s worth it to me. I did a form of therapy called Dialectical Behavioral Therapy for a couple of years. The rest is a consistent regimen of self-care, but there are a couple of things that are big for work. Not working nights or weekends, keeping it pretty 9–5. Walking to and from the office or riding my bike. I started a yoga practice immediately after getting diagnosed, and the mental discipline it’s given me dampens the intensity of how I react to stressful situations at work. This isn’t to say that I will refuse to work unless it’s easy. Essentially, if something catches on fire, these coping strategies help me keep my shit together for long enough to get out.

Spreading awareness

There are a lot of misconceptions about mental illness, in the web industry as much as anywhere else. Some are benign but annoying; others are pretty harmful. Here are some of the things we wish others knew about us and our struggles.

G: Nothing about my struggle is rational. It seems as if my body is wired to screw everything up and wallow in the shame of it. I have to keep moving, working against myself to get projects as close to perfect as possible. However, I am wired to really care about people, and that is probably why I’ve been successful in UX.

BG: Just because I look strong doesn’t mean I don’t need support. Just because I have problems doesn’t mean I need you to solve them. Sometimes, just checking in or being there is the best thing for me. I don’t want to be thought of as broken or fragile (although I admit, sometimes I am). I am more than my disorder, but I can’t completely ignore it either.

Also, there are still a lot of stigmas surrounding mental illness, to the point that I didn’t feel safe admitting to my disorder to a boss at a previous job. Mental illnesses are medical conditions that are often classified as legitimate disabilities, but employees may not be safe admitting that they have one—that’s the reality we live with.

SK: For others who are going through grief-related depression, I would say that talking about it with friends, family, and even strangers helps you process it a lot. And the old cliché that time is a healer really is true. Also, for any employers, be supportive [of those] with mental health conditions—as supportive as you would [be of those] with physical health situations. They will pay you back.

BP: I am a chronically ambitious human. Oftentimes, this comes from a place of working and doing versus dealing with what is bothering or plaguing me at the time. Much of my community involvement came from a place of needing a productive outlet. Fortunately or unfortunately, I have accomplished a lot through that—however, there are times where I simply need a break. I’m learning to absorb and understand that, as well as become OK with it.

X: I wish people knew how much it bothers me to hear the word bipolar being used as an adjective to casually describe things and people. It’s not given as a compliment, and it makes it less likely that I will ever disclose my illness publicly. I also wish people knew how many times I’ve come close to just being open about it, but held back because of the other major diversity and inclusion issues in the tech industry. Women have to deal with being called moody and erratic. People stereotype the ethnic group I belong to as being fiery and ill-tempered. Why would I give people another way to discriminate against me?

Working with External User Researchers: Part I

Tue, 01/16/2018 - 08:00

You’ve got an idea or perhaps some rough sketches, or you have a fully formed product nearing launch. Or maybe you’ve launched it already. Regardless of where you are in the product lifecycle, you know you need to get input from users.

You have a few sound options to get this input: use a full-time user researcher or contract out the work (or maybe a combination of both). Between the three of us, we’ve run a user research agency, hired external researchers, and worked as freelancers. Through our different perspectives, we hope to provide some helpful considerations.

Should you hire an external user researcher?

First things first–in this article, we focus on contracting external user researchers, meaning that a person or team is brought on for the duration of a contract to conduct the research. Here are the most common situations where we find this type of role:

Organizations without researchers on staff: It would be great if companies validated their work with users during every iteration. But unfortunately, in real-world projects, user research happens at less frequent intervals, meaning there might not be enough work to justify hiring a full-time researcher. For this reason, it sometimes makes sense to use external people as needed.

Organizations whose research staff is maxed out: In other cases, particularly with large companies, there may already be user researchers on the payroll. Sometimes these researchers are specific to a particular effort, and other times the researchers themselves function as internal consultants, helping out with research across multiple projects. Either way, there is a finite amount of research staff, and sometimes the staff gets overbooked. These companies may then pull in additional contract-based researchers to independently run particular projects or to provide support to full-time researchers.

Organizations that need special expertise: Even if a company does have user research on staff and those researchers have time, it’s possible that there are specialized kinds of user research for which an external contract-based researcher is brought on. For example, they may want to do research with representative users who regularly use screen readers, so they bring in an accessibility expert who also has user research skills. Or they might need a researcher with special quantitative skills for a certain project.

Why hire an external researcher vs. other options?

Designers as researchers: You could hire a full-time designer who also has research skills. But a designer usually won’t have the same level of research expertise as a dedicated researcher. Additionally, they may end up researching their own designs, making it extremely difficult to moderate test sessions without any form of bias.

Product managers as researchers: While it’s common for enthusiastic product managers to want to conduct their own guerilla user research, this is often a bad idea. Product managers tend to hear feedback that validates their ideas and most often aren’t trained on how to ask non-leading questions.

Temporary roles: You could also bring on a researcher in a staff augmentation role, meaning someone who works for you full-time for an extended period of time, but who is not considered a full-time employee. This can be a bit harder to justify. For example, there may be legal requirements that you’d have to pass if you directly contract an individual. Or you could find someone through a staffing agency–fewer legal hurdles, but likely far pricier.

If these options don’t sound like a good fit for your needs, hiring an external user researcher on a project-specific basis could be the best solution for you. They give you exactly what you need without additional commitment or other risks. They may be a freelancer (or a slightly larger microbusiness), or even a team farmed out for a particular project by a consulting firm or agency.

What kinds of projects would you contract a user researcher for?

You can reasonably expect that anyone or any company that advertises their skillset as user research likely can do the full scope of qualitative efforts—from usability studies of all kinds, to card sorts, to ethnographic and exploratory work.

Contracting out quantitative work is a bit riskier. An analogy that comes to mind is using TurboTax to file your taxes. While TurboTax may be just fine for many situations, it’s easy to overlook what you don’t know in terms of more complicated tax regulations, which can quickly get you in trouble. Similarly, with quantitative work, there’s a long list of diverse, specialized quantitative skills (e.g., logs analysis, conjoint, Kano, and multiple regression). Don’t assume someone advertising as a general quantitative user researcher has the exact skills you need.

Also, for some companies, quantitative work comes with unique user privacy considerations that can require special internal permissions from legal and privacy teams.

But if the topic of your project is pretty easy to grasp and absorb without needing much specialized technical or organizational insight, hiring an external researcher is generally a great option.

What are the benefits to hiring an external researcher?

A new, objective perspective is one major benefit to hiring an external researcher. We all suffer from design fixation and are influenced by organizational politics and perceived or real technical constraints. Hiring an unbiased external researcher can uncover more unexpected issues and opportunities.

Contracting a researcher can also expand an internal researcher’s ability to influence. Having someone else moderate research studies frees up in-house researchers to be part of the conversations among stakeholders that happen while user interviews are being observed. If they are intuitively aware of an issue or opportunity, they can emphasize their perspective during those critical, decision-making moments that they often miss out on when they moderate studies themselves. In these situations, the in-house team can even design the study plan, draft the discussion guide, and just have the contractor moderate the study. The external researcher may then collaborate with the in-house researcher on the final report.

More candid and honest feedback can come out of hiring an external researcher. Research participants tend to be more comfortable sharing more critical feedback with someone who doesn’t work for the company whose product is being tested.

Lastly, if you need access to specialized research equipment or software (for example, proprietary online research tools), it can be easier to get it via an external researcher.

How do I hire an external user researcher?

So you’ve decided that you need to bring on an external user researcher to your team. How do you get started?

Where to find them

Network: Don’t wait until you need help to start networking and collecting a list of external researchers. Be proactive. Go to UX events in your local region. You’ll meet consultants and freelancers at those events, as well as people who have contracted out research and can make recommendations. You won’t necessarily have the opportunity for deep conversations, but you can continue a discussion over coffee or drinks!

Referrals: Along those same lines, when you anticipate a need at some point in the future, seek out trusted UX colleagues at your company and elsewhere. Ask them to connect you with people that they may have worked with.

What about a request for proposal (RFP)?

Your company may require you to specify your need in the form of an RFP, which is a document that outlines your project needs and specifications, and asks for bids in response.

An RFP provides these benefits:

  • It keeps the playing field level, and anyone who wants to bid on a project can (in theory).
  • You can be very specific about what you’re looking for, and get bids that can be easy to compare on price.

On the other hand, an RFP comes with limitations:

  • You may think your requirements were very specific, but respondents may interpret them in different ways. This can result in large quote differences.
  • You may be eliminating smaller players—those freelancers and microbusinesses who may be able to give you the highest level of seniority for the dollar but don’t have the staff to respond to RFPs quickly.
  • You may be forced to be very concrete about your needs when you are not yet sure what you’ll actually need.

When it comes to RFPs, the most important thing to remember is to clearly and thoroughly specify your needs. Don’t forget to include small but important details that can matter in terms of pricing, such as answers to these questions:

  • Who is responsible for recruitment of research participants?
  • How many participants do you want included?
  • Who will be responsible for distributing participant incentives?
  • Who will be responsible for localizing prototypes?
  • How long will sessions be?
  • Over how many days and locations will they be?
  • What is the format of expected deliverables?
  • Do you want full, transcribed videos, or video clips?

It’s these details that will ultimately result in receiving informed proposals that are easy to compare.

Do a little digging on their backgrounds

Regardless of how you find a potential researcher, make sure you check out their credentials if you haven’t worked with them before.

At the corporate level, review the company: Google them and make sure that user research seems to be one of their core competencies. The same is true when dealing with a freelancer or microbusiness: Google them and see whether you get research-oriented results, and also check them out on social media.

Certainly feel free to ask for references if you don’t already have a direct connection, but take them with a grain of salt. Between the self-selecting nature of a reference, and a potential reference just trying to be nice to a friend, these can never be fully trusted.

One of the strongest indicators of experience and quality work is if a researcher has been hired by the same client for more than one project over time.

Larger agencies, individual researchers, or something in-between?

So you’ve got a solid sense of what research you need, and you’ve got several quality options to choose from. But external researchers come in all shapes and sizes, from single freelancers to very large agencies. How do you choose what’s best for your project while still evaluating the external researchers fairly?

Larger consulting firms and agencies do have some distinct advantages—namely that you’ve got a large company to back up the project. Even if one researcher isn’t available as expected (for example, if the project timeline slips), another can take their place. They also likely have a whole infrastructure for dealing with contracts like yours.

On the other hand, this larger infrastructure may add extra burden on your side. You may not know who exactly is going to be working on your project, or their level of seniority or experience. Changes in scope will likely be more involved. Larger infrastructure also likely means higher costs.

Individual (freelance) researchers also have some key advantages. You will likely have more control over contracting requirements. They are also likely to be more flexible—and less costly. In addition, if they were referred to you, you will be working with a specific resource that you can get to know over multiple projects.

Bringing on individual researchers can incur a little more risk. You will need to make sure that you can properly justify hiring an external researcher instead of an employee. (In the United States, the IRS has a variety of tests to make sure it is OK.) And if your project timeline slips, you run a greater risk of losing the researcher to some other commitment without someone to replace them.

A small business, a step between an individual researcher and a large firm, has some advantages over hiring an individual. Contracting an established business may involve less red tape, and you will still have the personal touch of knowing exactly who is conducting your research.

An established business also shows a certain level of commitment, even if it’s one person. For example, a microbusiness could represent a single freelancer, but it could also involve a very small number of employees or established relationships with trusted subcontractors (or both). Whatever the configuration,  don’t expect a business of this size to have the ability to readily respond to RFPs.

The money question

Whether you solicit RFPs or get a single bid, price quotes will often differ significantly. User research is not a product but rather a customized and sophisticated effort around your needs. Here are some important things to consider:

  • Price quotes are a reflection of how a project is interpreted. Different researchers are going to interpret your needs in different ways. A good price quote clearly details any assumptions that are going into pricing so you can quickly see if something is misaligned.
  • Research teams are made up of staff with different levels of experience. A quote is going to be a reflection of the overall seniority of the team, their salaries and benefits, the cost of any business resources they use, and a reasonable profit margin for the business.
  • Businesses all want to make a reasonable profit, but approaches to profitability differ. Some organizations may balance having a high volume of work with less profit per project. Other organizations may take more of a boutique approach: more selectivity over projects taken on, with added flexibility to focus on those projects, but also with a higher profit margin.
  • Overbooked businesses provide higher quotes. Some consultants and agencies are in the practice of rarely saying no to a request, even if they are at capacity in terms of their workload. In these instances, it can be a common practice to multiply a quote by as much as three—if you say no, no harm done given they’re at capacity. However, if you say yes, the substantial profit is worth the cost for them to hire additional resources and to work temporarily above capacity in the meantime.

To determine whether a researcher or research team is right for you, you’ll certainly need to look at the big picture, including pricing, associated assumptions, and the seniority and background of the individuals who are doing the work.

Remember, it’s always OK to negotiate

If you have a researcher or research team that you want to work with but their pricing isn’t in line with your budget, let them know. It could be that the quote is just based on faulty assumptions. They may expect you to negotiate and are willing to come down in price; they may also offer alternative, cheaper options with them.

Next steps

Hiring an external user researcher typically brings a long list of benefits. But like most relationships, you’ll need to invest time and effort to foster a healthy working dynamic between you, your external user researcher, and your team. Stay tuned for the next installment, where we’ll focus on how to collaborate together.

No More FAQs: Create Purposeful Information for a More Effective User Experience

Thu, 01/11/2018 - 08:00

It’s normal for your website users to have recurring questions and need quick access to specific information to complete … whatever it is they came looking for. Many companies still opt for the ubiquitous FAQ (frequently asked/anticipated questions) format to address some or even all information needs. But FAQs often miss the mark because people don’t realize that creating effective user information—even when using the apparently simple question/answer format—is complex and requires careful planning.

As a technical writer and now information architect, I’ve worked to upend this mediocre approach to web content for more than a decade, and here’s what I’ve learned: instead of defaulting to an unstructured FAQ, invest in information that’s built around a comprehensive content strategy specifically designed to meet user and company goals. We call it purposeful information.

The problem with FAQs

Because of the internet’s Usenet heritage—discussion boards where regular contributors would produce FAQs so they didn’t have to repeat information for newbies—a lot of early websites started out by providing all information via FAQs. Well, the ‘80s called, and they want their style back!

Unfortunately, content in this simple format can often be attractive to organizations, as it’s “easy” to produce without the need to engage professional writers or comprehensively work on information architecture (IA) and content strategy. So, like zombies in a horror film, and with the same level of intellectual rigor, FAQs continue to pop up all over the web. The trouble is, this approach to documentation-by-FAQ has problems, and the information is about as far from being purposeful as it’s possible to get.

For example, when companies and organizations resort to documentation-by-FAQ, it’s often the only place certain information exists, yet users are unlikely to spend the time required to figure that out. Conversely, if information is duplicated, it’s easy for website content to get out of sync. The FAQ page can also be a dumping ground for any information a company needs to put on the website, regardless of the topic. Worse, the page’s format and structure can increase confusion and cognitive load, while including obviously invented questions and overt marketing language can result in losing users’ trust quickly. Looking at each issue in more detail:

  • Duplicate and contradictory information: Even on small websites, it can be hard to maintain information. On large sites with multiple authors and an unclear content strategy, information can get out of sync quickly, resulting in duplicate or even contradictory content. I once purchased food online from a company after reading in their FAQ—the content that came up most often when searching for allergy information—that the product didn’t contain nuts. However, on receiving the product and reading the label, I realized the FAQ information was incorrect, and I was able to obtain a refund. An information architecture (IA) strategy that includes clear pathways to key content not only better supports user information needs that drive purchases, but also reduces company risk. If you do have to put information in multiple locations, consider using an object-oriented content management system (CMS) so content is reused, not duplicated. (Our company open-sourced one called Fae.)
  • Lack of discernible content order: Humans want information to be ordered in ways they can understand, whether it’s alphabetical, time-based, or by order of operation, importance, or even frequency. The question format can disguise this organization by hiding the ordering mechanism. For example, I could publish a page that outlines a schedule of household maintenance tasks by frequency, with natural categories (in order) of daily, weekly, monthly, quarterly, and annually. But putting that information into an FAQ format, such as “How often should I dust my ceiling fan?,” breaks that logical organization of content—it’s potentially a stand-alone question. Even on a site that’s dedicated only to household maintenance, that information will be more accessible if placed within the larger context of maintenance frequency.
  • Repetitive grammatical structure: Users like to scan for information, so having repetitive phrases like “How do I …” that don’t relate to the specific task make it much more difficult for readers to quickly find the relevant content. In a lengthy help page with catch-all categories, like the Patagonia FAQ page, users have to swim past a sea of “How do I …,” “Why can’t I …,” and “What do I …” phrases to get to the actual information. While categories can help narrow the possibilities, the user still has to take the time to find the most likely category and then the relevant question within it. The Patagonia website also shows how an FAQ section can become a catch-all. Oh, how I’d love the opportunity to restructure all that Patagonia information into purposeful information designed to address user needs at the exact right moment. So much potential!
  • Increased cognitive load: As well as being repetitive, the question format can also be surprisingly specific, forcing users to mentally break apart the wording of the questions to find a match for their need. If a question appears to exclude the required information, the user may never click to see the answer, even if it is actually relevant. Answers can also raise additional, unnecessary questions in the minds of users. Consider the FAQ-formatted “Can I pay my bill with Venmo?” (which limits the answer to one payment type that only some users may recognize). Rewriting the question to “How can I pay my bill online?” and updating the content improves the odds that users will read the answer and be able to complete their task. However, an even better approach is to create purposeful content under the more direct and concise heading “Online payment options,” which is broad enough to cover all payment services (as a topic in the “Bill Payments” portion of a website), as well as instructions and other task-orientated information.
  • Longer content requirements: In most cases, questions have a longer line length than topic headings. The Airbnb help page illustrates when design and content strategy clash. The design truncates the question after 40 characters when the browser viewport is wider than 743 pixels. You have to click the question to find out if it holds the answer you need—far from ideal! Yet the heading “I’m a guest. How do I check the status of my reservation?” could easily have been rewritten as “Checking reservation status” or even “Guests: Checking reservation status.” Not only do these alternatives fit within the line length limitations set by the design, but the lower word count and simplified English also reduce translation costs (another issue some companies have to consider).
Purposeful information

Grounded in the Minimalist approach to technical documentation, the idea behind purposeful information is that users come to any type of content with a particular purpose in mind, ranging from highly specific (task completion) to general learning (increased knowledge). Different websites—and even different areas within a single website—may be aimed at different users and different purposes. Organizations also have goals when they construct websites, whether they’re around brand awareness, encouraging specific user behavior, or meeting legal requirements. Companies that meld user and organization goals in a way that feels authentic can be very successful in building brand loyalty.

Commerce sites, for example, have the goal of driving purchases, so the information on the site needs to provide content that enables effortless purchasing decisions. For other sites, the goal might be to drive user visits, encourage newsletter sign-ups, or increase brand awareness. In any scenario, burying in FAQs any pathways needed by users to complete their goals is a guaranteed way to make it less likely that the organization will meet theirs.

By digging into what users need to accomplish (not a general “they need to complete the form,” but the underlying, real-world task, such as getting a shipping quote, paying a bill, accessing health care, or enrolling in college), you can design content to provide the right information at the right time and better help users accomplish those goals. As well as making it less likely you’ll need an FAQ section at all, using this approach to generate a credible IA and content strategy—the tools needed to determine a meaningful home for all your critical content—will build authority and user trust.

Defining specific goals when planning a website is therefore essential if content is to be purposeful throughout the site. Common user-centered methodologies employed during both IA and content planning include user-task analysis, content audits, personas, user observations, and analysis of call center data and web analytics. A complex project might use multiple methodologies to define the content strategy and supporting IA to provide users with the necessary information.

The redesign of the Oliver Winery website is a good example of creating purposeful information instead of resorting to an FAQ. There was a user goal of being able to find practical information about visiting the winery (such as details regarding food, private parties, etc.), yet this information was scattered across various pages, including a partially complete FAQ. There was a company goal of reducing the volume of calls to customer support. In the redesign, a single page called “Plan Your Visit” was created with all the relevant topics. It is accessible from the “Visit” section and via the main navigation.

The system used is designed to be flexible. Topics are added, removed, and reordered using the CMS, and published on the “Plan Your Visit” page, which also shows basic logistical information like hours and contact details, in a non-FAQ format. Conveniently, contact details are maintained in only one location within the CMS yet published on various pages throughout the site. As a result, all information is readily available to users, increasing the likelihood that they’ll make the decision to visit the winery.

If you have to include FAQs

This happens. Even though there are almost always more effective ways to meet user needs than writing an FAQ, FAQs happen. Sometimes the client insists, and sometimes even the most ardent opponent (ahem) concludes that in a very particular circumstance, an FAQ can be purposeful. The most effective FAQ is one with a specific, timely, or transactional need, or one with information that users need repeated access to, such as when paying bills or organizing product returns.

Good topics for an FAQ include transactional activities, such as those involved in the buying process: think shipments, payments, refunds, and returns. By being specific and focusing on a particular task, you avoid the categorization problem described earlier. By limiting questions to those that are frequently asked AND that have a very narrow focus (to reduce users having to sort through lots of content), you create more effective FAQs.

Amazon’s support center has a great example of an effective FAQ within their overall support content because they have exactly one: “Where’s My Stuff?.” Set under the “Browse Help Topics” heading, the question leads to a list of task-based topics that help users track down the location of their missing packages. Note that all of the other support content is purposeful, set in a topic-based help system that’s nicely categorized, with a search bar that allows users to dive straight in.

Conference websites, which by their nature are already focused on a specific company goal (conference sign-ups), often have an FAQ section that covers basic conference information, logistics, or the value of attending. This can be effective. However, for the reasons outlined earlier, the content can quickly become overwhelming if conference organizers try to include all information about the conference as a single list of questions, as demonstrated by Web Summit’s FAQ page. Overdoing it can cause confusion even when the design incorporates categories and an otherwise useful UX that includes links, buttons, or tabs, such as on the FAQ page of The Next Web Conference.

In examining these examples, it’s apparent how much more easily users could access the information if it wasn’t presented as questions. But if you do have to use FAQs, here are my tips for creating the best possible user experience.

Creating a purposeful FAQ:

  • Make it easy to find.
  • Have a clear purpose and highly specific content in mind.
  • Give it a clear title related to the user tasks (e.g., “Shipping FAQ” rather than just “FAQ”).
  • Use clear, concise wording for questions.
  • Focus questions on user goals and tasks, not on product or brand.
  • Keep it short.

What to avoid in any FAQ:

  • Don’t include “What does FAQ stand for?” (unfortunately, not a fictional example). Instead, simply define acronyms and initialisms on first use.
  • Don’t define terms using an FAQ format—it’s a ticket straight to documentation hell. If you have to define terms, what you need is a glossary, not FAQs.
  • Don’t tell your brand story or company history, or pontificate. People don’t want to know as much about your brand, product, and services as you are eager to tell them. Sorry.
In the end, always remember your users

Your website should be filled with purposeful content that meets users’ core needs and fulfills your company’s objectives. Do your users and your bottom line a favor and invest in effective user analysis, IA, content strategy, and documentation. Your users will be able to find the information they need, and your brand will be that much more awesome as a result.

Why Mutation Can Be Scary

Tue, 01/09/2018 - 08:00

A note from the editors: This article contain sample lessons from Learn JavaScript, a course that helps you learn JavaScript to build real-world components from scratch.

To mutate means to change in form or nature. Something that’s mutable can be changed, while something that’s immutable cannot be changed. To understand mutation, think of the X-Men. In X-Men, people can suddenly gain powers. The problem is, you don’t know when these powers will emerge. Imagine your friend turns blue and grows fur all of a sudden; that’d be scary, wouldn’t it?

h2 code, h3 code { text-transform: none; }

In JavaScript, the same problem with mutation applies. If your code is mutable, you might change (and break) something without knowing.

Objects are mutable in JavaScript

In JavaScript, you can add properties to an object. When you do so after instantiating it, the object is changed permanently. It mutates, like how an X-Men member mutates when they gain powers.

In the example below, the variable egg mutates once you add the isBroken property to it. We say that objects (like egg) are mutable (have the ability to mutate).

const egg = { name: "Humpty Dumpty" }; egg.isBroken = false; console.log(egg); // { // name: "Humpty Dumpty", // isBroken: false // }

Mutation is pretty normal in JavaScript. You use it all the time.

Here’s when mutation becomes scary.

Let’s say you create a constant variable called newEgg and assign egg to it. Then you want to change the name of newEgg to something else.

const egg = { name: "Humpty Dumpty" }; const newEgg = egg; newEgg.name = "Errr ... Not Humpty Dumpty";

When you change (mutate) newEgg, did you know egg gets mutated automatically?

console.log(egg); // { // name: "Errr ... Not Humpty Dumpty" // }

The example above illustrates why mutation can be scary—when you change one piece of your code, another piece can change somewhere else without your knowing. As a result, you’ll get bugs that are hard to track and fix.

This weird behavior happens because objects are passed by reference in JavaScript.

Objects are passed by reference in JavaScript

To understand what “passed by reference” means, first you have to understand that each object has a unique identity in JavaScript. When you assign an object to a variable, you link the variable to the identity of the object (that is, you pass it by reference) rather than assigning the variable the object’s value directly. This is why when you compare two different objects, you get false even if the objects have the same value.

console.log({} === {}); // false

When you assign egg to newEgg, newEgg points to the same object as egg. Since egg and newEgg are the same thing, when you change newEgg, egg gets changed automatically.

console.log(egg === newEgg); // true

Unfortunately, you don’t want egg to change along with newEgg most of the time, since it causes your code to break when you least expect it. So how do you prevent objects from mutating? Before you understand how to prevent objects from mutating, you need to know what’s immutable in JavaScript.

Primitives are immutable in JavaScript

In JavaScript, primitives (String, Number, Boolean, Null, Undefined, and Symbol) are immutable; you cannot change the structure (add properties or methods) of a primitive. Nothing will happen even if you try to add properties to a primitive.

const egg = "Humpty Dumpty"; egg.isBroken = false; console.log(egg); // Humpty Dumpty console.log(egg.isBroken); // undefined const doesn’t grant immutability

Many people think that variables declared with const are immutable. That’s an incorrect assumption.

Declaring a variable with const doesn’t make it immutable, it prevents you from assigning another value to it.

const myName = "Zell"; myName = "Triceratops"; // ERROR

When you declare an object with const, you’re still allowed to mutate the object. In the egg example above, even though egg is created with const, const doesn’t prevent egg from mutating.

const egg = { name: "Humpty Dumpty" }; egg.isBroken = false; console.log(egg); // { // name: "Humpty Dumpty", // isBroken: false // } Preventing objects from mutating

You can use Object.assign and assignment to prevent objects from mutating.


Object.assign lets you combine two (or more) objects together into a single one. It has the following syntax:

const newObject = Object.assign(object1, object2, object3, object4);

newObject will contain properties from all of the objects you’ve passed into Object.assign.

const papayaBlender = { canBlendPapaya: true }; const mangoBlender = { canBlendMango: true }; const fruitBlender = Object.assign(papayaBlender, mangoBlender); console.log(fruitBlender); // { // canBlendPapaya: true, // canBlendMango: true // }

If two conflicting properties are found, the property in a later object overwrites the property in an earlier object (in the Object.assign parameters).

const smallCupWithEar = { volume: 300, hasEar: true }; const largeCup = { volume: 500 }; // In this case, volume gets overwritten from 300 to 500 const myIdealCup = Object.assign(smallCupWithEar, largeCup); console.log(myIdealCup); // { // volume: 500, // hasEar: true // }

But beware! When you combine two objects with Object.assign, the first object gets mutated. Other objects don’t get mutated.

console.log(smallCupWithEar); // { // volume: 500, // hasEar: true // } console.log(largeCup); // { // volume: 500 // } Solving the Object.assign mutation problem

You can pass a new object as your first object to prevent existing objects from mutating. You’ll still mutate the first object though (the empty object), but that’s OK since this mutation doesn’t affect anything else.

const smallCupWithEar = { volume: 300, hasEar: true }; const largeCup = { volume: 500 }; // Using a new object as the first argument const myIdealCup = Object.assign({}, smallCupWithEar, largeCup);

You can mutate your new object however you want from this point. It doesn’t affect any of your previous objects.

myIdealCup.picture = "Mickey Mouse"; console.log(myIdealCup); // { // volume: 500, // hasEar: true, // picture: "Mickey Mouse" // } // smallCupWithEar doesn't get mutated console.log(smallCupWithEar); // { volume: 300, hasEar: true } // largeCup doesn't get mutated console.log(largeCup); // { volume: 500 } But Object.assign copies references to objects

The problem with Object.assign is that it performs a shallow merge—it copies properties directly from one object to another. When it does so, it also copies references to any objects.

Let’s explain this statement with an example.

Suppose you buy a new sound system. The system allows you to declare whether the power is turned on. It also lets you set the volume, the amount of bass, and other options.

const defaultSettings = { power: true, soundSettings: { volume: 50, bass: 20, // other options } };

Some of your friends love loud music, so you decide to create a preset that’s guaranteed to wake your neighbors when they’re asleep.

const loudPreset = { soundSettings: { volume: 100 } };

Then you invite your friends over for a party. To preserve your existing presets, you attempt to combine your loud preset with the default one.

const partyPreset = Object.assign({}, defaultSettings, loudPreset);

But partyPreset sounds weird. The volume is loud enough, but the bass is non-existent. When you inspect partyPreset, you’re surprised to find that there’s no bass in it!

console.log(partyPreset); // { // power: true, // soundSettings: { // volume: 100 // } // }

This happens because JavaScript copies over the reference to the soundSettings object. Since both defaultSettings and loudPreset have a soundSettings object, the one that comes later gets copied into the new object.

If you change partyPreset, loudPreset will mutate accordingly—evidence that the reference to soundSettings gets copied over.

partyPreset.soundSettings.bass = 50; console.log(loudPreset); // { // soundSettings: { // volume: 100, // bass: 50 // } // }

Since Object.assign performs a shallow merge, you need to use another method to merge objects that contain nested properties (that is, objects within objects).

Enter assignment.


assignment is a small library made by Nicolás Bevacqua from Pony Foo, which is a great source for JavaScript knowledge. It helps you perform a deep merge without having to worry about mutation. Aside from the method name, the syntax is the same as Object.assign.

// Perform a deep merge with assignment const partyPreset = assignment({}, defaultSettings, loudPreset); console.log(partyPreset); // { // power: true, // soundSettings: { // volume: 100, // bass: 20 // } // }

assignment copies over values of all nested objects, which prevents your existing objects from getting mutated.

If you try to change any property in partyPreset.soundSettings now, you’ll see that loudPreset remains as it was.

partyPreset.soundSettings.bass = 50; // loudPreset doesn't get mutated console.log(loudPreset); // { // soundSettings { // volume: 100 // } // }

assignment is just one of many libraries that help you perform a deep merge. Other libraries, including lodash.assign and merge-options, can help you do it, too. Feel free to choose from any of these libraries.

Should you always use assignment over Object.assign?

As long as you know how to prevent your objects from mutating, you can use Object.assign. There’s no harm in using it as long as you know how to use it properly.

However, if you need to assign objects with nested properties, always prefer a deep merge over Object.assign.

Ensuring objects don’t mutate

Although the methods I mentioned can help you prevent objects from mutating, they don’t guarantee that objects don’t mutate. If you made a mistake and used Object.assign for a nested object, you’ll be in for deep trouble later on.

To safeguard yourself, you might want to guarantee that objects don’t mutate at all. To do so, you can use libraries like ImmutableJS. This library throws an error whenever you attempt to mutate an object.

Alternatively, you can use Object.freeze and deep-freeze. These two methods fail silently (they don’t throw errors, but they also don’t mutate the objects).

Object.freeze and deep-freeze

Object.freeze prevents direct properties of an object from changing.

const egg = { name: "Humpty Dumpty", isBroken: false }; // Freezes the egg Object.freeze(egg); // Attempting to change properties will silently fail egg.isBroken = true; console.log(egg); // { name: "Humpty Dumpty", isBroken: false }

But it doesn’t help when you mutate a deeper property like defaultSettings.soundSettings.base.

const defaultSettings = { power: true, soundSettings: { volume: 50, bass: 20 } }; Object.freeze(defaultSettings); defaultSettings.soundSettings.bass = 100; // soundSettings gets mutated nevertheless console.log(defaultSettings); // { // power: true, // soundSettings: { // volume: 50, // bass: 100 // } // }

To prevent a deep mutation, you can use a library called deep-freeze, which recursively calls Object.freeze on all objects.

const defaultSettings = { power: true, soundSettings: { volume: 50, bass: 20 } }; // Performing a deep freeze (after including deep-freeze in your code per instructions on npm) deepFreeze(defaultSettings); // Attempting to change deep properties will fail silently defaultSettings.soundSettings.bass = 100; // soundSettings doesn't get mutated anymore console.log(defaultSettings); // { // power: true, // soundSettings: { // volume: 50, // bass: 20 // } // } Don’t confuse reassignment with mutation

When you reassign a variable, you change what it points to. In the following example, a is changed from 11 to 100.

let a = 11; a = 100;

When you mutate an object, it gets changed. The reference to the object stays the same.

const egg = { name: "Humpty Dumpty" }; egg.isBroken = false; Wrapping up

Mutation is scary because it can cause your code to break without your knowing about it. Even if you suspect the cause of breakage is a mutation, it can be hard for you to pinpoint the code that created the mutation. So the best way to prevent code from breaking unknowingly is to make sure your objects don’t mutate from the get-go.

To prevent objects from mutating, you can use libraries like ImmutableJS and Mori.js, or use Object.assign and Object.freeze.

Take note that Object.assign and Object.freeze can only prevent direct properties from mutating. If you need to prevent multiple layers of objects from mutating, you’ll need libraries like assignment and deep-freeze.

Discovery on a Budget: Part I

Thu, 01/04/2018 - 08:00

If you crack open any design textbook, you’ll see some depiction of the design cycle: discover, ideate, create, evaluate, and repeat. Whenever we bring on a new client or start working on a new feature, we start at the top of the wheel with discover (or discovery). It is the time in the project when we define what problem we are trying to solve and what our first approach at solving it should be.

Ye olde design cycle

We commonly talk about discovery at the start of a sprint cycle at an established business, where there are things like budgets, product teams, and existing customers. The discovery process may include interviewing stakeholders or pouring over existing user data. And we always exit the discovery phase with some sort of idea to move forward with.

However, discovery is inherently different when you work at a nonprofit, startup, or fledgling small business. It may be a design team of one (you), with zero dollars to spend, and only a handful of people aware the business even exists. There are no clients to interview and no existing data to examine. This may also be the case at large businesses when they want to test the waters on a new direction without overcommitting (or overspending). Whenever you are constrained on budget, data, and stakeholders, you need to be flexible and crafty in how you conduct discovery research. But you can’t skimp on rigor and thoroughness. If the idea you exit the discovery phase with isn’t any good, your big launch could turn out to be a business-ending flop.

In this article I’ll take you through a discovery research cycle, but apply it towards a (fictitious) startup idea. I’ll introduce strategies for conducting discovery research with no budget, existing user data, or resources to speak of. And I’ll show how the research shapes the business going forward.

Write up the problem hypothesis

An awful lot of ink (virtual or otherwise) has been spent on proclaiming we should all, “fall in love with the problem, not the solution.” And it has been ink spent well. When it comes to product building, a problem-focused philosophy is the cornerstone of any user-centric business.

But how, exactly, do you know when you have a problem worth solving? If you work at a large, established business you may have user feedback and data pointing you like flashing arrows on a well-marked road towards a problem worth solving. However, if you are launching a startup, or work at a larger business venturing into new territory, it can be more like hiking through the woods and searching for the next blaze mark on the trail. Your ideas are likely based on personal experiences and gut instincts.

When your ideas are based on personal experiences, assumptions, and instincts, it’s important to realize they need a higher-than-average level of tire-kicking. You need to evaluate the question “Do I have a problem worth solving?” with a higher level of rigor than you would at a company with budget to spare and a wealth of existing data. You need to take all of your ideas and assumptions and examine them thoroughly. And the best way to examine your ideas and categorize your assumptions is with a hypothesis.

As the dictionary describes, a hypothesis is “a supposition or proposed explanation made on the basis of limited evidence as a starting point for further investigation.” That also serves as a good description of why we do discovery research in the first place. We may have an idea that there is a problem worth solving, but we don’t yet know the scope or critical details. Articulating our instincts, ideas, and assumptions as a problem hypothesis lays a foundation for the research moving forward.

Here is a general formula you can use to write a problem hypothesis:

Because [assumptions and gut instincts about the problem], users are [in some undesirable state]. They need [solution idea].

For this article, I decided to “launch” a fictitious (and overly ambitious) startup as an example. Here is the problem hypothesis I wrote for my startup:

Because their business model relies on advertising, social media tools like Facebook are deliberately designed to “hook” users and make them addicted to the service. Users are unhappy with this and would rather have a healthier relationship with social media tools. They would be willing to pay for a social media service that was designed with mental health in mind.

You can see in this example that my assumptions are:

  • Users feel that social media sites like Facebook are addictive.
  • Users don’t like to be addicted to social media.
  • Users would be willing to pay for a non-addictive Facebook replacement.

These are the assumptions I’ll be researching and testing throughout the discovery process. If I find through my research that I cannot readily affirm these assumptions, it means I might not be ready to take on Mr. Zuckerberg just yet.

The benefit of articulating our assumptions in the form of a hypothesis is that it provides something concrete to talk about, refer to, and test. The whole product team can be involved in forming the initial problem hypothesis, and you can refer back to it throughout the discovery process. Once we’ve completed the research and analyzed the results, we can edit the hypothesis to reflect our new understanding of our users and the problems we want to solve.

Now that we’ve articulated a problem hypothesis, it is time to figure out our research plan. In the following two sections, I’ll cover the research method I recommend the most for new ventures, as well as strategies for recruiting participants on a budget.

A method that is useful in all phases of design: interviews

In my career as a user researcher, I have used all sorts of methods. I’ve done A/B testing, eye tracking, Wizard of Oz testing, think-alouds, contextual inquiries, and guerilla testing. But the one research method I utilize the most, and that I believe provides the most “bang for the buck,” is user interviews.

User interviews are relatively inexpensive to conduct. You don’t need to travel to a client site and you don’t need a fortune’s worth of equipment. If you have access to a phone, you can conduct an interview with participants all around the world. Yet interviews provide a wealth of information and can be used in every phase of research and design. Interviews are especially useful in discovery, because it is a method that is adaptable. As you learn more about the problem you are trying to solve, you can adapt your interview protocol to match.

To be clear, your interviewees will not tell you:

  • what to build;
  • or how to build it.

But they absolutely can tell you:

  • what problem they have;
  • how they feel about it;
  • and what the value of a solution would mean to them.

And if you know the problem, how users feels about it, and the value of a solution, you are well on your way to designing the right product.

The challenge of conducting a good user interview is making sure you ask the questions that elicit that information. Here are a couple tips:

Tip 1: always ask the following two questions:

  • “What do you like about [blank]?”
  • “What do you dislike about [blank]?”

… where you fill “[blank]” with whatever domain your future product will improve.

Your objective is to gain an understanding of all aspects of the problem your potential customers face—the bad and the good. One common mistake is to spend too much time investigating what’s wrong with the current state of affairs. Naturally, you want your product to fix all the problems your customers face. However, you also need to preserve what currently works well, what is satisfying, or what is otherwise good about how users accomplish their goals currently. So it is important to ask about both in user interviews.

For example, in my interviews I always asked, “What do you like about using Facebook?” And it wasn’t until my interview participant told me everything they enjoyed about Facebook that I would ask, “What do you dislike about using Facebook?”

Tip 2: after (nearly) every response, ask them to say more.

The goal of conducting interviews is to gain an exhaustive set of data to review and consider moving forward. That means you don’t want your participants to discuss one thing they like and dislike, you want them to tell you all the things they like and dislike.

Here is an example of how this played out in one of the interviews I conducted:

Interviewer (Me): What do you like about using Facebook?

Interviewee: I like seeing people on there that I wouldn’t otherwise get a chance to see and catch up with in real life. I have moved a couple times so I have a lot of friends that I don’t see regularly. I also like seeing the people I know do well, even though I haven’t seen them since, maybe, high school. But I like seeing how their life has gone. I like seeing their kids. I like seeing their accomplishments. It’s also a little creepy because it’s a window into their life and we haven’t actually talked in forever. But I like staying connected.

Interviewer (Me): What else do you like about it?

Interviewee: Um, well it’s also sort of a convenient way of keeping contacts. There have been a few times when I was able to message people and get in touch with people even when I don’t have their address or email in my phone. I could message them through Facebook.

Interviewer (Me): Great. Is there anything else you like about it?

Interviewee: Let me think … well I also find cool stuff to do on the weekends there sometimes. They have an events feature. And businesses, or local places, will post events and there have been a couple times where I’ve gone to something cool. Like I found a cool movie festival once that way.

Interviewer (Me): That seems cool. What else do you like about using Facebook?

Interviewee: Uh … that’s all I think I really use it for. I can’t really think of anything else. Mainly I use it just to keep in touch with people that I’ve met over the years.

From this example you can see the first feature that popped into the interviewee’s mind was their ability to keep up with friends that they otherwise wouldn’t have much opportunity to connect with anymore. That is a feature that any Facebook replacement would have to replicate. However, if I hadn’t pushed the interviewee to think of even more features they like, I might have never uncovered an important secondary feature: convenient in-app messaging. In fact, six out of the eleven people I interviewed for this project said they liked Facebook Messenger. But not a single one of them mentioned that feature first. It only came up in conversation after I probed for more.

As I continued to repeat my question, the interviewee thought of one more feature they liked: local event listings. (Five out of the eleven people I interviewed mentioned this feature.) But after that, the interviewee couldn’t think of any more features to discuss. You know you can move on to the next question in the interview when your participant starts to repeat themselves or bluntly tells you they have nothing else to say.

Recruit all around you, then document the bias

There are all sorts of ways to recruit participants for research. You can hire an agency or use a tool like UserTesting.com. But many of those paid-for options can be quite costly, and since we are working with a shoestring budget we have roughly zero dollars to spend on recruitment. We will have to be creative.

My post on Facebook to recruit volunteers. One volunteer decided to respond with a Hunger Games “I volunteer as tribute!” gif.

For my project, I decided to rely on the kindness of friends and strangers I could reach through Facebook. I posted one request for participants on my personal Facebook page, and another on the local FreeCodeCamp page. A day after I posted my request, twenty-five friends and five strangers volunteered. This type of participant recruitment method is called convenience sampling, because I was recruiting participants that were conveniently accessible to me.

Since my project involved talking to people about social media sites like Facebook, it was appropriate for my first attempt at recruiting to start on Facebook. I could be sure that everyone who saw my request uses Facebook in some form or fashion. However, like all convenience sampling, my recruitment method was biased. (I’ll explain how in just a bit.)

Bias is something that we should try—whenever possible—to avoid. If we have access to more sophisticated recruitment methods, we should use them. However, when you have a tight budget, avoiding recruitment bias is virtually impossible. In this scenario, our goals should be to:

  • mitigate bias as best we can;
  • and document all the biases we see.

For my project, I could mitigate some of the biases by using a few more recruitment methods. I could go to various neighborhoods and try to recruit participants off the street (i.e., guerilla testing). If I had a little bit of money to spend, I could hang out in various coffee shops and offer folks free coffee in exchange for ten-minute interviews. These recruitment methods also fall under the umbrella of convenience sampling, but by using a variety of methods I can mitigate some of the bias I would have from using just one of them.

Also, it is always important to reflect on and document how your sampling method is biased. For my project, I wrote the following in my notes:

All of the people I interviewed were connected to me in some way on Facebook. Many of them I know well enough to be “friends” with. All of them were around my age, many (but not all) worked in tech in some form or fashion, and all of them but one lived in the US.

Documenting bias ensures that we won’t forget about the bias when it comes time to analyze and discuss the results.

Let’s keep this going

As the title suggests, this is just the first installment of a series of articles on the discovery process. In part two, I will analyze the results of my interviews, revise my problem hypothesis, and continue to work on my experimental startup. I will launch into another round of discovery research, but this time utilizing some different research methods, like A/B testing and fake-door testing. You can help me out by checking out this mock landing page for Candor Network (what I’ve named my fictitious startup) and taking the survey you see there.

My Grandfather&#8217;s Travel Logs and Other Repetitive Tasks

Thu, 12/14/2017 - 07:45

My grandfather, James, was a meticulous recordkeeper. He kept handwritten journals detailing everything from his doctor visits to the daily fluctuations of stocks he owned. I only discovered this part of his life seven years after his death, when my family’s basement flooded on Christmas Eve in 2011 and we found his journals while cleaning up the damage. His travel records impressed me the most. He documented every trip he ever took, including dates, countries and cities visited, methods of travel, and people he traveled with. In total, he left the United States 99 times, visited 80 countries, and spent 1,223 days at sea on 48 ships.

A section of the travel log.

I was only twenty-four when he died, so I hadn’t yet realized that I’d inherited many of his record-keeping, journaling, and collecting habits. And I had never had the chance to ask him many questions about his travels (like why he went to Venezuela twelve times or what he was doing in Syria and Beirut in the 1950s). So, in an effort to discover more about him, I decided to make an infographic of his travel logs.

Today, we take for granted that we can check stocks on our phones or go online and view records from doctor visits. The kinds of repetitive tasks my grandfather did might seem excessive, especially to young web developers and designers who’ve never had to do them. But my grandfather had no recording method besides pencil and paper for most of his life, so this was a normal and especially vital part of his daily routine.

SS Amor in the West Indies. Taken by the author’s grandfather in 1939. New York City. Taken by the author’s grandfather, probably in the 1930s.

Whether you’re processing Sass, minifying, or using Autoprefixer, you’re using tools to perform mundane and repetitive tasks that people previously had to do by hand, albeit in a different medium.

But what do you do when you’re faced with a problem that can’t be solved with a plugin, like my grandfather’s travel data? If you’re a designer, what’s the best way to structure unconventional data so you can just focus on designing?

My idea for the travel web app was to graph each country based on the number of my grandfather’s visits. As the country he visited the most (twenty-two times), Bermuda would have a graph bar stretching 100 percent across the screen, while a country he visited eleven times (St. Thomas, for example) would stretch roughly 50 percent across, the proportions adjusted slightly to fit the name and visits. I also wanted each graph bar to be the country’s main flag color.

The big issue to start was that some of the data was on paper and some was already transcribed into a text file. I could have written the HTML and CSS by hand, but I wanted to have the option to display the data in different ways. I needed a JSON file.

I tediously transcribed the remaining travel data into a tab-separated text file for the countries. I added the name, number of visits, and flag color:

... honduras 1 #0051ba syria 1 #E20000 venezuela 16 #fcd116 enewetak 2 rgb(0,56,147) ...

For the ships, I added the date and name:

... 1941 SS Granada 1944 USS Alimosa 1945 USS Alcoa Patriot ...

Manually creating a JSON file would have taken forever, so I used JavaScript to iterate through the text files and create two separate JSON files—one for countries and one for ships—which I would later merge.

First, I used Node readFileSync() and trim() to remove any quotation marks at the end of the file so as to avoid an empty object in the results:

const fs = require('fs'); let countriesData = fs.readFileSync('countries.txt', 'utf8') .trim();

This returned the contents of the countries.txt file and stored it in a variable called countriesData. At that point, I outputted the variable to the console, which showed that the data was lumped together into one giant string with a bunch of tabs (\t) and newlines (\n):

"angaur\t2\t#56a83c\nantigua\t5\t#ce1126\nargentina\t2\trgb(117,170,219)\naruba\t10\trgb(0,114,198)\nbahamas\t3\trgb(0,173,198)\nbarbados\t6\trgb(255,198,30)\nbermuda\t22\trgb(0,40,104)\nbonaire\t1\trgb(37,40,135)\nguyana\t2\trgb(0,158,73)\nhonduras\t1\trgb(0,81,186)\nvirgin Islands\t2\trgb(0,40,104)\nbrazil\t3\trgb(30,181,58)\nburma\t1\trgb(254,203,0)\ncanary Islands\t1\trgb(7,104,169)\ncanal Zone\t7\trgb(11,14,98)\ncarriacou\t1\trgb(239,42,12)\n ..."

Next, I split the string at the line breaks (\n):

const fs = require('fs'); let countriesData = fs.readFileSync('countries.txt', 'utf8') .trim() .split('\n');

After split(), in the console, the countries’ data lived in an array:

[ "angaur\t2\t#56a83c", "antigua\t5\t#ce1126", "argentina\t2\trgb(117,170,219)", "aruba\t10\trgb(0,114,198)", "bahamas\t3\trgb(0,173,198)", "barbados\t6\trgb(255,198,30)", "bermuda\t22\trgb(0,40,104)", ... ]

I wanted to split each item of country data at the tabs, separating the name, number of visits, and color. To do this, I used map(), which iterates and runs a function on each item, returning something new. In this case, it split the string at each tab it found and returned a new array:

const fs = require('fs'); let countriesData = fs.readFileSync('countries.txt', 'utf8') .trim() .split('\n') .map(item => item.split('\t'));

After I used map(), countriesData was an array of arrays with each country and its data split into separate items:

[ [ "angaur", "2", "#56a83c" ], [ "antigua", "5", "#ce1126" ], [ "argentina", "2", "rgb(117,170,219)" ], [ "aruba", "10", "rgb(0,114,198)" ], [ "bahamas", "3", "rgb(0,173,198)" ], ... ]

To create the final output for each country, I used reduce(), which uses an accumulator and a function to create something new, whether that’s an object, a value, or an array. Accumulator is a fancy way of referring to the end product, which in our case is an object ({}).

const fs = require('fs'); let countriesData = fs.readFileSync('countries.txt', 'utf8') .trim() .split('\n') .map(item => item.split('\t')) .reduce((countries, item) => { return countries; }, {countries: []});

I knew I wanted {countries: []} to contain the data. So instead of creating it on the first pass and testing whether it existed on each iteration, I added {countries: []} to the resulting object. That way, it existed before I started iterating.

This process returned an empty object because I hadn’t told reduce() what to do with each array of data.

To fix this, I used reduce() to push and add a new object for each country with the name (item[0]), visits (item[1]), and color (item[2]) into the end result object. Finally, I used a capitalization function on each name value to ensure formatting would be consistent.

const fs = require('fs'); const cap = (s) => { return s.charAt(0).toUpperCase() + s.slice(1); }; let countriesData = fs.readFileSync('countries.txt', 'utf8') .trim() .split('\n') .map(item => item.split('\t')) .reduce((countries, item) => { countries["countries"].push({ name: cap(item[0]), visits: item[1], color: item[2] }); return countries; }, {countries: []});

I used the same method for the ships.txt file and merged the two using Object.assign, a method that takes two objects and creates a new one.

let result = Object.assign({}, countriesData, shipsData);

I could have created a function that took a text file and an object, or created a form-to-JSON tool, but these seemed like overkill for this project, and I had already transcribed some of the data into separate files before even conceiving of the infographic idea. The final JSON result can be found on CodePen.

I used the JSON data to create the infographic bars, defining the layout for each one with CSS Grid and dynamic styles for width and color. Check out the final product at ninetyninetimes.com. I think my grandfather would have enjoyed seeing his handwritten logs transformed into a visual format that showcases the breadth of his travels.

He passed away in 2005, but I remember showing him my Blackberry and explaining the internet to him, showing him how he could look at pictures from around the world and read articles. He took a sip of his martini and sort of waved his hand at the screen. I think he preferred handwritten notes and life outside of the internet, something many of us can appreciate. After sifting through all his travel logs, I more clearly understood the importance he placed on having different experiences, meeting new people, and fearlessly exploring the world. To him, his travels were more than just dates on a page. Now they’re more than that for me, too.

The author wishes to thank Mattias Petter Johansson, whose video series, “Fun Fun Function,” inspired some of the thinking in this article.

How the Sausage Gets Made: The Hidden Work of Content

Tue, 12/12/2017 - 06:00

I won an Emmy for keeping a website free of dick pics.

Officially, my award certificate says I was on a team that won a 2014 Emmy for Interactive Media, Social TV Experience. The category “Social TV Experience” sounds far classier than my true contribution to the project.

The award-winning Live From Space site served as a second-screen experience for a National Geographic Channel show of the same name. The show Live From Space covered the wonders of the International Space Station. The website displayed the globe as seen by astronauts, along with entertaining social data about each country crossed by the Space Station’s trajectory. One of those data points was an Instagram feed showcasing images of local cuisine.

The second-screen experience for National Geographic Channel’s Live From Space event, featuring an Instagram photo of local food.

You might think that adding this feed was a relatively simple task. Include a specific channel, or feed in images tagged with the food and the country in which the images were taken, connect to an API, and boom: a stream of images from food bloggers in South Africa, Taiwan, Mexico, what have you. One exec was so impressed that he called this feature “automagical.”

What he described as “automagical” was actually me sitting in front of a computer screen, scanning Instagram, hunting for the most appetizing images, avoiding the unappetizing ones, and pasting my choices into a spreadsheet for import by a developer. I wouldn’t call it automated, and I wouldn’t call it magical. As the team’s content manager, I performed this task because the Instagram API wasn’t playing nice with the developers, but we had to get that information into the site by the deadline somehow.

An additional, and perhaps worse, problem was that if you found a feed of images taken in certain countries and tagged #food, you might get pictures of sausage. But we’re talking about the kinds of sausages usually discussed in locker rooms or on school buses full of junior high boys. As you can imagine, you cannot add Instagram photos tagged #food to a family-friendly site without a little effort, either in terms of getting around an API or filtering out the naughty bits.

The mythical “automagical” tool

You might think I’m knocking the website, but I’m not. Many creative, brilliant people worked ridiculous hours to create a gorgeous experience for which they rightly earned an award, and the images of local cuisine made up only a small slice of the site’s data.

Yet I feel conflicted about my own involvement with Live From Space because most of the site’s users still have no idea how the sausage of apps and websites gets made. In fact, these people may never know because the site is no longer live.

Or they may not care. Few people are aware of the rote work that goes into moving or importing data from one website to another, which causes problems if they don’t understand how long the process takes to make content happen. Unless you’re working with a pristine data source, there often is no “content hose” or “automagical” tool that cleans up data and moves it from one app or content management system to another. Unfortunately, the assumption that a “content hose” exists can lead to miscommunication, frustration, and delays when it is time to produce the work.

Oftentimes, a person will need to go in, copy content, and paste that code into the new app or CMS. They must repeat this task until the app or site is ready for launch. This type of work usually spurs revolt within the workplace, and I can’t say I blame people for being upset. Unless you know some tips, tricks, and shortcuts, as I do, you have a long stretch of tedious, mind-numbing work ahead of you.

Did someone say shortcuts?

Yes, you do have shortcuts when it comes to pulling content into a website. Those shortcuts happen earlier in the site-building process than you may think, and they rely on making sure your entire team is involved in the content process.

The most important thing when you are creating a new site or migrating an existing one is to lock down the content you want to bring in, as early as possible.

In the case of the National Geographic Channel website, the team knew it needed the map data and the coordinates, but did it really need the Instagram feed with the food data? And, when the creative team decided it needed the food data, did anyone ask questions about how the food data would be drawn into the site?

This involves building tactical questions into the creative workflow. When someone is on a creative roll, the last thing I want to do is slow them down by asking overly tactical questions. But all brainstorming sessions should include a team member who is taking notes as the ideas fly so they can ask the crucial questions later:

  • Where will this content come from?
  • Do we have a team member who can generate this content from a data feed or from scratch?
  • If not, do we need to hire someone?

These questions are nothing new to a content strategist, but the questions must be asked in the earliest stages of the project. Think about it: if your team is in love with an idea, and the client falls in love with it, too, then you will have a harder time changing course if you can’t create the content that makes the site run.

Site updates and migrations are a little bit different in that most of the content exists, but you’d be surprised by how few team members know their content. Right now, I am working for a company that helps universities revamp their considerably large websites, and the first thing we do when making the sausage is halve the recipe.

First, we use Screaming Frog to generate a content inventory, which we spot-check for any unusual features that might need to be incorporated into the new site. Then we pass the inventory to the client, asking them to go through the inventory and archive duplicate or old content. Once they archive the old content, they can focus on what they intend to revise or keep as is.

A work-in-progress content inventory for a large community college.

During the first few weeks of any project, I check in with the client about how they are doing with their content archive. If they aren’t touching the content early, we schedule a follow-up meeting and essentially haunt them until they make tough decisions.

Perfecting the process

How do we improve the way our teams relate to content? How do we show them how the content sausage gets made without grossing anyone out? Here are a few tips:

Your content strategist and your developer need to be on speaking terms. “Content strategist” isn’t a fancy name for a writer or an editor. A good content strategist knows how to work with developers. For one site migration involving a community college, I used Screaming Frog to scrape the content from the original site. Then I passed the resulting .csv document back and forth to the developer, fine-tuning the alignment of fields each time so it would be easier for us to import the material into GatherContent, an editorial tool for digital projects.

Speaking of GatherContent ... set up a proper content workflow. GatherContent allows you to assign specific tasks to team members so you can divide work. Even better, GatherContent’s editorial tool allows each page to pass through specific points in the editorial process, including drafting, choosing pictures, adding tags, and uploading to the CMS.

Train the team on how to transform the current content. In my current workplace, not only do we train the client on how to use the CMS, but we also provide Content Guidelines, an overview of the basic building blocks that make up a web page. I’ve shown clients how to create fields for page metadata, images, image alt text, and downloads—and we do this early so the client doesn’t wait until the last minute to dive into details.

Sample slides from a Content Guidelines presentation for one of iFactory’s current clients.

Actually make the sausage. Clever uses of tools and advance training can only go so far. At some point you will need to make sure that what is in the CMS lines up with what you intended. You may need to take your content source, remove any odd characters, shift content from one field to another, and make the content safe for work—just like removing dick pics.

Make sure everyone on your team scrapes, scrubs, and uploads content at least once. Distributing the work ensures that your team members think twice before recommending content that doesn’t exist or content that needs a serious cleanup. That means each team member should sit down and copy content directly into the CMS or scrub the content that is there. An hour or two is enough to transform perspectives.

Push back if a team member shirks his or her content duty. Occasionally, you will encounter people who believe their roles protect them from content. I’ve heard people ask, “Can’t we get an intern to do that?” or “Can’t we do that through Mechanical Turk?” Sometimes, these people mean well and are thinking of efficiency, but other times, their willingness to brush content off as an intern task or as a task worth a nickel or two should be alarming. It’s demeaning to those who do the work for starters, but it also shows that they are cavalier about content. Asking someone to pitch in for content creation or migration is a litmus test. If they don’t seem to take content seriously, you have to ask: just how committed are these people to serving up a quality digital experience? Do you even want them on your team in the future? By the way, I’ve seen VPs and sales team members entering content in a website, and every last one of them told me that the experience was eye-opening.

People are the “automagical” ingredient

None of these shortcuts and process tips are possible without some kind of hidden content work. Content is often discussed in terms of which gender does what kind of work and how they are recognized for it. This worthwhile subject is covered in depth by many authors, especially in the context of social media, but I’d like to step back and think about why this work is hidden and how we can avoid delays, employee revolts, and overall tedium in the future.

Whether you’re scraping, scrubbing, copying, or pasting, the connecting thread for all hidden content work is that nearly no one thinks of it until the last minute. In general, project team members can do a better job of thinking about how content needs to be manipulated to fit a design or a data model. Then they should prepare their team and the client for the amount of work it will take to get content ready and entered into a site. By taking the initiative, you can save time, money, and sanity. If you’re really doing it right, you can make a site that’s the equivalent of a sausage … without dubious ingredients.


The Best Request Is No Request, Revisited

Tue, 11/28/2017 - 07:58

Over the last decade, web performance optimization has been controlled by one indisputable guideline: the best request is no request. A very humble rule, easy to interpret. Every network call for a resource eliminated improves performance. Every src attribute spared, every link element dropped. But everything has changed now that HTTP/2 is available, hasn’t it? Designed for the modern web, HTTP/2 is more efficient in responding to a larger number of requests than its predecessor. So the question is: does the old rule of reducing requests still hold up?

What has changed with HTTP/2?

To understand how HTTP/2 is different, it helps to know about its predecessors. A brief history follows. HTTP builds on TCP. While TCP is powerful and is capable of transferring lots of data reliably, the way HTTP/1 utilized TCP was inefficient. Every resource requested required a new TCP connection. And every TCP connection required synchronization between the client and server, resulting in an initial delay as the browser established a connection. This was OK in times when the majority of web content consisted of unstyled documents that didn’t load additional resources, such as images or JavaScript files.

Updates in HTTP/1.1 try to overcome this limitation. Clients are able to use one TCP connection for multiple resources, but still have to download them in sequence. This so-called “head of line blocking” makes waterfall charts actually look like waterfalls:

Figure 1. Schematic waterfall of assets loading over one pipelined TCP connection

Also, most browsers started to open multiple TCP connections in parallel, limited to a rather low number per domain. Even with such optimizations, HTTP/1.1 is not well-suited to the considerable number of resources of today’s websites. Hence the saying “The best request is no request.” TCP connections are costly and take time. This is why we use things like concatenation, image sprites, and inlining of resources: avoid new connections, and reuse existing ones.

HTTP/2 is fundamentally different than HTTP/1.1. HTTP/2 uses a single TCP connection and allows more resources to be downloaded in parallel than its predecessor. Think of this single TCP connection as one broad tunnel where data is sent through in frames. On the client, all packages get reassembled into their original source. Using a couple of link elements to transfer style sheets is now as practically efficient as bundling all of your style sheets into one file.

Figure 2. Schematic waterfall of assets loading over one shared TCP connection

All connections use the same stream, so they also share bandwidth. Depending on the number of resources, this might mean that individual resources could take longer to be transmitted to the client side on low-bandwidth connections.

This also means that resource prioritization is not done as easily as it was with HTTP/1.1: the order of resources in the document had an impact on when they begin to download. With HTTP/2, everything happens at the same time! The HTTP/2 spec contains information on stream prioritization, but at the time of this writing, placing control over prioritization in developers’ hands is still in the distant future.

The best request is no request: cherry-picking

So what can we do to overcome the lack of waterfall resource prioritization? What about not wasting bandwidth? Think back to the first rule of performance optimization: the best request is no request. Let’s reinterpret the rule.

For example, consider a typical webpage (in this case, from Dynatrace). The screenshot below shows a piece of online documentation consisting of different components: main navigation, a footer, breadcrumbs, a sidebar, and the main article.

Figure 3. A typical website split into a few components

On other pages of the same site, we have things like a masthead, social media outlets, galleries, or other components. Each component is defined by its own markup and style sheet.

In HTTP/1.1 environments, we would typically combine all component style sheets into one CSS file. The best request is no request: one TCP connection to transfer all the CSS necessary, even for pages the user hasn’t seen yet. This can result in a huge CSS file.

The problem is compounded when a site uses a library like Bootstrap, which reached the 300 kB mark, adding site-specific CSS on top of it. The actual amount of CSS required by any given page, in some cases, was even less than 10% of the amount loaded:

Figure 4. Code coverage of a random cinema webpage that uses 10% of the bundled 300 kB CSS. This page is built upon Bootstrap.

There are even tools like UnCSS that aim to get rid of unused styles.

The Dynatrace documentation example shown in figure 3 is built with the company’s own style library, which is tailored to the site’s specific needs as opposed to Bootstrap, which is offered as a general purpose solution. All components in the company style library combined add up to 80 kB of CSS. The CSS actually used on the page is divided among eight of those components, totaling 8.1 kB. So even though the library is tailored to the specific needs of the website, the page still uses only around 10% of the CSS it downloads.

HTTP/2 allows us to be much more picky when it comes to the files we want to transmit. The request itself is not as costly as it is in HTTP/1.1, so we can safely use more link elements, pointing directly to the elements used on that particular page:

<link rel="stylesheet" href="/css/base.css"> <link rel="stylesheet" href="/css/typography.css"> <link rel="stylesheet" href="/css/layout.css"> <link rel="stylesheet" href="/css/navbar.css"> <link rel="stylesheet" href="/css/article.css"> <link rel="stylesheet" href="/css/footer.css"> <link rel="stylesheet" href="/css/sidebar.css"> <link rel="stylesheet" href="/css/breadcrumbs.css">

This, of course, is true for every sprite map or JavaScript bundle as well. By just transferring what you actually need, the amount of data transferred to your site can be reduced greatly! Compare the download times for bundle and single files shown with Chrome timings below:

Figure 5. Download of the bundle. After the initial connection is established, the bundle takes 583 ms to download on regular 3G. Figure 6. Split only the files needed, and download them in parallel. The initial connection takes about as long, but the content (one style sheet, in this case) downloads much faster because it is smaller.

The first image shows that including the time required for the browser to establish the initial connection, the bundle needs about 700 ms to download on regular 3G connections. The second image shows timing values for one CSS file out of the eight that make up the page. The beginning of the response (TTFB) takes as long, but since the file is a lot smaller (less than 1 kB), the content is downloaded almost immediately.

This might not seem impressive when looking at only one resource. But as shown below, since all eight style sheets are downloaded in parallel, we still can save a great deal of transfer time when compared to the bundle approach.

Figure 7. All style sheets on the split variant load in parallel.

When running the same page through webpagetest.org on regular 3G, we can see a similar pattern. The full bundle (main.css) starts to download just after 1.5 s (yellow line) and takes 1.3 s to download; the time to first meaningful paint is around 3.5 seconds (green line):

Figure 8. Full page download of the bundle, regular 3G.

When we split up the CSS bundle, each style sheet starts to download at 1.5 s (yellow line) and takes 315–375 ms to finish. As a result, we can reduce the time to first meaningful paint by more than one second (green line):

Figure 9. Downloading single files instead, regular 3G.

Per our measurements, the difference between bundled and split files has more impact on slow 3G than on regular 3G. On the latter, the bundle needs a total of 4.5 s to be downloaded, resulting in a time to first meaningful paint at around 7 s:

Figure 10. Bundle, slow 3G.

The same page with split files on slow 3G connections via webpagetest.org results in meaningful paint (green line) occurring 4 s earlier:

Figure 11. Split files, slow 3G.

The interesting thing is that what was considered a performance anti-pattern in HTTP/1.1—using lots of references to resources—becomes a best practice in the HTTP/2 era. Plus, the rule stays the same! The meaning changes slightly.

The best request is no request: drop files and code your users don’t need!

It has to be noted that the success of this approach is strongly connected to the number of resources transferred. The example above used 10% of the original style sheet library, which is an enormous reduction in file size. Downloading the whole UI library in split-up files might give different results. For example, Khan Academy found that by splitting up their JavaScript bundles, the overall application size—and thus the transfer time–became drastically worse. This was mainly because of two reasons: a huge amount of JavaScript files (close to 100), and the often underestimated powers of Gzip.

Gzip (and Brotli) yields higher compression ratios when there is repetition in the data it is compressing. This means that a Gzipped bundle typically has a much smaller footprint than Gzipped single files. So if you are going to download a whole set of files anyway, the compression ratio of bundled assets might outperform that of single files downloaded in parallel. Test accordingly.

Also, be aware of your user base. While HTTP/2 has been widely adopted, some of your users might be limited to HTTP/1.1 connections. They will suffer from split resources.

The best request is no request: caching and versioning

To this point with our example, we’ve seen how to optimize the first visit to a page. The bundle is split up into separate files and the client receives only what it needs to display on a page. This gives us the chance to look into something people tend to neglect when optimizing for performance: subsequent visits.

On subsequent visits we want to avoid re-transferring assets unnecessarily. HTTP headers like Cache-Control (and their implementation in servers like Apache and NGINX) allow us to store files on the user’s disk for a specified amount of time. Some CDN servers default that to a few minutes. Some others to a few hours or days even. The idea is that during a session, users shouldn’t have to download what they already have in the past (unless they’ve cleared their cache in the interim). For example, the following Cache-Control header directive makes sure the file is stored in any cache available, for 600 seconds.

Cache-Control: public, max-age=600

We can leverage Cache-Control to be much more strict. In our first optimization we decided to cherry-pick resources and be choosy about what we transfer to the client, so let’s store these resources on the machine for a long period of time:

Cache-Control: public, max-age=31536000

The number above is one year in seconds. The usefulness in setting a high Cache-Control max-age value is that the asset will be stored by the client for a long period of time. The screenshot below shows a waterfall chart of the first visit. Every asset of the HTML file is requested:

Figure 12. First visit: every asset is requested.

With properly set Cache-Control headers, a subsequent visit will result in less requests. The screenshot below shows that all assets requested on our test domain don’t trigger a request. Assets from another domain with improperly set Cache-Control headers still trigger a request, as do resources which haven’t been found:

Figure 13. Second visit: only some poorly cached SVGs from a different server are requested again.

When it comes to invalidating the cached asset (which, consequently, is one of the two hardest things in computer science), we simply use a new asset instead. Let’s see how that would work with our example. Caching works based on file names. A new file name triggers a new download. Previously, we split up our code base into reasonable chunks. A version indicator makes sure that each file name stays unique:

<link rel="stylesheet" href="/css/header.v1.css"> <link rel="stylesheet" href="/css/article.v1.css">

After a change to our article styles, we would modify the version number:

<link rel="stylesheet" href="/css/header.v1.css"> <link rel="stylesheet" href="/css/article.v2.css">

An alternative to keeping track of the file’s version is to set a revision hash based on the file’s content with automation tools.

It’s OK to store your assets on the client for a long period of time. However, your HTML should be more transient in most cases. Typically, the HTML file contains the information about which resources to download. Should you want your resources to change (such as loading article.v2.css instead of article.v1.css, as we just saw), you’ll need to update references to them in your HTML. Popular CDN servers cache HTML for no longer than six minutes, but you can decide what’s better suited for your application.

And again, the best request is no request: store files on the client as long as possible, and don’t request them over the wire ever again. Recent Firefox and Edge editions even sport an immutable directive for Cache-Control, targeting this pattern specifically.

Bottom line

HTTP/2 has been designed from the ground up to address the inefficiencies of HTTP/1. Triggering a large number of requests in an HTTP/2 environment is no longer inherently bad for performance; transferring unnecessary data is.

To reach the full potential of HTTP/2, we have to look at each case individually. An optimization that might be good for one website can have a negative effect on another. With all the benefits that come with HTTP/2 , the golden rule of performance optimization still applies: the best request is no request. Only this time we take a look at the actual amount of data transferred.

Only transfer what your users actually need. Nothing more, nothing less.

Faux Grid Tracks

Tue, 11/21/2017 - 08:00

A little while back, there was a question posted to css-discuss:

Is it possible to style the rows and columns of a [CSS] grid—the grid itself? I have an upcoming layout that uses what looks like a tic-tac-toe board—complete with the vertical and horizontal lines of said tic-tac-toe board—with text/icon in each grid cell.

This is a question I expect to come up repeatedly, as more and more people start to explore Grid layout. The short answer is: no, it isn’t possible to do that. But it is possible to fake the effect, which is what I’d like to explore.

Defining the grid

Since we’re talking about tic-tac-toe layouts, we’ll need a containing element around nine elements. We could use an ordered list, or a paragraph with a bunch of <span>s, or a <section> with some <div>s. Let’s go with that last one.

<section id="ttt"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </section>

We’ll take those nine <div>s and put them into a three-by-three grid, with each row five ems high and each column five ems wide. Setting up the grid structure is straightforward enough:

#ttt { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); }

That’s it! Thanks to the auto-flow algorithm inherent in Grid layout, that’s enough to put the nine <div> elements into the nine grid cells. From there, creating the appearance of a grid is a matter of setting borders on the <div> elements. There are a lot of ways to do this, but here’s what I settled on:

#ttt > * { border: 1px solid black; border-width: 0 1px 1px 0; display: flex; /* flex styling to center content in divs */ align-items: center; justify-content: center; } #ttt > *:nth-of-type(3n) { border-right-width: 0; } #ttt > *:nth-of-type(n+7) { border-bottom-width: 0; }

The result is shown in the basic layout below.

Figure 1: The basic layout

This approach has the advantage of not relying on class names or what-have-you. It does fall apart, though, if the grid flow is changed to be columnar, as we can see in Figure 2.

#ttt { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); grid-auto-flow: column; /* a change in layout! */ } Figure 2: The basic layout in columnar flow order

If the flow is columnar, then the border-applying rules have to get flipped, like this:

#ttt > *:nth-of-type(3n) { border-bottom-width: 0; } #ttt > *:nth-of-type(n+7) { border-right-width: 0; }

That will get us back to the result we saw in Figure 1, but with the content in columnar order instead of row order. There’s no row reverse or column reverse in Grid like there is in flexbox, so we only have to worry about normal row and columnar flow patterns.

But what if a later change to the design leads to grid items being rearranged in different ways? For example, there might be a reason to take one or two of the items and display them last in the grid, like this:

#ttt > *:nth-of-type(4), #ttt > *:nth-of-type(6) { order: 66; }

Just like in flexbox, this will move the displayed grid items out of source order, placing them after the grid items that don’t have explicit order values. If this sort of rearrangement is a possibility, there’s no easy way to switch borders on and off in order to create the illusion of the inner grid lines. What to do?

Attack of the filler <b>s!

If we want to create standalone styles that follow grid tracks—that is, presentation aspects that aren’t directly linked to the possibly-rearranged content—then we need other elements to place and style. They likely won’t have any content, making them a sort of structural filler to spackle over the gaps in Grid’s capabilities.

Thus, to the <section> element, we can add two <b> elements with identifiers.

<section id="ttt"> <b id="h"></b> <b id="v"></b> <div>1</div> <div>2</div> <div>3</div> …

These “filler <b>s,” as I like to call them, could be placed anywhere inside the <section>, but the beginning works fine. We’ll stick with that. Then we add these styles to our original grid from the basic layout:

b[id] { border: 1px solid gray; } b#h { grid-column: 1 / -1; grid-row: 2; border-width: 1px 0; } b#v { grid-column: 2; grid-row: 1 / -1; border-width: 0 1px; }

The 1 / -1 means “go from the first grid line to the last grid line of the explicit grid”, regardless of how many grid lines there might be. It’s a handy pattern to use in any situation where you have a grid item meant to stretch from edge to edge of a grid.

So the horizontal <b> has top and bottom borders, and the vertical <b> has left and right borders. This creates the board lines, as shown in Figure 3.

Figure 3: The basic layout with “Filler <b>s”

Hold on a minute: we got the tic-tac-toe grid back, but now the numbers are in the wrong places, which means the <div>s that contain them are out of place. Here’s why: the <div> elements holding the actual content will no longer auto-flow into all the grid cells, because the filler <b>s are already occupying five of the nine cells. (They’re the cells in the center column and row of the grid.) The only way to get the <div> elements into their intended grid cells is to explicitly place them. This is one way to do that:

div:nth-of-type(3n+1) { grid-column: 1; } div:nth-of-type(3n+2) { grid-column: 2; } div:nth-of-type(3n+3) { grid-column: 3; } div:nth-of-type(-n+3) { grid-row: 1; } div { grid-row: 2; } div:nth-of-type(n+7) { grid-row: 3; }

That works if you know the content will always be laid out in row-then-column order. Switching to column-then-row requires rewriting the CSS. If the contents are to be placed in a jumbled-up order, then you’d have to write a rule for each <div>.

This probably suffices for most cases, but let’s push this even further. Suppose you want to draw those grid lines without interfering with the automatic flow of the contents. How can this be done?


It would be handy if there were a property to mark elements as not participating in the grid flow, but there isn’t. So instead, we’ll split the contents and filler into their own grids, and use a third grid to put one of those grids over the other.

This will necessitate a bit of structural change to make happen, because for it to work, the contents and the filler <b>s have to have identical grids. Thus we end up with:

<section id="ttt"> <div id="board"> <b id="h"></b> <b id="v"></b> </div> <div id="content"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </div> </section>

The first thing is to give the board and the content <div>s identical grids. The same grid we used before, in fact. We just change the #ttt rule’s selector a tiny bit, to select the children of #ttt instead:

#ttt > * { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); }

Now that the two grids have the same layout, we need to place one over the other. We could relatively position the #ttt container and absolutely position its children, but there’s another way: use Grid.

#ttt { /* new rule added */ display: grid; } #ttt > * { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); }

But wait—where are the rows and columns for #ttt? Where we’re going, we don’t need rows (or columns). Here is how the two grids end up occupying the same area with one on top of the other:

#ttt { display: grid; } #ttt > * { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); grid-column: 1; /* explicit grid placement */ grid-row: 1; /* explicit grid placement */ }

So #ttt is given a one-cell grid, and its two children are explicitly placed in that single cell. Thus one sits over the other, as with positioning—but unlike positioning, the outer grid’s size is dictated by the layout of its children. It will resize to surround them, even if we later change the inner grids to be larger (or smaller). We can see this in practice in Figure 4, where the outer grid is outlined in purple in Firefox’s Grid inspector tool.

Figure 4: The overgridded layout

And that’s it. We could take further steps, like using z-index to layer the board on top of the content (by default, the element that comes later in the source displays on top of the element that comes earlier), but this will suffice for the case we have here.

The advantage is that the content <div>, having only its own contents to worry about, can make use of grid-auto-flow and order to rearrange things. As an example, you can do things like the following and you won’t need all of the :nth-of-type grid item placements from our earlier CSS. Figure 5 shows the result.

/* added to #snippet13 code */ #ttt > #content { grid-auto-flow: column; } #ttt > #content > :nth-child(5) { order: 2; } Figure 5: Moving #5 to the end and letting the other items reflow into columns Caveats

The downside here, and it’s a pretty big one, is that the board and content grids are only minimally aware of each other. The reason the previous example works is the grid tracks are of fixed size, and none of the content is overflowing. Suppose we wanted to make the columns and rows resize based on content, like this:

#content { grid-template-columns: repeat(3,min-content); grid-template-rows: repeat(3,min-content); }

This will fall apart quickly, with the board lines not corresponding to the layout of the actual content. At all.

In other words, this overlap technique sacrifices one of Grid’s main strengths: the way grid cells relate to other grid cells. In cases where content size is predictable but ordering is not, it’s a reasonable trade-off to make. In other cases, it probably isn’t a good idea.

Bear in mind that this really only works with layouts where sizes and placements are always known, and where you sometimes have to layer grids on top of one another. If your Filler <b> comes into contact with an implicitly-placed grid item in the same grid as it occupies, it will be blocked from stretching. (Explicitly-placed grid items, i.e., those with author-declared values for both grid-row and grid-column, do not block Filler <b>s.)

Why is this useful?

I realize that few of us will need to create a layout that looks like a tic-tac-toe board, so you may wonder why we should bother. We may not want octothorpe-looking structures, but there will be times we want to style an entire column track or highlight a row.

Since CSS doesn’t (yet) offer a way to style grid cells, areas, or tracks directly, we have to stretch elements over the parts we want to style independently from the elements that contain content. There is a discussion about adding this capability directly to CSS in the Working Group’s GitHub repository, where you can add your thoughts and proposals.

But why <b>s? Why?

I use <b>s for the decorative portions of the layout because they’re purely decorative elements. There’s no content to strongly emphasize or to boldface, and semantically a <b> isn’t any better or worse than a <span>. It’s just a hook on which to hang some visual effects. And it’s shorter, so it minimizes page bloat (not that a few characters will make all that much of a difference).

More to the point, the <b>’s complete lack of semantic meaning instantly flags it in the markup as being intentionally non-semantic. It is, in that meta sense, self-documenting.

Is this all there is?

There’s another way to get this precise effect: backgrounds and grid gaps. It comes with its own downsides, but let’s see how it works first. First, we set a black background for the grid container and white backgrounds for each item in the grid. Then, by using grid-gap: 1px, the black container background shows between the grid items.

<section id="ttt"> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>6</div> <div>7</div> <div>8</div> <div>9</div> </section> #ttt { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); background: black; grid-gap: 1px; } #ttt > div { background: white; }

Simple, no Filler <b>s needed. What’s not to like?

The first problem is that if you ever remove an item, there will be a big black block in the layout. Maybe that’s OK, but more likely it isn’t. The second problem is that grid containers do not, by default, shrink-wrap their items. Instead, they fill out the parent element, as block boxes do. Both of these problems are illustrated in Figure 6.

Figure 6: Some possible background problems

You can use extra CSS to restrict the width of the grid container, but the background showing through where an item is missing can’t really be avoided.

On the other hand, these problems could become benefits if, instead of a black background, you want to show a background image that has grid items “punch out” space, as Jen Simmons did in her “Jazz At Lincoln Center Poster” demo.

A third problem with using the backgrounds is when you just want solid grid lines over a varied page background, and you want that background to show through the grid items. In that case, the grid items (the <div>s in this case) have to have transparent backgrounds, which prevents using grid-gap to reveal a color.

If the <b>s really chap your cerebellum, you can use generated content instead. When you generate before- and after-content pseudo-elements, Grid treats them as actual elements and makes them grid items. So using the simple markup used in the previous example, we could write this CSS instead:

#ttt { display: grid; grid-template-columns: repeat(3,5em); grid-template-rows: repeat(3,5em); } #ttt::before { grid-column: 1 / -1; grid-row: 2; border-width: 1px 0; } #ttt::after { grid-column: 2; grid-row: 1 / -1; border-width: 0 1px; }

It’s the same as with the Filler <b>s, except here the generated elements draw the grid lines.

This approach works just fine for any 3x3 grid like the one we’ve been playing with, but to go any further, you’ll need to get more complicated. Suppose we have a 5x4 grid instead of a 3x3. Using gradients and repeating, we can draw as many lines as needed, at the cost of more complicated CSS.

#ttt { display: grid; grid-template-columns: repeat(5,5em); grid-template-rows: repeat(4,5em); } #ttt::before { content: ""; grid-column: 1 / -1; grid-row: 1 / -2; background: linear-gradient(to bottom,transparent 4.95em, 4.95em, black 5em) top left / 5em 5em; } #ttt::after { content: ""; grid-column: 1 / -2; grid-row: 1 / -1; background: linear-gradient(to right,transparent 4.95em, 4.95em, black 5em) top left / 5em 5em; }

This works pretty well, as shown in Figure 7, assuming you go through the exercise of explicitly assigning the grid cells similar to how we did in #snippet9.

Figure 7: Generated elements and background gradients

This approach uses linear gradients to construct almost-entirely transparent images that have just a 1/20th of an em of black, and then repeating those either to the right or to the bottom. The downward gradient (which creates the horizontal lines) is stopped one gridline short of the bottom of the container, since otherwise there would be a horizontal line below the last row of items. Similarly, the rightward gradient (creating the vertical lines) stops one row short of the right edge. That’s why there are -2 values for grid-column and grid-row.

One downside of this is the same as the Filler <b> approach: since the generated elements are covering most of the background, all the items have to be explicitly assigned to their grid cells instead of letting them flow automatically. The only way around this is to use something like the overgridding technique explored earlier. You might even be able to drop the generated elements if you’re overgridding, depending on the specific situation.

Another downside is that if the font size ever changes, the width of the lines can change. I expect there’s a way around this problem using calc(), but I’ll leave that for you clever cogs to work out and share with the world.

The funny part to me is that if you do use this gradient-based approach, you’re filling images into the background of the container and placing items over that … just as we did with Faux Columns.


It’s funny how some concepts echo through the years. More than a decade ago, Dan Cederholm showed us how to fake full-height columns with background images. Now I’m showing you how to fake full-length column and row boxes with empty elements and, when needed, background images.

Over time, the trick behind Faux Columns fell out of favor, and web design moved away from that kind of visual effect. Perhaps the same fate awaits Faux Grid Tracks, but I hope we see new CSS capabilities arise that allow this sort of effect without the need for trickery.

We’ve outgrown so many of our old tricks. Here’s another to use while it’s needed, and to hopefully one day leave behind.

Feedback That Gives Focus

Tue, 11/14/2017 - 08:00

I have harbored a lifelong dislike of feedback. I didn’t like it in sixth grade when a kid on the bus told me my brand new sneakers were “too bright.” And I didn’t like it when a senior executive heard my pitch for a digital project and said, “I hate this idea.” Turns out my sneakers were pretty bright, and my pitch wasn’t the best idea. Still, those experiences and many others like them didn’t help me learn to stop worrying and love the feedback process.

We can’t avoid feedback. Processing ideas and synthesizing feedback is a big part of what we do for a living. I have had plenty of opportunities to consider why both giving and receiving feedback is often so emotionally charged, so challenging to get right.

And here’s what I’ve found to be true.

When a project is preoccupying us at work, we often don’t think about it as something external and abstract. We think about it more like a story, with ourselves in the middle as the protagonist—the hero. That might seem melodramatic, especially if your work isn’t the kind of thing they’d make an inspirational movie about. But there’s research to back this up: humans use stories to make sense of the world and our place within it.

Our work is no different. We create a story in our heads about how far we’ve come on a project and about where we’re going. This makes discussing feedback dangerous. It’s the place where someone else swoops in and hijacks your story.

Speaking personally, I notice that when I’m giving feedback (and feeling frustrated), the story in my head goes like this: These people don’t get it. How can I force them into thinking the same way I do so that we can fix everything that’s wrong with this project, and in the end, I don’t feel like a failure?

Likewise, when I’m receiving feedback (and feeling defensive), the story goes like this: These people don’t get it. How can I defend our work so that we keep everything that I like about this project, and in the end, I don’t feel like a failure?

Both of these postures are ultimately counterproductive because they are focused inward. They’re really about avoiding shame. Both the person giving and receiving feedback are on opposing sides of the equation, protecting their turf.

But like a good story, good feedback can take us out of ourselves, allowing us to see the work more clearly. It can remove the artificial barrier between feedback giver and receiver, refocusing both on shared goals.

Change your habits around feedback, and you can change the story of your project.

Here are three ways to think about feedback that might help you do just that.

Good feedback helps us understand how we got here

Here’s a story for you. I was presenting some new wireframes for an app to the creative leads on the project. There were a number of stakeholders and advisors on the project, and I had integrated several rounds of their feedback into the harmonious and brilliant vision that I was presenting in this meeting. That’s the way I hoped the story would go, anyway.

But at the end of the meeting, I got some of the best, worst feedback I have ever received: “We’ve gotten into our heads a little bit with this concept. Maybe it should be simpler. Maybe something more like this …” And they handed me a loose sketch on paper to illustrate a new, simpler approach. I had come for sign-off but left with a do-over.

I felt ashamed. How could I have missed that? Even though that feedback was hard to hear, I walked away able to make important changes, which led to a better outcome in the end. Here are the reasons why:

First, the feedback started as a conversation. Conversations (rather than written notes) make it easier to verify assumptions. When you talk face-to-face you can ask open-ended questions and clarify intent, so you don’t jump to conclusions. Talking helps you find where the trouble is much faster.

The feedback connected the dots between problems in our process so far (trying to reconcile too many competing ideas) and how it led to the current result (an overly complicated product). The person who gave the feedback helped me see how we got to where we were, without assigning blame or shaming me in the process.

The feedback was direct. They didn’t try to mask the fact that the concept wasn’t working. Veiled or vague criticism does more harm than good; the same negativity comes through but without a clear sense of what to do next.

Good feedback invites each person to contribute their best work No thought, no idea, can possibly be conveyed as an idea from one person to another. … Only by wrestling with the conditions of the problem … first hand … does he think. John Dewey, Democracy and Education

Here’s another story. I was the producer on an app-based game, and the team was working on a part of the user interface that the player would use again and again. I was convinced that the current design didn’t “feel” right. I kept pushing for a change, against the input of others, and I gave the team some specific feedback about what I wanted to see done. The designers played along and tried it out. But it became clear that my feedback wasn’t helping, and the design director (gently) stepped in and steered us out of my design tangent and back on course.

John Dewey had it right in that quote above; you can’t think for someone else. And that’s exactly what I was doing: giving specific solutions without inviting the team to engage with the problem. And the results were worse for it.

It’s very tempting to use feedback to cajole and control people into doing things your way. But that usually leads to mediocre results. You have a team for a reason: you can’t possibly do everything on your own. Instead, when giving feedback try to remember that you’re building a team of individual contributors that will work together to make a better end product.

Here are a few feedback habits that help avoid the trap of using feedback to control, and instead, bring out the best in people.

Don’t give feedback until the timing is right

Feedback isn’t useful if it’s given before the work is really ready to be looked at. It’s also not useful to give feedback if you have not taken the time to look at the work and think about it in advance. If you rush either of these, the feedback will devolve into a debate about what could have been, rather than what’s actually there now. That invites confusion, defensiveness, and inefficiency.

Be just specific enough

Good feedback should have enough specifics to clearly identify the problem. But, usually, it’s better to not give a specific solution. The feedback in this example goes too far:

The background behind the menu items is a light blue on a darker blue. This makes it hard to see some options. Change the background fill to white and add a thin, red border around each square. When an option is selected, perhaps the inside border should glow red but not fill in all the way.

Instead, feedback that clearly identifies the problem is probably enough:

The background behind the menu items makes it a little hard for me to see some options. Any way we might make it easier to read?

Give the person whose job it is to solve the problem the room to do just that.  They might solve it in a better way that you hadn’t anticipated.

Admit when you’re wrong

When you acknowledge a mistake openly and without fear, it gives permission for others on the team to do the same. This refocuses energies away from ego-protection and toward problem solving. I chose to admit I got it wrong on that app project I mentioned above; the designers had it right and I told them I was glad they stuck to their guns. Saying that out loud was actually easier than I thought, and our working relationship was better for it.

Good feedback tells a story about the future In my writing, as much as I could, I tried to find the good, and praise it. Alex Haley

We’ve said that good feedback connects past assumptions and decisions to current results, without assigning blame. Good feedback also identifies issues in a timely and specific way, giving people room to find novel solutions and contribute their best work.

Lastly, I’ve found that most useful feedback helps us look beyond the present state of our work and builds a shared vision of where we’re headed.

One of maybe the most overlooked tools for building that shared vision is actually pretty simple: positive feedback. The best positive feedback acknowledges great work that’s already complete, doing so in a way that is future-focused.  Its purpose is to point out what we want to do more of as we move forward.

In practice, I’ve found that I can become stingy with positive feedback, especially when it’s early in a project and there’s so much work ahead of us. Maybe this is because I’m afraid that mentioning the good things will distract us from what’s still in need of improvement.

But ironically, the opposite is true: it becomes easier to fix what’s broken once you have something (however small) that you know is working well and that you can begin to build that larger vision around.

So be equally direct about what’s working as you are with what isn’t, and you’ll find it becomes easier to rally a team around a shared vision for the future.  The first signs of that future can be found right here in the present.

Like Mr. Haley said: find the good and praise it.

Oh and one more thing: say thank you.

Thank people for their contributions. Let me give that a try right now:

It seemed wise to get some feedback from others when writing about feedback. So thanks to everyone in the PBS KIDS family of producers who generously shared their thoughts and experience with me in preparation of this article. I look forward to hearing your feedback.

Planning for Accessibility

Thu, 11/09/2017 - 08:00

A note from the editors: We’re pleased to share an excerpt from Chapter 3 (“Planning for Accessibility") of Laura Kalbag's new book, Accessibility for Everyone, available now from A Book Apart.

Incorporating accessibility from the beginning is almost always easier, more effective, and less expensive than making accessibility improvements as a separate project. In fact, building accessibility into your project and processes has a wealth of business benefits. If you’re looking to make the case for accessibility—to yourself, to coworkers, or to bosses and clients—you might start here:

  • Findability and ease of use: In the broadest terms, accessibility can make it easier for anyone to find, access, and use a website successfully. By ensuring better usability for all, accessibility boosts a site’s effectiveness and increases its potential audience.
  • Competitive edge: The wider your audience, the greater your reach and commercial appeal. When a site is more accessible than other sites in the same market, it can lead to preferential treatment from people who struggled to use competitors’ sites. If a site is translated, or has more simply written content that improves automated translation, increased accessibility can lead to a larger audience by reaching people who speak other languages.
  • Lower costs: Accessible websites can cut costs in other areas of a business. On a more accessible site, more customers can complete more tasks and transactions online, rather than needing to talk to a representative one-to-one.
  • Legal protection: In a few countries, an accessible site is required by law for organizations in certain sectors—and organizations with inaccessible sites can be sued for discrimination against people with disabilities.

Once you’ve made the case for incorporating accessibility into your work, the next step is to integrate an accessibility mindset into your processes. Include accessibility by default by giving accessibility proper consideration at every step in a product’s lifecycle.

Building Your Team

Web accessibility is the responsibility of everyone who has a hand in the design of a site. Design includes all of the decisions we make when we create a product—not just the pretty bits, but the decisions about how it works and who it’s for. This means everybody involved in the project is a designer of some sort.

Each specialist is responsible for a basic understanding of their work’s impact on accessibility, and on their colleagues’ work. For example, independent consultant Anne Gibson says that information architects should keep an eye on the markup:

“We may or may not be responsible for writing the HTML, but if the developers we’re working with don’t produce semantic structure, then they’re not actually representing the structures that we’re building in our designs.”

Leadership and support

While we should all be attentive to how accessibility impacts our specialism, it’s important to have leadership to help determine priorities and key areas where the product’s overall accessibility needs improvement. Project manager Henny Swan (user experience and design lead at the Paciello Group, and previously of the BBC) recommends that accessibility be owned by product managers. The product managers must consider how web accessibility affects what the organization does, understand the organization’s legal duties, and consider the potential business benefits.

Sometimes people find themselves stuck within a company or team that doesn’t value accessibility. But armed with knowledge and expertise about accessibility, we can still do good work as individuals, and have a positive effect on the accessibility of a site. For example, a designer can ensure all the background and foreground text colors on their site are in good contrast, making text easier to distinguish and read.

Unfortunately, without the support and understanding of our colleagues, the accessibility of a site can easily be let down in other areas. While the colors could be accessible, if another designer has decided that the body text should be set at 12 pixels, the content will still be hard to read.

When accessibility is instituted as a company-wide practice, rather than merely observed by a few people within a team, it will inevitably be more successful. When everybody understands the importance of accessibility and their role in the project, we can make great websites.

Professional development

When you’re just starting to learn about accessibility, people in your organization will need to learn new skills and undertake training to do accessibility well.

Outside experts can often provide thorough training, with course material tailor-made to your organization. Teams can also develop their accessibility skills by learning the basics through web- and book-based research, and by attending relevant conferences and other events.

Both formal training and independent practice will cost time away from other work, but in return you’ll get rapid improvements in a team’s accessibility skills. New skills might mean initially slower site development and testing while people are still getting their heads around unfamiliar tools, techniques, and ways of thinking. Don’t be disheartened! It doesn’t take long for the regular practice of new skills to become second nature.

You might also need to hire in outside expertise to assist you in particular areas of accessibility—it’s worth considering the capabilities of your team during budgeting and decide whether additional training and help are needed. Especially when just starting out, many organizations hire consultants or new employees with accessibility expertise to help with research and testing.

When you’re trying to find the right expert for your organization’s needs, avoid just bashing “accessibility expert” into a search engine and hoping for good luck. Accessibility blogs and informational websites (see the Resources section) are probably the best place to start, as you can often find individuals and organizations who are great at teaching and communicating accessibility. The people who run accessibility websites often provide consultancy services, or will have recommendations for the best people they know.

Scoping the Project

At the beginning of a project, you’ll need to make many decisions that will have an impact on accessibility efforts and approaches, including:

  • What is the purpose of your product?
  • Who are the target audiences for your product? What are their needs, restrictions, and technology preferences?
  • What are the goals and tasks that your product enables the user to complete?
  • What is the experience your product should provide for each combination of user group and user goal?
  • How can accessibility be integrated during production?
  • Which target platforms, browsers, operating systems and assistive technologies should you test the product on?

If you have answers to these questions—possibly recorded more formally in an accessibility policy (which we’ll look at later in this chapter)—you’ll have something to refer to when making design decisions throughout the creation and maintenance of the product.

Keep in mind that rigid initial specifications and proposals can cause problems when a project involves research and iterative design. Being flexible during the creation of a product will allow you to make decisions based on new information, respond to any issues that arise during testing, and ensure that the launched product genuinely meets people’s needs.

If you’re hiring someone outside your organization to produce your site, you need to convey the importance of accessibility to the project. Whether you’re a project manager writing requirements, a creative agency writing a brief, or a freelance consultant scoping your intent, making accessibility a requirement will ensure there’s no ambiguity. Documenting your success criteria and sharing it with other people can help everyone understand your aims, both inside and outside your organization.


Accessibility isn’t a line item in an estimate or a budget—it’s an underlying practice that affects every aspect of a project.

Building an accessible site doesn’t necessarily cost more money or time than an inaccessible site, but some of the costs are different: it costs money to train your team or build alternative materials like transcripts or translations. It’s wise to consider all potential costs from the beginning and factor them into the product budget so they’re not a surprise or considered an “extra cost” when they could benefit a wide audience. You wouldn’t add a line item to make a site performant, so don’t do it for accessibility either.

If you’ve got a very small budget, rather than picking and choosing particular elements that leave some users out in favor of others, consider the least expensive options that enable the widest possible audience to access your site. For example, making a carousel that can be manipulated using only the keyboard will only benefit people using keyboard navigation. On the other hand, designing a simpler interface without a carousel will benefit everyone using the site.

Ultimately, the cost of accessibility depends on the size of the project, team, and whether you’re retrofitting an existing product or creating a new product. The more projects you work on, the better you’ll be able to estimate the impact and costs of accessibility.

Want to read more?

This excerpt from Accessibility for Everyone will help you get started. Order the full copy today, as well as other excellent titles from A Book Apart.

Ten Extras for Great API Documentation

Tue, 11/07/2017 - 08:00

If you manage to create amazing API documentation and ensure that developers have a positive experience implementing your API, they will sing the praises of your product. Continuously improving your API documentation is an investment, but it can have a huge impact. Great documentation builds trust, differentiates you from your competition, and provides marketing value.

I’ve shared some best practices for creating good API documentation in my article “The Ten Essentials for Good API Documentation.” In this article, I delve into some research studies and show how you can both improve and fine-tune different aspects of your API documentation. Some of these extras, like readability, are closer to essentials, while others are more of a nice-to-have, like personality. I hope they give you some ideas for building the best possible docs for your product.

Overview page

Whoever visits your API documentation needs to be able to decide at first glance whether it is worth exploring further. You should clearly show:

  • what your API offers (i.e., what your products do);
  • how it works;
  • how it integrates;
  • and how it scales (i.e., usage limits, pricing, support, and SLAs).
Spotify’s API documentation clearly states what the API does and how it works, and it provides links to guides and API references organized in categories.

An overview page targets all visitors, but it is especially helpful for decision-makers. They have to see the business value: explain to them directly why a company would want to use your API.

Developers, on the other hand, want to understand the purpose of the API and its feature set, so they tend to turn to the overview page for conceptual information. Show them the architecture of your API and the structure of your docs. Include an overview of different components and an introduction into the request-response behavior (i.e., how to integrate, how to send requests, and how to process responses). Provide information on the platforms on which the API is running (e.g., Java) and possible interactions with other platforms.

As the study “The role of conceptual knowledge in API usability” found, without conceptual knowledge, developers struggle to formulate effective queries and to evaluate the relevance or meaning of content they find. That’s why API documentation should not only include detailed examples of API use, but also thorough introductions to the concepts, standards, and ideas in an API’s data structures and functionality. The overview page can be an important component to fulfill this role.

Braintree’s API overview page provides a clear overview of their SDKs, along with a visual step-by-step explanation of how their API works. Examples

For some developers, examples play a more important role in getting started with an API than the explanations of calls and parameters.

A recent study, “Application Programming Interface Documentation—What Do Software Developers Want?,” explored how software developers interact with API documentation: what their goals are, how they learn, where they look for information, and how they judge the quality of API docs.

The role of examples

The study found that after conducting an initial overview of what the API does and how it works, developers approach learning about the API in two distinct ways: some follow a top-down approach, where they try to build a thorough understanding of the API before starting to implement specific use cases, while others prefer to follow a bottom-up approach, where they start coding right away.

This latter group has a code-oriented learning strategy; they start learning by trying and extending code examples. Getting into an API is most often connected with a specific task. They look for an example that has the potential of serving as a basis to solve their problem, but once they’ve found the solution they were looking for, they usually stop learning.

Examples are essential for code-oriented learners, but all developers benefit from them. The study showed that developers often trust examples more than documentation, because if they work, they can’t be outdated or wrong. Developers often struggle with finding out where to start and how to begin with a new API—examples can become good entry points in this case. Many developers can grasp information more easily from code than text, and they can re-use code in examples for their own implementation. Examples also play other roles that are far from obvious: they automatically convey information about dependencies and prerequisites, they help identify relevant sections in the documentation when developers are scanning the page, and they intuitively show developers how code that uses the API should look.

Improve your examples

Because examples are such a crucial component in API documentation, better examples mean better docs.

To ensure the quality of your examples, they should be complete, be programmed professionally, and work correctly. Because examples convey so much more than the actual use case, make sure to follow the style guidelines of the respective community and show best-practice approaches. Add brief, informative explanations; although examples can be self-explanatory, comments included with sample code help comprehension.

Add concrete, real-life examples whenever you can. If you don’t have real examples, make sure they at least look real: use realistic variable names and functions instead of abstract ones.

When including examples, you have a variety of formats and approaches to choose from: auto-generated examples, sample applications, client libraries, and examples in multiple languages.

Auto-generated examples

Autodoc tools like Swagger Codegen and API Blueprint automatically generate documentation from your source code and keep it up-to-date as the code changes. Use them to generate reference libraries and sample code snippets, but be aware that what you produce this way is only skeleton—not fleshed out—documentation. You will still have to add explanations, conceptual information, quick-start guides, and tutorials, and you should still pay attention to other aspects like UX and good-quality copy.

On the Readme blog, they explore autodoc tools and their limitations in more depth through a couple of real-world examples.

Sample applications

Working applications that use the API are a great way to show how everything works together and how the API integrates with different platforms and technologies. They are different than sample code snippets, because they are stand-alone solutions that show the big picture. As such, they are helpful to developers who would like to see how a full implementation works and to have an overall understanding of how everything in the API ties together. On the other hand, they are real products that showcase the services and quality of your API to decision makers. Apple’s iOS Developer Portal offers buildable, executable source examples of how to accomplish a task using a particular technology in a wide variety of categories.   

Client libraries

Client libraries are chunks of code that developers can add to their own development projects. They are usually available in various programming languages, and cover basic functionality for an application to be able to interact with the API. Providing them is an extra feature that requires ongoing investment from the API provider, but doing so helps developers jump-start their use of the API. GitHub follows the practical approach of offering client libraries for the languages that are used the most with their API, while linking to unsupported, community-built libraries written in other, less popular languages.

Examples in multiple languages

APIs are platform- and language-independent by nature. Developers can use an API’s services with the language of their choice, but this means good documentation should cover at least the most popular languages used with that particular API (e.g., C#, Java, JavaScript, Go, Objective-C, PHP, Python, Ruby, and Swift). Not only should you provide sample code and sample applications in different languages, but also these samples should reflect the best-practice approach for each language.


API documentation is a tool that helps developers and other stakeholders do their job. You should adapt it to the way people use it, and make it as easy to use as possible. Consider the following factors:

  • Copy and paste: Developers copy and paste code examples to use them as a starting point for their own implementation. Make this process easier with either a copy button next to relevant sections or by making sections easy to highlight and copy.
  • Sticky navigation: When implemented well, fixing the table of contents and other navigation to the page view can prevent users from getting lost and having to scroll back up.
  • Clicking: Minimize clicking by keeping related topics close to each other.
  • Language selector: Developers should be able to see examples in the language of their choice. Put a language selector above the code examples section, and make sure the page remembers what language the user has selected.
  • URLs: Single page views can result in very long pages, so make sure people can link to certain sections of the page. If, however, a single page view doesn’t work for your docs, don’t sweat it: just break different sections into separate pages. .main-content figure figcaption { display: block;margin: 12px 0;text-align: center;font-size: 14px;line-height: 24px;font-style: italic;font-family: georgia,serif; } .main-content figure { margin-top: 36px;margin-bottom: 36px;overflow: hidden; } Great usability: Stripe’s API documentation changes the URL dynamically as you scroll through the page.

    Another best practice from Stripe: the language selector also changes the URL, so URLs link to the right location in the right language.

  • Collaboration: Consider allowing users to contribute to your docs. If you see your users edit your documentation, it indicates there might be room for improvement—in those parts of your docs or even in your code. Additionally, your users will see that issues are addressed and the documentation is frequently updated. One way to facilitate collaboration is to host your documentation on GitHub, but be aware that this will limit your options of interactivity, as GitHub hosts static files.


Providing an option for users to interact with your API through the documentation will greatly improve the developer experience and speed up learning.

First, provide a working test API key or, even better, let your users log in to your documentation site and insert their own API key into sample commands and code. This way they can copy, paste, and run the code right away.

As a next step, allow your users to make API calls directly from the site itself. For example, let them query a sample database, modify their queries, and see the results of these changes.

A more sophisticated way to make your documentation more interactive is by providing a sandbox—a controlled environment where users can test calls and functions against known resources, manipulating data in real-time. Developers learn through the experience of interacting with your API in the sandbox, rather than by switching between reading your docs and trying out code examples themselves. Nordic APIs explains the advantages of sandboxing, discusses the role of documentation in a sandboxed environment, and shows a possible implementation. To see a sandbox in action, try out the one on Dwolla’s developer site.


The study exploring how software developers interact with API documentation also explored how developers look for help. In a natural work environment, they usually turn to their colleagues first. Then, however, many of them tend to search the web for answers instead of consulting the official product documentation. This means you should ensure your API documentation is optimized for search engines and will turn up relevant results in search queries.

To make sure you have the necessary content available for self-support, include FAQs and a well-organized knowledge base. For quick help and human interaction, provide a contact form, and—if you have the capacity—a help-desk solution right from your docs, e.g., a live chat with support staff.

The study also pointed at the significant role Stack Overflow plays: most developers interviewed mentioned the site as a reliable source of self-help. You can also support your developers’ self-help efforts and sense of community by adding your own developer forum to your developer portal or by providing an IRC or Slack channel.


As with all software, APIs change and are regularly updated with new features, bug fixes, and performance improvements.

When a new version of your API comes out, you have to inform the developers working with your API about the changes so they can react to them accordingly. A changelog, also called release notes, includes information about current and previous versions, usually ordered by date and version number, along with associated changes.

If there are changes in a new version that can break old use of an API, put warnings on top of relevant changelogs, even on top of your release notes page. You can also bring attention to these changes by highlighting or marking them permanently.

To keep developers in the loop, offer an RSS feed or newsletter subscription where they can be notified of updates to your API.

Besides the practical aspect, a changelog also serves as a trust signal that the API and its documentation are actively maintained, and that the information included is up-to-date.

Analytics and feedback

You can do some research by getting to know your current and potential clients, talking to people at conferences, exploring your competition, and even conducting surveys. Still, you will have to go with a lot of assumptions when you first build your API docs.

When your docs are up, however, you can start collecting usage data and feedback to learn how you can improve them.

Find out about the most popular use cases through analytics. See which endpoints are used the most and make sure to prioritize them when working on your documentation. Get ideas for tutorials, and see which use cases you haven’t covered yet with a step-by-step walkthrough from developer community sites like Stack Overflow or your own developer forums. If a question regarding your API pops up on these channels and you see people actively discussing the topic, you should check if it’s something that you need to explain in your documentation.

Collect information from your support team. Why do your users contact them? Are there recurring questions that they can’t find answers for in the docs? Improve your documentation based on feedback from your support team and see if you have been successful: have users stopped asking the questions you answered?

Listen to feedback and evaluate how you could improve your docs based on them. Feedback can come through many different channels: workshops, trainings, blog posts and comments about your API, conferences, interviews with clients, or usability studies.


Readability is a measure of how easily a reader can understand a written text—it includes visual factors like the look of fonts, colors, and contrast, and contextual factors like the length of sentences, wording, and jargon. People consult documentation to learn something new or to solve a problem. Don’t make the process harder for them with text that is difficult to understand.

While generally you should aim for clarity and brevity from the get-go, there are some specific aspects you can work on to improve the readability of your API docs.

Audience: Expect that not all of your users will be developers and that even developers will have vastly different skills and background knowledge about your API and business domain. To cater to the different needs of different groups in your target audience, explain everything in detail, but provide ways for people already familiar with the functionality to quickly find what they are looking for, e.g., add a logically organized quick reference.

Wording: Explain everything as simply as you can. Use short sentences, and make sure to be consistent with labels, menu names, and other textual content. Include a clear, straightforward explanation for each call. Avoid jargon if possible, and if not, link to domain-related definitions the first time you use them. This way you can make sure that people unfamiliar with your business domain get the help they need to understand your API.

Fonts: Both the font size and the font type influence readability. Have short section titles and use title case to make it easier to scan them. For longer text, use sans serif fonts. In print, serif fonts make reading easier, but online, serif characters can blur together. Opt for fonts like Arial, Helvetica, Trebuchet, Lucida Sans, or Verdana, which was designed specifically for the web. Contrast plays an important role as well: the higher the contrast, the easier the text is to read. Consider using a slightly larger font size and different typeface for code than for text to help your users’ visual orientation when switching back and forth between their code editor and your documentation.

Structure: API documentation should cater to newcomers and returning visitors alike (e.g., developers debugging their implementation). A logical structure that is easy to navigate and that allows for quick reference works for both. Have a clear table of contents and an organized list of resources, and make sections, subsections, error cases, and display states directly linkable.

Great usability: Linkability demonstrated on Stripe’s API documentation.

Scannability: As Steve Krug claims in his book about web usability, Don’t Make Me Think, one of the most important facts about web users is that they don’t read, they scan. To make text easier to scan, use short paragraphs, highlight relevant keywords, and use lists where applicable.

Accessibility: Strive to make your API docs accessible to all users, including users who access your documentation through assistive technology (e.g., screen readers). Be aware that screen readers may often struggle with reading code and may handle navigation differently, so explore how screen readers read content. Learn more about web accessibility, study Web Content Accessibility Guidelines, and do your best to adhere to them.


You’ve worked hard to get to know your audience and follow best practices to leave a good impression with your API docs. Now, as a finishing touch, you can make sure your docs “sound” and look in tune with your brand.

Although API documentation and technical writing in general don’t provide much room for experimentation in tone and style, you can still instill some personality into your docs:

  • Use your brand book and make sure your API docs follow it to the letter.
  • A friendly tone and simple style can work wonders. Remember, people are here to learn about your API or solve a problem. Help them by talking to them in a natural manner that is easy to understand.
  • Add illustrations that help your readers understand any part of your API. Show how different parts relate to each other; visualize concepts and processes.
  • Select your examples carefully so that they reflect on your product the way you want them to. Playful implementations of your API will create a different impression than more serious or enterprise use cases. If your brand allows, you can even have some fun with examples (e.g., funny examples and variable names), but don’t go overboard.
  • You can insert some images (beyond illustrations) where applicable, but make sure they add something to your docs and don’t distract readers.
Think developer portal—and beyond

Although where you draw the line between API documentation and developer portal is still up for debate, most people working in technical communication seem to agree that a developer portal is an extension of API documentation. Originally, API documentation meant strictly the reference docs only, but then examples, tutorials, and guides for getting started became part of the package; yet we still called them API docs. As the market for developer communication grows, providers strive to extend the developer experience beyond API documentation to a full-fledged developer portal.

In fact, some of the ideas discussed above—like a developer forum or sandboxes—already point in the direction of building a developer portal. A developer portal is the next step in developer communication, where besides giving developers all the support they need, you start building a community. Developer portals can include support beyond docs, like a blog or videos. If it fits into the business model, they can also contain an app store where developers submit their implementations and the store provides a framework for them to manage the whole sales process. Portals connected to an API often also contain a separate area with landing pages and showcases where you can directly address other stakeholders, such as sales and marketing.

Even if you’re well into building your developer portal, you can still find ways to learn more and extend your reach. Attend and present at conferences like DevRelCon, Write The Docs or API The Docs to get involved in developer relations. Use social media: tweet, join group discussions, or send a newsletter. Explore the annual Stack Overflow Developer Survey to learn more about your main target audience. Organize code and documentation sprints, trainings, and workshops. Zapier has a great collection of blogs and other resources you can follow to keep up with the ever-changing API economy—you will surely find your own sources of inspiration as well.

I hope “The Ten Essentials for Good API Documentation” and this article gave you valuable insight into creating and improving your API documentation and inspire you to get started or keep going.

What the Failure of New Coke Can Teach Us About User Research And Design

Thu, 11/02/2017 - 06:46

In the late 1970s, Pepsi was running behind Coca-Cola in the competition to be the leading cola. But then Pepsi discovered that in blind taste tests, people actually preferred the sweeter taste of Pepsi. To spread the word, Pepsi ran a famous advertising campaign, called the Pepsi Challenge, which showed people tasting the two brands of cola while not knowing which was which. They chose Pepsi every time.

As Pepsi steadily gained market share in the early 1980s, Coca-Cola ran the same test and found the same result—people simply preferred Pepsi when tasting the two side by side. So, after conducting extensive market research, Coca-Cola’s solution was to create a sweeter version of its famous cola—New Coke. In taste tests, people preferred the new formula of Coke to both the regular Coke formula and to Pepsi.

Despite this success in tests, when the company brought New Coke to market, customers revolted. New Coke turned out to be one of the biggest blunders in marketing history. Within months, Coke returned its original formula—branded as “Coca-Cola Classic”—to the shelves.

In the end, sales showed that people preferred Coke Classic. But Coca-Cola’s research predicted just the opposite. So what went wrong?

The tests had people drink one or two sips of each cola in isolation and then decide which they preferred based on that. The problem is, that’s not how people drink cola in real life. We might have a can with a meal. And we almost never drink just one or two sips. User research is just as much about the way the research is conducted as it is about the product being researched.

For the purposes of designing and researching digital services and websites, the point is that people can behave differently in user research than they do in real life. We need to be conscious of the way we design and run user research sessions and the way we interpret the results to take real-life behavior into account—and avoid interpretations that lead to a lot of unnecessary work and a negative impact on the user experience.

To show how this applies to web design, I’d like to share three examples taken from a project I worked on. The project was for a government digital service that civil servants use to book and manage appointments. The service would replace a third-party booking system called BookingBug. We were concerned with three user needs:

  • booking an appointment;
  • viewing the day’s appointments;
  • and canceling an appointment.
Booking an appointment

We needed to give users a way to book an appointment, which consisted of selecting a location, an appointment type, and a person to see. The order of these fields matters: not all appointment types can be conducted at every location, and, not all personnel are trained to conduct every appointment type.

The first iteration of the booking journey, with three select boxes in one page.

Our initial design had three select boxes in one page. Selecting an option in the first select box would cause the values in the subsequent boxes to be updated, but because it was just a prototype we didn’t build this into the test. Users selected an option from each of the select boxes easily and quickly. But afterwards, we realized that the test didn’t really reflect how the interface would actually work.

In reality, the select boxes would need to be updated dynamically with AJAX, which would slow things down drastically and affect the overall experience. We would also need a way to indicate that something was loading—like a loading spinner. This feedback would also need to be perceivable to visually-impaired users relying on a screen reader.

That’s not all: each select box would need to have a submit button because submitting a form onchange is an inclusive design anti-pattern. This would also cover scenarios where there is a JavaScript failure, otherwise, users would be left with a broken interface. With that said, we weren’t thrilled with the idea of adding more submit buttons. One call to action is often simpler and clearer.

As mentioned earlier, the order in which users select options matters, because completing each step causes the subsequent steps to be updated. For production, if the user selected options in the wrong order, things could break. However, the prototype didn’t reflect this at all—users could select anything, in any order, and proceed regardless.

Users loved the prototype, but it wasn’t something we could actually give them in the end. To test this fairly and realistically, we would need to do a lot of extra work. What looked innocently like a simple prototype gave us misleading results.

Our next iteration followed the One Thing Per Page pattern; we split out each form field into a separate screen. There was no need for AJAX, and each page had a single submit button. This also stopped users from answering questions in the wrong order. As there was no longer a need for AJAX, the related accessibility considerations went away too.

The second iteration of the booking journey, with a separate page for each step.

This tested really well. The difference was that we knew the prototype was realistic, meaning users would get a similar experience when the feature went into production.

Viewing the day’s appointments

We needed to give users a way to view their schedule. We laid out the appointments in a table, where each row represented an appointment. Any available time was demarcated by the word “Available.” Appointments were linked, but available times were not.

The schedule page to view the day’s appointments.

In the first round of research, we asked users to look at the screen and give feedback. They told us what they liked, what they didn’t, and what they would change. Some participants told us they wanted their availability to stand out more. Others said they wanted color-coded appointment types. One participant even said the screen looked boring.

During the debrief, we realized they wanted color-coded appointments because BookingBug (to which they had become accustomed) had them. However, the reason BookingBug used color for appointments was that the system’s layout squeezed so much information into the screen that it was hard to garner any useful information from it otherwise.

We weren’t convinced that the feedback was valuable. Accommodating these changes would have meant breaking existing patterns, which was something we didn’t want to do without being sure.

We also weren’t happy about making availability more prominent, as this would make the appointments visually weaker. That is, fixing this problem could inadvertently end up creating another, equally weighted problem. We wanted to let the content do the work instead.

The real problem, we thought, was asking users their opinion first, instead of giving them tasks to complete. People can be resistant to change, and the questions we asked were about their opinion, not about how to accomplish what they need to do. Ask anyone their opinion and they’ll have one. Like the Coca-Cola and Pepsi taste tests, what people feel and say in user research can be quite different than how they behave in real life.

So we tested the same design again. But this time, we started each session by asking users questions that the schedule page should be able to answer. For example, we asked “Can you tell me when you’re next available?” and “What appointment do you have at 4 p.m.?”

Users looked at the screen and answered each question instantly. Only afterward did we ask users how they felt about it. Naturally, they were happy—and they made no comments that would require major changes. Somewhat amusingly, this time one participant said they wanted their availability to be less prominent because they didn’t want their manager seeing they had free time.

If we hadn’t changed our approach to research, we might have spent a lot of time designing something new that would have had no value for users.

Canceling an appointment

The last feature involved giving users a way to cancel an appointment. As we were transitioning away from using BookingBug, there was one situation where an appointment could have been booked in both BookingBug and the application—the details of which don’t really matter. What is important is that we asked users to confirm they understood what they needed to do.

The confirm cancellation page.

The first research session had five participants. One of those participants read the prompt but missed the checkbox and proceeded to submit the form. At that point, the user was taken to the next screen.

We might have been tempted to explore ways to make the checkbox more prominent, which in theory would reduce the chance of users missing it. But then again, the checkbox pattern was used across the service and had gone through many rounds of usability and accessibility testing—we knew that the visual design of the checkbox wasn’t at fault.

The problem was that the prototype didn’t have form validation. In production, users would see an error message, which would stop them from proceeding. We could have spent time adding form validation, but there is a balancing act between the speed in which you want to create a throwaway prototype and having that prototype give you accurate and useful results.


Coca-Cola wanted its world-famous cola to test better than Pepsi. As soon as tests showed that people preferred its new formula, Coca-Cola ran with it. But like the design of the schedule page, it wasn’t the product that was wrong, it was the research.

Although we weren’t in danger of making the marketing misstep of the century, the design of our tests could have influenced our interpretation of the results in such a way that it would have created a lot more work for a negative return. That’s a lot of wasted time and a lot of wasted money.

Time with users is precious: we should put as much effort and thought into the way we run research sessions as we do with designing the experience. That way users get the best experience and we avoid doing unnecessary work.

Web Typography: Designing Tables to be Read, Not Looked At

Tue, 10/31/2017 - 07:15

A note from the editors: We’re pleased to share an excerpt from Chapter 2 of Richard Rutter’s new book, Web Typography.

Good designers spend a great deal of time sweating over typography. They agonise over typefaces, iterate through type scales and meticulously apply white space, all in the service of the reader. Then comes along a table with the temptation to get creative, and all thoughts of the reader go out of the window. And yet tables are there to be read, referenced and used, not merely looked at.

Set tables as text to be read

Tables come in many forms. Some contain simple numbers, others are complex with mixtures of numeric data and textual information. Some require reading row by row, others are scanned vertically. The potential use for tables is as varied as the written word. They can be financial statements, bus timetables, multilanguage dictionaries, tables of contents, numerical conversions, pricing options, feature comparisons, technical specifications, and so on.

Despite the huge variation in table size, complexity, contents and purpose, every table shares two simple design principles: they should be readable and support a sense of the data held within. They should not be prettied up to satisfy a sense of aesthetic when simply looked at. That said, a well-designed table can still be a thing of beauty but with the form following the function. Tables are not pictures of data: they are catalogues of data to be perused, parsed, referenced and interrogated. A well-designed table will enable the information to be read and understood, and will reveal the patterns and correlations inherent in the data. As Jan Tschichold, the virtuoso of typography design, put it in Asymmetric Typography1:

Tabular matter need no longer be a rather unpleasant job to design: on the contrary, it can become a really charming and artistic exercise, in no way less interesting than any other area.

Wherever possible plan the readability of every table in advance. Your design process should be an investigation into making the data undemanding to read, simple to follow and easy to extract.

Just as you wouldn’t design body text with the aim of fitting as many words as possible on the screen, so you shouldn’t treat designing a table as an exercise in cramming as much data as possible into one space. You might be tempted to reduce the text size of your table – and if the data is entirely numeric you might be able to get away with it. Your reader should still be able to be comfortably read and interpret the table from their normal position, without needing to lean in.

Don’t stretch tables

Many designers will instinctively apply a width to their tables – just as they might an image – stretching them to fill the text column or page. And that is the appeal of setting tables full-width: you can make them look somewhat image-like when viewed from afar. However, while a table spread across the screen might look preferable from a distance, on closer inspection it will be harder to read as the data will be unnecessarily separated. To add insult to injury, tables set full-width are often replete with background colours and borders to give the table further the texture of an image, when what your reader really requires is the texture of text. For the sake of your readers, avoid these temptations.

You might consider making all the columns an even width. This too does nothing for the readability of the contents. Some table cells will be too wide, leaving the data lost and detached from its neighbours. Other table cells will be too narrow, cramping the data uncomfortably. Table columns should be sized according to the data they contain. Columns of small numbers should be narrow, and columns of paragraphs should be relatively wide. This sounds like a lot of effort, and for a print designer it would be, as they would have to size each column manually in their layout software. Fortunately, web browsers are very clever when it comes to laying out tables and will do all that hard work for you. Browsers have been laying out tables automatically according to complex algorithms since long before CSS came along – just let them do their thing.

Keep table furniture and fills to a minimum

The statistician and information designer Edward Tufte introduced the concept of data-ink in his 1983 classic, The Visual Display of Quantitative Information. He defines data-ink as ‘the non-erasable core of the graphic’, whereas non-data-ink is the ink used in the graphic, not to directly represent data but for scales, labels, fills and edges. Tufte goes on to define the data-ink ratio as the proportion of ink that is used to present actual data compared to the total amount of ink used in the entire graphic. The goal is to design a graphic with the highest possible data-ink ratio (tending towards 1.0) without eliminating what is necessary for effective communication.

Where Tufte talks about graphics he includes charts, diagrams and tables, and where he uses ‘ink’ we can think of pixels. In terms of tables, he’s saying that we should remove almost everything in the design which is not data or white space. Minimise furniture, maximise information. This is an ideal first principle to bear in mind when considering the typographic design of a table.

As a starting point, avoid any border or frame surrounding the table. This is a Victorian embellishment which is entirely unnecessary as text alignment will shape the table just fine.

Try to achieve a readable table using just alignment, spacing and grouping. Avoid zebra striping, tints and fills, and any other backgrounds. These can be superficially pretty but are usually a distraction. They serve to distort the meaning of the data by highlighting every other row to the detriment of neighbouring rows. Only use tints as a subtle means of guiding your reader’s eyes, and then only if you cannot arrange the data to that end. If you choose to tint, do so only in the primary direction of reading: down if lists, across otherwise.

When it comes to lines and borders between rows and columns – typographically referred to as rules – the same applies: use them judiciously and preferably not at all. In Asymmetric Typography Jan Tschichold sums this up wonderfully:

Tables should not be set to look like nets with every number enclosed. Try to do without rules altogether. They should be used only when they are absolutely necessary. Vertical rules are needed only when the space between columns is so narrow that mistakes will occur in reading without rules. Tables without vertical rules look better. Thin rules are better than thick ones.

Avoid using row or column borders unless the data alignment, spacing and grouping are not sufficient to guide your reader’s eye. If you do need to use rules for this purpose, use them in one direction only and employ a lighter colour to reduce the impact of the lines: you are making a distinction, not constructing a barricade.

Left-align text, right-align numbers, and align headings with data

In the spirit of treating tables as artefacts to be read, don’t centre text within tables. Align table text as you would anywhere else; that is, aligned left. As text in tables tends to end up in narrow columns, don’t justify the text either – leave it ragged-right – or you will end up with rivers flowing down the tables, potentially causing confusion and certainly harming readability. You can hyphenate, however, particularly if the table columns would otherwise have a pronounced rag.

Right-align numbers to help your reader make easier comparisons of magnitude when scanning down columns. To aid scanning in this manner you will need consistent precision of your numeric data; that is, use the same number of decimal places.

For consistency and ease of understanding, match the alignment of headings to the alignment of the data. Right-align headings of numeric data and left-align headings of columns with text, for example:


th.nums, td.nums { text-align: right; } Country Area Population GDP Capital Austria 83,858 8,169,929 339 Vienna Belgium 30,528 11,007,000 410 Brussels Denmark 43,094 5,564,219 271 Copenhagen France 547,030 66,104,000 2,181 Paris Germany 357,021 80,716,000 3,032 Berlin Greece 131,957 11,123,034 176 Athens Ireland 70,280 4,234,925 255 Dublin Italy 301,230 60,655,464 1,642 Rome Luxembourg 2,586 448,569 51 Luxembourg Netherlands 41,526 16,902,103 676 Amsterdam Portugal 91,568 10,409,995 179 Lisbon Spain 504,851 47,059,533 1,075 Madrid Sweden 449,964 9,090,113 447 Stockholm United Kingdom 244,820 65,110,000 2,727 London Align to the decimal point

You may find yourself not having control of numerical precision, or perhaps the data you’re working with is rounded to the same significant number rather than adhering to the same precision. In this case, simply right-aligning a column of numbers will not help your reader scan down the column – small, high-precision numbers will look at first glance like a large number. Instead, align numbers to the decimal point. This will enable your reader to more readily compare magnitudes among a wider variety of data:

+-------------+ | Call charge | +-------------+ | $1.30 | | $2.50 | | $10.80 | | $111.01 | | $85 | | N/A | | $.05 | | $.06 | +-------------+

Aligning to the decimal point was theoretically possible by using the HTML 4 char attribute on a <td> tag, but in reality it was never supported. The modern way to align numbers to a decimal point (or to any character, in fact) is through a new value of the text-align property, although at the time of writing this is languishing in the CSS Text Level 4 Module2 and support is patchy at best.

The syntax of the new value is simple. You include the alignment character (usually a full stop or comma) in quotes, followed by a space and your desired alignment keyword, which defaults to right if you omit it. For example, the following will centre the data and align to a decimal point as in our prior example:

td { text-align: "." center; }

By specifying different alignment characters you can lay out more complex tables in a useful way; in this example, aligning digits to ‘×’ and ‘:’.

Selected display standards Video standard Resolution Pixels Aspect QQVGA 160 × 120 19k 4 : 3 HQVGA 240 × 160 38k 3 : 2 QVGA 320 × 240 76k 4 : 3 WQVGA 480 × 272 130k 16 : 9 VGA 640 × 480 307k 4 : 3 SVGA 800 × 600 480k 4 : 3 XGA 1024 × 768 786k 4 : 3 HD 1260 × 768 967k 16 : 9 WXGA 1280 × 800 1,024k 16 : 10 SXGA 1280 × 1024 1,310k 5 : 4 UXGA 1600 × 1200 1,920k 4 : 3 FHD 1920 × 1080 2,073k 16 : 9 DCI 2K 2048 × 1080 2,211k 19 : 10 WQXGA 2560 × 1600 4,096k 16 : 10 4K UHD 3840 × 2160 8,294k 16 : 9 8K UHD 7680 × 4320 33,177k 16 : 9 Use tabular lining numerals in tables of numbers

Many tables, such as financial statements or timetables, are made up mostly of numbers. Generally speaking, their purpose is to provide the reader with numeric data, presented in either columns or rows, and sometimes in a matrix of the two. Your reader may use the table by scanning down the columns, either searching for a data point or by making comparisons between numbers. Your reader may also make sense of the data by simply glancing at the column or row. It is far easier to compare numbers if the ones, tens and hundreds are all lined up vertically; that is, all the digits should occupy exactly the same width.

Digits of the same width can inherently be found in monospaced fonts, and there is nothing wrong with choosing a suitable monospaced font to present a table of data (see ‘Combining typefaces’). However, many proportionally spaced fonts (those where a 1 is narrower than an 8, and a W is wider than an I) also come with additional sets of figures which are monospaced. These are called tabular numerals. As well as being of equal width, tabular numerals will be subtly designed differently from the standard proportional numerals. For example, a 1 will normally have a bar for its base, and a 0 (zero) may be designed slightly narrower to better fit the chosen number width. Tabular numerals are usually available in old-style and lining variations. Use tabular lining numerals to provide your reader with the most effective way to reference vertically and horizontally in tables of data.

Different numeral styles compared.

To specify tabular lining numerals, set the font-variant-numeric property with a value of lining-nums and tabular-nums:

table { font-variant-numeric: lining-nums tabular-nums; }

The equivalent properties for legacy browsers requiring font-feature-settings, use the lnum and tnum OpenType feature tags.

Proportional numerals

If you need to specify proportional numerals, set the font-variant-numeric property with a value of proportional-nums. For legacy browsers requiring font-feature-settings, use the pnum OpenType feature tag.

Put white space to work to group and separate

Having eliminated rules and fills (borders and backgrounds) from your table, you will need to apply white space to your table so your reader can make sense of it. It is at this point that you should remove from your mind’s eye all visions of spreadsheets and other such uniform grids, and think instead in terms of typography and simple gestalt grouping principles.

You will primarily need to separate the data so that each element can be individually identified and read as separate from the others. To have more control over the spacing, first collapse the spacing between borders:

table { border-collapse: collapse; }

In traditional HTML tables, adjacent cells each have their own distinct borders which are separated from each other, with the separation still present even if the borders are not. In the collapsed border model, adjacent table cells share borders. As we are removing (almost) all cell borders, and any we retain will be single key lines, the collapsed border model is the most appropriate.

Now apply padding to the table cells to separate the data. You’ll find that adding a smaller amount of padding to the top of the cell is a useful way to provide a visually balanced separation from the rows above and below. To ensure everything lines up nicely, apply the same padding to heading cells as to data cells. Because line lengths are often very short in tables, you can reduce the line height right down. In the following example, we’ve removed all additional line spacing, but you may need more depending on your choice of font and the amount of text in the table cells.

td, th { padding: 0.125em 0.5em 0.25em 0.5em; line-height: 1; }

The gestalt grouping principles most useful in tables are those of proximity and similarity. Move related data closer together to be distinct from other data; in other words, space apart groups of rows or columns. A by-product of grouping rows is that the data becomes much easier to scan and refer to than if the table consisted of a succession of undifferentiated rows. Ensure data of a similar content or meaning look similar at a glance, which you can do through alignment, colour and font style.

Table captions

We will attend to the typographic specifics of table captions in ‘Choosing typefaces for functional text’ but it’s worth noting now how to mark up captions for tables. If you are choosing to place your table inside a <figure> element, which is a perfectly reasonable thing to do, then use a <figcaption> element before or after the table. If your table is not inside a <figure> element, or you have multiple items in the figure, use the aptly named <caption> element, which HTML provides specifically for tables. Always write the <caption> tag immediately after the opening <table> tag and before any table data, like this:

<table> <caption> Imperial to metric conversion factors <p><i>Values are given to three significant figures</i></p> </caption> <thead> … </thead> <tbody> … </tbody> </table>

You can position the caption either above or below the table using the caption-side property and a corresponding value of either top or bottom.

caption { caption-side: bottom; }

The following table shows a caption and demonstrates gestalt grouping principles by separating the data into related rows:

Imperial to metric conversion factors

Values are given to three significant figures unless exact

To convert into multiply by Length inches millimetres (mm) 25.4 feet centimetres (cm) 30.48 yards metres (m) 0.91444 miles kilometres (km) 1.61 Area square inches sq. millimetres (mm²) 645 square feet square metres (m²) 0.0929 square yards square metres (m²) 0.836 acres hectares 2.47 Volume cubic inches millitres (ml) 16.4 cubic feet litres 28.3 imperial gallons litres 4.55 US barrels cubic metres (m³) 0.159

Note that, in this example, the numbers do not align to the decimal point. This is because the purpose of the table is for the reader to easily identify and extract a multiplication factor. In this instance there is no obvious use case for comparing the relative magnitudes of the factors, which is when decimal alignment would be useful.

Do not over-stylise tables

The French writer-aviator Antoine de Saint-Exupéry wrote3 perfection is attained not when there is nothing more to add, but when there is no longer anything to take away. Quoting de Saint-Exupéry may have become a cliché, but his idiom is entirely apt when applied to table design. There is no need to make a table look like a spreadsheet. A spreadsheet is a tool unto itself; a table is for presenting data and information that can be read. Spreadsheet software offers a multitude of options for table styles, which add text formatting, borders, background fills and all manner of ornament. They may make pretty pictures but do nothing for table readability, so do not try to emulate them. Tables can be beautiful but they are not works of art. Instead of painting and decorating them, design tables for your reader.

A typical spreadsheet-styled table set full-width with borders, fills and centred alignment. 1. Remove stretch and size columns to data. 2. Remove fills, gridlines, border and bolding. 3. Left-align text, right-align numbers and align headings with data. 4. Put white space to work to group and separate. 5. Use tabular lining numerals, consistent precision, and remove repetition. Adapt tables to small screens

Tables regularly require a fair bit of horizontal space to display the information they contain. Even when judiciously designed and edited, a typical table may need to be wider than the 45–75 characters we normally allow for paragraphs of text. For small screens, such as phones, designing readable tables which work under such cramped conditions presents us with a serious challenge. The best approaches always deal with each table on case-by-case basis, but that’s not always possible if we need to generically style whatever comes out of a CMS database.

One immediate approach is to use either a condensed font or a slightly smaller size (but not both smaller and condensed). In both cases, readability must remain paramount and other options should also be explored.

Consider setting oblique headings to save space

One way to save horizontal space, particularly when you have short pieces of data but long headings, is to set the headings at an oblique angle.

Using oblique headings to save space.

You can use a simple CSS translation to achieve the effect. You will also need to absolutely position the headings so the original width of the columns isn’t retained and they shrink to wrap the data instead.

th { transform-origin: bottom left; position: absolute; } th.degC { transform: translate(2.58em,-2em) rotate(-60deg); } th.degF { transform: translate(5.14em,-2em) rotate(-60deg); } Let the browser handle tables with horizontal scrolling

The simplest solution to help tables of any size and complexity is to let the browser lay out the table as best it can and render part of the table off-screen as necessary. Provided you then enable your reader to scroll the table sideways independently of the rest of the text, the table can be relatively easily brought into view.

Using a crawl bar to scroll a table into view.

To do this, first wrap your table in a <figure> element:

<figure class="fig-table"> <table> … </table> </figure>

Then apply the following simple rules to hide the portion of the table off-screen and enable your reader to scroll the table without affecting the rest of the text:

.fig-table { max-width: 100%; overflow-x: scroll; }

It is important not to set a width on your table; the browser can then compress the table as far as it can before overflowing off the screen. To preserve readability, make good use of non-breaking spaces and white-space:nowrap to limit the amount the data wraps in the cells. It’s better to have a readable table that requires scrolling than an unreadable one which doesn’t.

Linearise simple tables into lists

You can safely linearise simple data tables when space is limited. The tables most suitable for this treatment are lists of structured data; for example, an employee directory:

Name Email Title Phone Jones, Claire claire.jones​@domain.com Managing Director 01234 567890 Smith, Darren darren.smith​@domain.com Head of Sales 01234 567891

When there is not enough room for the table to render comfortably, we can set it with a completely different layout. This is less compact overall, and takes more space vertically, but it succeeds in fitting the table into a much narrower viewport:

Name: Jones, Claire Email: claire.jones@domain.com Title: Managing Director Phone: 01234 567890 Name: Smith, Darren Email: darren.smith@domain.com Title: Head of Sales Phone: 01234 567891

The two renderings of our employee directory table use exactly the same markup, comprising the conventional HTML elements you would expect in any table. The one addition is a data-title attribute on each cell enabling us to repeat the label in the list view, should we need to.

<th data-title="Name">Jones, Claire</th> <td data-title="Email">claire.jones@domain.com</td> <td data-title="Title">Managing Director</td> <td data-title="Phone">01234&nbsp;567890</td>

There are four simple steps to turning the table into a list, using a media query and CSS (no JavaScript is required).

  1. Identify the viewport width at which the table starts to render poorly.
  2. Apply display:block to all table-related elements so they align vertically instead of as a table.
  3. Hide the header row and any empty cells.
  4. Display labels for each data item (optional).

You will need to apply some additional styling for aesthetics and readability, but the responsiveness described can be accomplished in these few lines of CSS:

@media (max-width: 25em) { table, caption, tbody, tr, th, td { display: block; text-align: left; } thead, th:empty, td:empty { display: none; visibility: hidden; } th[data-title]:before, td[data-title]:before { content: attr(data-title) ": "; display: inline-block; width: 3.5em; } }

This technique was first popularised by Aaron Gustafson4.

Make tables responsive according to their purpose

There are many different techniques5 available for making data tables responsive. Some are simple CSS-only methods (we’ve covered two already); others are complex, enhanced by JavaScript. When considering which technique to use, ask yourself how your reader will use the table. In particular, consider if your reader is likely to compare either rows or columns – these kinds of tables need extra attention owing to the way they are used.

When being able to compare columns is important, one method is to hide non-essential fields and provide an option to turn them back on. This technique was popularised by Filament Group6 using a stocks table as an example:

A data-rich table as rendered on a large screen. The same table with hidden columns and options to toggle.

Tables are a frequently overlooked aspect of reading, sometimes overstyled, sometimes poorly thought out. Responsiveness is a particularly thorny issue as the best solutions depend very much on the utility of the table. Tables can be packed with data, rich in content and meaning. Give them the attention they deserve.

Want to read more?

This excerpt from Web Typography will help you get started. Order the full copy today.

  • 1. Asymmetric Typography by Jan Tschichold (1967, after 1935 original).
  • 2. Character-based Alignment in a Table Column (http://wbtyp.net/103) in the CSS Text Module Level 4.
  • 3. Terre des Hommes (translated into English as Wind, Sand and Stars) by Antoine de Saint-Exupéry (1939).
  • 4. ‘Responsive Tables’ (http://wbtyp.net/16) by Aaron Gustafson on Easy Designs blog (2013).
  • 5. See CSS-Tricks’ ‘Responsive Tables’ (http://wbtyp.net/148) for the latest options.
  • 6. Filament Group’s ‘Tablesaw’ (http://wbtyp.net/15) responsive table plug-ins.