Naming things to improve accessibility

One thing you can do to improve the accessibility of your work is to always ensure things have accessible names. Unique and useful names, ideally, so that they can be used for navigation. In this post I’ll explain how browsers decide on the names for links, form fields, tables and form groups.

This post is based on part of my talk 6 ways to make your site more accessible, that I gave at WordCamp Rotterdam last week.

Accessibility Tree

When a user accesses your site, the server will send markup to the browser. This gets turned into trees. We’re probably all familiar with the DOM tree, a live representation of your markup, with all nodes turned into objects that we can read properties of and perform all sorts of functions on.

What many people don’t know, is that there is a second structure that the browser can generate: the accessibility tree. It is based off the DOM tree, and contains all meta information relation related to accessibility: roles, names and properties. Another way to say it: the accessibility tree is how your page gets exposed to assistive technologies.

Assistive Technology

Assistive Technology (AT) is an umbrella term for all sorts of tools that people use to improve how they access things. For computers and the web, they include:

  • alternate pointing devices, like a mouse that attaches to a user’s head
  • screen magnifiers, they enlarge the screen
  • braille bars, they turn what’s on the screen into braille
  • screenreaders, they read out what’s on the screen to the user
Alternate pointing devices, braille bars, screen magnifiers and screenreaders

All of these tools, to work efficiently, need to know what’s happening on the screen. To find out, they access Platform APIs, built into every major platform, including Windows, Mac and Linux. The APIs can expose everything in the OS, so they know about things like the Start Bar, Dock or the browser’s back button. One thing they don’t know about, is the websites you access. They can’t possibly have the semantic structure of every website built into their APIs, so they rely on an intermediary — this is where the Accessibility Tree comes in. It exposes your website’s structure. As I said, it is based on the DOM, which is based on our mark-up.

Your markup becomes a DOM tree which the accessibility is based on which is then sent to platform APIs and ultimately ends up at assistive technologies A handy flow chart

The accessibility tree exposes roles (is this a header, a footer, a button, a navigation?), names (I’ll get into those in a bit), properties (is the hamburger menu open or closed, is the checkbox checked or not, et cetera) and a number of other things.

If you want to see what this looks like on a site of your choosing, have a look at the Accessibility Panel in Firefox Developer Tools, or check out the accessibility info boxes in Chrome, Safari Tech Preview or Edge developer tools.

Accesssible name computation

Names are one of the things the accessibility tree exposes for its objects. What a thing’s name is, gets derived from markup. There are many aspects that can influence this. If you want to know this in detail, check out the Accessible Name and Description Computation Specification.

Unique names help distinguish

Before going more into how to expose names, let’s look at which names we want. What the names are is crucial for whether they are accessible or not.

What if your family has four cats, and each of them is named ”Alice”? This would be incredibly impractical, as it would make communication difficult. “Has Alice been fed yet?”, you might wonder. “Is Alice outside?”, you might ask your partner. Ambiguity is impractical. Yet, this is what we do when our homepage has four news items, with each “Read more” as its link text.

Four very cute cats Imagine all of your cats were named Alice (photo: stratman2 on Flickr)

This is very common, sadly. In the WebAIM Million project, in which WebAIM looked at over a million sites and ran automated accessibility checks, they found:

24.4% of pages had links with ambiguous link text, such as ‘click here’, ‘more’, ‘continue’, etc.

Reusing “Read more” as the link text for each news item makes our code and content management simpler, but it provides bad usability for screenreader users. When they use the link shortcut to browse through links on the page, they will have no idea where each links leads them. In the example above, when you ask an AT to read out all links, it will read “Link Read more, Link Read more, Link Read more, Link Read more”.

Naming things

So, unique and descriptive names are useful to AT users. Let’s look at which HTML can help us provide names. As I said before, the heuristics for determining names are in a spec, but with just HTML providing names for most things is trivial. The following section is mostly useful for people whose HTML is rusty.


The contents of an <a> element will usually become the accessible name.

So in:

<a href="/win-a-prize">
Win a prize</a>

the accessible name would compute as “Win a prize”.

If there’s just an image, its alt text can also get used:

<a href="/win-a-prize">
  <img src="prize.png" alt="Win a prize" />

And, to be clear, if there’s nothing provided, the name would be null or empty string, so some people would be unable to win any prize.

Form fields

Form fields get labelled using the <label> element. In their aforementioned research, WebAIM also found:

59% of form inputs were not properly labeled.

Let’s look at what a labelling mistake could look like:

<div>Email</div> <!-- don't do this-->
<input type="email" id="email" />

In this example, the word “Email” appears right before the input, so a portion of your users might be able to visually associate that they belong together. But they aren’t associated, so the input has no name— it will compute as null or '' in the accessibility tree.

Associating can be done by wrapping the input in a <label> element, or by using a for attribute that matches the input’s id attribute:

<label for="email">Email</label> <!-- do this-->
<input type="email" id="email" />


To give a table a name, you can use its <caption> element. This is used as the first element in a <table>.

Groups in a form

