DEV Community

Cover image for Reponsive by default
Charles F. Munat for Craft Code

Posted on • Edited on • Originally published at craft-code.dev

Reponsive by default

Until we use CSS to wreck it, that is.

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 many 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:

More often than not, we use CSS to destroy responsiveness rather than to maintain or enhance it.

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> and 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.

Here, then, is your page foundation:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta
      content="width=device-width, initial-scale=1" 
      name="viewport"
    >
    <title>Responsive by default</title>
  </head>
  <body>
    <!-- content goes here -->
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

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 level. 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 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 HTML5 Outliner shows a text outline of the page with properly nested headings.

You can see that it is a proper page hierarchy with correctly-nested heading elements.

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? 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>, <col>, <colgroup>, <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> with the srcset attribute. Donʼt forget the alt 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 the title attribute for the expansion of the abbreviation.
    • <em> and <strong> for emphasis and strong emphasis.
    • <q> and <blockquote> for quotations (inline and block, respectively).
    • <cite> for citations. Have you ever used this one? But you must have cited someone at some time. No?
    • <sub> and <sup> for subscript and superscript letters, respectively (great for footnotes).
    • <time> for dates and times. Again, ever used it?
    • a few more obscure elements: <kbd> for keyboard input. <samp> for <samp> (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? Eh! 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?

body {
  quotes: "“" "”" "‘" "’";
}
Enter fullscreen mode Exit fullscreen mode

And how many of us have remembered to cite the source?

<q
  cite="https://craft-code.dev/essays/code/responsive-by-default"
>
  <abbr title="HyperText Markup Language">HTML</abbr>
  is responsive by default.
</q>
Enter fullscreen mode Exit fullscreen mode

But how does an actual page look? Iʼve created a responsive-by-default example to illustrate.

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.

Our plain HTML page is easy to read and fully usable by smart phone.

Ugly, true. But usable on any screen or screen reader.

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:

The responsive HTML-only page is perfectly usable on the Lynx text-only browser.

What about performance?

So. How does this score in Lighthouse?

Lighthouse says 100% on performance, accessibility, and best practices, but 88% on SEO. Urk.

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. Responiveness 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.

Top comments (0)