Bhinish Dhiman
How to write link and button text that makes sense out of context
Write every link so its words alone name the destination, and every button so its words name the outcome: “Pricing and plans”, not “Click here”; “Create account”, not “Submit”. Screen-reader users often list every link on a page at once, which strips away the sentence around each one. Then check that any aria-label starts with the visible words, or voice control breaks (WCAG 2.5.3).
A sentence such as “To see our prices, click here” reads perfectly on the page. Pulled out of the sentence, the link is two words that point nowhere in particular, and pulled out of the sentence is exactly how a lot of people meet it.
Why the sentence around a link disappears
A link list is the view a screen reader offers of every link on a page at once, so its user can jump straight to the one they want. It is one of the fastest ways to move around a page, and it shows each link as its own words and nothing else. Eleven links reading “Read more” become eleven identical rows.
An accessible name is the text assistive technology announces for a link or a control. The tool works it out in this order: an aria-label if there is one, then aria-labelledby, then the element’s own text, then the alt text of an image inside it, then the title attribute. Whatever comes out first is what the link list shows and what voice control listens for.
So the job is not to write better sentences around links. It is to make the accessible name do the work on its own.
The criteria behind the rule
Every finding the tool reports cites one of five WCAG success criteria, which turns “this label is vague” from an opinion into something a ticket can carry.
| Criterion | Level | What fails it | How the tool reports it |
|---|---|---|---|
| 2.4.4 Link Purpose (In Context) | A | A link with no accessible name, or one whose whole label is a phrase such as “click here”, “learn more” or “download” | Error. A raw URL over 30 characters used as the label is a warning |
| 2.4.9 Link Purpose (Link Only) | AAA | The same words used for links that go to different places | Warning |
| 2.4.6 Headings and Labels | AA | A button that names no action: “Submit”, “OK”, “Send”, “Done” | Warning |
| 2.5.3 Label in Name | A | An aria-label that does not contain the button’s visible text |
Error |
| 4.1.2 Name, Role, Value | A | A control with no accessible name; a link named only by its title |
Error; warning for the title case |
One nuance on 2.4.4: strictly, it lets the surrounding sentence or list item count as context, which is why a “Read more” can technically pass at Level A. The tool marks those labels as errors anyway, because the link list is precisely the place where that context is gone. 2.4.9, the AAA criterion, is the one that requires the link’s own words to be enough.
Audit a page with the tool
- Open the page you are checking, right-click the area with the links, choose Inspect, and copy the element’s markup from the developer tools. Copy the markup rather than the visible text: the
aria-labelattributes are where half the findings are. - Open the Link & button text auditor. The box under Paste your markup starts with a sample, so press Clear in the bar at the bottom first, then paste.
- Read the four counts at the top: Links, Controls, Errors and Warnings.
- Work through the errors before the warnings. Each finding shows its severity, the WCAG criterion and level, the rule it broke, the offending text, why it matters, and a line starting “Fix:”.
- Rewrite the labels in your source, paste the new markup and repeat until the panel reads “Every link and control here names where it goes or what it does.”
- Press Copy report (or the C key) to take the findings as plain text, one block per finding with its criterion, for a ticket or a pull request.
The sample markup, worked through
The sample the tool opens on is ten lines with most of the common mistakes in it. It counts 5 links and 3 controls, and finds 4 errors and 2 warnings:
| Markup | Finding | Criterion |
|---|---|---|
<a href="/pricing">Click here</a> |
Link text is meaningless out of context (error) | 2.4.4, A |
<a href="/docs">Learn more</a> |
Link text is meaningless out of context (error) | 2.4.4, A |
Two links reading “Documentation”, to /help and /api |
Same link text, different destinations (warning) | 2.4.9, AAA |
<a href="/home"> holding only an empty icon |
Link has no accessible name (error) | 2.4.4, A |
<button>Submit</button> |
Control label does not name its action (warning) | 2.4.6, AA |
<button aria-label="Find records">Search</button> |
Visible text is missing from the accessible name (error) | 2.5.3, A |
<button>Delete 3 invoices</button> |
Nothing: it names the outcome and the count | None |
The two “Documentation” links count as one finding, because the problem is the pair. The search button is the one people miss. It sounds fine in a screen reader, which announces “Find records”. But someone using voice control says the word they can see, “Search”, and nothing happens, because “Search” is not in the accessible name. Starting the label with the visible word, as in “Search records”, satisfies both.
The readability score that rewards the worst labels
The obvious shortcut is to run labels through a readability checker. It gives exactly the wrong answer. Readability formulas divide by sentence count and were fitted on continuous prose, so a two-word string sends them off the scale. Flesch–Kincaid rates “Learn more” and “Click here” at a reading ease of 120.2, above the top of its own scale, and rates the far clearer “Download invoice PDF” at 62.8.
That is why the auditor shows no reading-level score at all, and says so on the page. What can be tested about a label is whether it names a destination or an action, and whether its accessible name agrees with what is on screen.
Where the checks stop
A tool that cites criteria is only as good as the rules it runs, and these have edges worth knowing:
- The vague-word lists match a whole label, not a phrase inside one. “Click here” is flagged; “Click here to compare plans” is not, though it still makes a listener wait for the useful words.
- The list for links is longer than the list for buttons. A link reading “Download” is an error; a button reading “Download” passes, and still deserves to say what it downloads.
- It cannot tell whether a label is accurate, only whether it is specific. A button marked “Delete” that archives will pass every check.
- It cannot fetch a page from a URL. Browsers stop one site reading another site’s HTML, and there is no server behind the tool to do it instead, which is why you paste markup.
Other ways to do it
There is no built-in operating-system method for auditing link text. The manual version is the same test the link list applies: read each link’s words on their own, in a column, without the page around them, and ask whether you would know where each one goes. For buttons, ask whether the label names what happens after the press. It is slow on a large page, and it will not catch an aria-label that contradicts the visible text, because you cannot see one without reading the markup.
Checking nothing was sent
The markup is parsed by your own browser in the tab. Open the Network panel in the developer tools, paste a block of markup and watch: no request carries it. Disconnecting from the network after the page loads works as well, and the tool keeps auditing.
Next
Paste a navigation bar or a card grid into the Link & button text auditor; those are where repeated “Read more” links tend to collect. If your icon buttons use inline SVG, the SVG optimiser keeps each file’s <title> element by default rather than stripping it to save bytes.