Within forms, you sometimes want to group a set of form inputs, for example a collection of radiobuttons or checkboxes that answer the same question. HTML has <fieldset> for grouping form elements. To name this group as a whole, use the <legend> element:

  <legend>Don't you love HTML?</legend>
  <input type="radio" name="yesno" id="yes"/>
  <label for="yes">Yes</label>
  <input type="radio" name="yesno" id="no"/>
  <label for="no">No</label>

If you were to inspect this fieldset in the accessibility tree, you will notice that the group is now known as “Don’t you love HTML?”.

What about ARIA?

Those familiar with the Accessible Name and Description Computation spec might wonder at this point: doesn’t ARIA also let us give elements accessible names? It totally does, for instance through the aria-label / aria-labelledby attributes. When added to an element, they overwrite the accessible name (if there was one).

Good reasons to prefer standard HTML tags over ARIA include:

  • better browser support (a lot of browsers support most ARIA, but all support all HTML, generally speaking)
  • more likely to be understood by current or future team members that don’t have all the ARIA skills
  • less likely to be forgotten about when doing things like internationalisation (in your own code, or by external tools like Google Translate, see Heydon Pickering’s post aria-label is a xenophobe)

Sometimes ARIA can come in handy, for example if an element doesn’t play along well with your CSS (like if you want a Grid Layout in a fieldset), or if your (client’s) CMS is very inflexible.

It’s the markup that matters

In modern browsers, our markup becomes an accessibility tree that ultimately informs what our interface looks like to assistive technologies. It doesn’t matter as much whether you’ve written this markup:

  • in a .html file
  • in Twig, Handlebars or Nunjucks
  • as the <template> in a Vue Single File Component
  • exported in the JSX of your React component
  • outputted by a weird legacy CMS

It is which markup that determines if your site is pleasurable to experience for AT users. In short: it’s the markup that matters

There’s good chance your site already uses all of the above HTML elements that name things. They have existed for many years. But I hope this post explains why it is worth the effort to always ensure the code your site serves to users, includes useful names for assistive technologies. Markup-wise it is trivial to assign names to all things on our site, the real challenge is probably two fold. It’s about content (do we come up with useful and distinguishable names), and about tech (can we ensure the right markup gets into our user’s DOMs).

Comments, likes & shares (193)

Eka, Jitendra Vyas, , Anneke Sinnema, adrian , Phil Thompson, Timon van Hasselt, Erik Kroes, Dean Birkett, geertmelotte, Andreea Popescu, Guillaume Deblock, Juan Olvera , Randall Kaemmerer, Alberto Calvo, Stefan Etoh, Ser Bob of Tarth, Enmanuel Ruffinelli, 지성봉(Seong bong Ji), GnarlyQuinn, desliguei o aquecedor da piscina, Johan Groenen, Erwin / (perceived) performance / technical UX/CRO, patak, Alistair Shepherd, jpagroenen, Accessabilly, Matt Edgar, Justin 👋🏻, Juhis, Kees de Kooter :mastodon:, Harley Eades, Sami Määttä, Accessabilly, James Bateson, Tim Kraut, Sheri Richardson, María Ozámiz, Anuradha Kumari, Kitty Giraudel, Lenn Grey :v_enby: :v_trans:, Logan, Gustavo :mastodon_com_br:, Max R. Cerrina (he/him), Sammie, muffindev, Nikita, Kathiravan J, JP de Vries, Frank van Eldijk-Smeding, André 📔, Mario Vasquez, Stephen B, Meagan, Lexi, Hana Lee | 이하나, Tyler Sticka, Misty, negi4a, Qais Alrefai, Florian Geierstanger, Eric Eggert, グレェ「grey」, JeffGPT, Bogdan Cerovac, Tatiana Fokina, Thibault Mahé, The Samus Aran-Contra affair, Joe Lanman, Chris, Chris :python: :rust:, Nic, Luz De León, Pauxlll Kruczynski, max k, Michaël Vanderheyden, Michael Spellacy (Spell), James Fleeting, Benjy Stanton 🦣, Leire Díez, Amy, Martin Lexelius, Ama 🐝, Casey Robinson👨🏻‍💻, Carys, 🦞 Todd, Creyawn, David, Kyle Morris, ☯Evil Jim O'Donnell, Michael Jovel, joseph and liked this

Milo Vermeulen, Jitendra Vyas, geertmelotte, Shari Hunt, Eric Bailey, Kat, Ser Bob of Tarth, Eric Bailey, Tim Kraut, Линкольн | :bantu: | لينكولن, loapher, Juhis, Harley Eades, Alistair Shepherd, jpagroenen, Accessabilly, Sarah Fossheim :they_them:, tanvi.css, Drazi Crendraven :verified:, Max R. Cerrina (he/him), Kathiravan J, Misty, Web Axe, Hana Lee | 이하나, Mario Trost, Marjon Bakker, グレェ「grey」, Florian Geierstanger, Eric Eggert, Adrian Cochrane, Jeremy Neander, Chris :python: :rust:, Σ🌈Jedi🦻👓∉, Luz De León, Henri Helvetica 🇭🇹 👨🏾‍🚀 🚀, Amy, Justin Yarbrough, Winnie-a11y member, Julie Toral, Alexander Lehner, enqueue, Carys, Creyawn and ☯Evil Jim O'Donnell reposted this

Roel Van Gils wrote on 20 April 2019:
What if your family has four cats, and each of them is named Alice? That sounds very impractical, but it’s what poor markup translates to for screenreader users. In this latest post, @hidde explains how to name things properly. #a11y…
Michael Scharnagl wrote on 23 April 2019:
Naming things to improve accessibility…
Andreea Popescu wrote on 23 April 2019:
Great article.
Benjy Stanton wrote on 23 April 2019:
Using "read more" as link text makes as much sense as having 4 cats and calling them all Alice.…
Claire Brotherton wrote on 23 April 2019:
Why naming things in your code is so important for accessibility…
Rogier Barendregt wrote on 23 April 2019:
Naming things to improve accessibility…
Rachel Ann Fraser wrote on 26 April 2019:
Naming things to improve accessibility…
Yohan J. Rodríguez wrote on 26 April 2019:
#CSS #Automated | Naming Things to Improve Accessibility…
Ann wrote on 25 April 2019:
Naming things to improve accessibility…
Fresh Frontend Links wrote on 26 April 2019:
Naming things to improve accessibility…
Ruthie Edwards wrote on 28 April 2019:
Something I didn’t consider when building my current website — accessible component names!…
Eduardo Meza-Etienne, MSc, MIM, CPACC wrote on 28 April 2019:
Naming things to improve accessibility #a11y…
지성봉(Seong bong Ji) wrote on 29 April 2019:
I am very grateful for sharing a good article. I would like to translate this article into Korean and share it with developers via my blog, would you allow me?
Hidde wrote on 29 April 2019:
Absolutely, please do. Could you please link back to the original and send me a link so that I can link to your translation? Thanks!
지성봉(Seong bong Ji) wrote on 29 April 2019:
Oh! Thank you. Of course. I'll send you a link after I translate and post it. :)
Hana Lodhi wrote on 29 April 2019:
'...this post explains why it is worth the effort to always ensure the code your site serves to users, includes useful names for assistive technologies...…
ダーシノ wrote on 29 April 2019:
Naming things to improve accessibility… セマンティックマークアップもリンクのテキストも重要という話。「詳細はこちら」というリンク、「こちら」ってどちらだよ!ってなるから意味の伝わるテキスト(名前)を付けましょうとか、labelやcaptionで名前を付けようという内容
Jeremy Keith wrote on 29 April 2019:

Some good advice from Hidde, based on his recent talk Six ways to make your site more accessible.

Adactio Links wrote on 29 April 2019:
Naming things to improve accessibility…
Baldur Bjarnason wrote on 29 April 2019:
“Naming things to improve accessibility”…
Ann wrote on 29 April 2019:
Naming things to improve #accessibility…
Floor Drees wrote on 30 April 2019:
TIL: Reusing link text ("Read more") for each item makes our code and content management simpler, but it provides bad usability for screenreader users.

Also label your form fields correctly, and other tips
Floor Drees wrote on 30 April 2019:
TIL: Reusing link text ("Read more") for each item makes our code and content management simpler, but it provides bad usability for screenreader users.

Also label your form fields correctly, and other tips
Federica Dardi wrote on 30 April 2019:
Una cosa che puoi fare per migliorare il tuo lavoro è assicurarti che le cose abbiano nomi accessibili…
DEVELOPER NEWZ wrote on 1 May 2019:
Naming things to improve accessibility…
Dakshraj Enterprise wrote on 2 May 2019:
Naming things to improve accessibility…
freshmade wrote on 2 May 2019:
Naming things to improve accessibility… via @chriscoyier
Charlie Charlie wrote on 2 May 2019:
Naming things to improve accessibility…
越智です wrote on 2 May 2019:
Arturo Wibawa wrote on 2 May 2019:
Naming things to improve accessibility…
Priya wrote on 2 May 2019:
Naming things to improve accessibility… #a11y
Finest Design LTD wrote on 2 May 2019:…
The A11Y Project wrote on 3 May 2019:
"One thing you can do to improve the accessibility of your work is to always ensure things have accessible names."…
Animadio wrote on 4 May 2019:
Naming things to improve accessibility…
Web Axe wrote on 5 May 2019:
Naming things to improve accessibility:… HT @LyndonDunbar #webdev #a11y #html
dailydevlinks. wrote on 6 May 2019:
Naming things to improve accessibility:…

