UI Components that Abstract Mistakes

2017, October 14th.

A cloudy day [1] of Autumn in Berlin, probably something else in the place you live, and you’ve read the same date twice and this introduction actually doesn’t matter. But let me tell you about something that matters.

Everything is made up of <div>s and <span>s again, utterly hidden behind abstractions proudly called components. No one seems to remember (or do they?) the difference between p and span, let alone the point of using section rather than div.

Bad decisions – to not just to say bad and even invalid HTML markup – are buried in components developers find awesome to compose user interfaces with. The web, and people, pay the price.


Creating components

From now on, to explain my point, I'll be assuming some familiarity with React (a JavaScript library), although this applies to any kind of component abstraction.

Let’s say you just started a brand new React web app. You need to create a button at some point, and, because it’s reused in other parts of the app, has custom styles and also a fancy icon, you decide to introduce a component with all that abstracted out. Nice! You could do it like this:

const Button = ({ onClick, children }) =>
  <span class="my-horrible-button" onClick={onClick}>
    <i class="my-terrible-font-awesome-icon"></i>
    {children}
  </span>

The user interface is then composed as the following:

<h1>Brazilian Bananas (1 kg)</h1>
<p>Sweet and healthy bananas!</p>
<p>Absolutely the best.</p>
<Button onClick={() => alert('🍌')}>Buy $0.99</button>

It looks good! You were born for this, weren’t you?

Quite easy to miss what’s wrong when components are just used like that. A button, isn’t it? The engineering team can easily grasp what that means and what that does, after all.

It could also be a <FormLabel /> or <Paragraph /> as span elements, or divs all over that place. Although they all work, mistakes are abstracted in components.

I specifically talk about markup as the mistake throughout this article, however it could be anything really. Components look inoffensive when you're using them.

The web isn’t your abstraction

Now that HTML is all abstracted through JavaScript libraries and frameworks (which is not wrong), I wonder whether developers only went for semantic elements for the sake of making markup more readable for themselves. With React, your <Header> now may be a div. Out of the abstraction, though, you’d think twice before going for a div to make a header – you’d rather use HTML5’s header.

Because of the abstraction, output markup isn’t something we talk that much about anymore.

Did we really get the benefits of HTML5 and why new elements were introduced? Why button? [2] What’s header useful for? Why should one use section at all?

By the way, do you know how many occurrences of header, article, section I've found on Netflix's landing page? Zero. It's all div soup.

Matter of fact is that browser engines and people – nothing less than the ones who you really write code for – won’t ever know about your abstractions. A screen reader won’t know your “button” is actually a button[3]. (They will definitely get to know the span though, and that won’t help.)

xkcd, comic #1444
xkcd: Tags

Also, it’s never been easier to write invalid markup without even realizing it! After React, it seems acceptable to place a button inside an anchor link, and even giant elephants inside span. Has anyone ever thought why they are considered invalid markup in the first place?

Don’t make it hard

Browsers and assistive technologies are smarter than ever[4], indeed, yet they still count on developers to write code they can understand and people can benefit from. By doing so, you make it easy for:

  1. people, who will be able to navigate around the website, skipping over navigation sections or quickly jumping from one article to another[5].
  2. yourself, so you don’t have to reimplement default browser behaviours.

Therefore, please: don’t waste features that technologies try to give users, and developers, out of the box.

Remember who you write code for.


  1. If I had managed to publish this yesterday, the day would be sunny. I’ve missed the opportunity to make the article seems a little happier. ↩︎

  2. The button element was first introduced in HTML4. (Source) ↩︎

  3. What’s wrong with using a non-semantic element as a button? Well, if the button is accessible, nothing really. But doing so demands extra work that nobody is up for, besides that fact that you can’t actually create a button. ↩︎

  4. Technologies may even process <span class="tel">123-456-7890</span> as a telephone, and allow for automatic dialling of it. See microformat for more information. ↩︎

  5. Why not, right? After all, articles are for independent pieces of content, e.g., an user-submitted comment or a forum post. (Source) ↩︎

Tags: html, javascript