Accessibility by design
More than one way in.Shown on this very page.
Not everyone arrives with a mouse, sharp eyes and a wide screen. On our new system, a page starts with a real structure, a focus you can always see, contrast that is computed, each picture we place described or declared decorative, and text that follows the reader’s own size. This page shows what we build and what we check, then reads its own markup in your browser.
Readings are taken live from this page, in your browser, and sent nowhere. Diagrams are illustrative where marked.
01 · Structure
Every page has a spine.
A screen reader does not see a layout. It gets a language, a few named regions and an outline of titles. Here are this page’s own, read from its markup in your browser, from the main title down.
Declared language —
01 · Regions
- —
02 · Titles
- —
Reading this page…
—
Read from this page in your browser. On a new site, a page with no main title, or two, stops the build.
How this is read
- The language
- The lang attribute of the document, as written, then put in words by your browser. Nothing is typed here: a page without the attribute would say so.
- The regions
- The page’s top-level header and footer, its main content and every navigation, in the document’s order, leaving out whatever is hidden from a keyboard and from assistive technology. A navigation waiting in a closed menu is listed with a note that says so. A navigation’s name is derived from the markup: aria-labelledby, then aria-label. No web API returns what a screen reader says, and nothing here claims it. The page’s sections are regions too, each named by its own title: they are drawn once, as titles.
- The titles
- Every h1 to h6 in the document’s order, under the same rule. A level is skipped when a title sits more than one level under the title before it. Beside each section title, the sub-titles under it are counted. A title whose section has an anchor is a real link to it.
- The scale
- Each part of the page is placed from its measured top and height against the document’s full height, read again at each replay and when the window changes. The bracket is your window, moved as you scroll.
- The landing
- A section’s scroll margin, less the bottom edge of the bars pinned at the top, plus the distance from the section’s edge to its title. Every linked section is measured and the smallest result is printed.
- What a build checks
- On a new site, every planned page is opened in a real browser, 1280 and 390 wide, and the build stops when a page has no main title, or two. Regions and levels are read here, live, on this page: they are care taken while building, not a build check.
02 · Keyboard
Every stop, in order, in sight.
Press Tab on this site and the first thing offered is a way past the menu. After that, focus moves through the page in its own order, and a ring always shows where it is. Here is the route, drawn from the page’s real boxes.
The keyboard’s route through the top of this page
Where a keyboard, a switch or a screen reader begins.
Reading this page…
Where the ring isStop — of ———
Reading this page…
—stops on this page with the menus closed, —
Read from this page, in your browser. The ring on the plan is a drawing: your own focus moves only when you press the white button.
How this is read
- The stops
- Every link, button, field, summary and element given a tab index that the keyboard can reach right now: not disabled, not hidden, not inside a closed menu or panel. They are taken in the document’s order, which is the tab order when none carries a positive tab index; the second finding counts those that do. The count is taken with the menus closed: on a wide screen, focus on a group’s name in the header opens its panel, and Tab walks its pages before going on.
- The names
- A name is derived from three attributes and the text: aria-labelledby, then aria-label, then an image’s alt, then the element’s own text; a field with none of them takes its label’s. It is a simple derivation, not the browser’s full computation. No web API returns what a screen reader says, and nothing here claims it.
- The drawing
- Each box is the element’s real box, measured against its own bar and scaled to this stage; the section bar is drawn as it stands at the top of the page, and where it runs past the edge of a narrow screen, the stops out of sight are counted with those that follow. The ring that hops and the keys that dip during the story are a drawing: the story never moves your focus. No step of our build verifies focus order: this is a reading of this page, taken in your browser.
- With your own keyboard
- The white button puts your focus on this site’s skip link, which slides in at the top left of the screen. After a click, a browser may not draw the ring until the next key. From there, Tab walks the header; past it, the page scrolls up to follow your focus, away from this stage. On a Mac, some browsers reach links with Option + Tab. Keys are listened to while this stage is on screen, never intercepted, and nothing is sent anywhere.
04 · Contrast
Contrast is computed, not judged by eye.
A new site’s theme is refused unless body text reaches 7 to 1, and secondary text, links, the focus colour and button labels 4.5 to 1. A brand colour that falls short ships only as the client’s own decision, written down.
A sample theme, on its two grounds
| Pair | On the page | On the soft band | Line to reach | Verdict |
|---|---|---|---|---|
| Body text | Not read yet | Not read yet | 7 to 1 | Not read yet |
| Secondary text | Not read yet | Not read yet | 4.5 to 1 | Not read yet |
| Link | Not read yet | Not read yet | 4.5 to 1 | Not read yet |
| Button label | Not read yet | 4.5 to 1 | Not read yet | |
| Focus ring | Not read yet | Not read yet | 4.5 to 1 | Not read yet |
Reading the colours shown…
Text over a photograph or a gradient is not computed: it is looked at on the finished page. A label on a brand fill that falls short ships only as the client’s written decision.
How this is computed
- The figures
- Each ratio is the contrast ratio of two colours as WCAG 2 defines it, from 1 to 1 for the same colour to 21 to 1 for black on white. It is computed in your browser, from the colours this specimen is painted with, by the same code as this site’s contrast checker. A figure is cut to two decimals and never rounded up past a line.
- The lines
- 7 to 1 for body text and 4.5 to 1 for secondary text, links, the focus colour and button labels are the lines our build uses when it checks a new site’s theme. It checks them on every ground the theme defines: the page, the soft band and the surface of a card. The specimen shows two; the third is checked the same way. On the finished page, titles and main controls are also checked at 3 to 1 against a flat ground.
- The specimen
- The theme shown is a sample drawn for this page. The range changes one colour of the sample, the secondary text, and nothing else on the page. A colour that cannot be read is shown as not computable, never guessed.
05 · Images and names
Every image carries a decision.
On a new site, every picture we plan carries a decision: described in the words of its page, or declared decorative and passed over. An icon-only button still has a name. Slide the line to read this section as words.
One plate, two readings
Three photographs, one decorative band and three buttons that show only an icon. Where the reading line has passed, each one gives way to the words this page gives for it.




