Hiding UI Elements

At the start of March 2019 I ran a poll on Twitter to see how devs hide UI elements. Here’s the tweet and results.

50% CSS "display:none",5% HTML "hidden" attribute,27% JS framework state,18% Something else

Admittedly, not a very scientific sample size but it was enough to confirm my suspicion that very few people use the “hidden” attribute. I should probably call it a property rather than an attribute as it’s a Boolean and acts in a similar way to “disabled” or “required” which we often use on form elements. And, by contrast, the most common method seems to be to use the CSS “display:none”. Probably no great surprise to anyone.

I think it’s interesting to think about what we’re really doing when we hide an element. Is the visibility of the element just for screen users or for all users? Do we still want the element available for non visual media? Or is the content going to be used by another part of the page in some way? Does it need to be in the DOM at all or are we just keeping it there because it’s easier?

If we use JavaScript, either native or a framework, we can insert and remove elements as needed based on logic. If it’s playing no part in our document why not just leave it out altogether? This keeps the DOM light and performant and easier to work with. If you’re working with something like automated testing you can check for an element’s existence rather than trying to figure out if it’s visible or not.

If we use CSS to hide an element and respect the separation of concerns principle then are we saying that hiding this element is a presentational choice rather than a semantic one? Maybe we are hiding it, maybe temporarily, rather than denying its existence?

In the case where we want an element to be hidden in one medium and shown in another, CSS feels like the right choice. Whilst “display:none” and “visibility:hidden” are valid, other techniques like “height:0”, “opacity:0” or “left:9999px” feel very unclear in their intentions and too focused on the visual user.

The HTML “hidden” property is a more semantic choice. It is stating that this element is not to be considered when reading the document, whether that be on screen or via assistive technologies. It is about more than visibility and is probably badly named. Maybe “ignore” would have been more fitting? It is more about the state of the element and closer in meaning to the input[type=hidden] that we used to see in the days before Ajax.

If you take away the JavaScript and CSS – maybe some network issues, maybe the HTML gets copied elsewhere – the element stays hidden. The point is that it’s meant to be hidden, it’s not styling.

The “hidden” property is also easy to work with and change in JavaScript. In fact, it’s easier than using a CSS class as you don’t have to write any CSS and you know it will work regardless.

<p class="disclaimer" hidden>This is a disclaimer</p>

  const disclaimer = document.querySelector('.disclaimer');
  function showDisclaimer() {
    // with a CSS class
    // with the hidden property
    disclaimer.hidden = false;

Think about why your content is hidden and how it may be reused and choose the most appropriate method of hiding it (or removing it).

Experiment: Font Size vs Colour Contrast

One of the things I’ve learned early on in web accessibility is the importance of colour contrast to make things easy to read on screen. High contrast is good but the size of text is also a factor. If it’s larger it’s easier to read even if the contrast drops.

At the same time, having very large text with high contrast is quite “full on”. It can feel a bit like you’re being shouted at. Oppressive is the word I’d use.

This got me thinking. I wonder if we can scale colour contrast with font size so that it always feels good. It’s really an extension of responsive design.

So, I tried it in CodePen.

See the Pen Font Size vs Color Contrast by Chris Smith (@chris22smith) on CodePen.1248

I’ve just done some very crude maths to make the RGB colour proportional to the font-size. As the font gets larger so do the RGB values, and vice versa.

I’m sure there’s probably some beautiful golden formula for getting the optimum contrast at every size but I wouldn’t really know how to go about finding these optimum settings. This experiment seems to prove that the general idea is sound though.

Please feel free to play around with it, take it further and let me know how you get on.

Making Icons Accessible

I’ve been using the excellent Font Awesome for a few years and it’s become part of almost every new design that I do. For a long time I’ve just slapped my icon down on the page, styled it and added a click event where needed. Job done.

Having spent some time looking a bit more deeply into accessibility, I can now see that this is not a great approach. There’s more to consider. If you can’t see it what is it actually doing?

Here’s how I approach using icons now. It may not be the perfect solution but it’s certainly a lot closer than most use cases I see. The way I use HTML depends on the use case.

If the icon is purely decorative – there in addition to text, e.g. a floppy disk icon next to the word “Save” on a button, then I think we can reasonably just forget about it and hide it for non screen users. A simple aria-hidden=”true” attribute should do.

<button><i class="fa fa-save" aria-hidden="true"></i> Save</button>

If it is there as an indicator, in place of a label, like where a hotel might have icons for TV, bath, etc. then we can use an <span> to wrap it. Inside the span we add our icon and another span with a text alternative. We show the icon and hide the inner span for screens, show the text only for other media.

Finally, if the icon is interactive and acts like a link or button, let’s make it a link or button. Like the previous example, use the <button> or <a> tag to wrap the icon and a span text alternative and show/hide for the appropriate media. This has the added bonus of making it possible to tab to the icon and so use just the keyboard to navigate the page. It also handles the icon’s active state and visited in the case of a link.

Alternatively, if you didn’t want to add a span with text inside your button or link, you could use the aria-label attribute to provide a text alternative.

One little tip. If you use an icon inside a link or button, do not leave whitespace between the outer wrapper element and the inner icon as you may get unwanted effects in the styling, such as underlined spaces either side of your icon. Keep it tight.

Accessible Colour Contrast

When I started looking at accessibility and using the aXe accessibility testing tool, one of the first things that it reported was insufficient colour contrast. So, I started looking into it. The page I tested had quite a few different shades of grey (not 50, before anyone else says it) so this seemed like a good place to start.

How light can grey text be against a white background, or flipped around, how dark does a grey background need to be for white text to be clear?

And the same with black. How dark can grey text go on a black background and how light does a grey background need to be for black text to be easily legible?

The results are shown in the embedded pens below. Please share if you find this useful. :)

See the Pen Accessibility – Colour Contrast with White by Chris Smith (@chris22smith) on CodePen.dark

See the Pen Accessibility – Colour Contrast with Black by Chris Smith (@chris22smith) on CodePen.dark

The next task is to find the acceptable contrast blacks and whites for pale greys, like #EEE or #F7F7F7, and dark greys, like #222.

Native Browser Controls Rule

It’s become very common for designers to replace the standard native browser controls with their own custom controls. There are good reasons for this, consistent appearance across browsers and devices being the main one. However, there’s a lot more to consider than just how it looks.

Form Controls

Let’s think about something like a slider switch in place of a good old fashioned checkbox. It looks cool but…

Is it accessible?
How does it appear to a non screen user?

Does it have a disabled state?
And a read-only state?
And a focus state?
Do these states all also work for non visual users?

Can you tab to it?

Does it go back to its initial state using a form reset?

Does it work with touch gestures, e.g. swipe left to right?


Now let’s think about a simple link. It’s pretty common to see icons used with an onclick event instead of links. But its not the same.

How would a user know that it’s an interactive control? Maybe it has a hover state style change but this would not help a non screen user.

A link (a tag with href attribute) does other things. You can tab to it. On Windows, you can use Ctrl + click to open in a new tab, Shift + click to open in a new window, right click and “Save link as…” (or equivalent) to download the target file. Wrapping the icon in an tag opens up a lot more possibilities.

I’m not saying don’t use your own controls but before replacing native controls think about what you might be sacrificing and make sure you’ve got it all covered.