Handmade HTML Style Guide

I was getting ready to write a couple of articles for this site and I got to thinking about why HTML is kind of a hassle to hand-write. I mean, it's not meeting-that-could-have-been-an-email unpleasant, but I guess it's unappealing enough that a lot of folks balk at it and there are certainly a lot of tools out there to help avoid it (e.g. static site generators, special editors, content management systems, and so on).

Anyway, I thought on it some and I figured maybe I could make it more pleasant by keeping the document structure simple and avoiding verbose code. I thought a simple document structure would be less mentally taxing and less code would be less tiring to my fingers.

I set out to see how simple I could make the document structure and how sparse I could make the code. Bearing in mind, though, that a document must serve its purpose (not the other way around), so I wouldn't be able to leave out anything necessary to the commercial or artistic purposes of the document or anything whose absence would unduly impair the usability of the document.

Happily for this experiment, the articles I was preparing to write did not have any particular commercial or artistic requirements; I just thought it would be nice to share some recent experiences.

I don't propose to convince you that you should author all of your documents in the way I describe below, but I would like to share my experience in the hope that it might encourage you to undertake a similar exercise of questioning the assumptions you may have about what a good HTML document requires.

For the purposes of this experiment, I tried to set aside what I knew of best-practices for preparing HTML documents. I figured that many or most of these were probably meant to cope with the complexity or verbosity I was trying to reduce and that it was probably worth re-thinking them in this new context.

Starting out

In the interest of reducing verbosity, I wanted to figure out what minimal boilerplate was required for an empty document. I was surprised after reading the spec how much it could be pared down. A document type declaration is required, along with the title tag. The html, head, and body tags can be omitted and the user agent will understand them to be implied as long as certain reasonable requirements are met so that they're not ambiguous.

It's also necessary to specify the character encoding, but this can be done with a Content-type header from the server or by including a UTF byte-order marker (BOM) at the beginning of the file rather than by using a meta tag. I often use Sublime Text, which includes an easy way to save UTF-8 with a BOM (File → Save with Encoding → UTF-8 with BOM). I chose this method since it saves a tag that doesn't really add to the document (all conforming documents are UTF-8) and doesn't rely on server configuration to serve conforming documents.

A minimal conforming document, then, can be as simple as:

<!DOCTYPE html>
<title>Test document</title>

Though this leaves some usability opportunities. In particular, I wanted my documents to work well on mobile devices as well as personal computers. The document above fails on both points: on mobile devices the page is rendered too small to be readable without zooming in while on personal computers the measure of the text content will be too wide for comfortable reading if rendered full-screen.

For mobile devices, I chose to include viewport metadata that would cause the user agent to render the page at the device's natural width and scale.

For personal computers, I chose to include max-width styling on the body element that would limit the measure of the text for ease of reading. 30 em seems to be preferred, but you may find that a little more or less suits your material. I went with 40em. I find this width comfortable to read on the desktop. It also lines up well with 80-column text in a pre element (watch out for overflow — more on that later). I chose to add the style to the body element's style attribute rather than adding a style element to the head element.

I didn't expect to hit this max-width on a phone, but in landscape orientation on Mobile Safari, I learned that the font-size is scaled 200% without any adjustment to the em, effectively cutting the measure in half. An effective measure of 15 em looks silly; 20 is narrow, but passable. It leaves a bit of margin on the right hand side of my phone — someplace to put my thumb, I guess. If you're considering a narrower measure, this is probably something to keep an eye on. There's a CSS property to control this scaling, but I chose not to interfere; I think the scaling is probably what most folks expect and that it helps make sites more usable on small screens.

In the end, I came up with this for a minimal conforming, usable document:

<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test document</title>
<body style="max-width: 40em">

How much style

For content that is primarily textual, I find the base style sheets used by most user agents to be pretty believable. Of course any design or typography nerd can find lots of opportunities in them, but for a lot of what I do they're up to the task and contradicting them would require effort better spent elsewhere. I do have documents, though, that should adopt currently popular conventions and styles for commercial reasons (to set folks at ease as they enter their billing details).

I would encourage you to test any assumptions you have about how much styling your documents need. Of course, if the document is in part an artistic expression or if it has particular commercial requirements, then you've got to do what you've got to do. But it may be worth checking what those requirements really are and how they would be best served.

There's an entire industry of building sites to soak up search traffic by re-spinning existing content and arranging it to appear high in search rankings. For sites like this, the quality of each document's content is often quite low to minimize the expense of each document. On the other hand, the styling and design of the sites is often pretty sophisticated since any expenditure in this area can be amortized over all of the low-quality content on the site.

