A List Apart

  1. Feedback That Gives Focus

    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.

  2. Planning for Accessibility

    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.

    Cover from Accessibility for Everyone
  3. Ten Extras for Great API Documentation

    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).
    Screenshot: The homepage of Spotify's API documentation.
    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.

    Screenshot: Braintree's API overview page has an illustration showing how it works.
    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.


    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.
      Screenshot: A specific section of the Stripe API documents with the location bar showing that the URL has changed.
      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.

    Screenshot: When the cursor hovers over specific arguments in Stripe's API, a linked icon appears.
    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.

  4. What the Failure of New Coke Can Teach Us About User Research And Design

    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. 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.

    Screenshot of an app to book an appointment
    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.

    Screenshot showing an app to book appointments split across three screens
    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.

    Screenshot of an app view to display the day's appointments
    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 the booking system (to which they had become accustomed) had them. However, the reason they 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 the third-party system, there was one situation where an appointment could have been booked in both that system 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.

    Screenshot showing an app page to confirm a cancellation
    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.

  5. Web Typography: Designing Tables to be Read, Not Looked At

    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:


    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.

    A table 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:

        Imperial to metric conversion factors
        <p><i>Values are given to three significant figures</i></p>
        <thead> … </thead>
        <tbody> … </tbody>

    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.

    Initial badly designed table
    A typical spreadsheet-styled table set full-width with borders, fills and centred alignment.
    Table design progressed
    1. Remove stretch and size columns to data.
    Table design progressed
    2. Remove fills, gridlines, border and bolding.
    Table design progressed
    3. Left-align text, right-align numbers and align headings with data.
    Table design progressed
    4. Put white space to work to group and separate.
    Table design progressed
    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.

    A table showing Fahrenheit against Celsius with oblique headings.
    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.

    A table wider than a phone’s screen
    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>

    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:

    Table with 7 rows and 9 columns of stocks data
    A data-rich table as rendered on a large screen.
    Table with 7 rows, 2 columns of stocks data
    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.

    Cover of Web Typography


    • 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.
  6. Coding with Clarity

    Working code isn’t necessarily good code. Your code also needs to be easy to read, understand, and modify. It needs clarity, and to achieve that, it has to be organized well, with careful planning and proper separation of ideas taking place before you even open your code editor. Coding for clarity is something that separates the great developers from the merely good, and there are a few basic principles that can set you on that path.

    Note: Though the principles in this article are applicable to a variety of programming languages, most of the examples pull from object-oriented JavaScript. If you’re not familiar with this, A List Apart has articles on the module pattern and prototypal inheritance to help bring you up to speed.

    The single responsibility principle

    Imagine you’re working on a home project and you pick up a drill to drive a screw into a wall. When you pull the drill away from the screw, you discover that this drill has an interesting feature: it squirts a quick-drying drywall compound over the driven screw to hide it. Well, that’s great if you want to paint over the screw, but that’s not always the case. You shouldn’t have to get a second drill just to drill a hole in something. The drill would be much more usable and reliable if it just did one thing, and it would also be flexible enough to use in a variety of situations.

    The single responsibility principle states that a block of code should do one thing, and do it well. Like the drill above, limiting its functionality actually increases the usefulness of a block of code. Coding this way not only saves you a lot of headache, but it will save future developers on the project a lot of headache as well.

    Think of functions and methods in terms of responsibilities. As you increase its responsibilities, a block of code becomes less flexible and reliable, more demanding of changes, and more susceptible to errors. For the most clarity, each function or method should have one responsibility.

    If you’re describing what a function does and you have to use the word “and,” that function is probably too complex. What a function does should be simple enough to explain with only a descriptive function name and descriptive arguments.

    I was tasked recently with creating an electronic version of the Myers-Briggs personality test. I’d done this before, and when I first approached the problem a few years ago, I coded one giant function called processForm—it gathered the scores, generated the charts, and took care of everything in the DOM to display things to the user.

    The problem was that if anything had to change, you had to search through a mountain of code to figure out where to make the alteration. Also, if something went wrong in the middle of the function, it was a lot harder to find the error.

    So when facing the problem this time, I broke everything down into single-responsibility functions wrapped up in a module object instead. The resulting function called upon form submission looked like this:

    return {
        processForm: function() {

    (View complete app here)

    Extremely easy to read, understand, and modify—even a non-coder can make sense of this. And each of those functions does (you guessed it!) only one thing. This is the single responsibility principle in action.

    If I wanted to add form validation, rather than having to modify a giant working function (potentially breaking it), I could simply add a new method. This approach also enables related logic and variables to be segmented off, cutting down on conflicts for greater reliability, and it makes it very easy to reuse the function for other purposes if needed.

    So remember: one function, one responsibility. Large functions are where classes go to hide. If a function does lots of things that are closely tied together and that are working with the same data, it would make more sense to break it up into an object with methods, much like I did with my large form function.

    Command-query separation

    The funniest email chain I’ve ever seen was the series of Missing Missy posters from David Thorne about a missing cat. Each time his coworker Shannon makes a request, David complies, but puts his own little twist on it and delivers something different than what was expected. The exchange is very funny and worth a read, but it’s less funny when your code does the same thing.

    Command-query separation provides a basis of safeguarding your code against unintended side effects to avoid surprises when functions are called. Functions fall into one of two categories: commands, which perform an action, and queries, which answer a question. You should not mix them. Consider the following function:

    function getFirstName() {
        var firstName = document.querySelector("#firstName").value;
        firstName = firstName.toLowerCase();
        setCookie("firstName", firstName);
        if (firstName === null) {
            return "";
        return firstName;
    var activeFirstName = getFirstName();

    This is a simplistic example—most side effects are harder to find—but you can see some potentially unanticipated side effects in action.

    The function name, getFirstName, tells us that the function is going to return the first name. But the first thing it does is convert the name to lowercase. The name says it’s getting something (a query), but it’s also changing the state of the data (a command)—a side effect that is not clear from the function name.

    Worse, the function then sets a cookie for the first name without telling us, potentially overwriting something we could have been counting on. A query function should never, ever overwrite data.

    A good rule of thumb is that if your function answers a question, it should return a value and not alter the state of the data. Conversely, if your function does something, it should alter the state of the data and not return a value. For maximum clarity, a function should never return a value and alter the state of the data.

    A better version of the code above would be:

    function getFirstName() {
        var firstName = document.querySelector("#firstName").value;
        if (firstName === null) {
            return "";
        return firstName;
    setCookie("firstName", getFirstName().toLowerCase());

    This is a basic example, but hopefully you can see how this separation can clarify intent and prevent errors. As functions and code bases become larger, separation becomes much more important, as hunting for the function definition whenever you want to use it just to find out what it does is not an efficient use of anybody’s time.

    Loose coupling

    Consider the difference between a jigsaw puzzle and Lego blocks. With a jigsaw puzzle, there’s only one way to put the pieces together, and there’s only one finished product. With Lego, you can put the pieces together any way you want to make any end result you want. If you had to pick one of these types of building block to work with before you knew what you’d be building, which would you choose?

    Coupling is a measure of how much one program unit relies on others. Too much coupling (or tight coupling) is rigid and should be avoided. That’s the jigsaw puzzle. We want our code to be flexible, like Lego blocks. That’s loose coupling, and it generally results in much greater clarity.

    Remember, code should be flexible enough to cover a wide variety of use cases. If you find yourself copying and pasting code and making minor changes, or rewriting code because code changed somewhere else, this is tight coupling in action. (For example, to make the getFirstName function from earlier reusable, you could replace the hard-coded firstName with a generic ID passed to the function.) Other signs of this include hard-coded IDs in functions, too many function parameters, multiple similar functions, and large functions that violate the single responsibility principle.

    Tight coupling is most prevalent in a group of functions and variables that really should be a class instead, but it can also happen when classes depend on methods or properties from other classes. If you’re having trouble with interdependencies in functions, it’s probably time to think about breaking your functions into a class.

    I encountered this when looking at some code for a series of interactive dials. The dials had a number of variables, including dimensions, handle size, fulcrum size, and more. Because of this, the developer was forced to either use an absurd amount of function parameters or create multiple copies of each function with the variables hard-coded in each one. Additionally, each dial did something different when interacted with. This led to three sets of nearly identical functions—one for each dial. In short, coupling was increased due to the hard-coding of variables and behavior, so, like a jigsaw puzzle, there was only one way to put those pieces together. The codebase was unnecessarily complex.

    We solved the problem by breaking up the functions and variables into a reusable class that was instantiated for each of the three dials. We set up the class to take a function as an argument for output, so different outcomes could be configured when the individual dial objects were instantiated. As a result, we had fewer functions, and the variables were stored in only one place, making updates much easier.

    Classes that interact with each other can also be culprits of tight coupling. Let’s say we have a class that can create objects of another class, like a college course that can create students. Our CollegeCourse class works fine. But then we need to add a parameter to the constructor of the Student class. Oh no! Now we have to modify our CollegeCourse class to account for the change in the Student class.

    var CollegeCourse = (function() {
        function createStudent_WRONG(firstName, lastName, studentID) {
            If the Student constructor changes, we'll have to modify this method and all calls to it, too!
        function createStudent_RIGHT(optionsObject) {
            Passing an object as an argument allows the Student object to deal with the change. We may need to change this method, but we won’t need to change any existing calls to it.

    You shouldn’t have to modify a class because another class changes. This is a classic case of tight coupling. Constructor parameters can be passed as an object with the receiving object having fallback default values, which loosens coupling and means code won’t break when you add new parameters.

    The point is that you should build your code like Lego blocks, not like jigsaw puzzle pieces. If you find yourself facing problems similar to the ones above, the problem is probably tight coupling.

    High cohesion

    Have you ever seen a kid clean a room by stuffing everything into the closet? Sure, it works, but it’s impossible to find anything and things that don’t belong together often get placed right next to each other. The same can happen with our code if we don’t strive for a high level of cohesion.

    Cohesion is a measure of how much the various different program units belong together. A high level of cohesion is good and adds clarity to code blocks; a low level of cohesion is bad and leads to much confusion. Functions and methods in a code block should make sense together—they’ll have a high level of cohesion.

    High cohesion means sticking related things, like database functions or functions relating to a particular element, in one block or module. This helps not only with understanding how such things are laid out and where to find them, but also with preventing naming conflicts. If you have 30 functions, the chances of a conflicting name are far greater than if you have 30 methods split over four classes.

    If two or three functions use the same variables, they belong together; this is a great case for an object. If you have a series of functions and variables that control a page element, like a slider, it’s a great opportunity for high cohesion, so you should bundle them up into an object.

    Remember the example above about the class we made that decoupled the solution for the dial? That’s a great case of high cohesion as a cure for tight coupling. In that case, high cohesion and tight coupling were on opposite ends of a sliding scale, and focusing on one fixed the other.

    Repeated code is a sure sign of low cohesion. Similar lines of code should be broken into functions, and similar functions should be broken into classes. The rule of thumb here is that a line of code should never be repeated twice. In practice, this isn’t always possible, but for clarity’s sake you should always be thinking about how to cut down on repetition.

    Similarly, the same bit of data should not exist in more than one variable. If you’re defining the same bit of data in multiple places, you definitely need a class. Or if you find yourself passing references to the same HTML element to multiple functions, the reference should probably be a property in an instance of a class.

    Objects can even be put inside other objects to increase cohesion further. For example, you might put all AJAX functions in a single module that includes objects for form submission, grabbing content, and login syntax, like so:

    Ajax.Login.validateUser(username, password);

    Conversely, you shouldn’t throw unrelated things together in the same class. An agency I used to work for had an internal API with an object called Common that had a hodgepodge of common methods and variables that had nothing to do with each other. The class became huge and confusing simply because there was little thought given to cohesion.

    If properties are not used by multiple methods in a class, this can be a sign of low or bad cohesion. Similarly, if methods can’t be reused in a few different situations—or if a method isn’t used at all—this can also be a sign of low or bad cohesion.

    High cohesion helps to alleviate tight coupling, and tight coupling is a sign that greater cohesion is needed. If the two ever come into conflict, though, choose cohesion. High cohesion is generally a greater help to the developer than loose coupling, although both can usually be accomplished together.


    If our code is not immediately clear, problems occur. Achieving clarity is about so much more than proper indentation—it takes careful planning from the beginning of the project. While tough to master, abiding by the principles of single responsibility, command-query separation, loose coupling, and high cohesion can improve clarity in our code greatly. It should be a consideration in any significant programming project.

  7. The New CSS Layout, An Excerpt

    A note from the editors: We’re pleased to share an excerpt from Chapter 3 (“The New Layout”) of Rachel Andrew’s new book, The New CSS Layout, available now from A Book Apart.

    As we have seen, flexbox wasn’t designed for grid layouts—but this is where our newest specification is most at home. CSS Grid Layout does exactly what its name suggests: it enables the creation of grid layouts in CSS. This is two-dimensional layout—laying things out as a row and a column at the same time. We’ll go over many more examples of Grid Layout in the rest of this book, but let’s start by seeing how Grid can solve the problem we had with making flexbox display like a grid.

    In this example, I’m creating a three-column grid (Fig 3.17). My container has display: grid, and I’ve created three equal-width columns with the grid-template-columns property, plus a new unit created for Grid: a flexible-length unit known as fr. We’ll take a closer look at this unit in Chapter 5; for now, keep in mind that it represents a fraction of the space available in the grid container. With three tracks all set to 1fr each, the available space is divided into three and distributed equally. This is all we need to do to get the direct child of the container to display as a grid. Unlike with flexbox, we don’t need to add any rules to the children; they will just pop themselves into each cell of the grid.

    .cards {
    	margin: 0 -10px;
    	display: grid;
    	grid-template-columns: 1fr 1fr 1fr;

    Code example: http://bkaprt.com/ncl/03-14/

        Screenshot: A 3 column, 2 row grid with 5 card elements. Each element takes a single column and row cell, leaving an empty cell in the right-most column of the second row.

    Fig 3.17: The basic grid layout.

    As you can see, the items form a strict grid, without us needing to set any widths on them. We can solve another issue that we have with creating a flexbox grid, using properties that are part of the Grid specification. To create gaps between our flex items, in our flexbox example we used margins on the flex items and then needed to add a negative margin on the container to account for the unwanted left and right margin on the far left and right items. CSS Grid Layout includes a grid-gap property to space items out. This property is shorthand for grid-column-gap and grid-row-gap, which can also be specified individually.

    To demonstrate how this works, I’ve removed the margins on the items and the negative margin on the container and spaced the items out with grid-gap. You’ll produce the exact same layout as above in the browser, but without the need to mess around with margins and negative margins.

    .cards {
    	display: grid;
    	grid-template-columns: 1fr 1fr 1fr;
    	grid-gap: 20px;

    Code example: http://bkaprt.com/ncl/03-15/

    Just as this book was going to print, the CSS Working Group resolved to change the name of the grid-gap properties. grid-column-gap will become column-gap, grid-row-gap will become row-gap, and the grid-gap shorthand will simply be gap. In addition, the definition of these properties has been moved to the Box Alignment Specification. This means that in the future, flexbox may also support gaps in the same way as Grid.

    Because browsers have already shipped these properties, they will alias the grid-* names to the new names for the foreseeable future. At time of writing, no browser supports the new property names, so I’ve retained the grid-* versions in these examples. If you want to be sure of supporting both versions, there’s no reason not to list both in your CSS, as in this example:

    .cards {
    	display: grid;
    	grid-template-columns: 1fr 1fr 1fr;
    	grid-gap: 20px;
    	gap: 20px;

    Positioning items around the grid

    We can quickly move away from what flexbox allows us to do by taking advantage of our two-dimensional grid and positioning items on it. The most basic way of doing this is by using line numbers. A grid has numbered grid lines; they start from 1 for both rows and columns. Note that these lines are numbered per the writing mode of the document. Working in English, a left-to-right (LTR) language, column line 1 is on the left-hand side of the grid; row line 1 is at the top. In Arabic, a right-to-left (RTL) language, column line 1 appears on the right of the grid. The far edge of the grid (right in a LTR language and left in a RTL language) is represented by -1.

    .cards {
    	display: grid;
    	grid-template-columns: 1fr 1fr 1fr;
    	grid-gap: 20px;
    .card1 {
    	grid-column: 1 / 3;
    	grid-row: 1;
    .card2 {
    	grid-column: 3;
    	grid-row: 1;
    .card3 {
    	grid-column: 1;
    	grid-row: 2 / 4;
    .card4 {
    	grid-column: 2 / 4;
    	grid-row: 2;
    .card5 {
    	grid-column: 2 / 4;
    	grid-row: 3;

    Code example: http://bkaprt.com/ncl/03-16/

        Screenshot: The 3 column, 2 row grid has now become a 3 column, 3 row grid, still with 5 card elements. Card 1 spans the first 2 columns of the first row. Card 2 is in the third column of the first row. Card 3 spans the second and third row of the leftmost column. Card 4 spans the second and third column of the second row, and card 5 spans the second and third column of the third row.

    Fig 3.18: Cards placed on the grid by line number.

    You can immediately see some of the power of Grid Layout here. We can span columns and rows—something that is hard to do using existing layout methods. The background color of our cards extends to the gutter, even if the content is shorter. It’s also very easy to change how far a block spans—we can even leave white space! If I change the start line of card 3 to row line 3, we get an empty cell (Fig 3.19). Nothing can rise and land in the grid cell; this differs from the behavior of floats, which try to float up and fill the available space.

        Screenshot: The 3 by 3 grid remains similar to figure 3.18. Card 3 no longer spans the second and third row. Instead it is placed in the first column of the third row, leaving a blank space in the first column of the second row.

    Fig 3.19: White space made easy with CSS Grid Layout.

    Another method of positioning items on a grid involves using named areas. This allows you to describe your layout right in your CSS. To do this with our example, we first give each card a name with the grid-area property. I’m just using letters a through e.

    .card1 { grid-area: a; }
    .card2 { grid-area: b; }
    .card3 { grid-area: c; }
    .card4 { grid-area: d; }
    .card5 { grid-area: e; }

    Next, I add the grid-template-areas property to the container. The value of this property describes what our layout should look like (Fig 3.20).

    .cards {
    	display: grid;
    	grid-template-columns: 1fr 1fr 1fr;
    	grid-gap: 20px;
    		"a a b"
    		"c d d"
    		"c e e";

    Code example: http://bkaprt.com/ncl/03-17/

        Screenshot: This grid layout is identical to the 3 by 3 grid from figure 3.18. Cards 1-5 are now represented by named areas a, b, c, d, and e in the same order.

    Fig 3.20: The value of grid-template-areas shows visually what our layout looks like.

    There are a few things to keep in mind with grid-template-areas. To span across cells, we repeat the name of the area. Card 1 spans across the first two column tracks; thus a is repeated. The areas must be rectangular in nature—we can’t yet create an L-shaped area.

    To leave white space, and to leave a cell empty, use a full-stop character. If you replace the first c with ., that cell will remain empty when the layout is created (Fig 3.21).

    .cards {
    	display: grid;
    	grid-template-columns: 1fr 1fr 1fr;
    	grid-gap: 20px;
    		"a a b"
    		". d d"
    		"c e e";
        Screenshot: This grid layout is identical to the 3 by 3 grid from figure 3.19. Cards 1-5 are now represented by named areas a, b, c, d, and e in the same order. Card 3 (named c) no longer spans the second and third row, but instead only sits in the first column of the third row, leaving a blank space (represented by a full stop in the grid-template-areas) in the first column of the second row.

    Fig 3.21: We now have white space left in our layout.

    If your grid-area names are longer than one character, you may want to line up the visual rows and columns in the value of grid-template-areas. This is possible because more than one full-stop character can denote an empty cell—if they have no white space between them. You can also add more than one white-space character to space out grid-area names.

    This is a very nice way to work with layouts, given how easy it is to move items around. I enjoy working like this during the prototyping stage—rather than worrying about how to achieve layout, I can figure out the best way for my interface to be presented. Then I can go back to the markup to make sure it’s in a logical order based on those decisions.

    With these few examples, you already have enough knowledge to start using Grid Layout, and to make decisions about which layout methods to use. There is more to come, but keep in mind that although the specification is large and can do a lot of things, it is very simple at its core. You can do a lot with very little CSS. As you start building layouts, you will have questions, and will want to achieve more with these layout methods. That’s where the rest of this book comes in!


  8. The Story of CSS Grid, from Its Creators

    A note from the editors: We want to thank the Microsoft Edge team for sharing transcripts of the interviews they conducted with many of the brilliant people who have contributed to the development of CSS Grid. Those transcripts proved invaluable in compiling this history. You can watch the short video they produced from those interviews, Creating CSS Grid, on Channel 9.

    On October 17th, Microsoft’s Edge browser shipped its implementation of CSS Grid. This is a milestone for a number of reasons. First, it means that all major browsers now support this incredible layout tool. Second, it means that all major browsers rolled out their implementations in a single year(!), a terrific example of standards success and cross-browser collaboration. But third, and perhaps most interestingly, it closes the loop on a process that has been more than 20 years in the making.

    Not a new idea

    While the modern concept of a “grid layout” has been with us since the Industrial Revolution, grids have been a design tool for centuries. As such, it shouldn’t come as a shock that grid-based layouts have been a goal of CSS since the beginning.

    According to Dr. Bert Bos, who co-created CSS with Håkon Wium Lie, grid-based layouts have actually been on his mind for quite some time.

    “CSS started as something very simple,” Bos recalled. “It was just a way to create a view of a document on a very simple small screen at the time. Twenty years ago, screens were very small. So, when we saw that we could make a style sheet for documents, we thought, Well, what else can we do now that we have a system for making style sheets?

    Looking at what books and magazines were doing with layout was a great inspiration for them.

    “Independent of the content on every page, it has a certain layout,” Bos said. “Page numbers are in certain places. And images are always aligned to the certain sides—left or right or in the middle. We wanted to capture that.”

    Early on, browser makers wrote off the idea as “too complex” to implement, but grid layout concepts kept cropping up. In 1996, Bos, Lie, and Dave Raggett came up with a “frame-based” layout model. Then, in 2005, Bos released the Advanced Layout Module, which later turned into the Template Layout Module. Despite enthusiasm for these concepts from the web design community, none of them ever shipped in a browser.

    Once more, with feeling

    With grid concepts being thrown at the wall of the CSS Working Group with some regularity, folks were hopeful one of them would stick eventually. And the idea that did was a proposal from a couple of folks at Microsoft who had been looking for a more robust layout tool for one of their web-based products.

    Phil Cupp had been put in charge of the UI team tasked with reimagining Microsoft Intune, a computer management utility. Cupp was a big fan of Silverlight, a browser plug-in that sported robust layout tools from Windows Presentation Foundation, and initially had planned to go that route for building the new Intune. As it happened, however, Microsoft was in the planning stages of Windows 8 and were going to enable building apps with web technologies. Upon learning this, Cupp wanted to follow suit with Intune, but he quickly realized that the web was in desperate need of better layout options.

    He joined a new team so he could focus on bringing some of the rich layout options that existed in Silverlight—like grid layout—to the web. Interestingly, folks on this new team were already noticing the need. At the time, many app developers were focusing on iPhones and iPads, which only required designers to consider two different fixed canvas sizes (four, if you consider portrait and landscape). Windows had to support a ton of different screen sizes, screen resolutions, and form factors. Oh, and resizable windows. In short, Microsoft needed a robust and flexible layout tool for the web desperately if the web was going to be an option for native app development on Windows.

    After working extensively with various teams within Microsoft to assemble a draft specification, Cupp and his team shipped a grid layout implementation behind the -ms- vendor prefix in Internet Explorer 10 in 2011. They followed that up with a draft Grid Layout spec, which they presented to the W3C in 2012.

    Of course, this was not the first—or even the third—time the W3C had received a grid layout spec to consider. What was different this time, however, was that they also had an actual implementation to evaluate and critique. Also, we, as developers, finally had something we could noodle around with. Grid layout was no longer just a theoretical possibility.

    A handful of forward-thinking web designers and developers—Rachel Andrew, an Invited Expert to the W3C, chiefly among them—began to tinker.

    “I came across CSS Grid initially at a workshop that Bert Bos was leading in French. And I don’t really speak French, but I was watching the slides and trying to follow along,” Andrew recalled. “I saw him demonstrate … the Template Layout spec. I think he was really talking about it in terms of print and using this stuff to create print layouts, but as soon as I saw that, I was like, No, we want this for the web. This is something that we really need and its feasibility to properly lay things out. And so I started digging into it, and finding out what he was doing, and building some examples.”

    “Then I saw the Microsoft implementation [of the draft Grid Layout spec], which gave me a real implementation that I could build examples to show other people. And I wanted to do that—not just because it was interesting, and I like interesting things to play with—it was because I wanted to get it out there and get other people to have a look at it. Because I’ve been doing this for a long time and I know that specs often show up, and then no one really talks about them, and they kinda disappear again. And I was absolutely determined that Grid Layout wasn’t gonna disappear, it was gonna be something that other people found out about and got excited about it. And hopefully we’d actually get it into browsers and be able to use it.”

    The spec evolves

    The draft spec that Cupp presented to the W3C, and that his team shipped in IE10, is not the Grid Layout spec we have today. It was a step in the right direction, but it was far from perfect.

    “The one [Phil Cupp submitted] was a very track-based system,” recalled Elika Etemad, an Invited Expert to the W3C and an Editor of the CSS Grid Layout Module. “There was only a numeric addressing system, there were no line names, there [were] no templates, none of that stuff. But it had a layout algorithm that they … were confident would work because they had been doing experimental implementations of it.”

    “The original grid that Bert [Bos] came up with … was really the reason I joined the CSS Working Group,” recalled Google’s Tab Atkins, another Editor of the CSS Grid Layout Module. “At the time, I was learning all the terrible layout hacks and seeing the possibility to just write my page layout in CSS and just have it all, kinda, work was astonishing. And then seeing the draft from Phil Cupp … and seeing it all laid out properly and with a good algorithm behind it, I knew that it was something that could actually exist now.”

    It was also a compelling option because, unlike previous proposals, which specified rigid layouts, this proposal was for a responsive grid system.

    “You can [be] explicit about the size of a grid item,” Etemad explained. “But you can also say, Be the size that your content takes up. And that was what we needed to move forward.”

    However, the draft spec wasn’t as approachable as many on the CSS Working Group wanted it to be. So the group looked to bring in ideas from some of its earlier explorations.

    “What we really liked about Bert [Bos]’s proposal was that it had this very elegant interface to it that made it easy to express layouts in a way that you can intuitively see,” Etemad said. “It’s like an ASCII art format to create a template, and you could put [it] in your code, like the width of the columns and the heights of the rows. You could embed those into the same kind of like ASCII diagram, which made it a lot easier to see what you were doing.”

    Peter Linss, then Co-Chair of the CSS Working Group, also suggested that they incorporate the concept of grid lines in the spec (instead of only talking about tracks). He believed including this familiar graphic design concept would make the spec more accessible to designers.

    “When we were thinking initially about CSS Grid, we were thinking about it in a very app-centric model,” recalled Microsoft’s Rossen Atanassov, who is also an Editor on the spec. “But grid is nothing new. I mean, grid’s been here for a very long time. And that traditional type of grid has always been based on lines. And we’d been kind of ignoring the lines. When we realized that we could marry the two implementations—the app side and the typography side of the Grid—this for me, personally, was one of those aha moments that really inspired me to continue working on Grid.”

    So the CSS Working Group began tweaking Microsoft’s proposal to incorporate these ideas. The final result allows you to think about Grid systems in terms of tracks or lines or templates or even all three at once.

    Of course, getting there wasn’t easy.

    Refine, repeat

    As you can probably imagine, reconciling three different ideas—Microsoft’s proposal, Bos’ Advanced Layout, and Linss’ addition of grid lines—wasn’t a simple cut and paste; there were a lot of tricky aspects and edge cases that needed to be worked out.

    “I think some of the tricky things at the beginning [were] taking all the different aspects of … the three proposals that we were trying to combine and coming up with a system that was coherent enough to gracefully accept all of that input,” Etemad said.

    Some ideas just weren’t feasible for phase one of a CSS grid. Bos’ concept, for instance, allowed for any arbitrary descendent of the grid to lay out as though it were a child element of the grid. That is a feature often referred to as “subgrid” and it didn’t make the cut for CSS Grid Layout 1.0.

    “Subgrid has been one of those things that was pointed out immediately,” Atanassov said. “And that has been a blessing and kind of a hurdle along the way. It was … one that held back the spec work for quite a bit. And it was also one that was scaring away some of the implementers. … But it’s also one of the features that I’m … most excited about going forward. And I know that we’re gonna solve it and it’s gonna be great. It’s just gonna take a little while longer.”

    Similarly, there were two options for handling content mapped to grid lines. On the one hand, you could let the grid itself have fixed-dimension tracks and adjust which ending grid line the overflowing content mapped to, based on how much it overflowed. Alternately, you could let the track grow to contain the content so it ended at the predefined grid line. Having both was not an option as it could create a circular dependency, so the group decided to put the grid-snapping idea on hold.

    Ultimately, many of these edits and punts were made in light of the CSS Working Group’s three primary goals for this spec. It needed to be:

    1. Powerful: They wanted CSS Grid to enable designers to express their desires in a way that “made simple things easy and complex things possible,” as Etemad put it;
    2. Robust: They wanted to ensure there would not be gaps that could cause your layout to fall apart, inhibit scrolling, or cause content to disappear accidentally;
    3. and Performant: If the algorithm wasn’t fast enough to elegantly handle real-world situations like browser resize events and dynamic content loading, they knew it would create a frustrating experience for end users.

    “[T]his is why designing a new layout system for CSS takes a lot of time,” Etemad said. “It takes a lot of time, a lot of effort, and a lot of love from the people who are working on it.”

    Where the rubber meets the road

    Before a Candidate Recommendation (aka, a final draft) can become a Proposed Recommendation (what we colloquially refer to as a “standard”), the W3C needs to see at least two independent, interoperable implementations. Microsoft had implemented their draft proposal, but the spec had changed a lot since then. On top of that, they wanted to see other browsers take up the torch before they committed more engineering effort to update it. Why? Well, they were a little gun-shy after what happened with another promising layout proposal: CSS Regions.

    CSS Regions offered a way to flow content through a series of predefined “regions” on a page, enabling really complex layouts. Microsoft released an implementation of CSS Regions early on, behind a prefix in IE 10. A patch landed support for Regions in WebKit as well. Safari shipped it, as did Chrome (which was still running WebKit under the hood at the time). But then Google backed it out of Chrome. Firefox opposed the spec and never implemented it. So the idea is currently in limbo. Even Safari will drop its experimental support for CSS Regions in its next release. Suffice it to say, Microsoft wanted to be sure Grid wouldn’t suffer the same fate as Regions before committing more engineering resources to it.

    “We had implementers that immediately said, ‘Wow, this is great, we should definitely do it,’” recalled Atanassov of Grid. “But [it’s] one thing … saying, ‘Yeah this is great, we should do it,’ and then there’s the next step where it’s adding resources and paying developers to go and actually implement it.”

    “There was desire from other implementers—one of the spec editors is from Google—but there was still hesitancy to actually push code,” recalled Microsoft’s Greg Whitworth, a member of the CSS Working Group. “And … shipping code is what matters.”

    In an interesting turn of events, the media company Bloomberg hired Igalia, an open source consultancy, to implement CSS Grid for both Blink and WebKit.

    “Back in 2013 … [we] were contacted by [Bloomberg] … because they had very specific needs regarding defining and using grid-like structures,” recalled Sergio Villar Senin, both a software engineer at and partner in Igalia. “[T]hey basically asked us to help in the development of the CSS Grid layout specification, and also [to] implement it for [Blink and WebKit].”

    “[Igalia’s work] helped tremendously because then developers [could] see it as possibly something that they can actually use when developing their sites,” Whitworth added.
    But even with two ready-made implementations, some folks were still concerned the feature wouldn’t find its footing. After all, just because a rendering engine is open source doesn’t mean its stewards accept every patch. And even if they do, as happened with CSS Regions, there’s no guarantee the feature will stick around. Thankfully, a good number of designers and developers were starting to get excited about Grid and began to put pressure on browser vendors to implement it.

    “There was a pivotal shift with CSS Grid,” Whitworth said. “Starting with Rachel Andrew coming in and creating a ton of demos and excitement around CSS Grid with Grid by Example and starting to really champion it and show it to web developers and what it was capable of and the problems that it solves.”

    “Then, a little bit later, Jen Simmons [a Designer Advocate at Mozilla] created something called Labs where she put a lot of demos that she created for CSS Grid up on the web and, again, continued that momentum and that wave of enthusiasm for CSS Grid with web developers in the community.”

    Grid facilitates both traditional and (as shown here) non-traditional layouts. This is a Grid Layout example from Jen Simmons’ Labs, as seen in Edge 16. If you’d like to see it working in Edge but don’t run Windows, you can also view it in BrowserStack (account required).

    With thought leaders like Andrews and Simmons actively demonstrating the power and versatility of CSS Grid, the web design community grew more excited. They began to experiment on sites like CodePen, sharing their ideas and developing their Grid layout skills. We don’t often think about it, but developer enthusiasm has the power to bolster or bury a spec.

    “We can write a spec, we can go implement things, but if there isn’t developer demand or usage of the features, it doesn’t really matter how much we do with that,” Whitworth said.

    Unfortunately, with ambitious specs like Grid, the implementation cost can often deter a browser vendor from making the commitment. Without a browser implementation enabling developers to tinker and experiment, it’s hard to build enthusiasm. Without developer enthusiasm, browser vendors are reluctant to spend the money to see if the idea gains traction. I’m sure you can see the problem here. In fact, this is partly what has doomed Regions—performance on mobile chipsets was another cited reason—at least for now.

    Thankfully, Bloomberg willingly played the role of benefactor and got the ball rolling for this new incarnation of CSS Grid. So, with its help, Google landed an implementation of CSS Grid in Chromium 56 for Android in January of 2017. It landed its Chrome implementation in early March, just two days after Mozilla shipped its own implementation in Firefox. Before the month was over, Opera and Safari had also shipped support for CSS Grid.

    Ironically, the last company to ship CSS Grid was Microsoft. But it released its implementation in Edge earlier this week.

    “With features on the web platform … you’re waiting for a sweet spot,” Whitworth said, just prior to Grid’s release in Edge. “You want a solid spec, you want implementer interest, and you want tons of demand from web developers. Late 2016/early 2017 was that sweet spot. All of that happened. We upgraded our implementation and are stoked to ship it.”

    “I don’t recall a feature ever shipping like CSS Grid has shipped. Every major browser will have shipped it within a matter of a single year, and it will be interoperable because we’ve been… implementing [it] behind flags, testing it, making future changes behind flags, and then when it was deemed stable, all the browsers are now shipping it natively.”

    “With everybody shipping at approximately the same time,” Atkins said, “[Grid] goes from an interesting idea you can play with to something that you just use as your only layout method without having to worry about fallbacks incredibly quickly. … [It’s been] faster than I expected any of this to work out.”

    What Grid means for CSS

    With Grid support no longer in question, we can (and should) begin to make use of this amazing tool. One of the challenges for many of us old timers who have been working with CSS for the better part of two decades, is that CSS Grid requires a whole new way of thinking about layout.

    “It’s not just attaching your margins and properties to each individual element and placing them,” Bos said. “[Y]ou can now have a different model, a model where you start with your layout first and then pull in the different elements into that layout.”

    “It is the most powerful layout tool that we have invented yet for CSS,” Atkins said. “It makes page layouts so ridiculously easy. … [P]eople have always been asking for better layouts. Just for author-ability reasons and because the hacks that we were employing weren’t as powerful as the old methods of just put[ting] it all in a big old table element—that was popular for a reason; it let you do powerful complex layouts. It was just the worst thing to maintain and the worst thing for semantics. And Grid gives you back that power and a lot more, which is kind of amazing.”

    “CSS Grid takes all of that complicated stuff that we had to do to [achieve] basic layouts and makes it completely unnecessary,” Etemad said. “You can talk to the CSS engine directly[—]you, yourself, without an intermediary translator.”

    CSS Grid offers a lot of power that many of us are only just starting to come to grips with. It will be interesting to see where we go from here.

    “I think it’s going to be transformative,” Etemad said. “It’s going to take CSS back to what it was meant to be, which is styling and layout language that lifts all of that logic away from the markup and allows that clean separation of content and style that we’ve been trying to get from the beginning.”

    “I’m excited about the future of CSS layout,” Whitworth said. “CSS Grid is not the end; it’s actually just the beginning. In IE 10 … [we shipped] CSS Regions as well as CSS Exclusions. I think as web designers begin to utilize CSS Grid more and more, they’ll realize why we shipped all three together. And maybe we can continue what we did with CSS Grid and continue to improve upon those specifications. Get vendor desire to implement those as well. Get the community excited about them and push layout on the web even further.”

    “I think that now we have Grid, Exclusions makes absolute sense to have,” Andrew said. “It gives us a way to place something in [a grid] and wrap text around it, and we don’t have any other way to do that. … And then things like Regions … I would love to see that progress because … once we can build a nice grid structure, we might want to flow content through it. We don’t have a way of doing that.”

    “[A]s far as I’m concerned, this doesn’t stop here; this is just the start.”

    Getting into Grid

  9. Web Typography: Numerals

    A note from the editors: We’re pleased to share an excerpt from Chapter 2 of Richard Rutter’s new book, Web Typography.

    When it comes to numbers we have just ten digits. Throw in a comma and a period and we’ve got grand total of twelve characters. You might not think that would present much of a challenge to a typographer, but to a professional typesetter (that’s you if you’re a designer) numerals require far more nuance and variation than you might think at first glance. Numbers deserve the same care and attention as text - this excerpt reveals the numerical situations you should be looking out for, and how to tackle them to benefit your reader.

    Use old-style numerals in running text

    In ‘Ligatures and abbreviations’ we established that writing systems based on the Latin alphabet, in addition to Greek and Cyrillic, use a bicameral script, with each letter represented by two different forms – uppercase and lower (or majuscule and minuscule, to use more formal terms). The same is true of numerals. We have at our disposal ‘uppercase’ numbers 0123456789 called lining or titling numerals, and ‘lowercase’ numerals 0123456789 called old-style or text numerals.

    Unlike capital and lowercase letters, different forms of numbers do not convey different meanings; they are, however, an essential component of the typographer’s palette. Just as a string of capital letters in the middle of a sentence SHOUTS at your reader, so numbers set in lining numerals call undue attention to themselves. Are pounds, dollars, dates and quotas really more important than the words and ideas which give them context and meaning?

    Treat numbers as you would letters, making sure they don’t stand out unnecessarily. Do this by using old-style numerals in all your running text. Most modern, professional fonts will include both old-style and lining numerals as OpenType features. One or other of these styles will be used for the default numbers. More often it will be the old-style numerals, but there is no strict rule or consistency, and the choice of default is down to the type designer.

    It’s also the case that the vast majority of fonts are neither modern nor professional, if modern means OpenType-enabled and professional means designed with both sets of numerals. Take Georgia, for example. Designed by Matthew Carter in 1993 as a screen font for Microsoft, it is extremely well put together, elegant and appealing, and one of the most popular and widely distributed fonts in the world. But it is not packaged as an OpenType font and so only contains one set of numbers, in this case old-style numerals. Times New Roman, which is similarly widespread but, again, not as an OpenType font, is packaged only with lining numerals. Georgia and Times New Roman are so widely distributed because they are bundled free of charge with Windows and Mac operating systems. However, both these fonts – like many others – are available to buy in professional versions, which do come as OpenType fonts complete with both sets of numerals, small caps and many other features.

    Graphic showing numerals in Times New Roman and Georgia
    Top: Numerals in Times New Roman Pro.
    Bottom: Numerals in Georgia Pro.

    To specify old-style numerals, set the font-variant-numeric property with a value of oldstyle-nums. If most of what you’re designing on a page is running text, then your best approach is to set old-style numerals so that they are inherited from the <body>.

    body {
        font-variant-numeric: oldstyle-nums;

    For legacy browsers requiring font-feature-settings, use the onum OpenType feature tag. As explained in ‘Ligatures and abbreviations’, you can add an @supports rule to cater for legacy browsers that only support font-feature-settings:

    body {
        font-feature-settings: "onum" 1;
    @supports (font-variant-numeric: oldstyle-nums) {
        body {
            font-feature-settings: normal;
            font-variant-numeric: oldstyle-nums;

    Many sans serif fonts of the early to mid-twentieth century, including Helvetica, were never designed with anything other than lining numerals. This is one of the reasons why Helvetica is rarely your best choice for body text. That said, the lining numerals are less of a problem in Helvetica than they are in some other typefaces. As we saw in ‘Designing paragraphs: line spacing’, Helvetica has a large x-height. A consequence of this is that its lowercase letters are closer in stature to its lining numerals when compared to other sans serif fonts such as Futura and Avenir, which have far smaller x-heights.

    Graphic showing two styles of numerals in Avenir

    Compared with old-style numerals, lining numerals shout loudly in Avenir.

    Clearly Paul Renner and Adrian Frutiger, the designers of Futura and Avenir respectively, recognised the need for old-style numerals in their fonts as both these typefaces were designed with them from the start. Sadly, the versions of Futura and Avenir widely distributed with Apple devices have lining numerals as the default, and do not include old-style numerals as OpenType features (the macOS version of Avenir Next, however, does include them).

    Use lining numerals in headings

    Old-style numerals are your go-to glyphs for making numbers sit well in running text. For the same reason they are at ease with lowercase letters, so old-style numerals feel uncomfortable in close proximity to capital letters. If you set headings in anything other than sentence case, in particular ALL CAPS, or Title Case, then don’t use old-style numerals. Lining numerals will sit far more naturally in the company of uppercase letterforms.

    Graphic showing Lining and Old-Style Numerals

    Lining numerals sit more naturally in headings than old-style numerals.

    On those occasions when numbers are the star attraction, lining numerals are the way to give them the attention they crave. Old-style numerals have a wavy rhythm to them, with some numbers reaching upwards towards the capitals, some squatting at the x-height, and others ducking down below the baseline: 1234567890. This is why they work so well in continuous reading – they replicate the patterns of words in running text. However, if your reader is scanning a sequence of numbers, looking for patterns, making comparisons, or hunting for data in a list, table or other setting, they will find it far easier to do so with the familiarity and evenness of lining numerals. To specify lining numerals, set the font-variant-numeric property with a value of lining-nums:

    h1 {
        font-variant-numeric: lining-nums;

    For legacy browsers requiring font-feature-settings, use the lnum OpenType feature tag.

    Use proper subscripts and superscripts

    Subscripts and superscripts are tiny numerals which are lowered or raised. They are used in chemical and mathematical formulas, as footnote indicators, and other specialist situations. For example: ‘Caffeine1 is C8H10N4O2.’ Mark this up meaningfully in HTML using the <sup> and <sub> elements:

    Caffeine<sup>1</sup> is C<sub>8</sub>H<sub>10</sub>

    Browsers’ default styling for <sup> and <sub> is to take a regular numeral, make it a bit smaller, and raise or lower it accordingly:

    Graphic showing default styling for sub and sup tags

    This works fine up to a point, but the numerals are still a little too big aesthetically and they affect the line spacing, causing unevenness in the rhythm:

    Graphic showing the default styling for sub and sup tags in the context of a paragraph

    Most professional fonts contain properly designed subscripts and superscripts built in as OpenType features. These numerals are smaller and squatter than regular numbers, and because their position relative to other characters is part of their design, the line spacing is unaffected:

    Graphic showing proper sub and sup tags

    To use proper subscripts and superscripts, use the font-variant-position property, like this:

    sub { font-variant-position: sub; }
    sup { font-variant-position: super; }

    Unfortunately, this still leaves us with a problem: the browser’s default styling is still applied. Our special subscript character is being made smaller and it’s getting moved downwards, affecting the line spacing:

    Graphic showing various sub styles

    Top: Default <sub> styling. Middle: Proper subscripts with browser default styling. Bottom: Proper subscripts only.

    The styles the browser applies to our subscript characters are these:

    vertical-align: sub;
    font-size: smaller;

    We need to remove those styles to get the desired effect, so our rule now becomes:

    sub { vertical-align: baseline;
          font-size: inherit;
          font-variant-position: sub; }

    That will work fine for browsers that support OpenType. But browsers that don’t will get C8H10N4O2, a degraded rendering compared with the browser defaults. To address this we can use an @supports rule to check if the browser supports font-variant-position and only override the browser’s default <sub> styling if that’s the case:

    sub { font-variant-position: sub; }
    @supports ( font-variant-position: sub ) {
      sub { vertical-align: baseline;
            font-size: inherit; }

    For legacy browsers requiring font-feature-settings, use the sups OpenType feature tag for superscripts, and subs for subscripts. If we factor these in, we get comprehensive, backwards-compatible style rules, but where two simple properties should have done the job, we now have a far more verbose proposition:


    sub { font-feature-settings: "subs" 1; }
    @supports (font-variant-position: sub) {
        sub { font-feature-settings: normal;
              font-variant-position: sub; }
    @supports ((font-variant-position: sub) or (font-feature-settings: "subs" 1)) {
        sub { vertical-align: baseline;
              font-size: inherit; }


    sup { font-feature-settings: "sups" 1; }
    @supports (font-variant-position: super) {
        sup { font-feature-settings: normal;
              font-variant-position: super; }
    @supports ((font-variant-position: super) or (font-feature-settings: "sups" 1)) {
        sup { vertical-align: baseline;
              font-size: inherit; }

    Reference notes with superscripts

    One particular use of superscripts is for footnotes. When you reference notes using numbers, use true superscripts in the text but full-size numbers in the notes themselves.

    Show footnotes in context

    While we’re on the subject of footnotes, it’s worth making a brief diversion into how the web improves their usability compared with the limitations of paper.

    Many forms of writing, including academic papers, historical novels, detailed journalism and non-fiction books such as this one, contain additional citations, explanations and thoughts referred to within the text itself. A symbol is used to connect the note to the relevant location in the text. The symbols employed as references to annotations are either superscripted numbers or an esoteric series of devices starting with asterisks* and processing through daggers† to double daggers‡ and beyond.

    Since the advent of mass printing in the Victorian era, the notes themselves have typically been positioned either at the bottom of the referring printed page (footnotes), or at the end of a chapter or the entire work (endnotes). However, this approach means the notes are located away from their position within the body of text. This can disturb the reader who wishes to refer to the annotation as they proceed through the text. The connected point in the text may well be halfway through a sentence in the middle of a paragraph at some point higher up the page, or on a different preceding page altogether, and attempting to return to it disrupts the reader’s rhythm.

    An earlier approach by medieval scribes and Renaissance printers placed notes in the margins (side notes) rather than at the bottom of the page. By including notes as marginalia, the annotations are present where needed and can be read with little more than a glance away from the main text.

    A crop of a hand-written document
    A side note in a 9th-century manuscript. Source: Einsiedeln, Stiftsbibliothek, Codex 172(1128)

    Although side notes are an improvement on footnotes, both solutions are designed within the confines of the two-dimensional printed page. The web is an interactive medium and provides us with at least three dimensions in which to work, implying you can use the z-axis to place the note on top of the main text.

    Enable your reader to reveal the note on demand in the very place they are reading. Put simply, link to the footnote using a conventional symbol, but have it pop up in the vicinity of the link, thus providing a thoroughly modern solution impossible within the limitations of a printed page.

    Partial screenshot
    Clicking a superscript could pop up a footnote in situ.

    Want to read more?

    This excerpt from Web Typography will help you get started. Order the full copy today.

    Cover of Web Typography
  10. The Right Way to Select Technology, An Excerpt

    A note from the editors: We’re pleased to share an excerpt from Chapter 4 of Tony Byrne and Jarrod Gingras’s new book, The Right Way to Select Technology, available now from Rosenfeld Media.

    After establishing a solid business case, enterprises will typically turn to assembling the oft-dreaded “requirements document”—or more accurately, a set of documents, spreadsheets, and diagrams that compose a multiheaded requirements package.

    Large requirements packages actually provide a false sense of security. Modern digital technology entails real people interacting with screens. Technology selection leaders need to capture those interactive requirements, but also remain realistic at this phase about their inability to fully know what their enterprise really needs and will adopt eventually.

    This section will show how long spreadsheets full of “what” requirements really don’t work, and instead will focus on “how” a solution might work. The best way to reveal key differences among suppliers is to craft narrative “user stories” with “personas” (rough equivalent to use-cases with actors).

    In other words, tell testable stories. Business users have stories; so do customers, partners, developers, sysadmins, designers, auditors, and others.

    This section will lead you through an approach to telling those stories in a way that’s more conducive to differentiating among technology suppliers.

    Capture requirements that don’t suck

    A solid understanding of your organization’s requirements is essential to project success. Getting that understanding will involve information gathering from various stakeholder groups, potentially utilizing a variety of techniques.

    Note that at this stage, your requirements should be business- and user-focused, rather than detailed technical specifications. (We’ll get to those in Chapter 6, “Ask Questions That Really Matter”). The final key step here is to analyze and prioritize your requirements, in order to determine which ones to emphasize in the RFP and subsequent demos and bake-offs.

    How not to articulate requirements

    Whatever you do, avoid “check box” requirements sheets where you ask the vendor: “Can you do this, can you do that?”

    As a practical matter, vendors have seen all these questions and have figured out how to check all the boxes. But what’s worse is that such spreadsheets convert the understanding of what should be a human-centered, interactive activity into a bloodless series of row-by-row activities better suited for robots repeatedly performing rote tasks.

    The typical pitfall here starts like this: a business analyst (BA) goes around interviewing users and other stakeholders, and she ends up with a long wish list of features. Excel allows her to categorize those features, which is handy, but because of the limitless rows, her spreadsheet will tend to emphasize comprehensiveness over business impact.

    To address the challenge of priorities, the typical enterprise process asks stakeholders to rank their needs, perhaps on a scale of 1 to 5, or using MoSCoW (Must Have/Could Have/Should Have/Won’t Have) or some other methodology. Not surprisingly, this generates a scrum where users compete to identify as many rows of “Must Haves” as possible.

    Ultimately, someone will ask the BA to tie back each requirement row to the business case (remember that?), so she then spends several days building new tables and cross-references in Excel. Ultimately, reviewers find exceptions and variants for each feature, so new columns get added. Now the spreadsheet is too big to fit on a standard screen, let alone print out. It’s impressive … and impressively unhelpful.

    The government agency with the massive checklist

    We once advised a major U.S. federal government agency to select a new portal platform as a hub for small business advice. We came late to the process after an initial round of vendor demos had failed to differentiate clearly among the bidders.

    The problem was Excel. Or more specifically, the entire RFP as a 10-tab worksheet, with some sheets going hundreds of rows deeps. Most of the tabs held feature requests—notably categorized by agency department rather than customer persona—with a long series of columns annotating those features. (Our favorite: the ever-beloved “Must be easy to use” requirement.) Nearly all the features were listed as “must have.” They were rigorously cross-tabbed to a long-but vague set of business objectives, but otherwise there was no prioritization.

    The vendors didn’t know what to demo, although several gamely tried. Mostly, they just talked about their (voluminous) proposal responses, most of which consisted of declaring, for each row, “We can do that!”

    Ultimately, we were able to recraft a more user-centered approach, with a narrower scope, that vendors could reasonably demo against.

    Lesson: Stay away from long, feature-based checklists.

    Applying UCD principles

    There’s a different way to do this than torturing your BA— and everyone else—with long spreadsheets, and it revolves around pursuing a user-centered design (UCD) approach that emphasizes narratives, which we’ll call stories here. People will disagree about the tactics of UCD, but we can generalize overall that a user-centered approach is:

    • Holistic to encompass the entire digital experience (and therefore not feature based)
    • Iterative, where you initially sketch light (and therefore imperfect) requirements and refine them over time via iteration
    • Story-based, with an emphasis on user narratives, often called “journeys” or “top tasks”

    There’s much more to UCD, but for our purposes, two key constructs stand out:

    • Personas: User archetypes that guide decisions about technology effectiveness. Personas are useful in the sense that they create a common shared understanding of the user group, but with a human existence to help keep it real.
    • User Stories: A to-be story about the “daily life of” or a journey undertaken by key personas. User stories are exceptionally valuable here because they offer test cases against which you can compare and contrast vendor bidders.

    Information gathering

    You can chose from among numerous well-known methods for eliciting information needed to create personas and user stories.

    • Document reviews: Including existing and prospective systems diagrams, planning documents, and analytics, but also the information that flows through the anticipated technology, like catalog entries for an ecommerce site, or forms in a document management system
    • Questionnaires: Including customer and employee surveys, as well as specialized questions you might want to pose in advance of any in-person meetings
    • Workshops: A useful way to debrief groups of people, as well as experiment with more forward-looking brainstorming; customer focus groups fall into this category as well
    • Interviewing: Debriefing individual stakeholders one-on-one, where they may become more candid
    • Shadowing: Following stakeholders around for a typical duration of time; this sort of contextual inquiry is often the most useful, but also labor intensive
    • Potentially others …

    Different practitioners will take different approaches, and clearly the level of effort here should be commensurate with the anticipated benefits and risks with the new technology.

    At Real Story Group when we’re creating personas and scenarios, we like to take a modified contextual inquiry approach. We gather individuals with similar roles in a conference room and debrief the team as a group. Using a projector, we may ask some members to log in to show specific examples of an incumbent system to the group. When we are gathering requirements for an interactive system, we make the environment as interactive as possible to get the maximum information exchange.

    We’ll send five questions in advance as the agenda for the workshop:

    1. Show us briefly, on the screen, what you do.
    2. What works well in the existing environment (top three only)?
    3. What doesn’t work well or is missing in the existing environment (top three only)?
    4. How is your work/market/environment/customer changing?
    5. What else is important that we haven’t discussed?

    The questions are deliberately open ended, to create as much of an open dialogue as possible. Note the emphasis on “top three”—we don’t want a laundry list of features, but rather the most important problems and opportunities.

    Sometimes, it’s hard for line employees to identify potential future opportunities, so it can be useful to introduce the whole process with an educational workshop describing industry best practices or examples of what other enterprises have done with the technology. This is particularly important when selecting a type of technology that the enterprise has never used before.

    The question still remains of staying aligned with the initial business plan. We like to book half-hour sessions with interested executives to understand the broader business currents and objectives underneath the technology selection effort.

    At this point, a lot of raw material has been accumulated. The next step is to convert it into the two core components of the future RFP: user stories and advanced Q&A.


    • You will need to invest in both information and process analysis, and this will require document analysis as well as contextual inquiry.
    • Avoid long, undifferentiated, spreadsheet-based feature lists in favor of uncovering material necessary to create key personas and scenarios.
    • Start with the user experience and work your way back into enterprise systems.
    • Avoid the temptation to broaden your scope beyond the original charter.
    • You don’t need to be perfect at this (or any other) phase, so focus inquiry into your stakeholders’ most burning problems or intense needs.
  11. UX for Lizard Brains

    Technology can make magic happen. In seconds, you can find all the blue sandals in a warehouse of millions of shoes. A million people can read the same article without killing one tree. You can undo, unsend, and even unfriend! But here’s the buzzkill: if unanticipated or unwelcome, the magic of technology is confusing, disorienting, and unintuitive—a UX designer’s worst nightmare.

    So how can we ensure that the magic we create is intuitive? Designers will often say, “If a design is intuitive, it behaves how a user expects it to.” Well, then … what do users expect?

    We want to know the following whenever we find ourselves in a new environment (physical or digital):

    • What are the objects?
    • Where are the objects?
    • How do these objects relate to me?
    • How do these objects relate to each other?
    • What is my role as an object within this environment?

    In physical spaces, these don’t require explicit thought to answer. However, in digital spaces, they often do. That is because our “lizard brains”—the part of the brain involved in motivation, emotion, learning, and memory—evolved alongside the physics of solid objects. Consequently, users may feel unsure when designers flout the perceptual expectations forged in the physical world. Without knowing what and where the objects are, we feel blind. Navigating feels uncomfortable. Taking action might even feel impossible.

    The remainder of this article introduces three ways to design digital objects that “play nice” with our evolved expectations of the physical world. By doing our best to concretize the dematerialized things of our screen-based world, we give our lizard brains better affordances for understanding.

    Lesson one: avoid shapeshifting objects

    The properties of user interfaces need to be consistent for us to learn them well. We hunger for stable landmarks in the often ambiguous maze of digital interfaces.
    Andrew Hinton, Understanding Context

    Objects in the real world don’t usually change form as they change context. When I bring a new toaster home from the store, it doesn’t change into a different toaster. When I remove a vase from the cabinet, it doesn’t turn into a coffee mug. Humans expect object permanence; we are taken aback when objects unexpectedly change shape.

    Why do babies love peekaboo so much? It’s a great way to practice the fundamentals of object permanence, an important lesson in survival (e.g., just because the tiger went behind the rock does not mean it has disappeared). Because babies are still coming to terms with this concept, peekaboo makes for a rollicking good time. So we might assume that if we up the ante on the surprise-factor, the game would be even more fun, right? Nope. Researchers measuring the level of toddlers’ delight during a series of hacked games of peekaboo discovered that the game loses its appeal when a different face pops up after hiding. The older the child, the more this hack kills the game. Evolution seems to be telling us: it’s not cool when objects suddenly change. But all that peekaboo practice is for naught when trying to navigate a digital world of shapeshifting objects.

    For instance, when this article was in the form of a Google Doc, it lived in both the Google Docs and the Google Drive environments. Depending on the environment, the article’s module changed form and function.

    Screenshot showing the same document with different menus in Google Docs (shorter) and Google Drive (longer)
    Different menu options in Google Docs and Google Drive.

    Moving from Docs to Drive, the shape of the document module shifts from about a 3:5 rectangular ratio to a 1:1 square ratio. If I want to see when I last opened a document, I will find that information directly on the module while in Docs; but within Drive, I must look to a disembodied side panel (not shown). Both modules have a menu of actions, but accessing it requires different interactions. (In Docs, I click the “more” icon; in Drive, I right-click the module.) Worst of all, the menu contains almost completely different options in each module! Only “Remove” and “Rename” are found in both menus. Adding insult to injury, even the icons for “Rename” are different.

    Chart and screenshot of the differences in the menus between Google Docs and Google Drive
    The form and behavior of the document module are significantly different on Google Docs than on Google Drive.

    We could chalk up the inconsistencies of Google Drive and Google Docs to siloed teams, but shapeshifting objects are common within products, too. On Meetup.com, the digital representation of my next meetup morphs multiple times across the site. Looking at the homepage, it displays as a big red banner at the top of the screen.

    Screenshot of Meetup.com showing the alert for next meetup.
    Meetup’s next-up module is highlighted in bold red at the top of the homepage when you’re logged in.

    Scrolling down the homepage to the calendar section, the same meetup is displayed as a white box sporting some green accents that signal my relationship with this particular object.

    Screenshot of Meetup's calendar showing the same event
    Meetup’s calendar module makes the same meetup look like a totally different type of thing.

    And finally, within the context of its parent group—in this case Ladies that UX ATL—the meetup object is represented differently yet again. (Let’s not even get started on the ontological ambiguity between Meetup the Group and Meetup the Event.)

    Screenshot of the same event in a different context on Meetup.com
    The meetup module on the Ladies that UX ATL parent page.

    Not only is my lizard brain trying to reconcile all these changes for potential threats, but these inconsistencies are making me work harder in a practical sense. I have to learn three displays for RSVP status, three positions for date and time, and three ways to find the number of people going. Every time the object changes, I have to make adjustments both to recognize it and to interact with it. These adjustments are small, but they add up across the experience. Designers can eliminate this cognitive load simply by creating a canonical object structure and sticking to it.

    Many users don’t log the deltas between modules explicitly. Users furrow their brows and simply do their best to relearn objects and keep track of what’s what. They might harbor a vague feeling that the website or app is “hard to use.” Or worse, they blame themselves for “stupidly” attempting to interact with an object in a way that worked in one context but does not work in their current context.

    Sure, there are complex platforms where it might make sense to re-prioritize object elements depending both on who is viewing it and under what conditions. But if we design screen-by-screen instead of object-by-object, we run the risk of doing this unintentionally and arbitrarily, introducing more shapeshifting than is absolutely necessary.

    Key takeaway

    Image showing a way to consolidate three conflicting styles of a module into one cohesive style.
    In this example, a veterinary portal might have multiple modules that represent “pet.” Instead of designing a different module for each context, design one module that works well for ALL contexts.

    When we move elements around within an object, we need to remember that we are making a sacrifice—we are sacrificing consistency. Sometimes it will be worth it, like perhaps in professional tools used by power users. But often, our users will be happier with a single, rock-solid representation of that object.

    Lesson two: avoid masked objects

    On the flip side of shapeshifters (i.e., various packages for the same object), designers also have a tendency to shove different objects into the same package. With the good intention of designing a system of reusable parts, we’ll often create one-size-fits-all modules. This might seem like a smart simplification strategy, but it actually hinders users from distinguishing various object types. Distinguishing them is critical for the user to understand the system.

    Screenshot showing five slightly different product modules on Amazon
    Modules on Amazon homepage

    Check out this bank of candy-colored modules on my Amazon homepage. Sure they house different colors and content, but they follow the same basic structure. If the text were in Latin (or if the user were skimming rapidly, which we should always assume is true), these modules would translate as the same type of thing. In looking at the first two, PRIME and FRESH, I might get the impression that these modules represent “services.” And indeed, when I click these modules, I enter sort of informational, sale-sy pages describing these services (although they follow completely different templates).

    Screenshot showing how similar modules on Amazon set an expectation of usage
    PRIME and FRESH module link to services

    But when I get to VIDEO, I have to pause. VIDEO…the service? Or does this module represent a TV series? The next module (MUSIC) brings up the same question. And the ALEXA module—will this take me to a service landing page or, perhaps, a product detail page?

    Screenshot showing the final destination of all five similar modules on Amazon
    VIDEO, MUSIC, and ALEXA modules linking to different types of content

    In fact, each module takes me to a different type of place. PRIME and FRESH take me to two separate templates for a “service.” VIDEO takes me to a detail page for The Americans. And MUSIC opens up Amazon Music in a new tab (with no sign of the ill-recommended Eminem album). The ALEXA module takes me to another “snowflake” landing page.

    Like opening identical doors in a game show (but not as fun), I never know what to expect when clicking on one of these tiles. (View a video of my full rant on these Amazon modules.)

    Let’s look at one more example. The Apple App Store leverages a small rectangular thumbnail module that can house apps, curated collections, broad categories, developer-based app suites, and even operating system updates.

    The same module represents various objects in the Apple App Store.

    In both the Amazon and Apple App Store examples, instances of the modules have distinct graphics and labels, but they are the same shape and size and they are grouped together, like apples at the market. As a general rule of thumb in Gestalt psychology, when objects are grouped together, we assume they are the same type of thing, especially if their overall shape is identical. When the same packaging (i.e., the module) turns out to contain various types of things, as in the App Store, users may feel confused or even tricked. This is like taking a sip from your Starbucks coffee cup and getting a mouthful of orange juice: objectively tasty, but if unexpected, you might spew it onto your barista.

    Key takeaway

    Graphic showing how to take similar modules with different purposes and make them distinct
    Continuing with the veterinary portal from lesson one, we have pet, appointment, and medication modules all leveraging the same basic module design. Instead, create distinct modules for distinct objects. Different things deserve different packaging!

    Designing one-size-fits-all modules might seem like a good idea for an efficient modular system, but this practice doesn’t allow users to predict what’s “behind the door.” Instead, design packaging (i.e., modules) that reflects the unique things inside. This way users can learn to recognize and understand the objects in your system, making for a more intuitive environment.

    Lesson three: avoid broken objects

    In the real world, our environments are made of surfaces and clear edges. We rarely have the problem of understanding where one object stops and another begins. If we happen across a tangle of snuggling kittens, our brain might freeze up—not only from cuteness overload, but also because we are compelled to figure out which paws belong to which head. We want objects to be whole; if they are not, our brain does its best to connect the dots. In digital environments, an object might not only shapeshift across screens or mimic other objects, it might also be broken. The information and interaction triggers of broken objects are scattered across their digital environments.

    Winc Wines, a lovely service that delivers algorithmically-recommended wine to your doorstep, prompts customers to rate their wines. Often, I’ll do this 3–4 months after receiving wines. Recently, I decided it would be a great form of procrastination to log into Winc to rate my past wines.

    Screenshot of the ratings tab of Winc.com
    The Ratings tab of Winc.com. These wine modules include the ability to star a wine and add a note, but don’t show the user when the wine was received.

    At a dinner party I hosted in May, we drank a delicious sparkling wine. I think it was Finke’s Widow, but I’m not positive. Hesitating to give it five stars until I am sure, I need to find out when the bottle of Finke’s was delivered. On the “Ratings” tab, I see all my past wines. But delivery dates are not displayed.

    Screenshot of Winc.com's product detail page
    The Winc’s wine detail page displays descriptive information about the wine, but nothing about the user’s past interactions with the wine.

    Clicking into the detail view, I am presented with a generic detail page, the same view of Finke’s Widow that everyone sees. Here I can find information about the wine, but no information about my relationship with the wine—mainly, when it was delivered and how (or if) I rated it.

    As a wild guess, I click the “Hello, Sophia” menu, where I see a link to Order History. Seems promising.

    Screenshot of Winc.com's order history page
    Winc’s Order History is not much more than a table of dates.

    The Order History page gives me a list of orders with no preview of the wines that were included in each order.

    Screenshot of Winc.com's order history detail page
    Winc’s Order History detail view is where I finally find the delivery date of the wine in question.

    After clicking into the April and May orders, I finally find Finke’s Widow. Mystery solved. So, can I rate the wine from here? Nope! I have to navigate back to the Ratings tab and then scroll down to find Finke’s Widow again. In the Winc world, relevant pieces of a bottle (like a customer’s order date, rating, and tasting notes) are scattered about, forcing a user to hop around to piece together the broken object. (Watch a video of this screen-hopping.)

    Key takeaway

    Graphic showing how to consolidate related information in one view
    Avoid scattering an object’s data and actions across settings, buried menu commands, and hierarchical navigation.

    In the Winc world, I have to be in Order History to see a wine’s delivery date and I have to be in Ratings to tell the system how much I liked a bottle of wine. But what if I am browsing wine and one of my past wines shows up in a curated collection? I’ll want to be reminded that this wine was delivered to me six months ago and I gave it 4 stars. Or, if I haven’t rated it yet, but I remember loving it, I’ll want to add my stars then and there. I definitely do not want to navigate over to Ratings, only to have to scroll down to re-find that bottle.

    We need to do our best as designers to encapsulate our digital objects, making them feel whole and directly manipulable, just like in the real world. I might be more likely to use the blender in the kitchen, but it still works just as well in the garage.

    Building a better mind palace

    Humans love to concretize things. Greek orators memorized their long speeches by visualizing the speech as rooms in a palace. Sherlock Holmes himself, a genius at making connections between the most subtle clues, did so by entering his mind palace, a visualized place where bits of information were concretized and manipulable.

    If the internet is the chaotic product of the human genius, this article is a call to action for designers to build a stronger mind palace for it. When we avoid shapeshifting, masking, and breaking digital objects, understanding will emerge more naturally. It’s a simple matter of making our digital environments feel a little more like the real world in which our ancestors evolved.

  12. Be a Mentor

    Looking back over my eleven-year career in the web industry, I owe most of my success to two people from early on: Holly and Rebecca. Both were supervisors; but, more importantly, both were mentors. I wouldn’t be where I am today without their mentorship. Three years into my career, I got a promotion and became a supervisor myself. It was so exciting to be in a position to mentor others and give back to the community! I only had one question: how the heck do I do that?

    Mentorship has always been a part of the web industry. One of the first pieces of advice given to young web professionals is to find a mentor, and many experienced web professionals are where they are today because of their mentors. I think most of us would agree that mentoring others is a great thing. But when do you start mentoring? How do you provide good mentorship? How do you find people to mentor? In short, how do you do this?

    The truth I learned is that just about anyone with professional experience has something to offer novice or aspiring web professionals. You don’t have to be a director or an international speaker to be a good mentor—you can start today, and it’s probably easier than you think. You just need to be present, positive, patient, and productive.

    Finding opportunities

    You don’t need to be a supervisor to be a mentor, but if you’re not, finding someone to mentor can be intimidating. You can make this process much easier by having a few things in order and looking in the right spots.

    Before you seek out a mentee, you need to have demonstrable expertise to offer them. Make sure your personal website or portfolio is up to date. Try to build a professional following on Twitter or Medium to showcase your expertise. Answer some questions on StackOverflow or another forum, or write some tutorials. These will all help you in your career, and, when done well, can be mentorship opportunities in their own right.

    Workplaces are usually ripe with opportunities for mentorship. If you hold a manager or senior title, mentorship is an expectation; but even if you don’t, there’s always a need for showing new or younger employees the ropes. Make sure to check with your supervisor first, but there’s usually a strong need for enthusiastic and experienced mentors.

    Outside of work, mentorship opportunities still abound. If you’re experienced and successful in your field, you might talk with the local college (or even high school) about sharing your experience with interested students. Meetup groups are also a great place to meet people in search of an experienced mentor. Even if your area is completely devoid of others in the same field, the internet is not. Browse forums and online user groups—it won’t take long to find someone looking for a mentor.

    Be present

    A while back, I got some personal business cards printed up. I wasn’t looking for work. I meet a lot of people new to the web industry who could use someone to answer a few questions or provide feedback. I gave out about twenty business cards to friends, colleagues, and willing strangers with the explanation that I would answer their questions or review their projects. Want to guess how many used the card to contact me?

    Zero. That’s how many people reached out to me for feedback. The reason? Just like it’s harder to keep up with friends who move away, it’s hard to ask for feedback from someone who doesn’t seem available. People don’t think about it, or they feel bad about bothering you, or they get busy—whatever the reason, it’s a lot harder to reach out to someone who’s not present.

    Being present means creating opportunities for meaningful interaction. This doesn’t just mean proximity, but that’s a big part of it. If your job involves mentoring someone, sitting next to them will make this much easier. If you’re trying to mentor someone outside of work, checking in from time to time will do wonders. Lunch and coffee are amazing catalysts for mentorship. A personal connection (like a phone call or email) will go much further than an impersonal one (like my business cards).

    But even if you sit next to them, if you’re overwhelmed with the other aspects of your life, you’ll have the same problems. Showing that you’re too busy, even if you’re not trying to tell them that, will quickly halt mentorship opportunities. Talking about how stressed out or busy you are, constantly wearing headphones, and putting off someone’s inquiries are surefire ways to do this. Make sure you’re portraying yourself as available and interested in what they have to ask you.

    Asking for mentorship is hard. People don’t like admitting that they don’t know something, nor do they like feeling indebted to or imposing on others. Asking for mentorship triggers these anxieties. That’s why there are so few people asking about mentorship, even though there are so many looking for it. Taking steps to ease these anxieties, like reassuring them that they’re doing well and showing them that you’re happy to help, makes it much easier for the other person to come to you.

    If you’re serious about mentoring, taking the initiative to schedule a check-in or review will improve the relationship greatly. The key word is intentionality. Good mentorship cannot happen by a happy accident—it takes action on your part to make it happen. If you don’t think scheduling a meeting would be appropriate, get their contact information and send a quick email or text. This opens the door for them to talk freely about what’s going on in their life and work.

    If your mentee doesn’t believe that they’re important to you, they’re never going to open up and ask for help. Being present shows them that they matter to you, and that requires some intentional action on your part. Mentorship often doesn’t happen without this. Taking steps to be present in others’ lives is usually a prerequisite to mentorship.

    Be positive

    Mentorship is about enabling positive change in your mentee. While this can be done in many ways, it usually starts with either convincing or inspiring. Convincing is very logical and is based in the present: how should you be thinking? Inspiring is more emotional and is based on the future: what could you become? While both are important, inspiring is usually the most effective way to produce change—people won’t change unless they want to, no matter how logical the argument.

    Inspiring requires a positive outcome to focus on, an end goal that’s enticing enough to sway someone from their current path. This can be concrete, like a better job, or abstract, like better people skills; but it’s always something that the mentee wants for their future.

    Here’s the catch: inspiration isn’t always something a mentee brings into a mentoring relationship. An inexperienced mentee may have no idea what they want for their future, or may have a very skewed view of what’s possible. Sometimes it’s up to the mentor to cast a vision and show the mentee what he or she may not even believe is attainable. This can only happen when you emphasize potential instead of problems, and that starts with positivity.

    It’s been said that attitudes are contagious. There’s actually some science behind that. When we talk to someone we perceive as similar, it’s very common to mimic them unconsciously: particularly their posture, behavior, speech patterns, and mannerisms. And we are very good at picking up on sentiment. A study showed that even non-verbal vocalizations, such as “hmm,” conveyed positive or negative emotions and evoked responses in others.

    Attitudes are contagious because we communicate them and people reflect them without even trying. You broadcast your sentiment to your mentees, and they pick up on it and mirror back to you what you’re feeling, even if you don’t intend to communicate it. So if you don’t focus on what inspires your mentees with your attitude and actions, there’s a good chance that they won’t either, even if your words say otherwise.

    Inspiring doesn’t mean ignoring the negative; it means framing the negative in the larger positive. Instead of saying, “You need to spend less time working on overly-complicated solutions,” you can say, “You can be more efficient and offer more value to your clients if you work on simplifying your approach.” The request is equivalent, but the goal is much greater. Offering a positive outcome is much more motivating than stating the immediate negative, even though the intended outcome is the same.

    Celebrating victories together is another great way to focus on the positive. Checking off big goals is fantastic, but it happens so infrequently that it can’t be counted on to sustain motivation. Celebrating milestones can offer some much needed encouragement along the way. If a junior developer is working toward being able to code an entire site, setting up form validation is a major milestone. If a designer is working toward being a creative director, having a coworker request their feedback can be a big achievement. You don’t have to bake them a cake, but simply acknowledging and praising these little victories can provide great help along the way toward a stronger future.

    Be patient

    Early on in my mentoring relationship with Rebecca, she stressed to me the importance of being more organized. I wish I could say I took this to heart and ran with it and totally changed my life based on that feedback, but honestly, I didn’t. Urgent things kept popping up, and it was easier to continue to deal with them in a way that was comfortable to me. Rebecca never forced me to change—she wanted it to be my decision. Eventually, I found that my methods were failing and—guess what?—I needed to be more organized. If I’d listened to Rebecca when she first gave me the advice, I would have improved much more quickly.

    As a mentor, this sort of thing happens all the time. Sometimes change happens slowly, and sometimes it doesn’t happen at all. What’s going on? Your mentee has come to you because he or she wants to get better—so why resist change?

    Motivational speaker Tony Robbins once said, “Change happens when the pain of staying the same is greater than the pain of change.” As a mentor, you’re going to have a clear view of your mentee’s pain of staying the same. Your mentee is going to have an intimate view of their own pain of changing. Never assume that both of you have a clear understanding of both of those pieces of information.

    If you’re lucky, your mentee will come to you after they’ve decided that they want to change. But many times, your mentee won’t know what change looks like until they work with you for a while. Your mentee may actually be shocked by how different change looks compared to what they imagined it would be. You may have to show your mentee the value of changing while disarming their anxieties.

    Even when the push for positive change has begun, there will be times when it will seem more like a glacier than a flowing river. Your mentee may make mistakes—sometimes the same mistake over and over. They could resist change through an arrogant or stubborn attitude. They could impede it by failing to respond to or take on good opportunities. This can be agonizing for a mentor to watch.

    There’s a story about a traveler who went to visit a particularly wise man to ask him what made him so much smarter than the average guy. The wise man answered, “I have made 10,000 mistakes.” The traveler, perplexed, asked how that’s different than the average guy. The wise man replied, “The average man makes 10 mistakes 1,000 times each.”

    Your job is not to stop your mentee from making any mistakes; it’s to stop them from making the same mistakes over and over. There will be times when you want to jump in and correct their every move. There will be times you want to give up. There will be times you want to tell them they’re not learning. Resist. If your mentee is open to change and is making progress, allowing them to fail and learn their own lessons can be an important part of the learning process. As long as your mentee is making new mistakes and not the same ones repeatedly, progress is happening.

    Your mentee may not be fully aware of the progress they are making. They may not see mistakes as forms of progress, or they may minimize how much they have accomplished. Sometimes, it just takes someone who has been around for longer to identify growth.

    Change can go much slower than you want it to. At times, it may also surprise you by moving faster than anticipated. The important thing to remember is that another person’s change does not happen on your timetable.

    Once change starts happening, it’ll be up to you to keep it moving toward a meaningful goal.

    Be productive

    Good feelings are great, but they don’t mean a thing if there’s no improvement. Your mentee has to work toward real goals for real-world improvement, and that’s not going to happen unless you get specific. Some structure goes a long way in helping your mentee succeed, and figuring that out beforehand can make or break the relationship.

    Have a schedule and stick to it. If you’re scheduling mentoring sessions haphazardly, they’re not going to happen regularly enough and they’ll just stop happening eventually. If neither party has anything for a meeting, you can cancel it, but you’d be surprised how many little things come up in regular sessions that wouldn’t necessitate their own meeting. Also, if you’re only scheduling sessions when they’re needed, there’s a tendency to only schedule sessions when something goes wrong. When that happens, mentoring sessions can feel like a punishment.

    Frequency is going to differ based on a lot of factors—it might be weekly or it might be once a quarter, and it might take a few sessions to figure that out. The rule of thumb is to start with more frequency. If a mentee is at a point where he or she can work independently and still make good progress, you can probably start meeting less frequently.

    Work together with your mentee to define an objective. Why does your mentee want to improve? An objective can be somewhat loosely defined, but it should have a specific outcome tied to the individual’s career. Being a good designer is too loose, but getting an excellent portfolio ready for a first job is much better. Being a great developer is similarly vague, but being a subject matter expert on a niche technology is much more helpful. This can and probably will end up changing as you and your mentee learn more, but it will at least give you a direction to head in.

    Once the objective is defined, create goals to establish milestones. Read up on SMART goals and make sure your mentee knows how to define them. Each goal should help your mentee toward his or her objective and should be a single measurable step. If a goal is not met in the specified time frame, it’s not the end of the world—just set a new one. If goals are consistently not met, you may have to have a hard conversation with your mentee about how realistic the goals are. Just make sure your mentee is constantly moving toward their objective.

    Make a loose agenda for your sessions. There should be some flexibility for urgent topics that come up, but you should know ahead of time what topics you want to discuss or ask about. The agenda should make sense to you and your mentee, so you’ll probably want to craft your own, but here’s one to get you started:

    1. How are you feeling?
    2. What have you been doing?
    3. How are you progressing toward your goals?
    4. How have you succeeded?
    5. What do you want to accomplish in the near future?

    Lastly, don’t forget to write everything down. It doesn’t matter how good your memory is; things will be lost between sessions if you don’t write them down. Write down notes for each section of your agenda, and review them before the next session. By doing this, there will be consistency between sessions, and you’ll often resolve issues that may have otherwise slipped through the cracks.

    Be a mentor

    Remember, you don’t have to be a famous speaker, a renowned expert, or even at the top of the career ladder to be a good mentor—you just have to be able to articulate what what got you where you are today to someone who’s not there yet. If you are willing to do this authentically by being present, positive, patient, and productive, you can be a great mentor today.

  13. Using Webfonts

    A note from the editors: We’re pleased to share an excerpt from Chapter 2 (“Using Webfonts") of Bram Stein's new book, Webfont Handbook, available now from A Book Apart.

    Now that you’ve selected a font, let’s put it on your website. Webfonts are defined in CSS through the @font-face rule. If you’re a web developer, you’ve most likely written, copied and pasted, or at the very least seen an @font-face rule. For the sake of completeness, though, let’s quickly run through a basic example:

    @font-face {
        font-family: Elena;
        src: url(elena-regular.woff);

    This creates a new webfont family that can be referenced through the font-family or font shorthand property. But something’s missing here. When referencing a webfont in a font stack, always make sure to include at least one fallback font in case the webfont fails to load. Here, if Elena fails to load, the browser will fall back on the generic serif font family:

    p {
        font-family: Elena, serif;

    We’ll talk more about fallback fonts and how they can be used to make your site appear to load faster in Chapter 3. For now, let’s keep our fallback stack simple by including only the generic serif and sans-serif font families.

    Font Families

    Creating a font family with multiple styles is accomplished by creating an @font-face rule for each style and using the same font-family name. The following @font-face rules create a family with a normal and bold style:

    @font-face {
        font-family: Elena;
        src: url(elena-regular.woff);
        font-weight: normal;
    @font-face {
        font-family: Elena;
        src: url(elena-bold.woff);
        font-weight: bold;

    You can use this font family in your CSS by referencing the family name and weight in your selectors. This applies the regular style to paragraphs and the bold style to strong paragraphs:

    p {
        font-family: Elena, serif;
    p strong {
        font-weight: bold;

    Besides font-weight, @font-face also accepts the font-style and font-stretch property descriptors, which define styles such as italic and condensed. All three property descriptors can be used to create a single font family with multiple styles. Theoretically, this lets you create a family containing 243 individual styles (nine font-weight values × three font-style values × nine font-stretch values). In practice, however, you’re limited to twenty-seven values, since some browsers don’t support font-stretch (Fig 2.1).

    Internet Explorer 8 Internet Explorer 9-11 Edge Chrome Firefox Safari Opera Android System
    No Yes Yes Yes Yes No Yes No

    Fig 2.1: Browser support for font-stretch at time of writing. (Check caniuse.com for current and version-specific browser support.)

    With luck, the remaining browsers will implement the font-stretch property soon, and you will be able to use all 243 font classifications.

    Font Formats

    The src descriptor tells a browser where to get a font file. The previous examples used a single font format, but you’ll often see URLs to multiple font formats combined with format hints, which are appended after the URL using the format("value") syntax. Format hints tell the browser what the format of the font file at a given URL is.

    @font-face {
        font-family: Elena;
        src: url(elena-regular.woff2) format("woff2"),
            url(elena-regular.woff) format("woff");

    If you list multiple formats, modern browsers will pick the first format they support based on the format hint. Therefore, it’s important to list webfont formats in the order of best compression to least. Even though format hints are optional, always include them—they let the browser know about the format without needing to download the font. For example, if a browser does not support WOFF2, but does support WOFF, it can skip the WOFF2 font file based on the format hint.

    Browsers support several webfont formats: OpenType (TrueType), EOT, WOFF, and WOFF2. Some browsers also support SVG fonts, but they’re deprecated and should no longer be used (and should not be confused with the new OpenType-SVG format). EOT, WOFF, and WOFF2 are technically not font formats. They are compressed OpenType files with varying degrees of compression. WOFF2 offers the best compression, followed by WOFF and EOT (Fig 2.2).

    Format Internet Explorer 8 Internet Explorer 9-11 Edge Chrome Firefox Safari Opera Android System
    WOFF2 No No Yes Yes Yes Yes Yes No
    WOFF No Yes Yes Yes Yes Yes Yes Yes
    OpenType No Yes Yes Yes Yes Yes Yes Yes
    EOT Yes Yes No No No No No No

    Fig 2.2: Browser support for font formats at the time of writing. Look for up-to-date and version-specific browser support for font formats at caniuse.com.

    In researching coverage for all browsers, you may have come across something called the bulletproof @font-face syntax by Fontspring. The bulletproof syntax uses EOT, WOFF2, WOFF, raw OpenType, and SVG font files for maximum browser coverage:

    @font-face {
        font-family: Elena;
        src: url(elena.eot?#iefix) format("embedded-opentype"),
             url(elena.woff2) format("woff2"),
             url(elena.woff) format("woff"),
             url(elena.otf) format("opentype"),
             url(elena.svg#elena) format("svg");

    The first URL line might look a little odd to you. Versions of Internet Explorer 8 and below do not support the syntax for multiple font formats, and treat the entire value of the src property as the URL. The bulletproof syntax tricks Internet Explorer 8 and below into thinking that the remaining URLs are part of the fragment identifier of the first URL. Because fragment identifiers are ignored when downloading files, Internet Explorer 8 and below simply use the first URL. Browsers other than Internet Explorer will skip the line because they do not support EOT. The rest of the entries are what you would expect: font formats listed in order of preference.

    But is the bulletproof syntax still relevant? No. In fact, I think it’s harmful. SVG fonts are deprecated and only supported by browsers that are no longer in use. Most websites support Internet Explorer 9 and up, yet the syntax lists EOT as the first preferred font format. Even though Internet Explorer 9 and up support WOFF, those versions will still download the EOT file, simply because it is listed first.

    Because most websites no longer support old browsers, I highly recommend using a simplified syntax. This simplified syntax covers all modern browsers, as well as slightly older ones that are still in active use, such as Android 4.4 and earlier:

    @font-face {
        font-family: Elena;
        src: url(elena.woff2) format("woff2"),
             url(elena.woff) format("woff"),
             url(elena.otf) format("opentype");

    Even though older Android versions are still used, worldwide reliance on these browsers is rapidly dwindling. Soon you will probably be able to drop the raw OpenType format as well, and simplify the syntax even further:

    @font-face {
        font-family: Elena;
        src: url(elena.woff2) format("woff2"),
             url(elena.woff) format("woff");

    In this case, someone running an older browser will simply see your fallback fonts instead of the webfont. That’s fine; they can still read the content in the fallback font. (More on fallback fonts later.)

    There’s another possible value for the src descriptor. The local function takes the name of a local font family. If the font happens to be installed on the system, the browser will use that instead, thereby avoiding an extra download.

    @font-face {
        font-family: Elena;
        src: local("Elena"),
             url(elena-regular.woff2) format("woff2"),
             url(elena-regular.woff) format("woff");

    While this may seem like a great optimization, nothing guarantees that the local font matches your webfont. You may get a different version of the font, a font with different language support, or even an entirely different font. For that reason, I usually recommend not using the local function unless you find these downsides acceptable.

    Want to read more?

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

    Cover from Webfont Handbook
  14. What I Talk About When I Talk About Sorting: Untangling Array#sort

    Sorting things is a fundamental part of our daily lives—it’s something we do everyday to make our lives easier, following all kinds of criteria. Whether you’re looking for a person’s phone number, the location of your favorite book, or even matching up your socks, sorting allows us to find what we are looking for in a faster and more effective way.

    This is also the case in the world of web development. But if you thought you knew exactly how JavaScript’s Array#sort works under the hood, think twice.

    Scratchin’ the surface

    No matter your skill level, if you’re a JavaScript developer you’ve probably come across the Array#sort method at some point. Do you remember the first time you tried sorting numbers in JavaScript? You were probably astonished to discover (just like the rest of us) that the sort method does NOT sort things quite as we might expect.  You don’t know what I’m talking about? Let’s dive into some code:

    const myArray = [33, 2, 98, 25, 4]
    myArray.sort() // [ 2, 25, 33, 4, 98 ]

    Wait, what? Is JavaScript nuts? In which world are 25 and 33 smaller than 4? Before you start rethinking your whole life, let’s figure this out.

    Lexicographical sorting

    What is actually happening here is that JavaScript is sorting our numerical array in a lexicographical manner—think alphabetical order, where every value is treated as a string.

    The catch here is that Array#sort can take a compare function as a parameter, but if you don’t supply it, “elements are sorted by converting them to strings and comparing strings in Unicode code point order” (according to the MDN docs). This means that JavaScript will treat the following arrays in a similar fashion when calling the sort method:

    const numbers = [80, 9]
    numbers.sort() // [80, 9]
    const strings = ['80', '9']
    strings.sort() // ['80', '9']

    In this case, “80” comes before “9” because it has a smaller Unicode code point. If you don’t believe me, let’s take a look at the code point value of the first character of each:

    "8".codePointAt(0)  // 56
    "9".codePointAt(0)  // 57

    Basically the function codePointAt() is simply a method of the String object that is used to get the Unicode code point value of any character at a given index.

    At this point, the following code shouldn’t be shocking to anybody because now we know that JavaScript is just converting all the elements in those arrays to strings and comparing their Unicode values. (Yes, Emojis also have Unicode code point values.)

    const emojis = ["😍","😂","😰"]
    emojis.sort() // ["😂", "😍", "😰"]
    const wtfJavaScript = [390, "😂", 1, "2325"]  
    wtfJavaScript.sort() // [1, "2325", 390, "😂"]

    Numerical sorting

    After all that mumbo jumbo, what if we actually JUST wanted to sort our array numerically? As stated before, we need to provide a compare function that will sort the array elements according to the return value of that compare function.

    • If the return value of compareFunction(a, b) is less than 0, a will come before b.
    • If the return value is greater than 0, b will come before a.
    • If the return value is 0, a and b will remain unchanged.

    To compare numbers instead of strings, provide a function that subtracts b from a. Here is an example:

    const myArray = [33, 2, 98, 25, 4]
    myArray.sort((a, b) => a - b) // [ 2, 4, 25, 33, 98 ]

    Rollin’ in the deep

    During all this JavaScript sorting fun, I bet you wondered at some point about the algorithm used by the native JavaScript sort method. No? That was just me? Either way, let’s check it out.

    Now, here’s the thing: the ECMAScript standard doesn’t specify which algorithm should be used, so each JavaScript engine is allowed to use whatever algorithm it wants. Why should you care about this? Keep reading, but first let’s find out which engines use which algorithms. (The good thing is that most of these engines are open source so we can look at the code and check what they are using.)

    How different JavaScript engines sort
    JavaScript Engine Sort Algorithm(s)
    SpiderMonkey (Mozilla) Insertion Sort (for short arrays)
    Merge Sort
    V8 (Google) Insertion Sort (for short arrays)
    Quick Sort
    Nitro (Apple) Merge Sort
    Chakra (Microsoft) Quick Sort

    Figure 1: As you can see, each JavaScript engine has its own algorithm for sorting.

    This isn’t a computer science article, but let’s get some things straight. Because JavaScript engines don’t use the same algorithm behind the native method, it is very likely that you’ll encounter different results when running the sort method in different browsers. You might find that elements are being sorted in a different way, or some sorts run faster than others (depending on the JavaScript engine). If your application relies crucially on sorting data, you have to pay attention to these kinds of details.

    For example, Google’s V8 that powers Chrome and NodeJS uses the quick sort algorithm, which is not a stable algorithm. Stability in the context of sorting means that it preserves the original order of the input set when having elements with equal values. If you have to sort a list of people in your database who were previously sorted alphabetically by last name, you might want to preserve that original order when sorting again, this time according to age and looking for people of the same age. This means you will need a stable sort.

    Since each JavaScript engine implements the Array#sort method with different algorithms (that may or may not be stable), stability is not guaranteed. Let’s check an example:

    const people = [
    	{ name: 'Kei Akamatsu', age: 32 },
    	{ name: 'Fumiaki Haida', age: 42 },
    	{ name: 'Tengo Kawana', age: 26 },
    	{ name: 'Sara Kimoto', age: 11 },
    	{ name: 'Midori Kobayashi', age: 11 },
    	{ name: 'Eri Kurono', age: 54 },
    	{ name: 'Haruki Murakami', age: 6 },
    	{ name: 'Satoru Nakata', age: 26 },
    	{ name: 'Yoshio Oumi', age: 26 },
    	{ name: 'Miss Saeki', age: 17 },
    	{ name: 'Yuzuki Shirane', age: 26 },
    	{ name: 'Kafka Tamura', age: 26 },
    	{ name: 'Tsukuru Tazaki', age: 32 },
    	{ name: 'Toru Watanabe', age: 12 }
    people.sort((a, b) => a.age - b.age)

    In V8, this is the result:

    { name: 'Haruki Murakami', age: 6 },
    { name: 'Midori Kobayashi', age: 11 },
    { name: 'Sara Kimoto', age: 11 },
    { name: 'Toru Watanabe', age: 12 },
    { name: 'Miss Saeki', age: 17 },
    { name: 'Kafka Tamura', age: 26 },
    { name: 'Satoru Nakata', age: 26 },
    { name: 'Yuzuki Shirane', age: 26 },
    { name: 'Yoshio Oumi', age: 26 },
    { name: 'Tengo Kawana', age: 26 },
    { name: 'Tsukuru Tazaki', age: 32 },
    { name: 'Kei Akamatsu', age: 32 },
    { name: 'Fumiaki Haida', age: 42 },
    { name: 'Eri Kurono', age: 54 }

    Notice how the previous alphabetical order for the people who are 26 years old is not preserved? In JavaScript engines implemented with stable algorithms, this is not a problem.  Just keep in mind that the sort method will sort differently depending on where you’re running it.

    What if it’s crucial for your application to maintain consistent behavior across engines? Is implementing your own version of the sort method even an option? Maybe yes, maybe no. If stability and performance are high on your priority list, it’s probably yes.

    Actually, implementing your own homemade JavaScript sorting function is not that difficult and takes only a few lines of code. There are plenty of books that explain how to implement the most popular sorting algorithms. Two good resources are The Algorithm Design Manual by Steven S. Skiena and Foundations of Algorithms by Richard Neapolitan et al.

    You can even extend the Array prototype to define your shiny new implemented sort functions:

    Array.prototype.InsertionSort = function() {
    	/* your implementation here */
    Array.prototype.MergeSort = function() {
    	/* your implementation here */
    Array.prototype.QuickSort = function() {
    	/* your implementation here */

    Believe it or not, self-implemented JavaScript sorting functions can be faster than the native method, though it depends on various things, such as the amount of space you have available, the kind and quantity of data you are sorting, and the JavaScript engine you are using.

    Testing and benchmarking

    Too hard to believe? Let’s do some benchmarking! The following table shows the results of testing the native JavaScript sort method against my own implementations of insertion sort, merge sort, and quick sort for dynamically created arrays with x elements. The values represent the operations per second done by each method:

    Operations per second
    Elements in Array
    100 1000 100,000 1,000,000 10,000,000
    Array#sort 1,967,829 127,999 5,601 8.61 1 0.08
    Insertion Sort 28,520,017 (fastest) 4,014,363 (fastest) 314,407 (fastest) 0.19 (slowest) - -
    Merge Sort 109,299 (slowest) 10,559 (slowest) 711 (slowest) 6.16 0.45 (slowest) 0.05 (slowest)
    Quick Sort 880,522 96,941 6,316 35.75 (fastest) 1.98 (fastest) 0.18 (fastest)

    Figure 2: Operations per second by different sort implementations. Fastest results are shown in bold and slowest results are shown in italics.

    As mentioned before, the quantity of data to be sorted directly impacts the performance of every algorithm. Notice how insertion sort performs better than the other methods (including the native sort) for the first thousand elements. As the data input increases, insertion sort becomes slower, and for a hundred thousand elements it becomes the least performant. At this point, quick sort takes the lead. For the remaining test cases, it continues to be more performant than the native version. (It is very important to clarify that the previous benchmark was tested in Chrome 56 on macOS 10.12.3.)

    Your homework now is to perform the same benchmark on different machines, with different input sizes and different JavaScript engines to see what results you get!

    JavaScript inception

    I might not be a fortune teller, but I bet you’re probably thinking: “How come self-implemented JavaScript sorting functions can beat the native sort C/C++ implementations?”

    First of all, let’s backtrack a little bit. C/C++ implementations? Are we even sure about that?

    If you peeked at the source code of the JavaScript engines, perhaps you noticed that in the case of V8 and Nitro, the implementation of the sort method is actually done in JavaScript itself. Wait again, what? Am I saying that those JavaScript engines are written in JavaScript? Is this some kind of JavaScript inception? Yes, indeed.

    In the world of computer science this is actually called self hosting: the art of implementing parts of a language in that very language itself. But then again, isn’t C++ supposed to be faster than JavaScript? Yes and no. C++ programs are definitely faster than JavaScript when they operate on C++ data structures but not on JavaScript ones.

    JavaScript arrays have methods like forEach, map, reduce, and of course sort. Each one takes a callback as an argument. The method then iterates over every element of the list and invokes the callback during each iteration. This means that the execution has to switch between compiled C++ code and interpreted JavaScript, and this context switch is expensive. By staying in the same execution context within the same language, we can boost performance. If you need some proof, try comparing the performances of Array#forEach and a simple for loop.

    In certain cases, you may notice that an engine’s Array#sort method implementation causes unneeded overhead. Calling callback functions for every element in our array adds an extra layer of complexity to the task of simply sorting numbers. It seems that the native implementations just do more overall (in terms of error handling and features) than the simple self-implementations.


    Yes, most people are aware of Array#sort, its funky behavior, and the fact that you’ll need a compare function to achieve a numerical sort. Because JavaScript. But did you know that the algorithms used to natively implement this method vary across engines? And that this produces different results depending on where you are running it?

    If you care about performance and consistency, creating your own self-implementation of the sort method might not be a wild idea. Of course, you should learn how to choose your battles depending on the needs of your applications, whether you’re handling complex databases in a NodeJS application or sorting in the front end. Don’t implement your own version for the sake of it, but take time to level the pros and cons. Only you can decide how pragmatic it is to spend time creating a homemade sort algorithm, as opposed to the native one.

  15. Considering Open Source Licenses

    So you have a project that you want to use open source tools to create—well, I tip my hat off to you as a developer. But do you know the questions you need to answer before you get started?

    What stage of development is your project in right now? Have you finished the planning phase? Are you going to work with a team? Will the project be split up into different modules? And so on.

    The principle of DRY (Don’t Repeat Yourself) has become an unwritten rule for developers. Instead of always starting from scratch on each new project, find ways to build upon previous work. This will save you time and other resources. In other words, do not reinvent the wheel; put to use the great work that others have perfected and made “freely” available for you to build upon.

    This principle of DRY can also be applied to open source works. When starting a new project, most developers first search carefully for frameworks, libraries, and packages that they can build on or modify to fit their needs.

    Best of all, there are thousands upon thousands of open source projects (OSes, frameworks, IDEs, libraries, database management systems, and so on) available for you to choose from.

    But wait just a minute!

    Imagine your project becomes a huge hit, only to get knocked flat by licensing issues required by the works you built it with. Do you really understand what it means to use open source work in your project?

    As the adoption of open source keeps increasing, so does the risk of non-compliance with licensing terms—which in turn leads to an increase in the number of litigations involving open source works.

    One of the most recent examples involves Hancom and Artifex, the developer of Ghostscript. The case is ongoing, but the direction seems to be clear from the following:

    To use Ghostscript for free, Hancom would have to adhere to its open-source license, the GNU General Public License (GPL). The GNU GPL requires that when you use GPL-licensed software to make some other software, the resulting software also has to be open-sourced with the same license if it’s released to the public. That means Hancom would have to open-source its entire suite of apps.

    Or, Hancom must pay a licensing fee to Artifex.

    Now you get a bit of the picture, right?

    Note: Nothing I say in this article is legal advice; if you’re unclear about the explanations or terms you find in a license, it’s a good idea to get qualified legal counsel. These are just a few things I’ve come across and want to point out to my fellow developers.

    Evaluating open source options

    Before you settle on an open source project to use or include in your own project, go back to your big idea (that is, the project that you are developing) and answer the following questions.

    1. What is the vision behind your project? Specifically, are you developing another open source project or will you be selling your project for profit?
    2. How will you make your project available to others? Will they be able to read the source code or will you make it off-limits?
    3. What redistribution rights will you allow? Will others be allowed to repackage your work and sell for profit, or will they be able to redistribute it for free?
    4. How should you handle embedding? Will others be able to embed your work into their own work, then sell or distribute for profit, or can they embed your work, but prevent access to the source so it’s unavailable to others?
    5. How will you handle attribution? What will you do to give credit to the original creators of included tools?

    Once you have answered the above questions, what’s next? It’s time to answer another question.

    What does open source mean?

    What comes to your mind when you come across a work categorized as open source—free to use as you deem fit? Learn what open source really means here from the Open Source Initiative.

    After reading that, do you still want to include open source work in your project? Will it derail your purpose and goal?

    Why are open source projects licensed?

    One reason why projects are licensed with an open source license is convenience.

    Open source licenses tell developers how to use your work and the limitations and restrictions that they must observe. You wouldn’t want a constant stream of emails from everyone interested in using your work—these could run into thousands of people.

    At the same time, open source licenses make it easy for others to contribute to a project,  as opposed to a closed system. Just imagine the talents that will be able to contribute to an open source project in contrast to an in-house project. You will be able to pull in far more resources toward achieving the goal of your project; yes, you will agree that much more can be achieved this way.

    Licensing serves as a protection for the creator of a work or body of works; others won’t go about claiming your work as their own. It makes sure that you get the credit you deserve as the author of a project.

    Read every license, every time

    Not all open source licenses are the same. Take a look at the table in Fig. 1 to see the types of differences you might encounter.

    Comparison table of open source licenses
    Fig. 1: Open source license comparison
    Image Source: https://choosealicense.com/appendix/

    Introduction to popular licenses

    Below are a few of the most popular open source licenses, with details of what power or limits they impose on you regarding usage and redistribution.

    MIT License

    A project with this open source license allows you “to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the software is furnished to do so.” This means that you can use this work for your project as you deem fit (even sell derivative works) with the only conditions being that you 1) leave the MIT license intact and 2) include a copyright notice.

    What they mean is that you must include a notice similar to this in the license file of your work:

    “[name of your project] includes code from [original creator of included work] and it is licensed under the MIT License” followed by the full MIT license text.

    One other thing to note before using a work with this license is that “MIT licensed software can be integrated into GPL software, but not the other way around.” Think about a situation where you have to include works with both the MIT and GPL licenses in your project. At the end, this combination will carry the GPL license, excluding the MIT license. (You can read about the GPL license below.)

    Apache License

    This license is somewhat similar to the MIT license. You can use works with this license in your project provided that you take note of the fact that it “requires preservation of the copyright notice and disclaimer.”

    The Apache License term is very strict about modifications. You are required to explicitly state that the original work has been modified and to include the following in your license notice:

    The Free Software Foundation considers all versions of the Apache License to be incompatible with the previous GPL versions 1 and 2 and, furthermore, considers Apache License versions before v2.0 incompatible with GPLv3. Because of version 2.0’s patent license requirements, the Free Software Foundation recommends it over other non-copyleft licenses, specifically recommending it either for small programs or for developers who wish to use a permissive license for other reasons.

    GNU General Public License (GPL) 3

    This license isn’t particularly permissive when compared to, say, the MIT license. But it does foster community effort greatly and it’s one of the most popular open source licenses out there.

    When you use work with GPL that you will be releasing to the public (or redistributing), this license requires that you make the modifications available (including how-to documentation for installation and building) under the GPL license.

    BSD 3-Clause License

    This is also very similar to the MIT license; it allows you to use it for commercial projects, to redistribute, and to modify, but the copyright notice and the BSD license itself must be included.

    Your decision between MIT and BSD now depends on what is suitable for your project. MIT and BSD licenses differ in terms of compatibility with other open source licenses—while MIT licensed work will allow you to include other work with different license terms, BSD licensed work won’t. More on that on license compatibility below.

    There are several other open source licenses that are not covered here. They require careful reading and understanding before delving into using works they are licensed with.

    Ignoring the terms of an open source license

    Considering suitable open source licenses all boils down to avoiding lawsuits in the future. Problems foreseen are problems half-solved. But what happens if you ignore the terms of a license?

    Will you be prosecuted when this is uncovered? The Free Software Foundation is an organization that volunteers their resources to ensure open source license compliance—kind of an open source license police. The following is a quote from their compliance page:

    Once we have established that a violation has occurred, we explain to the violator what they must do to come into compliance. They’ll make some appropriate changes — to their software, their product, their website, or whatever’s affected — and let us know. We check those changes, tell them about any new or outstanding issues we find, and ask them to make more changes. This back and forth goes on as long as necessary.

    License compatibility

    What about using works with different open source licenses? Will there be any implications? In other words, if you’re thinking of “mixing” work of different license terms in a project, this is where you have to start thinking of compatibility.

    If code components that were licensed under different license conditions are compiled to form a new work, a question arises: Is the common use of the code permissible under license law? If for example code A under license X is linked with code B under license Y to form a new program, licenses X and Y must permit this. If this is the case, license compatibility exists.

    ifrOSS (The Institute for Legal Questions on Free and Open Source Software)

    Perhaps you’ve found an open source work that will perfectly fit your project … But. The. License. Is. Not. Compatible! What can you do about it?

    First, consider the license of the open source work you are planning to use in your project.

    Obviously, license issues will be easier to manage when you use open source works with the same license, and one way to avoid license incompatibility is to read beyond the list of features—after reading the features section, be sure to scan down to the requirements section.

    As you investigate open source tools to use in your project, make “compatibility” your companion. Keep it close.

    In terms of compatibility, the MIT license is fairly generous; as of the time this article was written, this license only prevents you from suing the author of the work. So in general, a work licensed with an MIT license is great for most purposes. (Remember that this is not legal advice.)

    License infringement

    If a licensing case does affect you or your project, note that some legal cases pertaining to license infringement are settled out of court. You may be able to negotiate and reach a personal agreement with the author—an agreement that would allow you to use the work without infringement. Simply put, contact the author of the open source work to discuss the situation and possible compromises or alternatives they might consider. Negotiation done before embarking on your project could help clarify the license, ensure you and the author are on the same page, and avoid a legal situation entirely.

    Bringing it home

    Consideration of open source licenses should be part of the early planning phase of your project, not after development.

    To significantly reduce the risk of violations, ensure that you take open source license violations seriously and that appropriate open source policies are in place to guide your development team. Do not forget that your project will also need a license after you finish development (and production). What license will you be using? The license(s) included in the open source work used in your project will determine your own license.

    Most of all, as an individual developer or business entity that develops, distributes, or uses open source, you should make time to read and understand the terms and conditions of open source licenses you are using.

  16. How People Perceive Lossy Image Quality: A Study

    The notion that lossy image quality is subjective is not an unreasonable hypothesis. There are many factors that play into how humans perceive quality: screen size, image scaling, and yes, even performance.

    Many research projects have tackled this subject, but I’ve recently launched a survey that attempts to understand how people perceive image quality in a slightly different way: in the context of performance.

    This image quality assessment serves up 25 different specimens, each of which is presented in a random lossy quality setting between 5 and 100, in both JPEG and WebP formats. As participants complete the survey, navigation, resource and paint timings are collected (when available) from the browser, as well as other client details such as a device’s resolution, pixel density, and many other pertinent details.

    The real work of gathering data begins. This is where you can help out. If you have five to ten minutes to spare, please head over to https://imagesurvey.site and participate. When the survey is finished, I’ll post the raw data and write and article (or two) on the findings. If further experimentation is required, that will be pursued as well. I don’t know what we’ll find out, but we’ll find out together with your input. So please participate!

    Thank you!

    Note: If you have feedback for how to improve the survey, feel free to comment! Just be aware that your feedback can’t be implemented in this run of the survey, but it could be useful in constructing any follow-up surveys.

  17. The Ten Essentials for Good API Documentation

    API documentation is the number one reference for anyone implementing your API, and it can profoundly influence the developer experience. Because it describes what services an application programming interface offers and how to use those services, your documentation will inevitably create an impression about your product—for better or for worse.

    In this two-part series I share what I’ve learned about API documentation. This part discusses the basics to help you create good API docs, while in part two, Ten Extras for Great API Documentation, I’ll show you additional ways to improve and fine-tune your documentation. 

    Know your audience

    Knowing who you address with your writing and how you can best support them will help you make decisions about the design, structure, and language of your docs. You will have to know who visits your API documentation and what they want to use it for. 

    Your API documentation will probably be visited and used by the following audiences. 


    Based on their skills, experience, and role in projects, developers will generally be the largest and most diverse group. They’ll be using your docs in different ways.

    At Pronovix, we started conducting developer portal workshops with our clients to help them learn more about what developers need and how to best support their work—and what they’re really looking for in API documentation. This is also supported by solid research, such as the findings published in Stephanie Steinhardt’s article following a two-year research program at Merseburg University of Applied Sciences.

    Newcomers: Developers lacking previous experience with your API tend to need the most support. They will take advantage of quickstart guides that encourage them to start using your API—clear, concise, step-by-step tutorials for the most important topics, and sample code and examples to help them understand how to use it in real projects. If you can make onboarding pleasant for newcomers, they will be more likely to devote themselves to learning every nuance of your API.

    External developers: Developers already working with your API will come back repeatedly to your docs and use them as reference material. They will need quick information on all the functionality your API offers, structured in an easy to understand way to help them quickly find what they need.

    Debuggers: Developers using your API will encounter errors from time to time and use your documentation to analyze the responses and errors that crop up.

    Internal developers: API providers tend to focus so much on their external audience that they forget about their own developers; internal teams working on the API will use the API documentation, as well.

    These are just the most common use cases.

    Decision makers

    Decision makers like CTOs and product managers will also check out your API documentation and evaluate your API. They need to determine whether your API will be a good fit for their project or not, so it’s crucial to your business that this group can easily and quickly find what they’re looking for.

    Other audiences

    Although not as common, journalists, technical writers, support staff, developer evangelists, and even your competition might read your API documentation. 

    Remember the purpose of documentation

    The foundation of your API documentation is a clear explanation of every call and parameter.

    As a bare minimum, you should describe in detail:

    • what each call in your API does
    • each parameter and all of their possible values, including their types, formatting, rules, and whether or not they are required.

    Context-based structure

    People won’t read your API documentation in order, and you can’t predict which part they will land on. This means, you have to provide all the information they need in context. So following the best practices of topic-based authoring, you should include all necessary and related information in the explanation of each call.

    Context.IO, for example, did a great job documenting each of their API calls separately with detailed information on parameters and their possible values, along with useful tips and links to related topics.


    In order to be able to implement your API, developers need to understand it along with the domain it refers to (e.g., ecommerce). Real world examples reduce the time they need to get familiar with your product, and provide domain knowledge at the same time.

    Add the following to the description of each call:

    • an example of how the call is made
    • an explanation of the request
    • sample responses

    Studies have shown, that some developers immediately like to delve into coding, when getting to know a new API; they start working from an example. Analysis of eye-tracking records showed that visual elements, like example code, caught the attention of developers who were scanning the page, rather than reading it line by line.  Many looked at code samples before they started reading the descriptions.

    Using the right examples is a surefire way to improving your API docs. I’ll explore ways to turn good API docs into great ones using examples in my upcoming post “Ten Extras for Great API Documentation”.

    Error messages

    When something goes wrong during development, fixing the problem without detailed documentation can become a frustrating and time-consuming process. To make this process as smooth as possible, error messages should help developers understand:

    • what the problem is;
    • whether the error stems from their code or from the use of the API;
    • and how to fix the problem.

    All possible errors—including edge cases—should be documented with error-codes or brief, human-readable information in error messages. Error messages should not only contain information related to that specific call, but also address universal topics like authentication or HTTP requests and other conditions not controlled by the API (like request timeout or unknown server error).

    This post from Box discusses best practices for server-side error handling and communication, such as returning an HTTP status code that closely matches the error condition, human-readable error messages, and machine-readable error codes.

    Quickstart guide

    Newcomers starting to implement your API face many obstacles:

    • They are at the beginning of a steep learning curve
    • They might not be familiar with the structure, domain, and ideas behind your API
    • It’s difficult for them to figure out where to start.

    If you don’t make the learning process easier for them, they can feel overwhelmed and refrain from delving into your API. 

    Many developers learn best by doing, so a quickstart guide is a great option. The guide should be short and simple, aimed at newcomers, and list the minimum number of steps required to complete a meaningful task (e.g., downloading the SDK and saving one object to the platform). Quickstart guides usually have to include information about the domain and introduce domain-related expressions and methods in more detail. It’s safest to assume that the developer has never before heard of your service.

    Stripe’s and Braintree’s quickstart guides are great examples; both provide an overview of the most likely tasks you’ll want to perform with the API, as well as link you to the relevant information. They also contain links to contact someone if you need help.


    Tutorials are step-by-step walkthroughs covering specific functionality developers can implement with your API, like SMS notifications, account verification, etc.

    Tutorials for APIs should follow the best practices for writing any kind of step-by-step help. Each step should contain all the information needed at that point—and nothing more. This way users can focus on the task at hand and won’t be overloaded with information they don’t need.

    The description of steps should be easy to follow and concise. Clarity and brevity support the learning process, and are a best practice for all kinds of documentation. Avoid jargon, if possible; users will be learning domain-related language and new technology, and jargon can instill confusion. Help them by making all descriptions as easy to understand as possible. 

    The walkthrough should be the smallest possible chunk that lets the user finish a task. If a process is too complex, think about breaking it down into smaller chunks. This makes sure that users can get the help they need without going through steps they’re not interested in.

    Screenshot of Twilio's tutorials page
    Twilio’s tutorials explain the most-likely use cases with sample apps in a wide variety of programming languages and frameworks.

    Universal topics

    To implement your API, there are some larger topics that developers will need to know about, for example:

    • Authentication. Handled differently by each type of API, authentication (e.g., OAuth) is often a complicated and error-prone process. Explain how to get credentials, how they are passed on to the server, and show how API keys work with sample code.
    • Error handling. For now, error handling hasn’t been standardized, so you should help developers understand how your API passes back error information, why an error occurs, and how to fix it.
    • HTTP requests. You may have to document HTTP-related information as well, like content types, status codes, and caching.

    Dedicate a separate section to explaining these topics, and link to this section from each related API call. This way you can make sure that developers clearly see how your API handles these topics and how API calls change behavior based on them. 

    Layout and navigation

    Layout and navigation are essential to user experience, and although there is no universal solution for all API docs, there are some best practices that help users interact with the material.

    Dynamic layout

    Most good examples of API documentation use a dynamic layout as it makes navigation easier for users than static layouts when looking for specific topics in extensive documentation. Starting with a scalable dynamic layout will also make sure you can easily expand your docs, as needed.

    Single page design

    If your API documentation isn’t huge, go with a single page design that lets users see the overall structure at first sight. Introduce the details from there. Long, single page docs also make it possible for readers to use the browser’s search functionality.

    Screenshot of Stripe's API reference page
    Stripe managed to present extensive documentation in an easy to navigate single page.

    Persistent navigation

    Keep navigation visible at all times. Users don’t want to scroll looking for a navigation bar that disappeared.

    Multi-column layout

    2- or 3-column layouts have the navigation on the left and information and examples on the right. They make comprehension easier by showing endpoints and examples in context.

    Screenshot of Clearbit's API reference page
    Clearbit’s three-column layout displays persistent navigation (table of contents) on the left, references in the middle, and code examples on the right.

    Syntax highlighter

    Improving the readability of samples with syntax highlighting makes the code easier to understand.

    Screenshot of Plaid's API documentation page
    The syntax highlighter in action on Plaid’s API documentation site.

    If you’d like to start experimenting with a layout for your docs, you might want to check out some free and open source API documentation generators.

    To learn about the pros and cons of different approaches to organizing your API docs in the context of developer portals, this is an excellent article by Nordic APIs.


    All writing that you publish should go through an editing process. This is common sense for articles and other publications, but it’s just as essential for technical documentation.

    The writers of your API docs should aim for clarity and brevity, confirm that all the necessary information is there, and that the structure is logical and topics aren’t diluted with unnecessary content. 

    Editors should proofread your documentation to catch grammar mistakes, errors, and any parts that might be hard to read or difficult to understand. They should also check the docs against your style guide for technical documentation and suggest changes, if needed.

    Once a section of documentation is ready to be published, it’s a good idea to show it to people in your target audience, especially any developers who haven’t worked on the documentation themselves. They can catch inconsistencies and provide insight into what’s missing.

    Although the editing process can feel like a burden when you have to focus on so many other aspects of your API, a couple of iterations can make a huge difference in the final copy and the impression you make.

    Keep it up-to-date

    If your API documentation is out of date, users will get frustrated by bumping into features that aren’t there anymore and new ones that lack documentation. This can quickly diminish the trust you established by putting so much work into your documentation in the first place.

    When maintaining your API docs, you should keep an eye on the following aspects:

    • Deprecated features. Remove documentation for deprecated features and explain why they were deprecated.
    • New features. Document new features before launch, and make sure there’s enough time planned for the new content to go through the editorial process.
    • Feedback. Useful feedback you get from support, or analytics should be reflected in your docs. Chances are you can’t make your docs perfect at the first try, but based on what users are saying, you can improve them continuously.

    For all this to work, you will have to build a workflow for maintaining your documentation. Think about checkpoints and processes for the above mentioned aspects, editing, and publication. It also helps if you can set up a routine for reviewing your docs regularly (e.g. quarterly).

    Following these best practices, you can build a solid foundation for your API documentation that can be continuously improved upon as you gain more insight into how users interact with them. Stay tuned for part two, where I give you some tips on how to turn good API docs into amazing ones.

  18. Project Management for Humans

    A note from the editors: We’re pleased to share an excerpt from Chapter 6 of Brett Harned's new book, Project Management for Humans, available now from Rosenfeld Media.

    I loved the game Tetris as a kid. I played the Game Boy version for hours. It’s easy to get wrapped up in the concept of little shapes coming together in a logical way to clear a goal. The pieces complement one another, yet they all naturally work in different ways. The game has stuck with me since I was a kid (and, no, I’m not a gamer). I now have it on my phone and iPad and find myself playing it when I’m on a flight or bored, waiting for something to happen (which is never these days). Whether I’m playing the game a lot or not, the idea of making tiny boxes fit in neatly and clearing out rows of work is ingrained in my brain. It’s the project manager in me.

    But here’s the thing: What project managers do on a daily basis when it comes to managing resources or staffing is similar to Tetris, and it’s a big project management challenge that we all face. The biggest difference between resourcing and Tetris? The team members we’re trying to assign tasks to aren’t blocks. They’re human beings, and they need to be treated as such.

    Your Team Are People, Too!

    Let’s move away from calling people “resources,” please. We’re really just staffing projects or assigning tasks. We’re not using people to just get things done. We’re asking them to solve challenges that are presented in our projects.

    Set the Stage for Organized Resource Planning

    The challenge of managing a team is making sure that they stay busy and working on tasks, yet are not completely overbooked. It’s a difficult balance to find, particularly when your projects require a variety of skills at different times, which seem to change all too often.

    At the most basic level, you want to set up a system for tracking your projects and your team members’ time on those projects (see Figure 6.1). A simple goal is to ensure that you can confidently commit to deadlines on projects with the knowledge that your team is actually available to do the related work. It seems like a simple goal, but it’s often a difficult one to keep up with due to changes on projects, changes in personal schedules (hey, life happens), and an influx of new work and requests. But it’s not an insurmountable challenge. In fact, a simple spreadsheet could help you, particularly if you’re managing a smaller team. At the core, you want to track these items:

    • Projects (List them all, even the non-billable ones, or the other things that aren’t projects but end up taking a lot of time—like business development.)
    • People (List every person you work with.)
    • Estimated time (Track hours, days, weeks, etc. Make your best guess—based on your timeline or calendar—on how much each person will spend on a project or a task.)
    Spreadsheet showing each person as a column header, with rows corresponding to different tasks, all totaled at the bottom.
    Figure 6.1: Use a Google Spreadsheet, Numbers, or Excel to input your project and team data.

    A couple of notes on how to use a spreadsheet to forecast team availability:

    • This should be set up on a week-by-week basis to minimize confusion (use tabs in your spreadsheet for each new week).
    • Always consider the “nonbillable” things that people must do (like stand-up meetings, internal tasks, sales, etc.).
    • The final cell contains a formula that tallies the hours for you; if the hours go over your typical limit (think of a 40-hour work week), it will turn red to notify you. You’ll want to have a good idea for just how “utilized” someone should be (32 hours/week is usually a good target).
    • You can input the actual hours logged in your time tracking system if you’d like. It could help with future estimating. (If you’re not tracking time, check in with your team on time percentages to get a gut check.)
    • Check your estimates with your team to make sure that the hours actually align with their assessment of the task (This might help with avoiding that red number!)
    • Communicate these hours to the entire team each week. Making sure that everyone “is in the know” will help on any project. Discussing it with individuals will help you understand effort, blockers, and possibly even different ways of working.


    The landscape for project management tools is changing constantly. There are a number of tools in the marketplace for helping you manage and communicate this data. If you’ve working with a team of 10 or more, you might want to abandon the spreadsheet approach for something more official, organized and supported. Bonus: Many of these tools handle more than just resourcing!

    Here’s the thing—it’s not just about numbers. The issue that makes estimating a team’s project hours difficult is that everyone works differently. There is no way to standardize the human factor here, and that’s what makes it tough. Forget the fact that no one on your team is a robot, and they all work at their own pace. Think about sick days, vacations, client delays, changes on projects, and so on. It’s a never-ending flow of shapes that must fit into the box that is a project. Be sure to have an ongoing dialogue about your staffing plans and challenges.

    Match Resource Skills to Projects

    Projects only slow down when decisions are not made. In that magical moment when things are actually going well, you want to make sure that your team can continue the pace. The only way to do that is by connecting with your team and understanding what motivates them. Here are some things to consider:

    • Interests: If you have a team member who loves beer, why not put that person on the beer design site? Maybe you have multiple people who want to be on the project, but they are all busy on other projects. These are the breaks. You’ve got to do what is right for the company and your budget. If you can put interests first, it’s awesome. It won’t always work out that way for everyone, but it’s a good first step to try.
    • Skill sets: It’s as simple as getting to know each and every team member’s work. Some people are meant to create specific types of designs or experiences. It not only has to do with interests, but it also has to do with strengths within those tasks. Sure, I may love beer, but that doesn’t mean that I am meant to design the site that caters to the audience the client is trying to reach.
    • Moving schedules: Projects will always change. One week you know you’re working against a firm deadline, and the next week that has changed due to the clients, the needs of the project, or some other reason someone conjured up. It’s tough to know when that change will happen, but when it does, how you’ll fill someone’s time with other work should be high on your mind.
    • Holidays: People always extend them. Plan for that!
    • Vacations: It’s great to know about these in advance. Be sure you know your company’s policies around vacations. You never ever want to be the PM who says “Well, you have a deadline on X date and that will conflict with your very expensive/exciting trip, so, um … no.” Ask people to request trips at least a month in advance so that you can plan ahead and make it work.
    • Illness: We’re all humans and that means we’re fine one day and bedridden the next. You’ve always got to be ready for a back-up plan. It shouldn’t fall on your client stakeholders to make up time, but sometimes it has to. Or sometimes you need to look for someone to pitch in on intermediate tasks to keep things of track while your “rock star” or “ninja” is getting better.

    Align Plans with Staffing

    When you’re working hard to keep up with staffing plans, you’ve got to have updated project plans. A small change in a plan could cause a change in staffing—even by a few hours—and throw everything else off.

    Save Yourself and Your Team from Burnout

    If you’re busy and not slowing down any time soon, you want to keep this spreadsheet (or tool) updated often. If you’re working at an agency, knowing what’s in your pipeline can also help you. Stay aligned with the person in charge of sales or assigning new projects so that you can anticipate upcoming needs and timelines. In some cases, you may even want to put some basic data in your spreadsheet or tool so that you can anticipate needs.

    Good Resourcing Can Justify More Help

    The value of tracking this data goes beyond your projects. It can help business owners make important decisions on growing a company.

    No matter what you do, be sure to communicate about staffing as much as possible. If you’re in an organization that is constantly handling change, you’ll know that it’s a tough target to hit. In fact, your numbers will often be slightly off, but you’ll find comfort in knowing that you’re doing everything you can to stay ahead of the resource crunch. At the same time, your team will appreciate that you’re doing everything you can to protect their work-life balance.

    Stakeholders Are Resources, Too

    When you’re working on a team with a project, you have to consider the stakeholders as decision makers, too. Let’s face it—no one has ever been trained to be a good client, stakeholder, or project sponsor. In addition to that, they are likely to be working on several projects with several people at one time. Life as a client can be hectic! So do everything you can to help them plan their time appropriately. In general, you should let the stakeholders know they’ll have to plan for these things:

    • Meetings: You’ll conduct a kickoff meeting, weekly status updates, deliverable reviews, etc.
    • Scheduling: You’ll need stakeholders to wrangle calendars to get folks into said meetings.
    • Gathering feedback: This sounds easy, but it is not. You will need this person to spend time with all of the stakeholders to get their feedback and collate it for you to make sure there are no conflicting opinions.
    • Chasing down decisions: There are points on every project where one person will need to make sure there is agreement and decisions can be made to keep the project moving.
    • Daily ad hoc email, phone calls: Questions and requests will pop up, and you’ll need timely responses.
    • Operations: You might need invoices to be reviewed and approved or change requests to be reviewed and discussed. The stakeholders will need to make time to operate the project from their side of things.

    This is a lot of work. And just like PM work, it is very hard to quantify or plan. If you’re in good hands, you’re working with someone who has good PM skills. If not, give them the list above along with a copy of this book. But seriously, if you can assist them with planning their time, it might be as simple as including action items or to-dos for them in a weekly email or in your status report. Just remember, they are busy and want the project to run smoothly as well. Help them make that happen.

    TL; DR

    Managing projects is hard enough, but being the person to manage who works on what and when can be even more difficult. However, if you don’t keep track of this basic information, you’ll likely find it hard to meet deadlines and wrap up projects without major issues. Here are some simple things you can do to make sure your that your team stays busy, yet not completely overbooked:

    • Set up a simple spreadsheet to forecast projects and hours per team member.
      • This data should be based on what’s included in your project scopes and timelines—be sure to double-check that.
      • You may want to check out one of the resourcing tools that are out there now.
    • Be sure to account for a number of factors that you can’t necessarily control in this process—for example, interests, skill sets, moving schedules, holidays, vacations, and so on.
    • Account for your sales process if you’re in an agency and stay ahead of new project requests.
    • Remember that you’re dealing with people here.

    Want to read more?

    This excerpt from Project Management for Humans will help you get started. Order the full copy today, as well as other excellent titles from Rosenfeld Media.

    Project Management for Humans
  19. A List Apart volunteer update

    A note from the editors: A few days ago, we announced a reimagined A List Apart, with you, our faithful readers of nearly 20 years, contributing your talents. The response from this community was humbling, thrilling, and, frankly, a bit overwhelming. If you volunteered to help A List Apart and haven’t heard back from us yet, here’s what’s up.

    To the many wonderful souls who have so far volunteered to help A List Apart, thank you very, very much for your emails! And if you haven’t heard back from us yet,  please excuse the delay. We’ve been inundated with messages from hundreds of potential volunteers across a wide spectrum of disciplines and potential task groups, and we are going through your messages slowly and carefully, responding personally to each one.

    Some of you have written asking if we might be interested in having you write for us. Gosh, A List Apart has always welcomed articles from our community. Guidelines (plus how to submit your first draft, proposal, or outline) are available at alistapart.com/about/contribute. Please check them out—we’d love to look at any topically appropriate article you care to submit. 

    But writing articles is far from the only way to support and make your mark at the new (19-year-old) ALA.

    Meet the groups!

    If you’ve expressed an interested in organizing or hosting an ALA-themed monthly meet-up, or have other ideas that can help grow community, we’ll invite you to join our newly forming COMMUNITY group. If EDUCATION AND OUTREACH is more your thing, we are starting a group for that, as well. There are other groups to come, as well—a list of our ideas appears in the original post on the topic, and there may be more groups to come.

    How these groups will work, and what they will do, is largely going to be determined by the volunteers themselves. (That’s you folks.)

    As we’re starting the work of supporting and organizing these groups on Basecamp, you can’t just add yourself to a group, as you could on, say, Slack. But that’s okay, because we want to approach this somewhat methodically, adding people a few at a time, and having little written conversations with you beforehand.

    Our fear was that if we launched a bunch of Slack channels all at once, without speaking with each of you first, hundreds of people might add themselves the first day, but then nobody would have any direction as to what might be expected—and we might not have the resources ready to provide guidance and support.

    By adding you to Basecamps a few at a time, and hopefully identifying leaders in each new group as it begins forming, we hope to provide a lightly structured environment where you can design your own adventures. It takes a little longer this way, but that’s by design. (A List Apart started in 1997 as a 16,000-member message board. Big open channels are great for letting everyone speak, but not necessarily the best way to organize fragile new projects.)

    If you are interested in contributing to those projects, or curious about a particular area, and told us so in your initial email, we will eventually get to you and assign you to the right slot. If you haven’t yet volunteered, of course, you can still do so. (See the original post for details.)

    Editors, developers, and designers

    But wait, there’s more. Developers: if you have standards-oriented front-end development experience and would like to help out on day-to-day site maintenance, occasional minor upgrades, and an eventual redesign, just add yourself to A List Apart’s Github front-end repo: github.com/alistapart/AListApart.

    Those with backend experience (particularly in ExpressionEngine and WordPress), you will hear from us as we work our way through your emails.

    Editor-in-chief Aaron Gustafson and I have also been going slowly through your mails looking for additional editorial help. We’ve already found and added a few very promising people to our volunteer editorial staff, and will introduce them to you soon. If you’re an editor and we haven’t added you yet, not to worry! It likely means we haven’t gotten to your email yet. (So. Much. Email!)

    As might be expected, a majority of those who volunteered offered their services as designers, developers, or both. The number of emails we’ve received from folks with these skills is humbling, touching, and a bit overwhelming. We have not yet begun to dig through this particular pile of mail. So if you haven’t heard from us, that’s why. (But, as I just mentioned, if you’re a developer, you can add yourself to our front-end repo. So do that, if you wish, and say hi!)

    We love you

    Hope this helps clarify what’s up. We are grateful for every single email we’ve gotten. We will eventually speak with you all. Thank you all again.



  20. Patterns and Purpose, an Excerpt from Animation at Work

    A note from the editors: We’re pleased to share an excerpt from Chapter 2 of Rachel Nabors's new book, Animation at Work, available now from A Book Apart.

    So we can use animations to tap into users’ visual systems and give them a cognitive speed boost, terrific! But before animating every element of our designs, we must learn when and how to use this new tool: with great power comes great responsibility, and so forth. And as animation must vie with many other concerns for development and design time, it makes sense to spend our resources where they’ll go the farthest.

    This chapter sets you up with some core animation patterns and shows you how animation applies to a greater system. Then you’ll learn how to spot cognitive bottlenecks and low-hanging fruit, maximizing the impact of the animations you do invest in.

    Common Animation Patterns

    If you’ve looked at as many examples of animation on the web and in app interfaces as I have, certain patterns start to emerge. These patterns are helpful for identifying and succinctly verbalizing the purpose of an animation to others. Here are the categories I’ve found myself using the most:

    Transitions take users from place to place in the information space, or transition them out of one task into another. These tend to have massive impacts on the content on the page, replacing large portions of information.

    Supplements bring information on or off the page, but don’t change the user’s “location” or task. They generally add or update bits of additional content on the page.

    Feedback indicates causation between two or more events, often used to connect a user’s interaction with the interface’s reaction.

    Demonstrations explain how something works or expose its details by showing instead of telling.

    Decorations do not convey new information and are purely aesthetic.

    Let’s have a look at each of them and see how they impact the user’s experience.


    The web was originally designed as a series of linked documents. Clicking on a link caused the browser to wipe the screen, often causing a telltale flash of white, before painting the next page from scratch. While this made sense in the context of linked text-based documents, it makes less sense in an era where pages share many rich design elements and belong to the same domain. Not only is it wasteful of the browser’s resources to be recreating the same page layout over and over, but it also increases users’ cognitive load when they have to reorient and reevaluate the page’s content.

    Animation, specifically motion, can facilitate the user’s orientation in an information space by offloading that effort to the brain’s visual cortex. Using a transition between changes in task flow or locations in information architecture ideally reinforces where the user has been, where they are going, and where they are now in one fell swoop.

    For example, on Nike’s SB Dunk page, when a user clicks a navigation arrow, the current sneaker moves out of the way while the next sneaker moves in from the opposite direction (Fig 2.1). These transitions clearly show the user how they are navigating along a linear continuum of sneakers, helping them keep track of their place and reinforcing the spatial model of perusing a real-world row of sneakers.

    Fig 2.1: On this Nike page, transitions are used to navigate forwards and backwards along a linear continuum of sneakers. (Watch the accompanying video.)

    On another shoes site, fluevog.com, transitions move the user from task to task (Fig 2.2). After a user starts typing in the search field, the results are animated on top of a darker backdrop. This transitions the user from the browsing context to refining their search results, streamlining their focus while also reassuring them that they can get back to browsing without much effort.

    Fig 2.2: On Fluevog’s website, transitions move users from the browsing context to the searching context. (Watch the accompanying video.)


    While transitions move the user from state to state, supplemental animations bring ancillary information to the user. Think of times when information complementary to the main content of the page appears or disappears in view: alerts, dropdowns, and tooltips are all good candidates for a supplemental animation on entry and exit.

    Remember that these animations need to respect the user’s Cone of Vision: will they be looking directly at a tooltip appearing next to their cursor, or will their attention need to be directed to an alert on the side of their tablet?

    When a user adds a product to their shopping cart on glossier.com, rather than taking them to a whole new shopping cart page, the site merely updates the user as to their cart’s contents by popping it out as a sidebar (Fig 2.3c). While a transition would snap the user out of browsing mode, this supplemental animation lets the user dismiss the shopping cart and continue shopping.

    The shopping cart sidebar uses an additional supplemental animation to quickly and subtly attract the user’s eye: a progress meter gradually fills to show how much the user needs to spend to get free shipping (Fig 2.3d).

    Fig 2.3: Glossier.com uses supplemental animation to show and hide the user’s shopping cart, keeping them in the shopping context longer without forcing them into the purchasing context. (Watch the accompanying video.)

    This shopping cart process has a third animation pattern going on: the Add to Bag button gains a spinning icon when clicked, which gives the user feedback as to its loading state (Fig 2.3b). Speaking of feedback…


    Animation can give users direct feedback about their interactions. A depressed button, a swiping gesture—both link a human action to an interface’s reaction. Or the flip side: a loading spinner on a page indicates that we’re waiting on the computer. Without visual feedback, people are left wondering if they actually clicked that “pay now” button, or if the page is really loading after all.

    On the Monterey Bay Aquarium’s site, hovering over a button causes its color to fade from red to blue, indicating that the element is interactive and ready to react to user input (Fig 2.4). Button hovers are classic examples for this kind of animation, partly because the gain of giving users visual feedback on buttons is so measurable and important to business.

    Fig 2.4: On the Monterey Bay Aquarium’s site, hovering on a button triggers an animation that gives the user feedback that the element is interactive. (Watch the accompanying video.)

    Design studio Animal’s site uses a bar of color across the top of the page as well as an animated version of their logo to indicate the page’s loading and loaded states while providing interest and reinforcing their “wild” branding (Fig 2.5).

    Fig 2.5: Design studio Animal uses a progress to let users know how much of the page has loaded, and an animated logo to indicate when it’s fully loaded. (Watch the accompanying video.)


    Demonstrations are my personal favorite use of animation. They can be both entertaining and insightful. These animations put information into perspective, show what’s happening, or how something works. This makes demonstrative animations perfect partners for infographics. One thing all demonstrative animations do is tell a story, as you’ll see.

    “Processing…” pages are an opportunity to explain what’s happening to users while they wait. TurboTax makes good use of these processing pages (Fig 2.6). After users submit their US tax forms, it banishes any remaining anxiety by showing them where their information is headed and what they can expect—all while reinforcing their brand’s friendliness and accessibility. (It also helps that the animation distracts users from a rather lengthy page load with something visually engaging!)

    Fig 2.6: TurboTax both informs their users and masks long page loads by demonstrating what’s going on after the user submits their US tax forms. (Watch the accompanying video.)

    Coin famously uses demonstrative animations to explain their consolidation card’s value proposition to curious visitors as they scroll through the site (Fig 2.7)—no need to press play and sit through a video ad or wade through paragraphs of expository content. This page is the very essence of “show, don’t tell.”

    Fig 2.7: As visitors scroll through Coin’s site, the company’s value proposition plays out in front of them. (Watch the accompanying video.)


    It’s not hard to mistake decorative animations for demonstrative animations. But there is a key difference: where demonstrations bring new information into the system, decorative animations do not. They are the fats and sugars of the animation food pyramid: they make great flavor enhancers, but moderation is key.

    The best way to spot a purely decorative animation is to ask, “What can a user learn from this animation? Does this guide them or show them something they wouldn’t know otherwise?” If the answer is no, you might have a decorative animation on your hands.

    Even though they get a bad rap, decorative animations can help turn the ordinary into the extraordinary. Revisionist History’s site uses decorative animations judiciously to bring flat illustrations to life. The animations add just enough interest to allow for the visual content on the page to be more austere, letting users focus on the podcast (Fig 2.8).

    Fig 2.8: Revisionist History’s site uses decorative animations to add visual interest to non-visual media. (Watch the accompanying video.)

    Polygon.com epically used animated illustrations to create centerpieces for a series of console reviews. These decorative animations may not have added new information, but they crucially reinforced the Polygon brand. They also helped each console review stand out from the competition, which at the time sported indistinguishable photographs of the same devices.

    Fig 2.9: Polygon uses decorative animations as a showstopping feature to stand out from the competition. (Watch the accompanying video.)

    Want to read more?

    This excerpt from Animation at Work will help you get started. Order the full copy today, as well as other excellent titles from A Book Apart.

    Animation at Work by Rachel Nabors