Responsive by default
Time to read
, 1534 words, 3rd grade
Many developers believe that it is tricky to ensure responsiveness in web design. And that achieving a design that works on any screen resolution or aspect ratio is difficult.
Too many developers are not willing to make that effort. The consequence? Poorly-coded websites everywhere you look.
Unresponsive? Whereʼs a defibrillator when you need one?
Anyone who uses a smart phone to surf the internet encounters such sites daily. Unless like most people you hate the public sphere and spend all your time on Big Tech sites such as F**k or Instagram.
But here is a secret that many web developers have forgotten, if we ever knew it:
HTML is responsive by default.
What that means is this:
Itʼs not intentional, of course. Few realize that thatʼs what weʼre doing even as we do it. And this is because we start construction with the roof instead of the foundation.
First we use CSS to destroy responsiveness. Then we add a few media query hacks to try to get back some semblance of it. HTML is often an afterthought.
All we need are <div>
and <span>
elements,
right? Lots of ʼem.
It is like designing a car by building the skin first, then trying to force the engine, drivetrain, etc. to fit. You can do it that way, but it wonʼt be comfortable, safe, or maintainable.
Better to build it from the wheels up for performance and safety, and then to find an attractive body to fit over it. Why not do it right from the outset?
We can make our sites both responsive and attractive by following a simple approach. Donʼt code outside-in. Code inside-out.
Start with the foundation
Begin by creating your component, page, or even the whole site in semantic HTML. No CSS at all. No JavaScript.
Add the <!DOCTYPE>
, the <html>
(donʼt forget the lang
attribute), <head>
, and <body>
elements. Then add the viewport
and charset
<meta>
elements and a <title>
to the <head>
element:
Now youʼre ready to be responsive by default.
Build the body next. Start with the landmark elements. At the top level is <main>
. Note how all the
virtual DOM libraries screw this up by putting a
<div>
at the top. They donʼt care about correct
HTML. But coding by hand we can get it right.
Add the other landmark elements as needed: <header>
and <footer>
and optionally a <nav>
element. Nest these in <main>
if you prefer.
Hundreds of articles and tutorials have explained how to nest heading elements. Itʼs easy! Yet more than half of all web sites still get it wrong. Why? Craft Coders get this right.
Moving on, you may want an <article>
element with nested
<section>
elements. And, of course, properly nested <h1>
to <h6>
elements. How about an
<aside>
? Is there a <form>
? Be
sure that your use of each is correct and standards compliant.
How do you know if youʼve done this right? Many HTML tools will allow you to see your page hierarchy. Here is the Craft Code home page. But possibly the quickest way is to use the HTML5 outliner extension. Here is what the HTML5 outline of the Craft Code home page looks like:
The best resource for HTML help that weʼve found is Mozilla Developer Network (MDN). Of course, the final arbiter is the HTML standard itself.
Work your way down through your page hierarchy. Use the correct semantic
element for the type of content. For example, an <address>
element for a street address.
Parse through the text mentally and ask, What is this? And, Is there a way to make clear to the browser the type of this content with a semantic HTML element?
How many of these do you know? How many do you use regularly?
-
<p>
for paragraphs,<a>
for links,<button>
for buttons. -
<details>
and<summary>
for text that might not be of interest. We can hide it but keep it available to the user. -
<ol>
with<li>
for ordered lists — lists in which the order of elements matters. -
<ul>
with<li>
for unordered lists — lists in which the order of elements doesnʼt matter. -
<dl>
,<dt>
, and<dd>
with<dfn>
(if a definition) for description lists or glossaries. -
<figure>
with<figcaption>
for figures. They are more common than you might think. Great way to caption images, charts, graphs, etc. -
<form>
,<fieldset>
,<legend>
,<label>
,<input>
,<textarea>
,<select>
,<option>
,<optgroup>
,<datalist>
, and<button>
for forms. Do you know what all these do? Why not use them properly? -
<table>
,<caption>
,<thead>
,<tbody>
,<tfoot>
,<colgroup>
,<col>
,<tr>
,<th>
,<td>
for tabular data. And only for tabular data. You will rarely need a table. Avoid when possible. -
<picture>
,<source>
, and<img>
for your images. Or<img>
withsrcset
. Donʼt forget thealt
attribute. Consider wrapping these in<figure>
. -
There are many other worthwhile flow elements, such as:
-
<code>
for programming code. -
<pre>
for pre-formatted text. -
<mark>
for highlighted text. (Great with search results.) -
<ins>
and<del>
for insertions and deletions. -
<abbr>
for abbreviations. Use thetitle
attribute for the expansion of the abbreviation. -
<em>
and<strong>
for emphasis. -
<q>
and<blockquote>
for quotations. -
<cite>
for citations. Have you ever used this one? You must have cited someone at some time. -
<sub>
and<sup>
for subscript and superscript letters (great for footnotes). -
<time>
for dates and times. Again, ever used it? -
a few more obscure elements:
<kbd>
for keyboard input.<samp>
for sample output (from a computer program).<var>
for mathematical variables.
-
Why is it that so many of us try to represent the semantics of these data with CSS alone? We can encode the semantics right into the HTML with ease and then add the visuals with CSS by tag name.
But most devs — letʼs be honest — who want to apply a style to a
time will add a <span>
element and a
utility class. The <time>
element? Never heard of it.
Or weʼll mark up a quotation by adding quotation marks
rather than using the <q>
element. Donʼt we know
that the <q>
element can add the quotation marks for us?
And that we can use CSS to choose the quote style?
And how many of us have remembered to cite
the source?
When we ignore the semantic aspects of HTML we squander all the potential benefits. Such as machine-readability, accessibility, sustainability. And, often, responsiveness.
And all for naught because semantic HTML doesnʼt prevent us from doing whatever we want with CSS. It helps us.
Wouldnʼt it be nice if we didnʼt turn around and use CSS to mess everything up?
An example page
What does this look like in practice? Well, here is a simplified example:
But how does an actual page look? OK, Iʼve added one here. It is the essay on just-in-time coding, simplified a bit to make the html easier to follow.
Is it ugly as sin? You bet. But is it usable? Iʼd argue yes. More importantly, is it responsive? Well, here it is on my phone. Try it on yours.
We can also take a look at the page using the Lynx text-only browser. No CSS. No JS. No images. Nothing but text. So does it work? Take a look:
Performance
So. How does this score in Lighthouse?
So thatʼs looking pretty g… whoa! What the heck is up with that 88?
Well, partly it is because we have added the
<meta content="noindex" name="robots">
element to the <head>
. This prevents search engines from indexing the page. We donʼt want
users landing on this example page thinking that it is an actual site
page! But if we remove that, we still achieve only a 95%.
What gives?
This is actually a problem with the browser. Chromeʼs default stylesheet does not enforce a minimum “tap size” for links and buttons. The links in the unordered lists are too closely spaced (by browser default). Chrome oughta give more room for fat fingers. Like mine.
But users can zoom, we will fix it with CSS, and it is hard to imagine a
phone user without CSS. So weʼll leave it. (We could wrap the links
in <p>
elements to get that space, but thatʼs a hack, so weʼll avoid
it.)
There we have it. Responsiveness is not something we add to our web pages. It is something we destroy — if weʼre not careful and thoughtful as we code. Keep it responsive.
Next: progressive enhancement.