#html #css #javascript #webdev #dailydevlinks
Aurélie wrote on 9 May 2019:
Naming things to improve accessibility…
Hassell Inclusion wrote on 9 May 2019:
Hidde de Vries writes about improving the accessibility of your work by ensuring things have accessible names @hdv @TheUXCollective #UX #A11y #InclusiveDesign
Hassell Inclusion wrote on 9 May 2019:
Hidde de Vries writes about improving the accessibility of your work by ensuring things have accessible names @hdv @TheUXCollective #UX #A11y #InclusiveDesign
Jahangeer Ansari wrote on 16 May 2019:
Naming things to improve accessibility #UXdesign #UX…
Cath wrote on 17 May 2019:
naming things to improve accessibility:… #accessibility #ux
Delany Bisbee wrote on 12 October 2019:
Naming things to improve accessibility…
Women Who Code BOS wrote on 15 January 2020:
This post explains why it is worth the effort to always ensure the code your site serves to users includes useful names for assistive technologies.…
Christine Amsel wrote on 16 March 2020:
Naming things to improve accessibility…





WebAIM,是一家总部位于美国犹他州的非营利组织。自2019年,启动WebAIM Million’项目。每年发布综合分析报告,观察互联网可用性的发展趋势和改善/下降。


一是“易于感知的问题”和“对用户造成影响的问题”,两者无关,是不一样的。自动化测试也只涵盖了所有互联网可用性中的一小部分,因为有些问题机器(现在或永远)无法检测。我并不是说这会降低调查的作用,而是想明确指出这一点。W3C的ACT-Rules 组织致力于指定合理的测试规则。

好的,让我们看看当今最热门的问题以及开发人员、浏览器和 CMS 是如何解决问题的。


在某些情况下,文本颜色和背景颜色的对比度低于WCAG阈值(另请参见MDN on contrast)。

