Introduction

You may think hiding elements with CSS is trivial but there actually is an incorrect way of doing it, and you've probably done it. I know I have.

The problem with display: none;

The most common way of hiding an element is by simply adding display: none; to your CSS. But did you know that this can negatively affect accessibility? Let's say that someone is browsing your website using a screen reader. When you add display: none; to an element you are actually removing it from the DOM. This means that users visiting your website using screen readers can't see it.

Sometimes this isn't an issue because you're hiding something that doesn't need to be seen by those using a screen reader. But in some cases this can be detrimental to the user's experience.

Below we'll go over a couple examples of situations where using display: none; to hide elements can negatively affects the experience of visitors using screen readers.

Example 1 - Adding a label to a link

For this example let's say we have a link that contains an image or svg. You want to add a label to the link for those using a screen reader, but not for the visual users of your website. So you add a <span> element that will contain the label.

You may only want to show the label to users that are using screen readers. If you add display: none; to the <span> you are actually hiding it from from everyone, including those using screen readers. This is obviously not the intended outcome.

html

<a href="#">
  <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"/></svg>
  <span>Home</span>
</a>

Example 2 - Title of a sidebar navigation

In this example, let's pretend that we have a product listings page with a navigation on the left and the products listed on the right (pictured below). The navigation has multiple sections. One that lists the popular products, one for product categories, and one for product tags.

To make sure your page maintains proper heading ranks (this is important for accessibility) you give the navigation an <h2> title and you give each section <h3> titles. However, you don't really want the navigation title to be displayed on the page because it says something like "Shop Navigation" and visual users will be able to clearly see it's a navigation. Adding display: none; will make your <h2> title completely useless because those using screen readers won't ever see it.

Ashery Country Store shop page

The correct way to hide elements

In both examples above we do not want to use display: none; because doing so will negative affect the experience of visitors using screen readers and could cause quite a bit of confusion. There are few different CSS snippets we can use instead, that will hide the element from visual users while still keeping them around from those using screen readers. The first one is one that I've mainly used in projects where I'm not using TailwindCSS. Tailwind add their own utility class for this that I'll point out later.

css

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

Tailwind comes with a utility class for this so when I'm building a website with Tailwind I'll just stick with their built in sr-only class, which does the same things as above but with a slightly different approach. I honestly would just use the snippet Tailwind uses all the time but I started using the other one before I started using Tailwind so when I'm just using normal CSS that's what I reach for by default. Below is the CSS that the sr-only class uses.

css

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

Summary

It's important to always keep in mind the different ways people use our websites and the needs that they may have. Correctly hiding elements on the page may seem insignificant to some but it can play a big role in the experience some users have while they browse our websites.