Visually hidden text, only visible to screen readers

This article looks into content that is visually hidden, but visible to people using assistive technologies, like screen readers.

Screen reader only content might be needed when:

  • Rendering a button that is only an icon with no visible text. The button should contains a visually hidden text that tells what it does, e.g.: "Sort ascending". The accessible React icon component uses this pattern.
  • Rendering form fields with no visible labels, the label should be there, but it should be screen reader only.

Back in the day we simply used to do:

.visually-hidden {
  left: -9999px;
  position: absolute;
}

The needed CSS to hide a button properly

But it had its issues, after some amount iterations the collective understanding is to use something like this:

.visually-hidden {
  border: 0 !important;
  clip: rect(1px, 1px, 1px, 1px) !important;
  height: 1px !important;
  overflow: hidden !important;
  padding-bottom: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  padding-top: 0 !important;
  position: absolute !important;
  white-space: nowrap !important;
  width: 1px !important
})

Visually hidden React component

It’s pretty unsurprising... here’s one made using styled-components:

import styled from 'styled-components'
 
const VisuallyHidden = styled.span({
  border: '0 !important',
  clip: 'rect(1px, 1px, 1px, 1px) !important',
  height: '1px !important',
  overflow: 'hidden !important',
  paddingBottom: '0 !important',
  paddingLeft: '0 !important',
  paddingRight: '0 !important',
  paddingTop: '0 !important',
  position: 'absolute !important',
  whiteSpace: 'nowrap !important',
  width: '1px !important',
})
 
export default VisuallyHidden

With styled-components, you can just export that definition and use it, it’s already a React component, props.children will be passed along as it should.

Sources: