Skip to content

[css-display] create a display property value for visually hiding an element while making it available for AT #560

Closed

Description

@SaraSoueidan

While giving a talk at CSSConf last week, I mentioned how we should provide text for AT to be able to read when we are using only icons to represent that text visually. Basically: provide text in the DOM that screen readers can read, and then hide it visually by using one of several visually-hidden techniques/hacks that we currently use for this purpose.

After the talk, an attendee asked why we don't have a CSS property whose sole purpose would be to hide content visually while keeping it readable by screen readers, for example.

We know display: none and visibility: hidden both hide content visually but they also make it inaccessible by AT. Any chance we could get a display value that would hide text similar to the way display: none does but that also keeps the text accessible underneath?

Thanks!

Activity

  1. AmeliaBR commented on Oct 1, 2016

    @AmeliaBR
    Contributor

    There isn't a CSS proposal, but there is an ARIA property, at least in theory. aria-hidden: false is supposed to expose content to assistive technology even if it would normally be considered hidden because of display: none or visibility: hidden or width/height of 0.

    However, because browsers did not support aria-hidden: false consistently, accessibility best practice has developed to use a combination of properties (overflow/clip plus absolute positioning, and/or positioning off-screen) that none of the browsers use in their heuristics for deciding whether something is hidden or not.

    That said, this is definitely something that should be discussed as part of the new CSS Accessibility project.

  2. dauwhe commented on Oct 1, 2016

    @dauwhe
    Contributor

    See also #427

  3. pepelsbey commented on Oct 2, 2016

    @pepelsbey

    But isn’t there the box-suppress proposed property with show, discard, and hide values? Quoting Rachel Andrew’s explanation:

    • show: the element would be visible and use whichever display method was used to display itself and any child elements.
    • discard: the element would generate no boxes at all
    • hide: the element and any children would still be present but would not participate in layout and would be completely hidden.

    The hide value should solve this issue, just like we solve it today with visuallyhidden pattern today.

  4. thierryk commented on Oct 2, 2016

    @thierryk
    Contributor

    I think we already have the "clip technique" for this. To me, the problem is not how we can visually hide content but rather how to deal with focusable elements inside boxes styled this way. Because sighted keyboard users access these elements without any context. They know they are on a focusable element on the page but they have no clue where and what it is (unless it's a link for which the href value may appear at the bottom of the browser).

  5. AmeliaBR commented on Oct 2, 2016

    @AmeliaBR
    Contributor

    The problem with keyboard users and hidden content, brought up by @thierryk, is actually a good argument for having an easy declarative way of hiding content. Too many devs copy & paste the "screen reader only" CSS without actually thinking about whether it should be screen reader only (a label for an icon or a heading for a sidebar) or whether it should be hide-until-focused (like a skip-to-content link).

    A semantic, declarative method of hiding content would make it easier for browsers to override the hiding when content receives focus, or based on user settings (such as when images are turned off).

  6. noahblon commented on Oct 11, 2016

    @noahblon

    I agree @AmeliaBR. We do have the wonderful clip technique. However, we are currently in limbo with clip, considering that it has been deprecated and Edge hasn't yet picked up support for clip-path. In my opinion this is reason alone to move away from "hacks" towards a standard method of dealing with a very common need.

    In regards to focusable elements within visually hidden elements, my understanding of the Focus Visible Success Criterion of WCAG 2.0 says that an element must be visible when focused. When focused, and in this particular use case, such as for skip links, I would expect the browser to give the element a display, such as block or flex. If the developer needs to disable keyboards from focusing the elements, they should disable tabbing to the focusable elements.

  7. fantasai commented on Jan 3, 2017

    @fantasai
    Collaborator

    This feature already exists as speak in CSS Speech Level 1, fwiw. Just hasn't received much interest.

    Possible ways forward:

    • Trim down the Speech module to be just speak and possibly speak-as.
    • Move this property to the Display module so more people notice it exists.
  8. ianthedev commented on Feb 1, 2017

    @ianthedev

    Maybe absolute positioning, like the following example, can serve the purpose.

    .hidden-visually {
        position: absolute;
        left: -5000px;
    }
  9. thierryk commented on Feb 1, 2017

    @thierryk
    Contributor

    @Ian-Y this approach works for focusable elements (i.e. skip links) but it does not work on hidden elements that contain focusable elements.

  10. ianthedev commented on Feb 1, 2017

    @ianthedev

    @thierryk I see. Then @media not speech is also needed:

    .hidden-visually {
        position: absolute;
        left: -5000px;
    }
    
    @media not speech {
        .hidden-visually {
            display: none;
        }
    }

    But in such a case, I would agree with @AmeliaBR that it is too many devs copy & paste for a "screen reader only" purpose. A simpler way would be preferable.

  11. caduvieira commented on Feb 7, 2017

    @caduvieira

    Why aria-hidden do not resolve this besides the lack of support? Does aria-hidden=true disable focus on focusable elements?

  12. 21 remaining items

  13. scottaohara commented on Sep 9, 2024

    @scottaohara
    Member

    form controls w/out a label sounds like an aria-label use case. so nothing really to discuss there. (re: mention of translation issue as to why people advocate the hack - fix the issue, don't enshrine the hack).

    headings that don't exist in the design sounds like a use case for standardizing a feature to mitigating poor design - and that seems wrong to me.

    Or, the heading isn't actually necessary and properly labeling landmark containers might be the right solution - if the UI somehow makes it clear the purpose of the section of the content. hard to tell exactly we're both imagining the same scenario - but having come across many scenarios that seem like they'd fit this - that's my take at least until given more information to determine otherwise.

    again, standardizing what might work for visually hiding a heading (the standard ruleset that essentially creates an invisible 1x1px container) would be rubbish to use on a visually hidden control that may or may not need to remain visually hidden when focused (button, checkbox, etc.) for the reasons i've already written about.

    since there are a variety of ways one should/could be visually hiding content, i continue to fail to see a way this can get standardized that doesn't require it essentially boil down to only handling the position absolute, opacity 0 aspects of the classic ruleset...

    or, if something does get standardized that handles more than that, then a bunch of usage caveats need to be introduced, and then people will complain the thing they need to do isn't a single property for them to declare.

    i still question why some instances of the big visually hidden ruleset can't just be written as the following (so long as people don't need to handle legacy browser support - which, any new standardized property wouldn't be useful for anyway...so...)

    .example:not(:focus) {   /* remove :not(:focus) if needed */
    	scale: 0;
    	position: absolute;
    }
    

    other instances of needing to visually hide something but still having it discoverable if searching by touch, or screen readers that announce what's being hovered, then something like the below would be more appropriate.

    .example2 {   
    	opacity: 0;
    	position: absolute;
      /* it would not always be appropriate - if at all - to show on hover/focus.  e.g., visually hidden controls
          replaced by more robust design controls would not be expected to unhide.  but other controls that
          are meant to be hidden by default but overlay other content would become full opacity on hover/focus.
    }
    
  14. moved this to TPAC agenda items in CSSWG Agenda TPAC 2024on Sep 13, 2024
  15. moved this to FTF agenda items in CSSWG January 2025 meetingon Jan 22, 2025
  16. moved this from FTF agenda items to Regular agenda items in CSSWG January 2025 meetingon Jan 22, 2025
  17. travisvalerius commented on Feb 14, 2025

    @travisvalerius

    I originally came here to propose display: visually-hidden, and I’m disheartened to see that this idea has been discussed for nearly nine years without significant traction. While there are workarounds to achieve this effect, if we truly prioritize accessibility, there should be a dedicated property/value for this purpose.

    Hidden from A11y Tree Visible to A11y Tree
    Occupies Space visibility: hidden; opacity: 0
    Collapses Space display: none display: visually-hidden (ideally)

    Having a standardized way to visually hide content while keeping it available to assistive technologies would reduce reliance on custom CSS utility classes and improve accessibility consistency across the web.

  18. moved this from Regular agenda to Oldest unslotted in CSSWG April 2025 meeting agendaon Mar 28, 2025
  19. SaraSoueidan commented on Apr 16, 2025

    @SaraSoueidan
    Author

    I opened this issue back in 2016 (wow!) and since then a lot has changed.

    I've been teaching accessibility for a little less than a decade now and if there's one thing I learned is that developers will resort to using visually-hidden utility to do things that are more often than not just bad design decisions.

    Yes, there are valid and important use cases. But I agree with all of @scottaohara 's points, and most importantly I agree that we need to fix the underlying issues instead of standardizing a technique that is guaranteed to be overused and misused even more once it gets easier to use. Fixing underlying issues (such as translation issues with aria-label, for example) is far more important than standardizing a way to visually-hide labels. Naming form controls using aria-label is the standard, and resorting to visually-hidden in this case is a workaround for an issue that should be fixed so that using aria-label is no longer problematic.

    I am also reminded of the ARIA Notifications proposal explainer here.

    From the explainer:

    Content authors still rely on live regions because that is the only tool available for the job. They do the best that they can, resorting to ugly "hacks", fragile coding patterns, and blatant misuse of ARIA live regions. There is a better way.

    I know visually-hidden is one of the workarounds used to create accessible screen reader-only notifications. But with the ARIA Notifications proposal, the visually-hidden hack will no longer be necessary. I imagine a similar path can be taken with other use cases of visually-hidden so that very few use cases remain—too few to warrant standardization.

    Furthermore, not all visually-hidden content is hidden equally—or needs to be hidden equally. That is, not all visually-hidden content needs to be hidden using this long set of rules defined for the visually-hidden class. For example, interactive form controls can be hidden using a couple of lines of CSS. I have discussed this more in an article on my blog. Scott has also discussed this in more detail in his article that's already been referenced in previous comments.

    Most of us who asked for this feature to be standardized are more experienced devs who know how and when to use this utility class (and/or its alternative declarations). But once standardized, I can only imagine a whole new generation of developers who will resort to using this technique to hide things that shouldn't be hidden, either because they don't know enough about how hidden content affects assistive technology users and/or how different elements should be hidden, or simply because they work with very "stubborn" designers who want things done a certain way regardless of how it affects implementation and/or usability. The teacher in me would rather teach developers and designers about usability and how to improve the underlying patterns.

    As an experienced dev, I do wish I had to write fewer lines of CSS to visually-hide what needs to be visually hidden. But this would come at a higher cost IMO.

    With all this said, I no longer encourage the creation of a CSS property/value for the visually-hidden utility class.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions