What counts as a UI component?

When building apps, I make a practical distinction between what I call UI Elements and Product Components, but what is meant by the word component or element? Even when the context narrows to UI "stuff", what exactly are we referring to? There doesn't seem to be a strong consensus.

The word component simply means "a part or element of a larger whole."

The larger whole we build are websites and apps (the distinction between those does not make a difference here).

When building an engine, the block, cylinder heads, air intake, and fuel injectors are some of the components or "parts" used to build it.

When building a laptop, the body, display, battery, and keyboard are some of the components used.

Smaller parts, like an intake manifold or an LED array, are called subcomponents.

When building a website, we use HTML elements. But are those components? They certainly fit the dictionary definition.

Let's compare a plain HTML element to a framework component, which is what is generally understood to be a component, to see if they're the same.

We'll use the HTML <details> element and compare that to a React <Counter> component from the React examples. Here's counter

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You pressed me {count} times
    </button>
  );
}

We call that a component because it is. It's a part of a larger whole; part of a website.

Now the details element:

<details>
  <summary>Summary</summary>
  <p>Details</p>
</details>

We call this an element because that's what we were taught to call it. It too is also a part of the website.

Is there any meaningful difference between these two? Well, let's see:

Counter component
Using JavaScript, we've built a thing that manages a small bit of information, a count, by first initializing it to zero and then updating it by one each time its button is clicked. It also displays the button and the count on the screen. It does this with some help from the internal machinery of React.

Details element
Using HTML, we've built a thing that manages a small bit of information, an open or closed state. The state changes each time its summary is clicked. This information is publicly accessible as an open boolean attribute and as a property. When open the extra details are displayed, and when closed the content is hidden again. A toggle event is fired each time this happens and both the attribute and property are updated.

Additionally, users who depend on keyboard interaction can use the tab key to move focus to details and the spacebar key to open and close it.

Furthermore, details (and technically the React component too) has more than 100 other features like the hidden attribute, ARIA properties, draggability, the ability to scrollIntoView(), style customization, and so much more. It does all this with help from the internal machinery of the browser.

So, is there a difference?

Is details not a component because it's HTML not JavaScript?
Is details not a component because it doesn't use React or some other constructor?
Is details not a component because the browser rather than a 3rd party did all the behind-the-scenes work even though ultimately the browser is doing their work too?
Is details not a component because it doesn't have enough features?
Is it not a component because we didn't write enough code?

Of course not.

HTML elements are components. Sure, some HTML elements are more basic than framework components, but some framework components are more basic than some HTML elements.

Think about <table>. Table is a primary component of many web apps. It defines a strict pattern for assembling eight subcomponents that each play an important role in organizing and presenting tabular data, and several subcomponents have attributes that improve accessibility and table cell behavior.

Even some small and seemingly basic HTML elements like the humble <a> are packed with features. Anchors have several unique attributes that enable behaviors like:

  • navigating the internet! (that's one heck of a component right there)

    • with a new tab or window

    • with one of several security or privacy options

  • navigating to sections of a page

  • navigating to specific blocks of text on a page

  • downloading files and optionally renaming them

  • making phone calls!

  • drafting emails and text messages!

  • opening maps and other apps

Many framework components we build are weak compared to the mighty link!

What about lists? We shouldn't call those components, right? Ordered List manages and displays an auto-incrementing number state (hey, that's just like the React counter component!) and it has attributes for setting the starting number, reversing the numbers, and changing the number type, as well as logic that manages numbering for nested lists and supports some really cool customization with CSS. Lists are components!

So, what counts as a UI component? I think everything does.