Let's Kill Semantic HTML

I'm going to say something that (even in my own head) seems downright heretical. It's time to move past rigid separation of presentation and markup in web applications.

Many of us have been building things for the web long enough to remember the dark times, in the long-long-ago. Back when tables were used for layout, and the whole web looked, well, something like this.

As the web matured, we developers realized that six-deep nested tables weren't, perhaps, the best way to build things. And so began the age of the <div>. CSS allowed us to do everything (sort of, with a lot of hacky workarounds) we had done with tables, but now our markup could be gloriously free of style information. Gone were the <font> tags. Use of the style attribute became taboo, a sign of semantic weakness. And it was, if not good, at least better.

Somewhere around this time, however, a second important trend was brewing: the birth of the web application. Web sites that weren't just ways to display one's intense fandom for Doom II, but were ways to actually do things. As it turns out, browsers are quite the distribution mechanism.

Give and Take

True Fact: Square pegs do go in round holes if you hammer hard enough. That's how we used to get rounded corners.

As web applications grew more and more sophisticated, the contortions we applied using CSS to maintain semantics grew ever more bizarre. Floats within floats within relative-positioned negative-margin containers. Triple-nested <div> tags for that perfect sliding door rounded corner tab effect. The poor browsers, created to scroll top-to-bottom through a document's content, were being vigorously abused for the sake of better, more interactive applications.

Fortunately, browser standards change over time. Under the flag of HTML5 we got rounded corners, gradients, background image sizing, new tags like <section> and <header>. We even got stuff we didn't have to think about before, like media queries to make sites work on fast-growing mobile device categories. Our semantics were more semantic than ever, our buttons as glossy and round as we could ever care for them to be.

Building a proper interface or application layout, however, had scarcely gotten easier. Why is that? Because the semantics of HTML don't match those of application interfaces. Paragraphs, sections, articles, and lists are semantics that make sense in the context of a document, not an application.

Quibbling the Semantics of Semantic HTML

The document/application disconnect has given rise to frameworks like Bootstrap that provide much-desired UI widgets and layout constructs for building applications, not documents. You'll often see developers cringe at the inherent "wrongness" of "polluting" markup with Bootstrap classes. I posit that this is a reflexive and inappropriate reaction to what's really taking place.

Bootstrap, Foundation, and other similar projects are doing their best to equip developers with new semantics to describe interfaces. Interfaces are inherently visual; positioning, size, relative placement, and alignment are central semantic considerations for an interface's structure. There is no bright line between content and presentation because the presentation is the content.

Just look at modern JavaScript applications. Oftentimes the "document" content, the bit that was once central to the "semanticity" of a site, is JSON data loaded after the page loads and rendered to the interface using any of a number of client-side technologies. The HTML in these applications describes something fundamentally different from a rich text document.

Semantics are Dead, Long Live Semantics

UI and JavaScript frameworks provide stopgap measures to increase "app semanticity" in HTML, but they still function largely as hacks grafted onto an old, creaking system. Luckily for all of us, native solutions are finally beginning to arrive.

Flexbox solves many (if not most) of the fundamentally difficult aspects of building proper application layouts with HTML and CSS. It is a standard that gives us the power to do, and do it right.

Web Components offer us a real solution to the issue of app vs. content semantics. Namely, they let us define our own. If paragraphs and blockquotes don't suit your semantic requirements, how about user-profile or google-map? By freeing us from a set of predetermined tags, Web Components allow us to construct our own semantic context. They are going to change everything about how we build web applications.

The web is and will continue to be the best content distribution platform in existence. Nothing can rival its reach and simplicity. Now, after an extended awkward phase, the web seems finally ready to fight to ensure its spot as the best app distribution platform as well.

A Taste of the Future

What exactly does interface-semantic HTML look like? We can glimpse one possible future in Polymer, Google's Web Components polyfill and oh-so-much-more. It ships with a collection of layout attributes that allow developers to leverage Flexbox almost effortlessly.

Let's say I want my page to flow with a fixed header, then some content, then a footer at the bottom. Using layout attributes, it looks like this:

<body fullbleed vertical layout>
  <header>My Header content here</header>
  <section flex id="main">My main content</section>

With no custom CSS and a declarative syntax that reads almost like English, the layout attributes offer simple semantics with a kind of "it just works" magic to them. Memorize a few keywords and you can build complex application layouts just about as fast as you can type.

I don't know whether Polymer's layout attributes are the best way forward. What I do know is that using them feels natural, almost addictive. HTML is remarkable for its ability to be declarative and compositional. Polymer offers one potential solution, but the biggest potential lies in the ability of developers everywhere to strike out in new directions, ignoring the constraints of the past. We're going to make some mistakes, we're going to take things too far; that's how progress is made!

What to Take Away

When building applications (as opposed to authoring documents), the structure of HTML should be judged not on how closely it adheres to semantics of content but to those of interface. Don't sacrifice the future on the altar of semantic purity. The next time that vein in your forehead starts throbbing at some "non-semantic" HTML, ask yourself: what are the true semantics at play?

It's early days for the next HTML revolution. I strongly encourage everyone to start learning, start experimenting, and start questioning the status quo. The best practices of the future haven't been discovered yet. Now's your chance to play a part in writing them. My suggestions:

  1. Play with Web Components. The Polymer site is probably the most comprehensive starting point for practical use today.
  2. Challenge your assumptions. Pretend you aren't scarred by years of battling HTML. What would your HTML look like if you defined the semantics?
  3. Share your results! No one has invented the best way to do just about anything with Web Components yet. The more people there are thinking, doing, and sharing, the faster we'll discover those as a community.

Let's all go forth and define the semantics of a new generation. The web platform, despite being more than 20 years old, is still in its infancy.

Update: Let's NOT Kill Accessibility

As was pointed out in the comments, many users of the web have needs other than just looking at things and clicking on them. This post was aimed at the dogmatism of "pure" markup and was in no way intended to encourage making the web less accessible. Here are a couple great links about keeping accessibility while building Web Components:

Thanks to @stommepoes, @aardrian, and @marcysutton for pointing out the omission and supplying the links! We should remember that putting users first isn't just a good idea, it's the standard!