{"slug": "the-web-needs-a-native-visually-hidden", "title": "The Web Needs a Native .visually-hidden", "summary": "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.", "body_md": "One of the strangest artifacts of web accessibility to me is the `.visually-hidden`\n\nutility class. You might also know it as `.sr-only`\n\n(or possibly as `.screen-reader-text`\n\n, `.element-invisible`\n\n, or any number of other names throughout the ages).[ note 1](#fn-1)\n\nConventional ways to hide elements include the styles `display: none`\n\nor `visibility: hidden`\n\n, or using HTML's `hidden`\n\nattribute. 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](/blog/css-can-influence-screenreaders/#hidden-content). 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…\n\n- Controls such as\n[skip links](/blog/skip-links/)that we want to hide by default but reveal on focus for keyboard navigators - Providing a cleaner or more usable alternative to markup or text that’s visually nice but less friendly to assistive technologies\n[note 2](#fn-2) - Nestling screenreader-friendly text inside of icon links or buttons, instead of relying on\n[ARIA approaches which probably won’t auto-translate](https://adrianroselli.com/2019/11/aria-label-does-not-translate.html) [Hiding native form controls to provide custom controls](https://www.sarasoueidan.com/blog/inclusively-hiding-and-styling-checkboxes-and-radio-buttons/)that are still backed by semantic markup\n\nEnter, the `.visually-hidden`\n\nutility class, which usually *(foreshadowing!)* looks something like:\n\nI’ve borrowed this particular set of rules from [Kitty Giraudel’s .sr-only snippet](https://kittygiraudel.com/snippets/sr-only-class/). These rules make the applied element take up zero space, without triggering any of the heuristics browsers use to exclude elements from\n\n[assistive technology output](/blog/accessibility-tree/). To learn more about how these styles work, I recommend checking out\n\n[James Edwards’s breakdown of](https://www.tpgi.com/the-anatomy-of-visually-hidden/).\n\n`.visually-hidden`\n\nThis 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.**\n\n## Problems with Copypastas\n\n### It’s a Bundle of Hacks\n\nOr, at least, it *feels* that way.\n\nAfter 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`\n\nto 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.\n\n### Which Snippet Should You Use?\n\nAs my friend Evan noted, there’s not just one set of visually-hidden rules out there:\n\n–\n\n@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)]\n\nThere 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`\n\n, 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`\n\n. This is discouraged nowadays because it [caused issues](https://www.tpgi.com/the-anatomy-of-visually-hidden/#position) for right-to-left content, note 3 people using screen magnifiers, sighted screenreader users who benefit from seeing their screenreader’s cursor, and\n\n[mobile screenreader users who rely on touch](https://www.sarasoueidan.com/blog/inclusively-hiding-and-styling-checkboxes-and-radio-buttons/#hiding-the-checkboxes-inclusively).\n\nWhile 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).\n\nGiven 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?\n\n## What I’d Love to See\n\nGiven 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…\n\n…defined as identical to `display: none`\n\n, except that this style doesn’t disqualify the element from being exposed to assistive technologies.[ note 4](#fn-4)\n\nIn the wild, this would probably lead to style declarations like:\n\nAnd I think using it with Sass or [CSS nesting](https://webkit.org/blog/13813/try-css-nesting-today-in-safari-technology-preview/) would feel very clean:\n\nDepending on how closely this hypothetical `display: visually-hidden`\n\nmatches the behavior of `display: none`\n\n, this would have another leg up on the `.visually-hidden`\n\nstyles 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.\n\n### What Are The Options?\n\nAnd why do I think `display: visually-hidden`\n\nis the way to go?\n\nWhen I’ve [asked about proposals for native visually-hidden on Twitter before](https://twitter.com/BenDMyers/status/1520436278935920641), I’ve gotten a myriad of different potential implementations folks would like to see.\n\n#### Put It In HTML!\n\nSome responses I’ve gotten propose adding some attribute or new attribute value to HTML.\n\nIn some cases, people suggested adding a new value to the `hidden`\n\nattribute (maybe something like `hidden=\"visually\"`\n\n?), since `hidden`\n\nis 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.\n\nAdditionally, in the early days of the `hidden`\n\nattribute, many stylesheets added this rule to be able to start using `hidden`\n\nearlier.\n\nThis rule is still present on many sites, and in CSS resets and normalizers [such as normalize.css](https://github.com/necolas/normalize.css/blob/fc091cce1534909334c1911709a39c22d406977b/normalize.css#L347). Sites with a rule like this would still prevent visually-hidden content from being exposed to assistive technologies.\n\nThis brings us to a larger point about putting this in HTML: even if we were to create some sort of brand new `visuallyhidden`\n\nattribute, browsers’ default styles for HTML elements and attributes are *incredibly* easy to override. All it takes is a well-meaning developer to write…\n\n…and the attribute is toast for a site in a way that most developers would totally miss.\n\nAdditional concerns I have around putting this in HTML are that:\n\n- It doesn’t really facilitate responding to the viewport or container size without JavaScript\n*(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\n*(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\n\nIn my mind, if we’re going to have a native approach to visually hiding some element, it’s gotta be in CSS.\n\n#### Make a New CSS Property!\n\nI could definitely live with this!\n\nThis 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:\n\nThis gives us something that we can use along with all of our media queries, container queries, pseudo-classes, and more!\n\nThis is absolutely a step in the right direction for me!\n\nA weakness of a new property like this, however, is that it’s not entirely clear to me how this would resolve:\n\nWould the element still be hidden from assistive technologies because of the `display: none`\n\n?\n\nOr what about this?\n\nWould the element be visually hidden here, or would the `display: block`\n\nunhide it? **Could we articulate why that behavior is the way it is?**\n\nI’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.\n\nI think introducing a new property also comes with an education cost. CSS already has `display`\n\n, `visibility`\n\n, `content-visibility`\n\n, 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.\n\nIf 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\n\n`display: none`\n\nexcept without hiding content from assistive technologies, a new `display`\n\nproperty makes the most sense to me. Hence, `display: visually-hidden`\n\n!## The Road Ahead\n\nAn addition like this would go through the CSS Working Group. Back in 2016, Sara Soueidan filed [an issue recommending exactly this](https://github.com/w3c/csswg-drafts/issues/560), but the conversation seems to have stagnated. If a `display: visually-hidden`\n\nseems appealing to you, give it a thumbs up and consider contributing to the conversation.\n\nIf `display: visually-hidden`\n\never 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](https://css-tricks.com/evergreen-does-not-mean-immediately-available/)). For my money, the simplest and most robust approach would be to add the rule to our already-working `.visually-hidden`\n\n/`.sr-only`\n\nclasses:\n\n…at least until our browser stack has reliably supported this value for some time.\n\n## Conclusion\n\nWhile the `.visually-hidden`\n\n/`.sr-only`\n\nutility 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.\n\n** update:** Since publishing this article, a few people have published their responses! I’d especially recommend giving [Scott O’Hara’s response](https://www.scottohara.me/blog/2023/03/21/visually-hidden-hack.html) a read. It goes into some of the problems that would emerge from enshrining the `.visually-hidden`\n\ntechnique into the standards, and pitches a few improvements the web could make that would mitigate the need for visually hiding in the first place.\n\n## More CSS Wishlists\n\nThis article is inspired in part by [Dave Rupert’s CSS wishlist for 2023](https://daverupert.com/2023/01/css-wishlist-2023/). Several other people have put out their own CSS wishlists, and you should give them a read!\n\n[Manuel Matuzović’s wishlist](https://www.matuzo.at/blog/2023/css-wish-list/), which includes a call for a native approach to visually hidden styles[Mayank’s wishlist](https://blog.mayank.co/my-css-wishlist-2023), which also includes a call for a native approach to visually hidden styles[Stephanie Eckles’s wishlist](https://thinkdobecreate.com/articles/css-wishlist-2023/)[Eric Meyer’s wishlist](https://meyerweb.com/eric/thoughts/2023/02/08/css-wish-list-2023/)[Ahmad Shadeed’s wishlist](https://ishadeed.com/article/css-wishlist-2023/)\n\n## Footnotes\n\n“\n\n`.sr-only`\n\n,” short for “screenreader only,” is a widely used name for these styles, and would be especially familiar to[Tailwind users](https://tailwindcss.com/docs/display#screen-reader-only)and to[Bootstrap users](https://getbootstrap.com/docs/4.0/utilities/screenreaders/)before them.[WordPress, meanwhile, uses the name “](https://make.wordpress.org/accessibility/handbook/markup/the-css-class-screen-reader-text/)The name “`.screen-reader-text`\n\n.”`.element-invisible`\n\n” was once used in Drupal, but was[deprecated and replaced](https://www.drupal.org/node/2022859)with “`.visually-hidden`\n\n” to better align with the[HTML5 Boilerplate](https://html5boilerplate.com/).Although it’s common to explicitly reference screenreaders in the classname, I personally recommend using the name “\n\n`.visually-hidden`\n\n,” since content hidden this way would also be exposed to other assistive technologies, as well as be surfaced in[browser Reader Modes](https://www.sarasoueidan.com/blog/tips-for-reader-modes/)or[RSS readers](/blog/rss-semantics/), and so “screenreader-only” is a bit of a misnomer. |[Back to [1]](#fn-ref-1)The one-two punch of an\n\n`aria-hidden`\n\nnode for the visual treatment along with a`.visually-hidden`\n\nnode 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 substituting[punctuation that gets inconsistently announced by screenreaders](https://www.deque.com/blog/dont-screen-readers-read-whats-screen-part-1-punctuation-typographic-symbols/)out 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]](#fn-ref-2)This concern largely comes from a time before\n\n[logical properties](https://css-tricks.com/css-logical-properties-and-values/). 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`\n\n[Back to [3]](#fn-ref-3)I’ve worded it this way, and not as “the element is exposed to assistive technologies,” because\n\n*other*factors would still exclude the element from the accessibility tree, such as the`hidden`\n\nand`aria-hidden`\n\nattributes. 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]](#fn-ref-4)You’d definitely still get conflicts if you were to, say, combine\n\n`display: visually-hidden`\n\nand`visibility: hidden`\n\n. This would reduce the combinatorics here, but not eliminate them. |[Back to [5]](#fn-ref-5)", "url": "https://wpnews.pro/news/the-web-needs-a-native-visually-hidden", "canonical_source": "https://benmyers.dev/blog/native-visually-hidden/", "published_at": "2023-03-01 00:00:00+00:00", "updated_at": "2026-05-23 14:14:08.674099+00:00", "lang": "en", "topics": ["developer-tools", "open-source"], "entities": ["Kitty Giraudel"], "alternates": {"html": "https://wpnews.pro/news/the-web-needs-a-native-visually-hidden", "markdown": "https://wpnews.pro/news/the-web-needs-a-native-visually-hidden.md", "text": "https://wpnews.pro/news/the-web-needs-a-native-visually-hidden.txt", "jsonld": "https://wpnews.pro/news/the-web-needs-a-native-visually-hidden.jsonld"}}