Open SaraSoueidan opened 7 years ago
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.
See also #427
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 allhide
: 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.
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).
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).
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.
This feature already exists as speak
in CSS Speech Level 1, fwiw. Just hasn't received much interest.
Possible ways forward:
speak
and possibly speak-as
.Maybe absolute positioning, like the following example, can serve the purpose.
.hidden-visually {
position: absolute;
left: -5000px;
}
@Ian-Y this approach works for focusable elements (i.e. skip links) but it does not work on hidden elements that contain focusable elements.
@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.
Why aria-hidden do not resolve this besides the lack of support? Does aria-hidden=true disable focus on focusable elements?
Doesn't this part of @Ian-Y proposal already does the job ?
@media not speech {
.hidden-visually {
display: none;
}
}
I personally still hope to see a "CSS declaration" solution such as aria-hidden: true;
because using media query can be inconvenient. For example, if I have a long media query for responsiveness like the following one (each CSS rule is being represented by ......
for the purpose of this example):
@media (max-width: 1024px) {
......
......
......
......
......
......
......
......
......
......
......
......
......
......
......
}
And if I need to hide one of the CSS rules from assistive technologies and also want to preserve the order of those CSS rules, I would then have to break the original media query into three parts like this:
@media (max-width: 1024px) {
......
......
......
......
......
......
......
}
@media not speech and (max-width: 1024px) {
......
}
@media (max-width: 1024px) {
......
......
......
......
......
......
......
}
And if I need to hide more non-adjacent CSS rules from assistive technologies, I would then have to break the original media query into more parts. So that is inconvenient sometimes.
@AmeliaBR
this is definitely something that should be discussed as part of the new CSS Accessibility project.
An additional use case for this feature is described at https://github.com/w3c/imsc/issues/484#issuecomment-519169604 and further up that thread in more wordy fashion.
The CSS Working Group just discussed create a display property value for visually hiding an element while making it available for AT
.
Leonie, Amelia, Brian K, and Ian P, are going to draft something.
The CSS Working Group just discussed Display property value for visually hiding element while making available to assistive tech
.
This would be really great for us!
The CSS used to create these classes can be interpreted differently over time when assistive technologies are updated.
This is because some assistive technologies rely on CSS properties to change how content is announced.
For example in the GOV.UK Design System we had to update our visually hidden class since VoiceOver started interpreting it different breaking the content.
So it feels like a matter of time before it breaks again.
I would also very much like to see such a property!
tink: can try to put words together but need someone on CSS side AmeliaBR: I can help ACTION: Amelia and tink to draft a proposal Created ACTION-883 - And tink to draft a proposal [on Amelia Bellamy-Royds - due 2019-09-24]. IanPouncey: I can also help. astearns: and bkardell_
@LJWatson @AmeliaBR @IanPouncey @astearns @bkardell Did anything ever come of this?
This is stale for a while now, but I want to build upon what has been said.
In my case I'm building a Pills
input field. Like your email client Send to
field.
Selected items are visible
To add an item you use a combobox
and select the desired item.
To remove an item you click on the pill.
Selected items are not included in the combobox/listbox
, that would make them appear twice.
For someone visually impaired whom have to use screen reader it is to change the selected items using this component. You have two navigation trees, one for selected items, one for available items. So I would like to make the selected items non-focusable and the listbox
include the selected items, but only for screen readers.
<ul role="listbox">
<li role="option">Option 1</li>
<li role="option" aria-selected="true">Option 2</li> <!-- This should be not focusable/selectable by a non-screen-reader -->
</ul>
This goes further than just visibility ; current visibility hacks such as sr-only
won't do the trick, the element will still be focusable and when using keyboard navigation we would meet a "dead" position.
Multiple speakers at CSS day mentioned this lacking capability. I skimmed the meeting notes in this thread and it sounds like setting aria-hidden=false on a display:none element is the closest thing we have...? Is that what we should recommend? Or a new css property/value or a new HTML attribute/value?
@scottaohara @cookiecrook @frivoal
I also saw an article with opinions here: https://benmyers.dev/blog/native-visually-hidden/
@josepharhar re: aria-hidden=false
on a display:none
element - that's off the table. The ARIA spec actually has a pending update to specifically note that aria-hidden=false
needs to be treated the same as aria-hidden=undefined
/ e.g., as if the attribute wasn't even there, as there are many instances of where authors misused the false
value and making that re-reveal hidden content to the accessibility tree would actually break intended experiences.
As a counter point to the article you found - https://www.scottohara.me/blog/2023/03/21/visually-hidden-hack.html
and by pending update, i mean it's landed in the latest ARIA 1.3 draft:
Note As of ARIA 1.3, aria-hidden="false" is now synonymous with aria-hidden="undefined". Note
Note The original intent for aria-hidden="false" was to allow user agents to expose content that was otherwise hidden from the accessibility tree. However, due to ambiguity in the specification and inconsistent browser support for the false value, the original intent is no longer supported.
Seeing this thread being revived a few years later, I have an additional comment on my own "wish".
As a developer who kind of know what she's doing when she uses the .visually-hidden
utility class, I appreciate having a native alternative. Sure. And I know other accessibility practitioners who would also appreciate not having to use a utility class so often.
BUT as a teacher, I can't but understand and kinda agree with @scottaohara 's points.
Unfortunately, I think that by standardizing the utility class into a property, it would encourage more devs to misuse it and end up with more broken experiences.
The utility class is already being misused sometimes, and we already have a lot of work to do to teach (and learn) about all the nuances. It will be a lot harder to do when this is standardized.
Thanks Scott and Sara! It sounds like we should not add a CSS capability like .visually-hidden
and perhaps should instead focus on the items in Scott's blog post:
We should be able to navigate to landmarks (e.g., skip to main content) by default browser commands. We should be able to send dynamic messages to assistive technology, without having to rely on fragile, invisible, live regions. We should be able to use aria-label (and also aria-description) without having to worry about translation services. We should be able to fully and easily style common form controls. And we shouldn’t need to introduce a native way to do all these things, which covers various use cases for visually hidden content, but not all of them.
Read this thread and @scottaohara's article https://www.scottohara.me/blog/2023/03/21/visually-hidden-hack.html.
I agree with most of the points — it's better to fix specific issues rather than adding a hack to the specification.
However, there are cases where visually-hidden
is used today and aren't fix in future specifications. For example, headings that don't fit into the design are often visually hidden, and the same goes for form elements without a label. The developer doesn't have the final say on how the product will look, so if the designer or client decide that a section shouldn't have a heading or a form element shouldn't have a label, they are implemented using visually-hidden
.
What solution do you see as better than the standard display: visually-hidden
for addressing designs without headings or form elements without labels?
the same goes for form elements without a label
That’s a good example: when I try to solve this case with aria-label, accessibility experts usually say “it’s better to use visually hidden pattern” (not always auto-translatable, easy to miss in development, etc.) But this pattern is a hack on top of the missing feature that I’d rather use instead.
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.
}
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
andvisibility: hidden
both hide content visually but they also make it inaccessible by AT. Any chance we could get adisplay
value that would hide text similar to the waydisplay: none
does but that also keeps the text accessible underneath?Thanks!