# Accessibility as craft · Craft

<!-- https://learn-ui.com/chapters/craft/accessibility -->

It is obvious to give images and videos alternative text. The less obvious cases are illustrations built from HTML and CSS, code blocks, and focus.

### Label an illustration as one image

In [Crafting the Next.js Website](https://rauno.me/craft/nextjs) Rauno Freiberg notes that a screen reader walks through many elements of an HTML illustration and may still not convey it. His fix, credited to Adrian, is `aria-hidden` on the inner HTML and a custom `aria-label` on the group, so the user reaches one element and gets a description.

The Vercel site in [What will you ship?](https://rauno.me/craft/vercel) applies it everywhere: `role="img"`, a label with just enough detail, and a hidden inner tree. The pixel icons, drawn in Figma and extracted by a Ruby script, render to a hidden canvas inside a labelled wrapper, because “we treat the icons as images.”

> Figure. JSXRauno Freiberg, What will you ship?

### An accessible code block

The team went over the page with VoiceOver dozens of times, and three problems surfaced in the code block: the file icon announced itself as “image”; the copy button described neither its purpose nor gave feedback; and the line numbers were noise that could be mistaken for code.

The icon got `aria-hidden`, the copy button an `aria-label`, and feedback came from an **ARIA live region** (An element whose dynamic content changes are exposed to screen readers as they happen, so a message can be announced without moving focus.) with `role="log"` and `aria-live="polite"` carrying the visually hidden text “Copied code to clipboard”, hidden without `display` or `visibility`. The block became an `aside` with a high-level label so a reader can skip it.

Line numbers are pseudo elements driven by a CSS counter, and with no DOM node you cannot `aria-hidden` one. The answer is the second value of `content`, **alternative text for pseudo elements** (The second value of the CSS content property, after a slash, which supplies alternative text for a pseudo element; an empty string means nothing should be announced.). Combined, a screen reader gets more information on every example the component powers, hundreds of them.

> Figure. CSSRauno Freiberg, What will you ship?

Source

Rauno Freiberg, What will you ship?, sections Accessible Code Blocks, Code Driven Visuals, and Pixelated Iconography; Crafting the Next.js Website, Explicit Accessibility Labelling and Focus States.

### Focus, hit areas, real devices

The previous section covered Rauno’s double-shadow focus ring; the point to carry is that a reliable ring on every focusable thing across a shared surface area is the work. Emil Kowalski’s skill, excerpted in [Agents with Taste](https://emilkowal.ski/ui/agents-with-taste), adds two rules: a 44px minimum hit area for small buttons, drawn with a pseudo element, and body text capped at about 65ch. Jim Nielsen’s flexbox gap is the same rule from the other side: the target should be at least as big as the thing you see.

Kathryn Gonzalez, who built and led DoorDash’s Design Infrastructure org, defines it plainly in a [2020 interview](https://www.ryngonzalez.com/blog/design-leadership-interview-at-doordash): accessibility is “a way of thinking and designing so that we’re not only building something that works for the narrow group of people that look like us, but for people with different kinds of mental and physical capabilities and circumstances.”

Her 2017 [How to Build a Modal](https://www.ryngonzalez.com/blog/how-to-build-a-modal) adds: consider accessibility from the start, treat the WAI-ARIA examples as your friend, and test on real devices, because her team had tested only in Chrome’s responsive mode and found `overflow: hidden` did not stop body scrolling on iOS. A shared component distributes those practices to everyone.

### Sloppy UI is a security liability

In [A Sloppy Interface Is a Security Liability](https://blog.jim-nielsen.com/2026/sloppy-ui-is-security-liability/) (August 2026), prompted by Feross Aboukhadijeh’s talk on the Axios npm phishing attack and its fake Microsoft Teams interface, Jim Nielsen proposes “interface and interaction design as a security control.” The easier it is to sloppily reproduce what you sloppily ship, the easier your brand becomes a vehicle for exploiting customers.

“If everything you make was produced from a single prompt, then everyone else is one prompt away from imitating you.” The protection is what is hard to fake because it is hard to notice you need it: micro-interactions, loading behaviour, copy, edge cases, accessibility.

The Vercel essay names what almost everyone experiences: page speed, legible typography, information honesty, layout stability, focus states, auditory feedback, DOM order. Invisible, so first traded away. Take the opposite stance.
