A way to hide text visually but not from screen readers

When a page contains icon-only page elements (e.g. icon webfont buttons), it may be a good approach to provide a text alternative for screen readers. This text should be visually hidden (not appear on the page) but be read out by screen readers.

It seems that, in order to achieve this, one has to use CSS hacks like:

.screen-reader-text {
    position: absolute;
    left: -999em;

Source: https://www.joedolson.com/articles/2014/06/visual-icon-problem/comment-page-1/#comment-117924

Maybe we should introduce a CSS (or HTML) feature for this?


This should actually be possible with:

@media screen {
  .screen-reader-text {
    display: none;


.screen-reader-text {
  display: none;

@media speech {
  .screen-reader-text {
    display: block;

Problem is really that I think most screen readers don’t support this at the moment.

1 Like

Isn’t the media type for screen readers “speech”?

Spec: http://dev.w3.org/csswg/mediaqueries/#media-type

I know reader was recommended at one point: http://www.w3.org/TR/css3-reader/

Either way I think both are poorly supported; I assume they dropped the reader idea perhaps.

Anyway… I would advocate using that rather than inventing something else.

Looks like a media type for screen readers won’t happen, but a “screenreader” media feature might: https://bugzilla.mozilla.org/show_bug.cgi?id=946370#c11

@media (screenreader: none) {
    .screen-reader-text { display: none }

Yes, (screenreader) will exist.

As to reader, note that the WD is 10 years old, and there’s no editor’s draft or further updates. That means it’s dead. (Media types in general are dead. We’ve deprecated most of them, and the few remaining are just because we haven’t yet fully replaced them with media features.)


In this situation I use the following markup to achieved the solution

<button class="button button-close" aria-label="Close">x</button>

This is read it as “Close button”

And only in edge case I use the “visually-hidden” class borrowed from html5-boilerplate

* Hide only visually, but have it available for screen readers: h5bp.com/v

.visuallyhidden {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;

* Extends the .visuallyhidden class to allow the element to be focusable
* when navigated to via the keyboard: h5bp.com/p

.visuallyhidden.focusable:focus {
    clip: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    position: static;
    width: auto;

@tabatkins last time I think I discussed this was about 10 years ago to be honest and ever since I knew most screen readers looked at media type screen so was vastly not worth much interest, the new direction appears to be interesting though.

Out of interest is there a W3C developer guide hinting at the new direction of moving towards media features? I know the Authors guide is a newer concept but something similar might be useful for CSS having discussions on long term directional shifts as mentioned, even some of the much older pages like: this or this certainly helped steer me in where the W3C and standards are going (I struggled to find better examples of older conversational style pages - I know they exist though); Obviously the W3C hangs off more article writers publishing ‘good practice’ guides to help share the standards to the masses; a formal-ish document written by people like yourself on the intents (or is it wishes these days ;)) for CSS would certainly help this article based feedback loop.

We can come back in another 10 and see if Robin was right then: http://berjon.com/web-2024/

Well, the “media types are obsolete; use media features instead” bit is right in the spec: http://dev.w3.org/csswg/mediaqueries/#media-types

@tabatkins ah cool, I had read that before but rather than assume media features was better; I just assumed that it was the reason many like handheld was now deprecated.

For icon fonts or other composite “images”, a role=“img” element with an aria-label works well. e.g.



edit: I don’t why line breaks aren’t inserted into the code block.

The @media speech or @media (screenreader: none) concepts seem riddled with issues. Are the styles being applied to the screen-reader / speech-tool only, or are the styles being applied visually to the page when a screen reader is active? It seems like the later, and the later seems like the wrong use case, as far as what most people are targeting. Also, it seems like yet another vector to track people.

How about extending an existing property like visibility?

.visually-hidden {
	visibility: visually-hidden;

As I have understood this topic, is that most screenreader neither look for screen, reader, speech or anything at all. The browser is feeding the a11y API of the operating system with informations (content, semantics and some events) and from this information an a11y tree is produced/updated, which is than accessed by the screenreader.

This means at the end, that the screenreader gets what the browser is currently using to render the content.

Thought it’d be appropriate to x-ref these:

1 Like

Can you please explain why are we using overflow: hidden here?