cd /news/developer-tools/the-web-needs-a-native-visually-hidd… · home topics developer-tools article
[ARTICLE · art-11530] src=benmyers.dev ↗ pub= topic=developer-tools verified=true sentiment=· neutral

The Web Needs a Native .visually-hidden

The article argues that the web needs a native HTML or CSS method to visually hide elements while keeping them accessible to screen readers, replacing the current reliance on a "copypasta" utility class like `.visually-hidden`. It explains that conventional hiding methods like `display: none` also hide content from assistive technologies, while the existing `.visually-hidden` workaround is a bundle of hacks vulnerable to browser changes and has multiple unvetted variations. The author concludes that a standardized, built-in technique would be more reliable and safer for web accessibility.

read11 min views29 publishedMar 1, 2023

One of the strangest artifacts of web accessibility to me is the .visually-hidden

utility class. You might also know it as .sr-only

(or possibly as .screen-reader-text , .element-invisible

, or any number of other names throughout the ages). note 1 Conventional ways to hide elements include the styles display: none

or visibility: hidden

, or using HTML's hidden

attribute. When you use any of these approaches, the browser assumes no one is meant to access those elements, and it won’t expose that content to assistive technologies. This makes for a bit of a conundrum: what if you want to hide something visually, but still expose it to assistive technologies such as screenreaders? For instance…

Enter, the .visually-hidden

utility class, which usually (foreshadowing!) looks something like:

I’ve borrowed this particular set of rules from Kitty Giraudel’s .sr-only snippet. These rules make the applied element take up zero space, without triggering any of the heuristics browsers use to exclude elements from

assistive technology output. To learn more about how these styles work, I recommend checking out

James Edwards’s breakdown of. .visually-hidden

This snippet of styles works really well, and has been iterated upon and vetted by accessibility practitioners over the years. However, it would be a big win for the web to have a native HTML or CSS technique, no copypasta required, to visually hide elements while still exposing them to assistive technologies.

Problems with Copypastas #

It’s a Bundle of Hacks

Or, at least, it feels that way.

After all, the very reason for these styles is to make an element as hidden as possible without also triggering browsers’ heuristics for hiding elements from assistive technologies. The various rules could each constitute a point of failure if browsers adjust their heuristics, whether through conscious decision or as a bug. If a browser, for instance, stopped exposing content obscured by overflow: hidden

to assistive technologies, this ruleset would be toast. Ideally, browsers wouldn’t just break stuff like that — I don’t think there’s a big chance this would happen — but it would be safer not to rely on browser regression so much.

Which Snippet Should You Use?

As my friend Evan noted, there’s not just one set of visually-hidden rules out there:

@benthere’s also more than one magical copy-pasta floating around out there, and I’m never entirely sure which one I should use.[Evan (@darth_mall@notacult.social)]

There have been lots of takes on visually hidden styles over the years. Some are homegrown, unvetted, and brittle, such as one I found recently which leaned in large part on color: transparent

, which would be ignored in forced colors mode, causing invisible text to become visible again. Other approaches were once commonplace but are now discouraged — namely, an approach which put the contents very far off screen with absolute positioning or a large negative text-indent

. This is discouraged nowadays because it caused issues for right-to-left content, note 3 people using screen magnifiers, sighted screenreader users who benefit from seeing their screenreader’s cursor, and

