Search topics
Banner and image links with no name
A promo banner is made clickable with a link that holds only its photo, marked as decoration, or with an empty link laid over it, so the link has no name and a screen reader can say only "link" or its address.
<a href="/collections/autumn-roasts" class="banner-link"><img src="/images/autumn-roasts.jpg" alt=""></a> The problem
Screen reader users reach a banner link that says nothing, so they can't tell where it goes before they follow it.
A coffee roaster's home page opens with a promo banner: a photo of beans, the headline "Autumn roasts are here", a line about the new beans and a white "Shop the roasts" pill. The pointer turns to a hand anywhere on the banner, the pill fills on hover, and a click anywhere leads to the autumn collection. Pressing Tab puts focus on the banner, and a screen reader announces "link", or reads out the address, "collections/autumn-roasts". Someone who opens the screen reader's list of links finds an entry with no words, or only the address, and a voice control user who says "click Shop the roasts" gets no answer.
To make the whole banner clickable, the theme wraps the banner's photo in the link and stretches it over the banner, with the headline, the text and the pill laid on top. The photo is decoration, so it has alt="", and the link holds nothing else: it has no text and therefore no accessible name. With no alt at all, some screen readers read the image's file name instead, which is no better. Another common build reaches the same place by another route: the photo stays outside, and an empty <a> is laid over the banner with absolute positioning. Either way, the words sit in a sibling element, outside the link, and the pill looks like a button but is only drawn, a span that lets clicks through to the link under it. The browser makes the box clickable and focusable all the same, so the banner works for a mouse and looks finished.
WCAG 2.4.4 Link Purpose (In Context) asks that a link's purpose can be worked out from its text, alone or with context that software can tie to it, such as the sentence, paragraph or list item it sits in. The banner link has no text, and the headline and pill aren't its context in code: they are in a neighbouring element, not one that holds the link. So a screen reader has nothing to say but "link" or the address, and the person can't tell that it leads to the autumn roasts. An empty link fails whatever surrounds it. Links that have words, but the same vague ones on every card, are a different failure, covered in "Read more" links that all say the same thing.
Links are often read out of context, in a list or one at a time, so each one needs words of its own. Banners like this one sit at the top of home pages and campaign pages, where the link is often the main way into a sale.
2 of 10 groups affected
- No vision (affected)
- Low vision (not affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (not affected)
- Seizures (not affected)
- Without vision Screen reader users move through a page by its links or open a list of every link. An unnamed link gives them only "link" or its address, so they can't tell where it goes without following it.
- Limited manipulation Voice control users say a link's words to click it. "Click Shop the roasts", the words on the banner's pill, matches nothing, because the pill is only drawn and the link has no name, so they fall back on numbering every link on the page.
An automated check such as axe's link-name reliably flags the empty banner link. It does not judge whether a name is useful, so it passes a link named "IMG_2041.jpg", or an icon whose alt is "logo". A quick AI fix can add aria-label="Link" or aria-label="Banner", which silences the scanner and helps nobody, and leaves voice control users still unable to reach it by saying the words on the pill. A name only helps when a person reads it in a list and still knows where it goes.
Try it
Press Tab to reach the banner’s link, then try the simulated voice control.
The panel shows what a screen reader announces for the link, and its list of links. Does the banner’s link say where it goes, and does saying the words on its pill reach it?
Broken Can you fix this?
Screen reader says:
(Tab to a link)
Its list of links:
- (no name) collections/autumn-roasts
The fix
Give the banner's link the words on its pill: in the link you have, or by making the pill the link.
- 1Every link needs words: its text, an image's alt, or a name from aria-labelledby.
- 2Name the link laid over a banner after its pill, or make the pill the link, stretched by a pseudo-element.
- 3Name an image or icon link after where it goes, not after the picture.
The photo as the link, marked as decoration
<div class="banner"> <a href="/collections/autumn-roasts" class="banner-link"> <img src="/images/autumn-roasts.jpg" alt=""> </a> <div class="banner-text"> <h2>Autumn roasts are here</h2> <p>Three new single-origin beans, roasted this week.</p> <span class="banner-cta">Shop the roasts<span aria-hidden="true"> →</span></span> </div></div>Add the pill's words to the link you have
<div class="banner"> <a href="/collections/autumn-roasts" class="banner-link"> <img src="/images/autumn-roasts.jpg" alt=""> <span class="visually-hidden">Shop the roasts</span> </a> <div class="banner-text"> <h2>Autumn roasts are here</h2> <p>Three new single-origin beans, roasted this week.</p> <span class="banner-cta">Shop the roasts<span aria-hidden="true"> →</span></span> </div></div>The link's only content is an image with alt="", so it has no name, and it fails 2.4.4. The pill that says where it goes is a drawing over the link, not part of it.
Adding the words leaves the layout as it is. The banner link is now announced as "Shop the roasts, link", and voice control finds it when someone says the words on the pill. On a banner built the second way, the same span goes in the empty link laid over it, and nothing else changes. When the photo is the link's only content, its alt can carry the words instead, alt="Shop the roasts", as technique H30 describes: the alt then names where the link goes, not what the photo shows. The name uses the pill's words rather than the headline's because the pill is what reads as the thing to press: WCAG 2.5.3 Label in Name asks that a control's name contains the words that label it on screen, so people can say what they see. Instead of hidden text, the link can take its name from the pill with aria-labelledby, pointing at an id on the pill, or at the pill and then the headline (technique ARIA7), so the words can't drift apart. Either way, someone reading the banner from top to bottom hears the pill's words twice: once as the link and once as text.
Both options give the banner's link a name and meet 2.4.4. Adding the words is the smaller change: no layout changes, so it suits a theme or third-party slideshow you can't restructure. Making the pill the link is cleaner: one link, read once, named by the words people already see on the pill. Choose it when you can change the template. You can mix them, for example pill links on banners you own and a named overlay link on a slideshow you don't.
The stretched link covers other controls. Any other button or link inside the banner, such as a second call to action or a slideshow's pause button, needs position: relative and a z-index above the pseudo-element, or it can't be clicked. The overlay also stops people selecting the banner's text.
Wrapping the whole banner in one <a>. This is valid HTML and makes the banner clickable, but the link's name becomes everything inside it, so the screen reader reads the headline, the text and the pill as one long link. The banner also can't contain another link or button. A link on the pill avoids both problems.
Hidden text versus aria-label. Use a clip-based .visually-hidden class, not display: none, which removes the text from the accessible name too. An aria-label on the empty link also gives it a name, but some browser translation tools skip it and it can drift from the pill, so prefer hidden text or aria-labelledby.
Text over the photo. The words sit on a photo, so they need a dark scrim under them, darkest behind the text, for their contrast; check it against the lightest part of the photo behind any word, at every width the banner takes.
Image and icon links. When the image is the only content of a link, its alt names the destination ("Northside Roasters home", "Instagram"), not the picture. When the image sits next to text in the same link, give it alt="" so the name is not read twice. For an SVG icon, hide the SVG with aria-hidden="true" and put visually hidden text in the link.
Editable content. In a theme or CMS, the banner's pill text is often an optional field. If it is left empty, the stretched link has no name again. Require a link label when a link is set, or don't render the link when the label is empty.
Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.
Verify the fix
5 checks.
Test with: Keyboard, Screen reader, Speech input, Mouse
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared banner or slideshow component changes.
Limits
This is a starting pattern, not a guarantee for every application. Paths and class names in the snippets are placeholders. Content editors can still leave a banner's pill text empty later, so keep link names in your publishing review. Test the complete journey with your target assistive technology.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.