On the other hand, documents prepared by domain experts or enthusiastic hobbyists often have very good content with limited or outdated styling. The net result, I think, is a subtle signal to readers that a document that feels too slick might not have great content.

You may find that being economical in the styling of your document (though perhaps not so economical as I have been in preparing this one) sends a positive singal to your readers about the quality of your content.

Applying styles

For styles that would only apply to a single element, I chose to attach them as an attribute of that element (thinking that this would reduce cognitive overhead when writing or modifying the document).

For styles that would apply to many similar elements, I chose to use a style sheet embedded in the document (thinking that this would reduce the verbosity of the document).

Indentation and whitespace

Indentation is helpful in complex HTML documents to help keep track of nested elements. Since it was one of my goals to keep the complexity of my documents low, I thought I'd see if I could get away without indentation.

I found I could disable automatic indentation in Sublime Text by opening the HTML syntax specific settings (Sublime Text → Preferences → Settings → Syntax Speficic) and adding "auto_indent": false to the root JSON object.

This was doubly helpful since I would be omitting closing tags where I could to reduce verbosity and I didn't want to take a chance with the indenter getting confused.

Since I was preparing text content, I had a lot of paragraphs to write. I preferred to hard-wrap my prose at 80 columns — probably just a personal eccentricity — and chose some whitespace conventions to accomodate this. Sublime Text's wrap function works on so-called “paragraphs”: groups of lines set off from one another by blank lines. So, I set off each actual paragraph of my document with blank lines. For consistency, I treated most other block-level elements (headings, for example) the same. The closing tag of a paragraph element may be omitted in most circumstances, so I threw the opening tag at the beginning of my paragraphs and let it flow with the text. The result was something like this:

<h1>Test document</h1>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec justo
felis, imperdiet nec gravida non, dapibus quis eros. Pellentesque vehicula
tortor nec ex feugiat, ut pellentesque risus maximus. 

<p>Nam nec ante in ipsum posuere lobortis. Quisque porttitor vulputate
mauris elementum malesuada. Duis consectetur dignissim tortor, eget dignissim
sem sagittis id. 

This is what the main part of my documents ended up looking like and I was very pleased since the markup was a very small part of the text and the structure of the document was essentially as simple as the structure of the prose.

I ran into a little trouble with links. Sublime's word-wrap often greedily kept the a tag on one line while pushing its href attribute to the next (since it was typically a long run of uninterrupted text). In many cases, I would manually move the tag onto a line of its own.

Tag selection

The specification describes a great number of elements and suggests their use in a wide variety of situations. The current version of the spec focuses on the semantic value of markup (even going so far as to ret-con some old physical style elements like i and small into semantic roles).

I wanted to use as few tags as possible while meeting the needs of the document. My strategy was to select elements that provided desirable default styling while also fitting semantically. If they were short and allowed omission of the closing tag, so much the better. I tried not to use any markup that didn't serve the purpose of the document.

I used p elements almost everywhere I wanted text rendered as a block. It met all of my requirements: suitable default styling, semantically applicable to a wide variety of uses, short, and the closing tag can be omitted in most cases.

I used heading elements to render titles and set off major sections of my documents. The default styles provide the visual cues I wanted and the semantics got me the desired document outline and structure "for free". The tags are short, too.

I tried to include links (using the a element) where I thought they would be helpful to readers. Putting an URL inline with prose feels a little hokey, but the benefit to the reader is important.

I used pre elements for showing the contents of files or interactions at the computer console and code elements for specifying file names or tag names. In both cases, the default style includes a monospace font, which I wanted. I tried not to go too crazy with the code element or to get down a rabbit hole with kbd and samp. The spec provides some interesting semantic use-cases for complex nesting of these elements, but I didn't see how it would provide much value to my readers unless I wanted to provide more sophisticated styling (I did not). I tried not to over-use either element.

When using pre elements, the content might be wide enough to overflow the measure on smaller screens. Forty characters seems to be safe — everything old is new again. Forcing wrap probably isn't the right thing to do, but you could set overflow: scroll on these elements so that each one can scroll horizontally by itself. I chose to let them overflow the body since it was the default and provides about the same experience for the user.

<style>pre {overflow: scroll}<style>

I wanted to put some contact information at the bottom of each article. The address element ended up being a good fit for this. It provides default styling that sets the text off appropriately. Given the name of the element, I was surprised by the semantics, but it turns out they were just right.

Emoji and entitites

Forms

Tables

hit counter