[mobile screenreader users who rely on touch](https://www.sarasoueidan.com/blog/inclusively-hiding-and-styling-checkboxes-and-radio-buttons/#hiding-the-checkboxes-inclusively).

While today, accessibility practitioners have landed on the clip-paths-and-hidden-overflows approach provided above, there are still iterations and variations on the theme, all attempting to deal with new quirks or contexts faced in the real world. For instance, [Kitty Giraudel’s visually-hidden styles](https://kittygiraudel.com/snippets/sr-only-class/) are pretty similar to [those shared by Scott O’Hara](https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html#hiding-content-visually), except that Kitty also removes the element’s border, padding, and margins. These additions make the visually-hidden styles more robust in [edge-casier scenarios such as parents with overflow: auto](https://github.com/Orange-OpenSource/Orange-Boosted-Bootstrap/issues/84).

Given that we’re still occassionally finding quirks that need to be accounted for, how do we know that the visually-hidden styles that have been sitting in our codebase for a few years (including those provided by third-party libraries and CSS frameworks) are the latest, greatest, up-to-datest iterations? How should accessibility practitioners communicate incremental updates to the webdev community at large?

What I’d Love to See #

Given there’s a market for visually hiding content while still exposing it to assistive technologies, the web would benefit greatly from providing a native, spec’d out CSS/HTML technique that doesn’t require copying and pasting a magic snippet. And for my money, the approach I’d most love to see is…

…defined as identical to display: none

, except that this style doesn’t disqualify the element from being exposed to assistive technologies. note 4

In the wild, this would probably lead to style declarations like:

And I think using it with Sass or CSS nesting would feel very clean: Depending on how closely this hypothetical display: visually-hidden

matches the behavior of display: none

, this would have another leg up on the .visually-hidden

styles in that text hidden this way wouldn’t show up in Ctrl+F in-page searches or get added to the clipboard, either of which could be unexpected and unintuitive for sighted users.

What Are The Options?

And why do I think display: visually-hidden

is the way to go?

When I’ve asked about proposals for native visually-hidden on Twitter before, I’ve gotten a myriad of different potential implementations folks would like to see.

Put It In HTML!

Some responses I’ve gotten propose adding some attribute or new attribute value to HTML.

In some cases, people suggested adding a new value to the hidden

attribute (maybe something like hidden="visually"

?), since hidden

is no longer a simple boolean. I think this would be a dangerous route to go down (in my mind, a complete nonstarter), because the failure mode for a browser that doesn’t recognize the new value yet would be to exclude the content from assistive technology output altogether.

Additionally, in the early days of the hidden

attribute, many stylesheets added this rule to be able to start using hidden

earlier.

This rule is still present on many sites, and in CSS resets and normalizers such as normalize.css. Sites with a rule like this would still prevent visually-hidden content from being exposed to assistive technologies.

This brings us to a larger point about putting this in HTML: even if we were to create some sort of brand new visuallyhidden

attribute, browsers’ default styles for HTML elements and attributes are incredibly easy to override. All it takes is a well-meaning developer to write…

…and the attribute is toast for a site in a way that most developers would totally miss.

Additional concerns I have around putting this in HTML are that:

  • It doesn’t really facilitate responding to the viewport or container size without JavaScript (I could see wanting to use media queries or container queries to show/hide the text inside of an icon button at various viewport widths or container sizes, for instance) - It doesn’t really facilitate responding to states such as hover or focus without JavaScript either (consider the visually-hidden skip link which appears when it receives keyboard focus) - The notion of something being “visually” hidden is a very presentational, browser-centric idea, and I’m not sure how well these semantics would translate to other user agents

In my mind, if we’re going to have a native approach to visually hiding some element, it’s gotta be in CSS.

Make a New CSS Property!

I could definitely live with this!

This would require a bit of bikeshedding on the name, because naming is hard, but for the purposes of this article, let’s say it looks something like:

This gives us something that we can use along with all of our media queries, container queries, pseudo-classes, and more!

This is absolutely a step in the right direction for me!

A weakness of a new property like this, however, is that it’s not entirely clear to me how this would resolve:

Would the element still be hidden from assistive technologies because of the display: none

?

Or what about this?

Would the element be visually hidden here, or would the display: block

unhide it? Could we articulate why that behavior is the way it is?

I’m sure the specs would settle on an order of precedence here, but I’m not sure that precedence could ever be completely intuitive to a developer. In my opinion, that just increases the risk that some content might not get exposed to assistive technologies that’s intended to be.

I think introducing a new property also comes with an education cost. CSS already has display

, visibility

, content-visibility

, and other ways to hide an element, which is already a confusing jumble of similar names and functionality. If we introduce a new property, not only do we have to figure out how it interacts with the other CSS ways to hide something… we also add to the confusing jumble, which I feel would just make this wing of CSS just that much less approachable to newcomers.

If we want to avoid adding a new, similarly named CSS property to the pile and reduce how many other properties this could conflict with, note 5 then it seems to me that the way to go is to add a new value to a property that already exists. Since in my mind, the ideal functionality is like display: none

except without hiding content from assistive technologies, a new display

property makes the most sense to me. Hence, display: visually-hidden

!## The Road Ahead

An addition like this would go through the CSS Working Group. Back in 2016, Sara Soueidan filed an issue recommending exactly this, but the conversation seems to have stagnated. If a display: visually-hidden

seems appealing to you, give it a thumbs up and consider contributing to the conversation.

If display: visually-hidden ever does go through, I think it’s worth being strategic about how we start to incorporate it into our sites (given that “evergreen” doesn’t mean immediately available). For my money, the simplest and most robust approach would be to add the rule to our already-working .visually-hidden

/.sr-only

classes:

…at least until our browser stack has reliably supported this value for some time.

Conclusion #

While the .visually-hidden /.sr-only

utility styles have proven incredibly useful, the web would absolutely benefit in the long run from enshrining a native approach into the web standards. Such a rule would be easier to teach and easier to incorporate with CSS‘s responsive and stateful features. It’d also discourage unvetted, homegrown approaches from popping up, and it’d ensure that developers wouldn’t need to update their projects’ styles every few years when an improvement is discovered.

** update:** Since publishing this article, a few people have published their responses! I’d especially recommend giving Scott O’Hara’s response a read. It goes into some of the problems that would emerge from enshrining the .visually-hidden

technique into the standards, and pitches a few improvements the web could make that would mitigate the need for visually hiding in the first place.

More CSS Wishlists #

This article is inspired in part by Dave Rupert’s CSS wishlist for 2023. Several other people have put out their own CSS wishlists, and you should give them a read!

Manuel Matuzović’s wishlist, which includes a call for a native approach to visually hidden stylesMayank’s wishlist, which also includes a call for a native approach to visually hidden stylesStephanie Eckles’s wishlistEric Meyer’s wishlistAhmad Shadeed’s wishlist

Footnotes #

.sr-only

,” short for “screenreader only,” is a widely used name for these styles, and would be especially familiar toTailwind usersand toBootstrap usersbefore them.WordPress, meanwhile, uses the name “The name “.screen-reader-text

.”.element-invisible

” was once used in Drupal, but wasdeprecated and replacedwith “.visually-hidden

” to better align with theHTML5 Boilerplate.Although it’s common to explicitly reference screenreaders in the classname, I personally recommend using the name “

.visually-hidden

,” since content hidden this way would also be exposed to other assistive technologies, as well as be surfaced inbrowser Reader ModesorRSS readers, and so “screenreader-only” is a bit of a misnomer. |Back to [1]The one-two punch of an

aria-hidden

node for the visual treatment along with a.visually-hidden

node with a clearer experience for assistive technologies is pretty common. I’ve seen this approach used for icon buttons, expanding abbreviations and timestamps, providing an unsplit alternative for split text, or substitutingpunctuation that gets inconsistently announced by screenreadersout for its spelled-out name in signup form help text. Use with care — the assistive technology experience shouldn’t diverge too much from the visual experience. |Back to [2]This concern largely comes from a time before

logical properties. Were it not for the other concerns with offscreen positioning, a modern solution could have been to absolutely position the element with. |inset-inline-start

Back to [3]I’ve worded it this way, and not as “the element is exposed to assistive technologies,” because otherfactors would still exclude the element from the accessibility tree, such as thehidden

andaria-hidden

attributes. It’s not that this style would guarantee the element is in the accessibility tree; just that visually hiding the element would not be what prevents it from being exposed. |Back to [4]You’d definitely still get conflicts if you were to, say, combine

display: visually-hidden andvisibility: hidden

. This would reduce the combinatorics here, but not eliminate them. |Back to [5]

── more in #developer-tools 4 stories · sorted by recency
── more on @kitty giraudel 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/the-web-needs-a-nati…] indexed:0 read:11min 2023-03-01 ·