Modern HTML Boilerplate example

Modern HTML boilerplate for starting projects and responsive web designs. Use this as a base to get started and adjust as needed. Project uses npm and sass.

Feb 12, 2022 | Read time 10 minutes

In this article I will go over a modern HTML boilerplate that I use as a basis for my responsive web designs.

This is based on the great project https://github.com/h5bp/html5-boilerplate

With this HTML boilerplate, you will need to have some familiarity with SASS, NPM and HTML.

The final code is on GitHub here: https://github.com/kentaroau/html-boilerplate

How to get started

To get started using and building upon this HTML boilerplate do the following:

git clone https://github.com/kentaroau/html-boilerplate

Then open up the command line and cd into the root directory (ie the directory that contains the package.json file) and run the following to install our package dependencies:

npm init

Now we can build the project:

npm run build

The HTML document boilerplate

The boilerplate in its entirety is below.

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

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />

    <title>HTML boilerplate</title>

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

    <link rel="stylesheet" href="/public/css/main.css">

    <meta name="description" content="Page description">

    <!-- Open Graph data http://ogp.me/ -->
    <meta property="og:title" content="Html Boilerplate">
    <meta property="og:description" content="Page description">
    <meta property="og:image" content="https://www.example.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 property="og:url" content="https://www.example.com/page">

    <!-- Twitter Card data https://dev.twitter.com/cards/overview -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@kentaroau">
    <meta name="twitter:title" content="Html boilerplate">
    <meta name="twitter:description" content="Description">
    <meta name="twitter:creator" content="@kentaroau">
    <meta name="twitter:image" content="kentaroau.com/img/profile.png">    
    
    <link rel="canonical" href="https://www.example.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">
  </head>

  <body>
    <!-- your content here -->
  </body>

</html>

Explanation of the HTML

We first declare the DOCTYPE. With modern browsers, any other type is not needed. Seems like we still need to declare this for compatibility - distinguishing between quirks and standards mode.

<!DOCTYPE html>

Setting the lang attribute to english as default and with the class as no-js. We will use this CSS class for any specific styles when the user’s browser does not have javascript.

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

Below we need to define the specific character set. Leaving this out will cause some characters to display incorrectly (Safari vs Chrome, Firefox, etc).

<meta charset="UTF-8">

Next, we define the viewport settings to help us with our responsive designs. width=device-width sets the viewport to be the device’s width and initial-scale=1 sets the zoom level to be 1.

I have also added minimum-scale=1 to cater for a chrome device emulation bug where the width does not resize when you refresh the screen.

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

The below is my JavaScript detection code. When the user’s browser JavaScript is not enabled/supported, then the following code will not execute and the no-js style will stay. If it is supported we can go ahead with the js style. Also, the type="module" detects if the browser supports modern ES6.

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

Our link to the main.css stylesheet.

<link rel="stylesheet" href="/public/css/main.css">

The description used by search engines to display on the search results. Recommended to be around 160 characters.

<meta name="description" content="Page description">

