The classic hypertext philosophy says that HTML should define the semantic document structure (mark the headings, links, paragraphs, etc.), and leave it up to the browser to choose a suitable layout for its context. That matches how I'd like to use it. Alas, the browser flagrantly fails to do a decent default job of layout. Therefore even many people who might otherwise be inclined to write simple HTML reach immediately for a framework that provides better results out of the box, whether it's a content management system like Wordpress, or a web framework like Bootstrap — perhaps fearing (as I did) that the only alternative is to learn many arcane corners of the modern HTML/CSS/JS web stack in order to DIY it. Fortunately only a handful of arcane corners are really needed, and they can be handled by making a few boilerplate bureaucratic gestures to the browser.
A skeleton for a simple 1990s webpage might have looked like this:
<html> <head> <title>Mark's Homepage</title> </head> <body> <h1>Mark's Homepage</h1> <p>Welcome to Mark's home on the WWW! </body> </html>
Pretty simple! But looks pretty bad!
The required changes to the above skeleton involve overriding a handful of unfortunate browser defaults (some there for historical reasons).
1. Set a mobile viewport
The simple skeleton above will render terribly on a mobile browser. Mobile
devices typically have much narrower screens than desktop browser windows,
requiring suitably narrower content reflowing. You might think this would
happen automatically. It even seems like a perfect use-case for the semantic
HTML idea, where a device with different properties from a traditional desktop
browser can choose to reflow the page in a way that suits its display. Alas,
that isn't what happens. But if you put this incantation into your document's
<head>
section, you'll get the expected behavior:
<meta name=viewport content="width=device-width, initial-scale=1">
The reason: Unfortunately, when mobile browsers were first being introduced, there were already a large number of websites out on the internet that assumed a reasonably wide browser window, of the kind you'd find on a desktop browser. Webmasters used (or abused) HTML features such as tables and frames to produce layouts that included aspects such as left navigation sidebars. If not rendered with a certain minimum width (nobody tested on desktop browsers resized to be ultra-skinny), such pages would be unusable, since the only thing visible would be the navigation sidebar. To accommodate such layouts, mobile browsers render the document to a wider virtual screen, which is then either scaled down to the device's actual size (producing unreadably small text), or displayed zoomed in, requiring horizontal scrolling to read (which makes paragraphs of text effectively unreadable as well).
The above viewport
statement tells the mobile browser to render at
the actual device width (not a larger virtual width), producing more sensible
results.
2. Set the charset to UTF-8
Most text-editing software these days encodes non-ASCII characters in UTF-8. But there's a good chance that, at least in some circumstances, your HTML might default to being interpreted in an old encoding like windows-1252 or ISO 8859-1 for backwards compatibility reasons, giving you mojibake.
The most reliable way to fix this is to set an explicit UTF-8 character set
in the document's <head>
section:
<meta charset=utf-8>
There are other places this can be fixed, but they're less reliable than putting it in
the document. One alternative is to configure your webserver to announce in the
HTTP header that its documents are in UTF-8 (in Apache this can be done by
adding the line AddCharset UTF-8 .html
to your
.htaccess
). But that won't fix it everywhere; for example, if you
preview a page on your local computer by opening the file with a
file://
URL, it may default to an old charset again (on Firefox
on Mac, it defaults to windows-1252, even in HTML5 standards mode). So I prefer
to set the charset in the document.
3. Set HTML5 standards mode
Most browsers render HTML in something called quirks mode by
default, which is a hodge-podge of old de-facto standards and expectations
intended to avoid breaking existing pages. For simple pages this isn't really
a problem, so setting this is optional. But you might as well put your page
into HTML5 standards mode anyway, in order to avoid being befuddled down the
line by something not working the way documentation says it should. To do so,
put this as the very first line of your HTML file (before the opening
<html>
):
<!DOCTYPE html>
One caveat is that HTML5 standards mode deprecates a number of presentational
HTML elements, such as <font>
and
<center>
, so don't enable it if you use those. The way to
set fonts, alignment, etc. in HTML5 is through CSS, not HTML tags.
4. Set a maximum content width
Much as the default rendering is hard to read on narrow mobile screens, it's
also hard to read on wide desktop screens. Text will be flowed by default from
edge to edge of even very wide browser windows, producing unreadably long
lines. Fixing this requires a small bit of CSS. There are a variety of things
you can do here, but one simple fix is to put the following in your
<head>
section:
<style type=text/css>body { max-width: 800px; margin: auto; }</style>
This sets the page body's maximum width to 800 pixels, so it will use the full
browser's width for windows that are 800px or narrower, but will leave margins
if the browser window is greater than 800px. Setting the margins to
auto
makes them symmetrical, so the column of text will be
centered. You can vary the width and margins here, as well as do various other
things with only a slightly larger amount of CSS (I prefer a more left-aligned
text block personally), but this is a readable starting point that's easy to
get to.
In summary
By adding just four lines of browser bureaucracy to a 1990s HTML skeleton, it's still possible to write basic HTML that renders pretty well on the modern web:
<!DOCTYPE html> <html> <head> <meta name=viewport content="width=device-width, initial-scale=1"> <meta charset=utf-8> <style type=text/css>body { max-width: 800px; margin: auto; }</style> <title>Mark's Internet Presence</title> </head> <body> <h1>Mark's Internet Presence</h1> <p>At Mark's Internet Presence, we leverage HTML5 technologies to... </body> </html>
Update!
The nice folks at
lobste.rs pointed out that the <html>
,
<head>
, and <body>
tags are actually
optional, even in strictly validated, standards-compliant HTML5. If omitted,
the browser will infer which part is the head and which is the body (and that
the whole thing is HTML). This lets us atone for the four added lines of
boilerplate by axing six of the existing lines, producing a nicely compact
result, essentially the minimal document that renders well on modern browsers:
<!DOCTYPE html> <meta name=viewport content="width=device-width, initial-scale=1"> <meta charset=utf-8> <style type=text/css>body { max-width: 800px; margin: auto; }</style> <title>Mark's Internet Presence</title> <h1>Mark's Internet Presence</h1> <p>At Mark's Internet Presence, we leverage HTML5 technologies to...