How to hide an element visually but keep it for screen readers
Short answer
Make the element 1 pixel in size, clip it with clip-path and take it out of the flow:
<style>
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
</style>
<button>🛒 <span class="sr-only">Cart, 3 items</span></button>Only the icon is visible on screen, while a screen reader reads "Cart, 3 items". The class is usually called sr-only or visually-hidden and kept in the site's common styles.
Where it is needed
- A label for a field when the design has none — for example, for a search field with a magnifier button.
- An explanation for an icon or for a "Read more" link ("…about coffee roasting").
- A section heading that the eye gets from the layout but the page structure needs.
The opposite task
Sometimes the opposite is needed: show an element to the eye but hide it from a screen reader — for example, a decorative icon next to text. The aria-hidden="true" attribute does that:
<p><span aria-hidden="true">★★★★☆</span> <span class="sr-only">Rating: 4 out of 5</span></p>Common mistake
Text for screen readers is hidden with display: none or hidden. Screen readers do not see such elements either — the hint disappears for everyone. Hiding with opacity: 0 does not work either: the element stays in place and takes up space.
Functions used in this recipe
- clip-path — Clips an element to a shape: only the part inside the shape stays visible.
- position — How an element is positioned: in the normal flow or by offsets.
- overflow — What to do with content that does not fit into the element.
- aria-* — Accessibility attributes: the role, name and state of an element for screen readers.
- hidden — Hides an element: it is not shown and not available to screen readers.