We’ve covered the idea of hiding things in CSS many times here, the most recent post being Marko Ilic’s “Comparing Various Ways to Hide Things in CSS” which did a nice job of comparing different techniques which you’d use in different situations. Kitty Giraudel has done something similar in “Hiding Content Responsibly” which looks at 10 methods—and even those, you could say, aren’t totally comprehensive.
Does this mean CSS is messy and incomprehensible? Nah. I feel like all the methods are logical, have good use cases, and result in good outcomes. Allow me to do a have a pretend conversation walking through my thought process here.
I need to hide this thing completely. For everyone.
No problem, use display: none;
.
I need to hide this thing, but only hide it for screen readers, not visually. (For example, an icon that has no additional meaning for screen readers, as there is an accessible label nearby.)
No problem, that’s what the aria-hidden
attribute is for.
I need to hide this thing, but only visually, not for screen readers. (For example, the contents of non-active tabs.)
No problem, use a .sr-only
class. That leaves it accessible but hides it visually until you remove that class.
Oops, I actually want to hide this thing visually, but I still want it to take up physical space, not collapse. (For example, say a button has a loading spinner icon that is only needed when performing an action. The size of the button should factor in the size of that icon all the time, not just when the spinner is visible. That way, there’s no layout shifting when that icon comes and goes.)
No problem, use transform: scale(0)
which will visually collapse it, but the original space will remain, and will leave it accessible to screen readers.
Oh nice, I could transition
the transform, too, I suppose. But actually, that transition
doesn’t fit my site well. I just want something I can fade out and fade in.
The opacity
property is transitional, so transition that between 0 and 1 for fades. The good news is that visibility
is also transitional. When fading out, use visibility: hidden
, and when fading in, use visibility: visible
to hide and unhide the thing from screen readers.
That’s not entirely comprehensive, but I find that covers 95% of hiding cases.
Nice! It’s odd that
visibility: hidden;
isn’t the “responsible” way of hiding elements (and it’s not, in part because of artificial accessibility limitations but also browser behavior). But this really should just be one line of CSS without accessibility concern, in situations where an aria-label or something else is already serving that purpose.Don’t forget to add a delay on the fade out transition with visibility. Only then it can fade to opactiy: 0 and then set visibility to hidden.
I don’t think you have to do that.
visibility
magically knows what to do when transitioning. Withdisplay
you definitely have to do that though.The question is, what impact do these activities have on SEO?
I wonder if actually all the issue with screen readers won’t eventually fade, as are the IE becoming false problems too.
How many devs just stay to fix readability problems for say 1 in a million cases?
When my customers ask that their site to be visible in IE < 7 too I simply ignore such request. Read SOF to see that this is a global move. Wasting coding time for minor issues sometimes it is not worth, as politically incorrect as this could sound.
Intelligent people can solve problems, wise ones prefer to chose what problems are worth solving.
Wow, just in time. I have a question, which is partly related to this. If someone could chime in and answer, it would be fantastic.
I am working on my website that until now had the full-width layout. I like the centered content approach, helps focus (sort of?).
Anyways, I now need a sidebar, but with the content still centered. I am not sure if I can have the “content-sidbar” approach, because again, the content will shift to the left instead of being centered.
So, here’s what I came up with. Create the holy-grail layout (sidebar-content-sidebar) and keep the first sidebar (which is supposed to be on the left) hidden using “visibility: hidden”. This hidden sidebar has no use except to take up that space to keep the content centered.
This way, I still have my main content centered, with a sidebar I wanted on the right and nothing on the left except blank space.
Is this the kind-of right approach? Sorry, I am quite new to web development (self-taught). It would be great if someone (maybe @Chris?) could share their opinion and push me in the right direction.
Thank you for useful article. But as for me, hiding content sometimes can be harmful for your website SEO, but for sure in depends
For some reason, I can’t wrap my head around this. If I use display:none, that means I want it hidden from everyone, even with people who use screenreaders. So is that not the correct way to hide something? Why should I not use display:none?
Say you wanted to “hide” the contents in menu that opens on hover. Does that mean you want screen reader users to never ever access that navigation? No, screen reader users should be able to access that navigation, so rather than
display: none
hiding it, you use a different technique, so that navigation is still available.That’s totally correct, caj! As the post says,
display: none
will hide from everyone, including screen readers, if that’s what you need.But if you only want to hide an element, say visually, but still want screen reader support, then some sort of “screenreader-only” class that clips the element out of view will do the trick. And so on…
So bottom line: totally cool to hide things with
display: none
. But if you need to selectively hide an element in a way that it’s still accessible to assistive tech or that occupies physical space, then there are other techniques.I was thinking along the same lines as caj.
What if a hidden sidebar menu is not opened by hover but by a menu button in the header that the screen reader can see. Wouldn’t display: hidden be okay then?