Skip to content

Instantly share code, notes, and snippets.

@ffoodd
Last active November 5, 2024 20:54
Show Gist options
  • Save ffoodd/000b59f431e3e64e4ce1a24d5bb36034 to your computer and use it in GitHub Desktop.
Save ffoodd/000b59f431e3e64e4ce1a24d5bb36034 to your computer and use it in GitHub Desktop.
Improved .sr-only

Improved .sr-only

Theorically bulletproof CSS class for visually hide anything and keep it accessible to ATs.

A Pen by ffoodd on CodePen.

License.

<button type="button">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
<a href="/" class="sr-only sr-only-focusable">Skippy</a>
<div dir="rtl">
<button type="button">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
<a href="ffoodd.fr" class="sr-only sr-only-focusable">ffoodd.fr</a>
</div>
/*
Improved screen reader only CSS class
@author Gaël Poupard
@note Based on Yahoo!'s technique
@author Thierry Koblentz
@see https://www.cssmojo.com/hide-content-from-sighted-users/
* 1.
@note `clip` is deprecated but works everywhere
@see https://developer.mozilla.org/en-US/docs/Web/CSS/clip
* 2.
@note `clip-path` is the future-proof version, but not very well supported yet
@see https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path
@see http://caniuse.com/#search=clip-path
@author Yvain Liechti
@see https://twitter.com/ryuran78/status/778943389819604992
* 3.
@note preventing text to be condensed
author J. Renée Beach
@see https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
@note Drupal 8 goes with word-wrap: normal instead
@see https://www.drupal.org/node/2045151
@see http://cgit.drupalcode.org/drupal/commit/?id=5b847ea
* 4.
@note !important is important
@note Obviously you wanna hide something
@author Harry Roberts
@see https://csswizardry.com/2016/05/the-importance-of-important/
*/
.sr-only {
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important; /* 1 */
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important; /* 2 */
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important; /* 3 */
}
/*
Use in conjunction with .sr-only to only display content when it's focused.
@note Useful for skip links
@see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
@note Based on a HTML5 Boilerplate technique, included in Bootstrap
@note Fixed a bug with position: static on iOS 10.0.2 + VoiceOver
@author Sylvain Pigeard
@see https://github.com/twbs/bootstrap/issues/20732
*/
.sr-only-focusable:focus,
.sr-only-focusable:active {
clip: auto !important;
-webkit-clip-path: none !important;
clip-path: none !important;
height: auto !important;
margin: auto !important;
overflow: visible !important;
width: auto !important;
white-space: normal !important;
}
@sukima
Copy link

sukima commented Aug 22, 2022

Are the better examples because it doesn’t fit in the use of a button since a button can handle the same thing using aria-label

<button type="button" aria-label="Close">&times;</button>

Pretty sure the aria-label will override the text content of a button for screen readers. 🤔

@ffoodd
Copy link
Author

ffoodd commented Aug 23, 2022

It would indeed, but won't:

  1. appear when CSS is disabled for any reason,
  2. be taken into account when selecting the component,
  3. translate when using thing like Google Translate…

There might be more arguments, but you got the picture: I really think visually hidden content is better than ARIA attributes — and it also better respects ARIA rules, since we can use HTML & CSS to do this.

@GlitzSmarter
Copy link

Thank you so much for this. You may want to change the first see link (in the css) to an archive.org copy as the original is no longer available.

@ffoodd
Copy link
Author

ffoodd commented Apr 5, 2023

Thanks @GlitzSmarter for reporting, I managed to find a copy on the author's own blog.

@aquaductape
Copy link

Why position absolute as opposed to fixed?

@bjoernuhlig
Copy link

Why position absolute as opposed to fixed?

@aquaductape https://webaim.org/techniques/css/invisiblecontent/
"position:absolute; tells the browser to remove the element from the page flow and to begin positioning it."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment