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.
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.
<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>
<article>
<header>
<h2>Some post</h2>
<time datetime="2014-03-11">March 11, 2014</time>
</header>
<p>...</p>
</article>
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.