The development team at Medium have discussed some bad practices that break accessibility. In one example, they argue that opacity
is not well supported by screen readers and so if we want to hide an element in a transition then we should always use the visibility
attribute, too:
.m-fadeOut {
visibility: hidden;
opacity: 0;
transition: visibility 0s linear 300ms, opacity 300ms;
}
.m-fadeIn {
visibility: visible;
opacity: 1;
transition: visibility 0s linear 0s, opacity 300ms;
}
Remember opacity and visibility still leave an element in the document flow. If you need to remove it from flow, there is more work to do. In fact here’s a way to think about them…
can make thing invisible | can make thing unclickable | removes from doc flow | can be transitioned | can be reversed on child | |
---|---|---|---|---|---|
opacity | ya | no | no | yes | no |
visibility | ya | ya | no | yes | yes |
display | ya | ya | ya | no | no |
pointer-events | no | ya | no | no | no |
If you need to change the display value of an element after a fading, that’s tougher. Not really possible in CSS since display
isn’t transitionable. Snook has written about this, including some JavaScript to help.
I had the same problem for my accessible carrousel http://a11y.nicolas-hoffmann.net/carrousel/ : I had to detect when the transition end to add classes on “hidden” content.
Sometimes it is a real pain in the ass to manage :-\
It is not just for screen readers but also for keyboard focus navigation.
There should be another column in that table:
can make thing unfocusable
opacity
no
visibility
ya
display
ya
pointer-events
no
(markdown table fail, here’s a code block)
Though outside the scope of hiding an element, I found a (honest) mistake:
Actually, the opacity can be deactivated for the children if the target browser has support for the background-blend-mode, mix-blend-mode and isolation CSS properties.
Those ones have a very limited support, though; older browsers will suffer.
I’m a bit late, but in the table it should say that visibility cannot be transitioned, since an element can only be fully visible or not (there is no “half-visible” elements). Only thing we can do is use a transition-delay, which is not exactly the same as transitioning the visibility directly.
Nice Post, try to add next back button for move to next post. Here very difficult to find your posts.
It seems like you don’t need the transition-delay anymore for correct fading in and out – check the link for a demo (tested in Chrome and Firefox) – has anyone an info on that?
Yes, there is a trick I often use now:
visibility
can be delayed to be applied at the end of the transition:Example here: https://van11y.net/accessible-hide-show/
So basically, contents will be “hidden” by
visibility: hidden
at the end of the transition.Unfortunately, PageSpeed Insights flags
visibility
as non-compositable https://github.com/GoogleChrome/lighthouse/issues/11658although it doesn’t support ie8 and before,
pointer-events: none;, is ok to use i think, or use z-index: -1
Btw, the code thingy in this website isn’t working properly.