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>

<script>
  const disclaimer = document.querySelector('.disclaimer');
  function showDisclaimer() {
    // with a CSS class
    disclaimer.classList.add('show');
    // with the hidden property
    disclaimer.hidden = false;
  }
</script>

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).

HTML Semantics – Header or Sidebar?

Here’s a question on HTML semantics. We now have the not-so-new HTML5 semantic sectioning elements which define areas of the page and try to bring more meaning to it. This is generally seen as a step forward from using <div> which has no particular meaning. Does it always work?

There’s quite a common design pattern where a wider screen will show the logo and navigation in a sidebar on the left and then in a narrower screen will show it at the top. I’ve used this myself a few times. Here’s a quick illustration of what I mean:

screen with sidebar
Wider screen with sidebar

screen with header
Narrower screen with header

My own website, chrissmith.xyz currently uses this pattern. I’m using the WordPress theme twentyfifteen with my own child theme over it. The twentyfifteen theme uses an <aside> element for logo and navigation. When I’ve built my own sites I used the <header> element for this. My feeling was that the content was semantically header information, and that the fact that it appeared on the side on larger screens was not really important. To me <aside> means that the content is supplementary or in addition to the main content whereas <header>, used at the top level, is almost like a fixed part of the page layout template.

Ultimately, it comes down to the content. I’ve used the <aside> on this site in a fairly static, global way, so really it is a header. The theme creators can’t know how the area is going to be used – if it’s global or changes with the context of each page, so I guess it makes sense to keep the door open and use <aside>.

Changing Content

We don’t necessarily show the same content at different screen sizes. We might show contextual content in the sidebar but on a smaller screen we might choose not to use it. If we change the displayed content with media queries than how can we use semantic sectioning elements correctly? We could have an <aside> and a <header> in our markup but that’s a lot of unused bloat.

Aria Roles?

Maybe we keep the one element but change the aria-role with JavaScript, e.g. <aside aria-role=”banner”>? Or do we go back to a <div> and use aria-roles?

Replace HTML?

We could even switch out the element using JavaScript. Add the other element, append the content to it and then remove the original element. Or just get something different from the server, either by using a cookie or just a parameter in an Ajax request.

The example I’ve given is quite subtle but I can imagine wanting to combine header, sidebar or footer content on smaller screens. How do we handle this and keep it all semantic?