← All writing
Craft · · 6 min

Everything is a div

I've been writing div soup all year and nobody stopped me. The fix turned out to be less typing rather than more.

HTML Cross-Browser Compatibility

I opened a file I wrote about a year ago and counted forty-one divs in it. Not in the whole template, just in the header.

I’m not going to pretend that this was some moment of enlightenment where I saw the light and then rewrote everything. I closed the file and made the updates I was originally in there for. But it stuck with me and I’ve been picking at it since, and I think I’ve landed somewhere slightly different from the usual version of this argument.

The usual version is that semantic markup is good for screen readers and good for SEO. Both of those are true, I think, or true enough. But they’re also both arguments about somebody who isn’t in the room, and I’ve noticed that arguments about somebody who isn’t in the room tend to be losing arguments so let’s try the selfish one instead.

The selfish version

A div tells you nothing. That’s the whole point of it, it’s the element you reach for when you don’t want to say anything, and most of the time when I reach for one it’s because I genuinely don’t have anything to say. I need a box and, well, here’s a box.

But the file is a document that somebody reads. Often me, usually in about six months, typically while slightly annoyed about something else. And a file with forty-one divs in the header is a file where I have to hold the entire structure in my head to know where I am because the markup alone isn’t telling me. I’m counting indentation. I’m scrolling up to find the opening tag. I’ve written <!-- /.wrapper --> comments at the end of closing tags which is a workaround for markup that won’t say what it is.

Whereas </footer> says what it is.

That’s it, that’s the argument. It’s not about doing right by screenreaders or crawlers, it’s just that I keep paying for this and I hadn’t noticed until now.

HTML, I thought I knew you

Here’s the embarrassing part. I thought I knew HTML. I’ve been at this for a little while and I’ve been telling everyone confidently that I know HTML, but what I actually knew was maybe fifteen elements plus div and span for everything else.

The spec has north of a hundred. I went and read the list, and it felt a bit like finding out your house has a whole extra floor to it.

<figure> and <figcaption>, for an image with a caption attached to it, which I had been doing with a div and a p and a class called .caption. <time>, which takes a machine-readable datetime and means I stop writing <span class="date">. <address> for contact details, which I’d never used once. <abbr> with a title. <blockquote> with <cite>. <fieldset> and <legend>, which I’d been skipping in favor of a heading and some divs, and which is the actual grouping mechanism forms have had this entire time.

before.html
<div class="post">
  <div class="post-head">
    <div class="post-title">Some post</div>
    <span class="date">March 11, 2014</span>
  </div>
  <div class="post-body">...</div>
</div>
HTML
after.html
<article>
  <header>
    <h2>Some post</h2>
    <time datetime="2014-03-11">March 11, 2014</time>
  </header>
  <p>...</p>
</article>
HTML

Same rendering, roughly. But with six fewer classes, and the second one I can read at a glance in a year.

Shiv saves the day

So the obvious objection is that we’re supporting IE8 on this project and the sectioning elements don’t work in IE8. Which is true in that, for example, IE8 doesn’t know what a <header> is, so it won’t let you style it, so your entire layout falls over.

The workaround is a shiv, a little script that creates each unknown element in the DOM so IE will acknowledge it exists. It’s a few lines, it’s been around for years, it goes in a conditional comment in the head and you stop thinking about it. That’s all it takes and I’d been using “IE8” as a reason to not bother without ever actually checking what the fix cost.

And yeah, there’s a small but real cost. It’s a request, and it’s a request that only one tiny sliver of your users needs, and if you’re on a project where every kilobyte is being argued about then that’s a genuine conversation.

Try not to worry

I want to be careful not to overclaim here because my sense is that this could get silly in either direction.

The silly version on one side is div soup, which is what I was doing. The silly version on the other side is what I started doing for about two weeks after I read the spec, which was agonizing over whether a thing was an <article> or a <section>, reading four blog posts about it, and getting nothing done in the process. Nobody is served by that. If you cannot tell whether it’s a section or an article then it almost certainly doesn’t matter, and the honest answer is that the distinction is fuzzy in the spec too.

My new rule of thumb: use the element if I know it, use a div if I don’t, and don’t spend more than about ten seconds deciding. A div isn’t a sin. It’s just the answer to a question I didn’t ask.

The other thing I’d say is that basically none of this is extra work. It is not harder to type <footer> than <div class="footer">. It’s actually shorter so I suppose you could say I was doing the more effortful thing the whole time while calling it pragmatism.

Go and count the divs in something you wrote two years ago though. It takes about five minutes, it costs nothing, and if you’re anything like me then I can more or less promise it will annoy you.

Read similar posts
7 min

HTML email is stuck in 1997

A client asked for the newsletter to match the new site, which is a completely reasonable request, and the answer involves explaining that the largest corporate email client in the world renders HTML using a word processor.

6 min

Heading levels are an outline

On a page I audited last month the only `h1` was the logo, the section headings were all `h4` because `h4` was the right size, and the actual page title was a `div` with a class on it.