Skip to content

Essential Visually Hidden CSS Techniques for Web Accessibility

Fix vanishing focus indicators & conflicting sr-only classes. Learn the 3-state visibility model that transforms CSS hacks into logical accessibility decisions.

Building accessible websites means thinking about every user.

Purely visual elements on a website cannot be perceived by people who cannot see. In cases like this, you need to provide an alternative, often in the form of some text. Sometimes, depending on the design of a page, you’ll want to hide this text visually. Maybe it’s a text label for an icon button, skip navigation links, or an alert that pops up on screen.

But how do you hide content visually, while keeping it accessible to assistive technologies?

Many developers accidentally break accessibility when trying to solve this problem. They use CSS properties that seem logical but end up hiding content from everyone – including the people who need it most.

The good news is that there are reliable techniques that work. This guide shows you how to hide content properly, avoid common pitfalls, and ensure your implementations work for both screen readers and keyboard users.

Hiding content visually while keeping it accessible

Visually hidden content is text or elements that remain invisible to sighted users but stay fully accessible to screen readers and other assistive technologies. It’s a technique that solves a common accessibility challenge by providing extra context for people who are blind or have visual impairments without adding visible elements to a web page.

Think about a “Read more” link on a news archive page. Sighted users see which article it relates to from the visual context. But screen reader users hear “Read more” repeated dozens of times without context. The solution: Add visually hidden text like “Read more about sustainable gardening tips.”

This is just one way visually hidden content improves accessibility. Other common uses include:

  • Skip links that appear on keyboard focus.
  • Form labels that provide extra context without visual clutter.
  • Status updates for dynamic content changes.

What we’ll cover: This article focuses on the CSS techniques that make content visually hidden whilst keeping it accessible. While there are other approaches like ARIA labels and live regions for some of these use cases, we’ll concentrate on the core CSS methods you need to master first – they’re the foundation everything else builds on.

We’ll explore the CSS techniques and ARIA attributes that make this possible, plus show you how to test your implementations properly.

Before we get to that, let’s examine a common mistake that trips up many developers.  

Common pitfalls: when “display: none” breaks accessibility

You might think that display: none hides content you want screen readers to access.

It seems logical, right? You want to hide something visually but keep it available for assistive technology. So you reach for the most familiar CSS property.

Unfortunately, display: none is too thorough. It removes elements completely from the accessibility tree – the structure that screen readers use to understand your page. The same goes for visibility: hidden.

Imagine you’re giving directions over the phone whilst looking at a map. If you use display: none, it’s like tearing that section right off the map. You can’t describe what isn’t there anymore.

When you use these properties, people using screen readers miss out on important information like enhanced button labels, skip links, or form instructions that would help them navigate your site more easily.

The solution is simple: use CSS techniques that only affect visual presentation.

Breaking down visually hidden CSS techniques

Using the “Read more” example from earlier, here’s how you’d implement the CSS to hide that additional context visually:

The modern approach: clip-path technique

Today’s preferred method uses clipping instead of positioning:

.visually-hidden {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  margin: 0;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

Let’s break this down into smaller chunks:

  • border: 0 removes visible borders.
  • clip-path: inset(50%) clips the visible area to almost nothing (you can use inset(100%) too).
  • position: absolute removes from document flow but keeps it accessible.
  • width: 1px and height: 1px create a minimal visual footprint.
  • overflow: hidden prevents content spillage.
  • white-space: nowrap stops text wrapping that might expose content.

✅ Using this technique ensures that page content stays put instead of flying off-screen, which means screen magnifiers and other assistive technologies handle it more reliably.

While this is the recommended methodology, there may still be some issues if your visually hidden content is excessively repetitive. 

This is addressed in the WCAG guide, where it states:

This technique… has proved effective on some websites. Other screen reader users and accessibility experts don’t recommend this as a general technique because the results can be overly chatty and constrain the ability of the experienced screen reader user to control the verbosity. The working group believes the technique can be useful for web pages that do not have repetitive content in the hidden text areas.

That means you’ll need to use visually hidden content thoughtfully – for button context, skip links, and form guidance that genuinely improves the experience.

Making hidden content keyboard-accessible

There’s a catch when hiding interactive elements like buttons or links.

If you apply .visually-hidden to focusable elements, sighted keyboard users will lose track of where they are on the page. Imagine tabbing through a site and suddenly your focus indicator vanishes – quite disorienting!

Here’s the fix: Make hidden interactive elements visible when they receive focus.

.visually-hidden-focusable:not(:focus):not(:active) {
  /* Include all the visually-hidden properties above */
}

The :not(:focus):not(:active) selectors mean the hiding only applies when the element isn’t focused or activated. When someone tabs to the element, it becomes fully visible.

Browser compatibility: This uses the modern :not() selector. For older browser support (IE11 and below), you’ll need the alternative approach shown in WordPress’s accessibility handbook.

This technique is perfect for skip links – they stay hidden until keyboard users need them, then pop into view exactly when required.

Now, both sighted keyboard users and screen reader users get the navigation help they need.

Master accessibility implementation with our code course

Yes, hiding content properly is absolutely important, but it’s still just a small part of building truly accessible websites. What about managing keyboard focus in complex components? Creating accessible forms that actually work with screen readers? Implementing ARIA attributes correctly?

💡 The A11Y Collective’s Accessible Code course covers all of this and more.

You’ll learn to write semantic HTML that screen readers interpret correctly, manage focus in modals and mega menus, create accessible forms, and test your implementations with real assistive technologies. We cover everything from basic HTML5 semantics to advanced ARIA patterns.

Perfect for developers who want to:

  • Build accessibility in from the start, not retrofit later.
  • Meet WCAG guidelines confidently.
  • Create better experiences for all users.
  • Save time by getting it right the first time.

Enrol in our Accessible Code Course today and receive the practical knowledge to build websites that truly work for everyone.

Ready to master accessible CSS?

Build accessibility in from the start with practical, hands-on training.