What a picture shows, not every reader sees.
— images on this page: — described, — decorative, — undecided.— buttons and links show no words of their own.
Reading this page…
Counted on this page in your browser. On a new site, a planned image with no decision stops the build.
How this is read
- What is counted
- Every image element in this document, the header and the footer included. What sits inside the closed menu is left out of both counts until it opens. Described: it carries words (a filled alt attribute). Decorative: an empty description, or hidden from assistive technology on purpose. Undecided: no alt attribute at all. Backgrounds painted by the stylesheet and inline drawings are not images in this count.
- Where a name comes from
- Counted among the buttons and links on offer at this window size: those that show no words. An icon alone, a logo, or a figure hidden from assistive technology, as on the header’s points counter, whose name carries it instead. Each gets its name from three attributes and its text: aria-labelledby, then aria-label, then the alt of an image inside it. These are the names the page gives. No web API returns what a screen reader says, so nothing spoken is shown here.
- The plate
- The three photographs are real images of this page, and the band is a real image with an empty description. The words in each box are read back from the image itself, and each button’s name from the button, never from a second copy. On a new site, the build looks at the images a page is planned with; pictures that arrive later from a content library are outside it.
06 · Text size
You set the size.
Text is sized from your own setting, zoom is never locked, and a new site is refused if a page scrolls sideways at desktop or phone width. Here is your setting, read from your browser, and a specimen you can enlarge.
Your browser, this page
- Your browser’s text sizeBrowser text size
- —
- —
- This page’s textThis page’s text
- —
- —
- ZoomZoom
- —
- —
- Sideways scroll, this pageSideways scroll
- —
- —
- A control, on your screenA control, on your screen
- —
- —
One page, five sizes
Specimen
Read larger
The words grow and the lines re-break. The tiles regroup.
- Titles
- Text
- Buttons
Reading this page…
| Text size | Columns | Content width | Frame width | Content height |
|---|---|---|---|---|
| 100% | — | — | — | — |
| 125% | — | — | — | — |
| 150% | — | — | — | — |
| 175% | — | — | — | — |
| 200% | — | — | — | — |
Read from your browser. On a new site, every planned page is measured at 1280 and 390 px wide; one that scrolls sideways is refused.
How this is read
- Your browser
- Your text size is the size your browser gives the root of a page. This site sets none there, so the figure is yours; a phone’s system-wide text setting may not reach it. This page’s text is the size the browser computed for the body, declared as a multiple of yours and not as a number of pixels. Zoom is the page’s viewport line, printed as found; the reading looks in it for a maximum scale or a switch that turns zooming off. Pinch zoom comes from the browser’s visual viewport, where it has one. A browser’s own page zoom is not given to a page, so it is not shown.
- This page
- Sideways scroll compares the width of the document with the width of the window, and is read again whenever the window changes. On this site’s phone layout, one more row gives the size of the button that opens the menu: its box on your screen, with its invisible touch area where it has one. That row is a reading of this site, not something our build measures.
- The specimen
- One block, not the whole page: the five steps size the specimen only. Its text is your size times the step, and everything inside is counted in that size, so the lines re-break and the tiles regroup when the frame holds fewer of them. Each size is laid out and measured once: the frame’s width against its content’s, the number of columns, and the rectangle of each block, which stays behind as an outline. On a new site, the build measures every planned page at 1280 and 390 px wide and names the element responsible when one scrolls sideways.
The practice
Accessibility is built in, or it is missing.
It comes from ordinary decisions made early: a real heading, a real button, a colour that is computed, a picture someone described. Where a machine can check, our build refuses the page that falls short: one main title, no sideways scroll, computed contrast, a decision for every image. The rest is care, taken page by page. We say what we do and what we check, nothing more.
What this page shows is our new system, the way we build today. Sites we delivered before it may not include it.
Want a site more people can use?
Tell us about your project. We will show you what we would check first.