通过安装插件(如:Contrast Ratio 设计师可以检查对比度。

开发人员可以使用自动对比度检查器,来确保避免使用低对比度文本。运行一个检查器,如Firefox 开发工具辅助功能面板中的检查器或CI/CD 的ax,或者将两种颜色粘贴到一个手动工具中,如 Contrast Ratio。

设计人员和开发人员都可以使用 Polypane 的对比度检查器,它会给出替代方案建议,这不仅可以更轻松地找到问题,还可以同时修复问题。

用户可以使用像Fix Contrast这样的插件:它可以即时微调颜色,这样就不必忍受低对比度文本。



当你创建内容,对图片进行描述。在使用Twitter的内容管理器,甚至在GitHub上发布帖子:使用替代文本功能,以便看不到图像的用户可以访问图片的替代文本。在不支持替代文本的平台上,例如 Slack 或移动 LinkedIn (!),可以用文本描述图像。如果您选择 CMS 或内容平台,确保它可以处理或设置使用替代文本。

生成的 HTML 如下:

<!-- image with text -->
<img src="website-logo.png" alt="" />

<!-- image with redundant content -->
<img src="hidde.png" alt="" /> 
<p>Photo of Hidde</p>

你可根据Alt Decision Tree书写替代文本。文本内容的要点是,如果图像的位置显示出一个正方形,在正方形中写什么以使其不影响阅读?可以选择将其留空。就像上面的例子一样,有一张照片,下面有一段描述它的段落。在这种情况下,在alt属性中写“Hidde”或“Hidde 的照片”是多余的,最好使用一个空的alt(但不要将属性保留在那里,否则某些浏览器会使用图像 URL 作为替代)。

用户可以使用 Microsoft Edge,它可以填补缺失的替代文本。AI 不擅长理解意图或背景,但精通识别文本。下次新闻网站再发布新冠病毒防治新规则的图片,并不带有替代文本时(就像荷兰主要新闻网站在整个疫情期间所做的那样),Edge 的用户可以理解其内容。



屏幕阅读器说“这里有 4 个按钮:按钮、按钮、按钮和按钮”与“这里有 4 个按钮:发布内容、删除内容、更改为草稿、上传图像”,想象一下两者之间的区别。在第一种情况下,需要按一下按钮才知道按钮的用处;在第二种情况下,不需要任何额外操作。



<!-- names that make sense out of context -->
<button>Submit form</button>
<button>Publish content</button>
<button>Expand filters</button>
<a href="//">Wikipedia</a>
<a href="//">Hidde on Twitter</a>

<!-- names that are confusing -->
<a href="/">click here</a><!-- avoid -->
<a href="/">read more</a><!-- avoid -->

<!-- names that are missing; avoid or add a name -->
<a href="//"><svg/></a><!-- avoid -->
<a href="//"><img src="" alt="" /></a><!-- avoid -->
<button><img/><button><!-- avoid -->





<!-- “for” and “id” are same, this connects them -->
<label for="field">Address</label>
<input id="field" />

他们还可以给输入框添加一个aria-label属性(注意,ARIA 标签解析得不好)。


开发人员应确保元素具有 lang 属性,并使用正确语言:

<!-- marks this document as 'in English -->
<html lang="en">

有时有忘记,因为<html> 元素存在于哪些从未修改过的模板中,但这并不难,因此请务必仔细检查此属性是否存在并设置为正确的语言。

如果页面的一部分内容是另一种语言的,在相应DOM节点元素上再次设置lang属性。当使用国际化的插件时,确保设置了 langs 。

CMS可以确保 lang 属性的正确设置。浏览器可以猜测语言,但也有可能出错,特别是在区分方言时:它们通常对人很重要,而对机器则不那么重要。


HTML, CSS, JavaScript, Python, PHP, C++, Dart — there are so many programming languages out there and you may even be totally fluent in several of them! But as we aim to write more and better code, the way we write and communicate in everyday language becomes more and more important… and perhaps even overlooked.

The way we write about and around code is arguably as important as the code itself. And despite where you fall on that line, we can all agree that our words have the potential to both help and hurt code’s effectiveness.

In this article, I want to outline how these two seemingly distinct fields — programming and writing — can come together and take our developer skills to the next level.

Wait, technical writing? Yes, that’s exactly what I mean. I truly believe we are all writers in one sense or another. And I’m here to give you a primer with writing tips, advice, and examples for how it can make you both a better developer and communicator.

Table of contents

Technical writing is everywhere

Last year, the team behind the popular Mac Git client, Tower, polled more than 4,000 developers and found that nearly 50% of them spent between 3-6 hours a day writing code.

Bar chart showing actual programming time per day.

And yes, that’s one survey polling a pretty niche group, but I imagine many of us fall somewhere in that range. Whatever the case, a developer isn’t writing code 24/7, because as this poll suggests, we’re spending plenty of time doing other things.

That might include:

  • demoing a new feature,
  • documenting that new feature,
  • updating a work ticket related to that new feature, or
  • backlogging work to support that new feature.

Of course, there’s always time for bathroom breaks and Wordle too.

Anyway, most of the things we typically do involve communicating with people like your team, colleagues, clients, users, and other developers.

So we do spend a good chunk of our time communicating with humans through words in addition to the communication we have with computers through code. Words are written language. And if we wrote our words better, we’d communicate better. When we communicate better, we’re more likely to get what we want.

That’s Technical Writing 101.

Venn diagram showing the overlap between technical writing and coding.

And it doesn’t even end here.. Some programmers also like to make their own products, which means they need to make marketing part of their job. Technical writing plays a huge role in that too. So, yeah. I think it’s pretty fair to say that technical writing is indeed everywhere.

What is good grammar?

With so many programming languages out there, the last thing we want is to learn another one.

Grammar is an integral part of English, and it unlocks the full potential of communication. It makes us more formal, professional, and coherent.

Let me give you a quick rundown on language.

The English syntax

Just like programming languages, English has a well-defined syntax, and it starts with words.

Words are the building blocks of English, and they fall into eight buckets:

Color coded sentence showing the English syntax.

These can be names of people, animals, places, concepts, and objects.

CSS is one of the core languages of front-end development.


Verbs convey action. Even “is” can be considered an action.

Marcia codes in the morning and answers emails in the afternoon.


Adjectives are how we describe nouns. They’re like meta that adds more detail to a sentence to paint a vivid picture.


  • CSS is an elegant and poetic language.
  • The HTML for tables is complex and cumbersome.
  • The Box Model is important to understand CSS.

Prepositions create a relationship between a noun and other words, often indicating direction, time, location, and space.


  • Did you commit your work to the repo?
  • What is the best approach for this component?
  • We conducted interviews with real users.

Sometimes actions need to be more specific, so we use adverbs such as “runs fast” and “compiles slowly.” They often end in “-ly.”


  • This is easily the best idea of them all.
  • Chip waited patiently for Dale’s feedback.
  • The team worked diligently on the project.

Conjunctions connect phrases in a sentence. Remember this classic song from the show School House Rocks?


  • CSS for styling while HTML is for markup.
  • Yes, I write code, but I also work on design.
  • That fixes the bug. Yet it introduced a new one.

Paragraphs are made of sentences that are connected to each other using transitions.


  • There are many programming languages. However, only a few are used in the web industry.
  • First, clone the directory.
  • I like this approach but on the other hand, I know another one.

When nouns become repetitive, we replace them with pronouns such as: “he,” “it,” and “that.”


  • CSS is a stylesheet language. We use it to style websites.
  • Tony loves to code and he practices every day.
  • Our customers are tech-savvy because they know code.

Think of these like UI components: they are modular pieces you can move around to construct a complete and robust sentence, the same way you might piece together a complete and robust UI. Do all of the components need to be there all of the time? Certainly not! Assemble a sentence with the pieces you need to complete the experience, just as you would with an interface.

Voice and tone

Vocabulary, punctuation, sentence structure, and word choice. These are all the ingredients of English. We use them to share ideas, communicate with our friends and family, and send emails to our coworkers.

But it’s crucial to consider the sound of our messages. It’s amazing how one exclamation point can completely shift the tone of a message:

  1. I like programming.
  2. I like programming! 🙂

It’s easy to confuse voice for tone, and vice versa.

Voice is what concerns our choice of words, which depends on context. For example, a tutorial for beginners is more likely to use slang and informal language to convey a friendly voice, whereas documentation might be written in a formal, serious, and professional manner in an effort to get straight to the point.

The same message, written in two different voices:

  • Fun: “Expand your social network and stay updated on what’s trending now.”
  • Serious: “Find jobs on one of the largest social networking apps and online jobs market.”

It’s not unusual to accidentally write messages that come across as condescending, offensive, and unprofessional. This is where tone comes into play. Read your messages out loud, get other people to read them for you, and experiment with your punctuation and sentence structure. That’s how you hone your tone.

Here’s another way to think of it: your voice never changes, but your tone does. Your voice is akin to who you are as a person, whereas tone is how you respond in a given situation.

Active and passive voice

A sentence always contains an actor, a verb, and a target. The order in which these come determines if the sentence is written in an active or passive voice.

The actor comes first in an active voice. For example: “CSS paints the background.”

Sentences that use an active voice are more straightforward than their counterparts. They’re clearer, shorter, and more understandable — perfect for a more professional voice that gets straight to the point.

With a passive voice, the actor comes last. (See what I did there?) That means our actor — CSS in this case — comes at the end like this: “The background is painted by CSS.”

Readers usually convert a passive voice to an active voice in their heads, resulting in more processing time. If you’ve ever heard that writing in an active voice is better, this is usually the reason why. Tech writers prefer the active voice most of the time, with very few exceptions such as citing research: “It has been suggested that …”

But that doesn’t mean you should always strive for an active voice. Switching from one to the other — even in the same paragraph — can make your content flow more seamlessly from one sentence to another if used effectively.

Avoiding mistakes

Grammar is all about the structure and correctness of language, and there’s nothing better to achieve that than a quick proofreading of your document. It’s very important to rid your writings of spelling mistakes, grammar issues, and semantic imperfections.

At the end of this article, I’ll show you the invaluable tools that professionals use to avoid writing mistakes. Obviously, there are built-in spell checkers in just about everything these days; our code editors even have spell-checking and linting plugins to help prevent mistakes.

But if you’re looking for a one-stop tool for all-things grammar, Grammarly is one of the most widely-used tools. I’m not getting a kickback for that or anything. It’s just a really great tool that many editors and writers use to write clean and clear content — similar to how you might use Emmet, eslint, or any other linter to write clean and clear code.

Writing code comments

The things we write for other developers can have a big impact on the overall quality of our work, whether it’s what we write in the code, how we explain the code, or how we give feedback on a piece of code.

It’s interesting that every programming language comes with a standard set of features to write a comment. They should explain what the code is doing. By that, I don’t mean vague comments like this:

red *= 1.2 // Multiply `red` by 1.2 and re-assign it

Instead, use comments that provide more information:

red *= 1.2 // Apply a 'reddish' effect to the image

It’s all about context. “What kind of program am I building?” is exactly the kind of question you should be asking yourself.

Comments should add value

Before we look at what makes a “good” code comment, here are two examples of lazy comments:

const age = 32 // Initialize `age` to 32
filter: blur(32px); /* Create a blur effect with a 32px radius */

Remember that the purpose of a comment is to add value to a piece of code, not to repeat it. If you can’t do that, you’re better off just leaving the code as-is. What makes these examples “lazy” is that they merely restate what the code is obviously doing. In this case, the comments are redundant because they tell us what we already know — they aren’t adding value!

Comments should reflect the current code

Out-of-date comments are no rare sight in large projects; dare I say in most projects.

Let’s imagine David, a programmer and an all-around cool guy to hang out with. David wants to sort a list of strings alphabetically from A to Z, so he does the obvious in JavaScript:

cities = sortWords(cities) // sort cities from A to Z

David then realizes that sortWords() actually sorts lists from Z to A. That’s not a problem, as he can simply reverse the output:

cities = sortWords(cities) // sort cities from A to Z
cities = reverse(cities)

Unfortunately, David didn’t update his code comment.

Now imagine that I didn’t tell you this story, and all you saw was the code above. You’d naturally think that after running that second line of code, `cities` would be sorted from Z to A! This whole confusion fiasco was caused by a stale comment.

While this might be an exaggerated example, something similar can (and often does) happen if you’re racing against a close deadline. Thankfully, this can be prevented by following one simple rule… change your comments the same time you change the code.

That’s one simple rule that will save you and your team from a lot of technical debt.

Now that we know what poorly written comments look like, let’s look at some good examples.

Comments should explain unidiomatic code

Sometimes, the natural way of doing things isn’t right. Programmers might have to “break” the standards a bit, but when they do, it’s advisable to leave a little comment explaining their rationale:

 function addSetEntry(set, value) {    
  /* Don't return `set.add` because it's not chainable in IE 11. */  
  return set;

That’s helpful, right? If you were responsible for reviewing this code, you may have been tempted to correct it without that comment there explaining what’s up.

Comments can identify future tasks

Another useful thing to do with comments is to admit that there’s more work to be done.

// TODO: use a more efficient algorithm

This way, you can stay focused on your flow. And at a later date, you (or someone else) can come back and fix it.

Comments can link back to the source

So, you just found a solution to your problem on StackOverflow. After copy-pasting that code, it’s sometimes a good thing to keep a link to the answer that helped you out so you can come back to it for future reference.

Screenshot of copying a link at StackOverflow.
// Adds handling for legacy browsers

This is important because solutions can change. It’s always good to know where your code came from in case it ever breaks.

Writing pull requests

Pull requests (PRs) are a fundamental aspect of any project. They sit at the heart of code reviews. And code reviews can quickly become a bottleneck in your team’s performance without good wording.

A good PR description summarizes what change is being made and why it’s being made. Large projects have a pull request template, like this one adapted from a real example:

## Proposed changes
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.

## Types of changes
What types of changes does your code introduce to Appium?
 - [ ] Bugfix (non-breaking change which fixes an issue)
 - [ ] New feature (non-breaking change which adds functionality)
 - ...

## Checklist
 - [ ] I have read the CONTRIBUTING doc
 - [ ] I have signed the CLA
 - [ ] Lint and unit tests pass locally with my changes

## Further comments
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc…

Avoid vague PR titles

Please avoid titles that look like this:

  • Fix build.
  • Fix bug.
  • Add patch.

These don’t even attempt to describe what build, bug, or patch it is we’re dealing with. A little extra detail on what part of the build was fixed, which bug was squashed, or what patch was added can go a long way to establishing better communication and collaboration with your colleagues. It level-sets and gets folks on the same page.

PR titles are traditionally written in imperative tense. They’re a one-line summary of the entire PR, and they should describe what is being done by the PR.

Here are some good examples:

  • Support custom srcset attributes in NgOptimizedImage
  • Default image config to 75% image quality
  • Add explicit selectors for all built-in ControlValueAccessors

Avoid long PRs

A large PR means a huge description, and no one wants to review hundreds or thousands of lines of code, sometimes just to end-up dismissing the whole thing!

Instead, you could:

  • communicate with your team through Issues,
  • make a plan,
  • break down the problem into smaller pieces, or
  • work on each piece separately with its own PR.

Isn’t it much cleaner now?

Provide details in the PR body

Unlike the PR title, the body is the place for all the details, including:

  • Why is the PR being done?
  • Why is this the best approach?
  • Any shortcomings to the approach, and ideas to solve them if possible
  • The bug or ticket number, benchmark results, etc.

Reporting bugs

Bug reports are one of the most important aspects of any project. And all great projects are built on user feedback. Usually, even after countless tests, it’s the users that find most bugs. Users are also great idealists, and sometimes they have feature ideas; please listen to them!

For technical projects, all of this stuff is done by reporting issues. A well-written issue is easy for another developer to find and respond to.

For example, most big projects come with a template:

 <!-- Modified from angular-translate/angular-translate -->
 ### Subject of the issue
 Describe your issue here.

 ### Your environment
 * version of angular-translate
 * version of angular
 * which browser and its version

 ### Steps to reproduce
 Tell us how to reproduce this issue.

 ### Expected behavior
 Tell us what should happen.

 ### Actual behavior
 Tell us what happens instead.

Gather screenshots

Capture the issue using your system’s screen-shooting utility.

If it’s a screenshot of a CLI program, make sure that the text is clear. If it’s a UI program, make sure the screenshot captures the right elements and states.

You may need to capture an actual interaction to demonstrate the issue. If that’s the case, try to record GIFs using a screen-recording tool.

How to reproduce the problem

It’s much easier for programmers to solve a bug when it’s live on their computer. That’s why a good commit should come with the steps to precisely reproduce the problem.

Here’s an example:

Update: you can actually reproduce this error with objects:

 <div *ngFor="let value of objs; let i = index">
   <input [ngModel]="objs[i].v" (ngModelChange)="setObj(i, $event)" />

 export class OneComponent {
   obj = {v: '0'};
   objs = [this.obj, this.obj, this.obj, this.obj];
  setObj(i: number, value: string) {
     this.objs[i] = {v: value};

 The bug is reproducible as long as the trackBy function returns the same value for any two entries in the array. So weird behavior can occur with any duplicate values.

Suggest a cause

You’re the one who caught the bug, so maybe you can suggest some potential causes for why it’s there. Maybe the bug only happens after you encounter a certain event, or maybe it only happens on mobile.

It also can’t hurt to explore the codebase, and maybe identify what’s causing the problem. Then, your Issue will be closed much quicker and you’re likely to be assigned to the related PR.

Communicating with clients

You may work as a solo freelancer, or perhaps you’re the lead developer on a small team. In either case, let’s say you’re responsible for interfacing with clients on a project.

Now, the programmer stereotype is that we’re poor communicators. We’ve been known to use overly technical jargon, tell others what is and is not possible, and even get defensive when someone questions our approach.

So, how do we mitigate that stereotype? Ask clients what they want, and always listen to their feedback. Here’s how to do that.

Ask the right questions

Start by making sure that you and the client are on the same page:

  • Who is your target audience?
  • What is the goal of the site?
  • Who is your closest competitor and what are they doing right?

Asking questions is also a good way to write positively, particularly in situations when you disagree with a client’s feedback or decision. Asking questions forces that person to support their own claims rather than you attacking them by defending your own position:

  • Are you OK with that even if it comes with an additional performance cost?
  • Does moving the component help us better accomplish our objective?
  • Great, who is responsible to maintain that after launch?
  • Do you know offhand if the contrast between those two colors passes WCAG AA standards?

Questions are a lot more innocent and promote curiosity over animosity.

Sell yourself

If you’re making a pitch to a prospective client, you’re going to need to convince them to hire you. Why should the client choose you? It’s important to specify the following:

  • Who you are
  • What you do
  • Why you’re a good fit for the job
  • Links to relevant work you’ve done

And once you get the job and need to write up a contract, remember that there’s no content more intimidating than a bunch of legalese. Even though it’s written for design projects, the Contract Killer can be a nice starting point for writing something much friendlier.

Your attention to detail could be the difference between you and another developer trying to win the same project. In my experience, clients will just as easily hire a develop they think they will enjoy working with than the one who is technically the most competent or experienced for the job.

Writing microcopy

Microcopy is the art of writing user-friendly UI messages, such as errors. I’ll bet there have been times where you as a developer had to write error messages because they were put on the backburner all the way to launch time.

That may be why we sometimes see errors like this:

Error: Unexpected input (Code 693)

Errors are the last thing that you want your users to deal with. But they do happen, and there’s nothing we can do about it. Here are some tips to improve your microcopy skills.

Avoid technical jargon

Most people don’t know what a server is, while 100% of programmers do. That’s why it’s not unusual to see uncommon terms written in an error message, like API or “timeout execution.”

Unless you’re dealing with a technical client or user base, It’s likely that most of your users didn’t take a computer science course, and don’t know how the Internet works, and why a particular thing doesn’’t work. Hence, the error.

Therefore, a good error message shouldn’t explain why something went wrong, because such explanations might require using scary technical terms. That’s why it’s very important to avoid using technical jargon.

Never blame the user

Imagine this: I’m trying to log into your platform. So I open my browser, visit your website, and enter my details. Then I’m told: “Your email/password is incorrect.”

Even though it seems dramatic to think that this message is hostile, it subconsciously makes me feel stupid. Microcopy says that it’s never okay to blame the user. Try changing your message to something less finger-pointy, like this this example adapted from Mailchimp’s login: “Sorry, that email-password combination isn’t right. We can help you recover your account.”

I’d also like to add the importance of avoiding ALL CAPS and exclamation points! Sure, they can be used to convey excitement, but in microcopy they create a sense of hostility towards the user.

Don’t overwhelm the user

Using humor in your microcopy is a good idea! It can lighten up the mood, and it’s an easy way to curb the negativity caused by even the worst errors.

But if you don’t use it perfectly, it can come across as condescending and insulting to the user. That’s just a big risk to take.

Mailchimp says it well:

[D]on’t go out of your way to make a joke — forced humor can be worse than none at all. If you’re unsure, keep a straight face.

(Emphasis mine)

Writing accessible markup

We could easily spend an entire article about accessibility and how it relates to technical writing. Heck, accessibility is often included in content style guides, including those for Microsoft and Mailchimp.

You’re a developer and probably already know so much about accessibility. You may even be one of the more diligent developers that makes accessibility a core part of your workflow. Still, it’s incredible how often accessibility considerations are put on the back burner, no matter how important we all know it is to make accessible online experiences that are inclusive of all abilities.

So, if you find yourself implementing someone else’s copywriting into your code, writing documentation for other developers, or even writing UI copy yourself, be mindful of some fundamental accessibility best practices, as they round out all the other advice for technical writing.

Things like:

Andy Bell offers some relatively small things you can do to make content more accessible, and it’s worth your time checking them out. And, just for kicks, John Rhea shows off some neat editing tricks that are possible when we’re working with semantic HTML elements.


Those were six ways that demonstrate how technical writing and development coincide. While the examples and advice may not be rocket science, I hope that you found them useful, whether it’s collaborating with other developers, maintaining your own work, having to write your own copy in a pinch, or even drafting a project proposal, among other things.

The bottom line: sharpening your writing skills and putting a little extra effort into your writing can actually make you a better developer.

Technical writing resources

If you’re interested in technical writing:

If you’re interested in copywriting:

If you’re interested in microcopy:

If you’re interested in using a professional style guide to improve your writing:

If you’re interested in writing for accessibility:

Technical Writing for Developers originally published on CSS-Tricks. You should get the newsletter.

These tips and a lot more advice on providing accessible names are in…. Note, you don't need to use ARIA to provide names, text content in the appropriate HTML elements (<label>, <legend>, <caption>, <button>, <a>) works just fine.…

@hdv this is all great feedback again. Hey @snugug, you may be interested in this too.

@hdv Thanks for sharing this. Really useful

@judin thank you, you're welcome!

@hdv But nobody gives the money for stuff like that! :) LOL

RT If I got a dollar every time I wrote “X doesn't have an accessible name” in accessibility audits, I would be a millonaire. More on accessible names: - Naming things to improve accessibility… - Better accessible names (1/2)

@vick21 well luckily I do get paid for audits!

@hdv I know the feeling! It's shocking for me how many devs obviously only think in terms of a visual, mouse operated user experience 🤦‍♂️