The following are Open Graph meta tags. They just control how your webpage will appear on social media platforms like Facebook, Twitter, Discord, etc (https://ogp.me/)

Images are recommended to be square and have aspect ratio of 2:1

<meta property="og:title" content="Html Boilerplate"> <!-- Recommended 60 characters -->
<meta property="og:description" content="Page description"> <!-- Recommended 155 - 160 characters -->
<meta property="og:image" content="https://www.example.com/image.jpg"> <!-- Recommended: 1200 x 630-->
<meta property="og:image:alt" content="Image description"> <!-- Image description -->
<meta property="og:locale" content="en_GB"> <!-- language -->
<meta property="og:type" content="website"> <!-- website type -->

Next we have our definition for Twitter Cards. In the below instance we are defining a card that is for a large summary image. For Twitter there are two options for websites, summary and summary_large_image.

Similar to the Open Graph meta tags, using square images is recommended.

<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@kentaroau">
<meta name="twitter:title" content="Html boilerplate">
<meta name="twitter:description" content="Description">
<meta name="twitter:creator" content="@kentaroau">
<meta name="twitter:image" content="kentaroau.com/img/profile.png">

The following are our favicon settings. With modern browsers we can set the favicon to be SVG. However with older browsers, we have to use the .ico format. Favicons should be 32x32 pixels.

<link rel="icon" href="/favicon.ico">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">

The below is our icon when iPhone users add our web page onto their homescreen.

<link rel="apple-touch-icon" href="/apple-touch-icon.png">

Similar to the above, for Andriod users - we need to define a .webmanifest file for when they add our webpage to their homescreens.

<link rel="manifest" href="/my.webmanifest">
{
    "name": "weekendprojects.dev",
    "icons": [
        { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
        { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
    ]
}

SASS structure

My SASS structure follows the 7-1 architecture. This is just structuring our source directory to have 7 folders and 1 main.scss file.

Although the name suggests that we should have 7 folders (abstracts, base, components, layout, pages, themes, vendors), I opted to use only 6 since I found no need for the theme folder.

All of the scss files in each folder will be combined in the main.scss file. I am using the @use rule instead of the soon to be deprecated @import rule that you see most SASS boilerplates use.

sass/
|
|– abstracts/
|   |– _variables.scss   # Sass Variables
|   |– _functions.scss   # Sass Functions
|   |– _mixins.scss      # Sass Mixins
|   |– _helpers.scss     # Class & placeholders helpers
|
|– base/
|   |– _reset.scss       # Reset/normalize
|   |– _typography.scss  # Typography rules
|   ...                  # Etc…
|
|– components/
|   |– _buttons.scss     # Buttons
|   |– _carousel.scss    # Carousel
|   |– _cover.scss       # Cover
|   |– _dropdown.scss    # Dropdown
|   ...                  # Etc…
|
|– layout/
|   |– _navigation.scss  # Navigation
|   |– _grid.scss        # Grid system
|   |– _header.scss      # Header
|   |– _footer.scss      # Footer
|   |– _sidebar.scss     # Sidebar
|   |– _forms.scss       # Forms
|   ...                  # Etc…
|
|– pages/
|   |– _home.scss        # Home specific styles
|   |– _contact.scss     # Contact specific styles
|   ...                  # Etc…
|
|– vendors/
|   |– _reset.scss       # CSS Reset by Eric Myers
|   ...                  # Etc…
|
|
`– main.scss             # Main Sass file

Description of each SASS folder

  • abstracts: This folder will not contain any styles, but will contain reusable things such as functions, mixins, variables, etc.

  • base: Our common styles that will be used across the site.

  • components: Styles for the components of the site such as forms, buttons, icons, etc.

  • layout: Will contain layout specific styles across the site. This may include things like footers, headers, navigation.

  • pages: Styles that are specific to each of the pages (such as index.html, contact.html)

  • vendors: contains styles that will be specific to a third-party vendor such as Bootstrap. In our case we are using Eric Meyers CSS reset.

NPM as a build tool

I decided to use NPM as a build tool for this and not use a specifc popular tool such as webpack, gulp, or now vite is because I want to keep it as simple.

We can get more powerful functionality with those tools, I just want someone who wants to pick this up to only know NPM. My guess is that most people will have basic familiarity with NPM.

The build compliles our assets in /src and outputs it into the /public folder. Specifically it performs the following functions:

  • compiles our SASS code into main.css - making sure we have browser prefixes (eg -webkit-, -moz-, etc)

  • minify our .html pages

Final thoughts

In this article, I have gone through how I created a modern HTML boilerplate as a basis for my web designs. The boilerplate uses tools such as SASS for the styling, NPM to build the project and the basic HTML.

Our HTML boilerplate covers things such as:

  • setting the character encoding
  • define the viewport settings for responsive web designs
  • set the Open Graph and Twitter meta tags so that they display correctly when shared on social media
  • having checks for JavaScript support and even modern ES6 features
  • setting the favicons
  • set meta tags so that it is SEO friendly: such as meta descriptions, titles

This is a start and with future iterations, I would imagine it could contain:

  • Boilerplate JavaScript

  • (Maybe) Anime.js - still not decided on this one since one hand, I always use animations in my designs. But if I include it could be overkill.