Language and labels
How to identify and describe elements of the interface
Interfaces are exchanges of information. Any interface where one party is human must share information as human readable text.
Even interfaces not displaying text need to be encoded with text. Text is parsable by crawlers, agents, and assistive software like screen readers. Tacit forms of communication (symbols and icons, shapes and colors) are not.
Page language
Section titled “Page language”A French speaker can identify French when they hear it. Programmatic parsers are not so skilled. You need to explicitly set a language for every screen of your interface.
In web applications, this just means applying a lang attribute, with a suitable BCP 47 language tag, to the <html> element:
<html lang="fr">Now parsers know to expect French content. A screen reader will choose a French voice profile and the page will be read in a suitably French accent. If your application supports multiple languages, change the lang value alongside translation.
If the language reads right to left, pair the lang attribute with the dir attribute and a value of "rtl":
<html lang="ar" dir="rtl">Multilingual pages
Section titled “Multilingual pages”Occasionally, a French page might include a section of content in another language. The parser must know when to code-switch. Apply another lang attribute, but to the element containing the embedded language:
<p>Je suis français!</p><div lang="en"> <p>I am English.</p></div>The page title
Section titled “The page title”HTML offers lots of ways to label elements, and not just with the <label> element.
The <title> element labels the screen itself. It’s visible in the browser tab, but also parsed by crawlers and assistive software. In a search engine result, it’s the text linking to the page. To a screen reader user, it’s announced when arriving on the page.
Give sufficient context by including both the page and application name in each <title>.
<title>[name of the page] – [name of the application]</title>This identifies the page among other open tabs.
Headings
Section titled “Headings”The Structure guide covers using heading levels to describe document structure.
Equally important is the wording used for each heading. Headings are labels for the content they introduce. You should not have to read the content to make sense of its heading. This is especially important given screen readers and other parsers extract headings from content to create lists of links.
Here are good and bad examples for a company’s stated use of artificial intelligence:
/* ✅ Direct; uses relevant terminology */<h2>Our policy on artificial intelligence</h2>
/* ❌ Vague and abstract; could be referring to anything */<h2>Cautiously embracing the future</h2>Controls
Section titled “Controls”Interactive controls use their label to state what they do.
Buttons without visible labels, showing just icons, must be encoded with text-based labels. Apply a label to IconButton using the label prop:
<IconButton label="Download"> <Icon href={svgDownload} /></IconButton>For buttons with visible labels, do not give the icon a label of its own. The text label should be sufficient.
/* ❌ */<Button endIcon={<Icon href={svgAdd} alt="plus symbol" />}>Create new</Button>
/* ❌ */<Button endIcon={<Icon href={svgAdd} alt="create new icon" />}>Create new</Button>
/* ✅ */<Button endIcon={<Icon href={svgAdd} />}>Create new</Button>A link transports you to a new location. Its label should tell you where you are being taken. If the destination is a new page, consider making the link’s text part of that page’s <title>:
/* the link */<a href="https://en.wikipedia.org/wiki/Infrastructure">Infrastructure</a>
/* the page's title */<title>Infrastructure - Wikipedia</title>Since links, like headings, are frequently aggregated into lists, avoid generic and unhelpful labels like “read more” or “click here”.
Individual labels
Section titled “Individual labels”Make sure each form field (<input>, <select>, <textarea>) is associated with a label, using the <label> element. The for and id attributes must have a matching value, even when nested.
<!-- ✅ --><label for="email">Email</label><input type="text" name="email" id="email" />
<!-- ✅ --><label for="email"> Email <input type="text" name="email" id="email" /></label>Form fields implemented with non-native form elements may not be compatible with <label>. The aria-labelledby attribute is required to associate the <label> element to the input. The Select component renders like this (some attribution removed for brevity):
<label id="ds-label">Design system:</label><div role="combobox" aria-haspopup="listbox" aria-labelledby="ds-label" {...}> {/* list of options here */}</div>Descriptions
Section titled “Descriptions”Avoid using the placeholder attribute, either as a principle label or as a description for the field. Since placeholder is rendered inside the input itself, it can be mistaken for a completed entry. It is also not persistent, disappearing when the input is focused.
For TextField descriptions, use helperText. Unlike placeholder, helperText appears persistently, under the input, and while the user is typing.
<TextField label="Verification code:" helperText="This was emailed to the address associated with your account."/>Group labels
Section titled “Group labels”Sets of related or interdependent form fields must be associated with a common group label.
Using radio buttons, the group label—provided with the <fieldset>’s <legend>—represents the choice to be made. Individual labels represent the options for that choice.
<fieldset> <legend>Design system:</legend> <label> iTwinUI <input type="radio" name="system" value="iTwinUI" /> </label> <label> StrataKit <input type="radio" name="system" value="StrataKit" /> </label></fieldset>StrataKit’s Radio guide exemplifies this pattern.
Error messages
Section titled “Error messages”Like labels, supplementary descriptions must be programmatically associated with input fields.
<TextField label="Email" error helperText={ <> <span style={visuallyHidden}>Error: </span>Invalid email address </> }/>Using the TextField’s helperText prop, this error message is associated with the input using aria-describedby. When the input is focused, a screen reader will announce the error description after the field’s label (“Email”), role (“textbox”), and state (“invalid”).
Error messages must actively help the user to resolve the error. If your application includes messages like “Error 41”, “Incorrect format”, or “Please try again”, users will not know how to proceed.
Alternative text
Section titled “Alternative text”Media that may not be seen must be described. Alternative text is primarily for blind and partially sighted users. But it also gives recourse to crawlers and agents, since it converts what’s seen in the image into a parsable text format.
Writing good alternative text is difficult to automate and should be part of your design and editorial process. While agents can describe detail in an image, they struggle piecing the details together to convey the image’s intent.
/* ❌ Verbose and missing relevant terminology */<img src="/photos/worker.webp" alt="A figure, in profile, wearing a yellow hat and holding a tablet device. The sky is pale blue and there are buildings along the horizon."/>
/* ✅ Concisely captures the scene */<img src="/photos/worker.webp" alt="A construction worker, on site, surveying a large project." />The way the alternative text should be written depends on the role of the image in the interface. If an image is used as a Link, it must describe the link’s location. A common example is the logo-as-homepage link:
/* ❌ The application is not a design case study */<Link href="/"> <img src="/images/logo.svg" alt="The company logo, using green, sans-serif lettering and featuring an icon of a citrus fruit exploded into independent segments." /></Link>
/* ✅ Simply names the site */<Link href="/"> <img src="/images/logo.svg" alt="LimeWorld homepage" /></Link>Purely decorative images and other images in some contexts can have empty alternative text (alt=""). Complex images like charts and infographics need to be accompanied by longer explanations or data tables. Consult the alt decision tree if you are unsure.