Every element I use for the basic structure of a HTML document, with explanations why.

Usually when I start a new project, I either copy the HTML structure of the last site I built or I head over to HTML5 Boilerplate and copy their boilerplate. Recently I didn’t start a new project, but I had to document the structure we use at work for the sites we build. So, simply copying and pasting wasn’t an option, I had to understand the choices that have been made. Since I spent quite some time researching and putting the structure together, I decided to share it with you.

My boilerplate

This is the final document. Scroll down for details.

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">

  <title>Unique page title - My Site</title>

  <script type="module">
    document.documentElement.classList.remove('no-js');
    document.documentElement.classList.add('js');
  </script>

  <link rel="stylesheet" href="/assets/css/styles.css">
  <link rel="stylesheet" href="/assets/css/print.css" media="print">

  <meta name="description" content="Page description">
  <meta property="og:title" content="Unique page title - My Site">
  <meta property="og:description" content="Page description">
  <meta property="og:image" content="<https://www.mywebsite.com/image.jpg>">
  <meta property="og:image:alt" content="Image description">
  <meta property="og:locale" content="en_GB">
  <meta property="og:type" content="website">
  <meta name="twitter:card" content="summary_large_image">
  <meta property="og:url" content="<https://www.mywebsite.com/page>">
  <link rel="canonical" href="<https://www.mywebsite.com/page>">

  <link rel="icon" href="/favicon.ico">
  <link rel="icon" href="/favicon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  <link rel="manifest" href="/my.webmanifest">
  <meta name="theme-color" content="#FF00FF">
</head>

<body>
  <!-- Content -->
  <script src="/assets/js/xy-polyfill.js" nomodule></script>
  <script src="/assets/js/script.js" type="module"></script>
</body>
</html>

Line by line explanation

General

<!DOCTYPE html>

For the old-schoolers among you, you don’t need any of the other doc types you’ve learned by heart. This is the one and only. Even though today there are no other real options, it has to be present for compatibility reasons.

<html lang="en" class="no-js">

The lang attribute is one of the most important attributes in HTML, because it’s powerful and responsible for many things. You can read more about it in On Use of the Lang Attribute and The lang attribute: browsers telling lies, telling sweet little lies. Applied to the html element, it defines the natural language of the page. It contains a single “language tag” in the format defined in Tags for Identifying Languages (BCP47), for example en for English, de for German or ru for Russian.

I use the no-js class in case I want to apply styling to specific components in browsers that don’t support JavaScript. This class will be removed in browsers that support and execute modern JavaScript.

This attribute declares the document’s character encoding. Leaving it off might cause specific characters to display incorrectly in some browsers.

Here’s how Safari displays my name with and without the charset meta tag.

Manuel Matuzović - Manuel Matuzović

It must come before the <title> element to avoid faulty characters in the page title.

<meta name="viewport" content="width=device-width, initial-scale=1">

The viewport meta tag allows us to change the width of the viewport, which is necessary for responsive web design. width=device-width sets the viewport width to the width of the screen. initial-scale controls the zoom level when the page is first loaded.

I’m not sure if setting initial-scale=1 is still necessary. I believe I read somewhere that it was only needed for Safari on < iOS 9, but I can’t find the article anymore.