Learning From The HTML5 Boilerplate

16 May 2013

The HTML5 Boilerplate is a starting point for front end development focusing on best practices and common inclusions. It might not be necessary to replicate it, especially if you like starting all of your projects from the ground up as I do, but at the very least it is a great accompaniment to your workflow and having it open when starting a website can ensure you don't miss anything important.

It can also be a fantastic learning tool too get into the habit of using these best practices yourself. Doing a simple read-through will no doubt reveal some practices that might have been missed or introduce some tweaks that can make everything run more efficiently. During a read-through I decided to note both some of the most important inclusions in the boilerplate as well as the useful points that may not be as commonly used.


The default file in the root directory of the HTML5 Boilerplate is fairly simple, only forty lines long, but houses some samples and best practices that are smart to remember.

Declaring the character set ensures that the Unicode characters on the page can be easily read by the browser. Before HTML5, it needed to be written in more of a long form, but the new HTML5 specs make many of the commonly used lines much easier to remember.

    // Previous spec

    <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>

    // HTML5

    <meta charset='utf-8'>

Similarly, the doctype declaration is now more easily written.

    // Previous spec

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

    // HTML5

    <!DOCTYPE html>

One extremely important line for modern web developement is the viewport tag. Without it, your mobile friendly additions like using percentage widths can fail. MDN has a great example of this.

The boilerplate uses the following viewport tag

    <meta name="viewport" content="width=device-width">

However, adding initial-scale and maximum-scale can help control zoom on the page, initial showing the zoom amount on page load, and maximum specifying the maximum amount a user can zoom. An example of this put to use would be

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

In addition to the main.css file, there are two other files linked to in the <head> of the document that can be extremely useful.

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

Normalize.css is an alternative to CSS resets that was written by Nicolas Gallagher. Normalize has always been my favorite stylesheet for providing similar experiences cross-browser, but there are numerous other good resets that can be very helpful.

Combing through these to create your own can also be worthwhile. Saving time on rewriting code over and over again is the great part about resets or boilerplates, so don't be afraid to add your own.

The other linked file is to the Modernizr library. Modernizr is extremely convenient for ensuring your code gracefully degrades on old browsers by detecting supported features. Once the features are detected, you can use the conditional yep/nope loader to load the correct files for the task.

    Modernizr.on('testname', function( result ) {
      if (result) {
        // load normal JavaScript library
      else {
        // load IE-specific JS library
        // load polyfills

As you would expect, the rest of the JavaScript is loaded after the rest of the content in the <body>. It comes with the usual jQuery link and plugin.js and main.js where you would put your custom JavaScript code. One line that references jQuery is worth looking at though.

    // Google Code jQuery Host
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    // Conditional jQuery
    <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>

The first line references the jQuery code that is hosted on Google. Hosting to this is convenient because it automatically updates and you can be confident that it will always be online, and because the Google version is commonly used, it may be already cached in the users' browser and won't have to be loaded again. However, the second line is a backup just in case it fails, as you never want to have site functionality contingent on someone else's server.

In the <script> tags, window.jQuery first attempts to access the already loaded jQuery instance. Using ||, the code then asks if the window.jQuery doesn't return a value, to write in a local reference. This ensures that the local copy is only referenced when necessary, but if the Google host isn't available for some reason, that there is a backup copy available.

However, Alex Sexton has written and talked that this may not be necessary, and that the best option would be to build jQuery yourself, then host it on your own CDN with the rest of your build to keep the entire process to one HTTP request. Then you can have full control over your assets caching and only do it during updates.


Since Normalize.css is already included in the HTML5 Boilerplate, the default styling in main.css is geared toward opinionated defaults of the authors. These include aethestic changes that wouldn't be included in a reset, where the goal is to increase consistency and eliminate bugs. This is definitely worth looking through before pasting them into your site's code, as they may conflict with your current CSS or cause unintended effects.

The vertical-align property sets the top and bottom alignment of an inline element. It can be used not only to set element alignment compared to text, but also create subscript and superscript notations. HTML5BP adds this property to images by default.

    img {
        vertical-align: middle;

A common mistake is for a developer to see that an image is lined up with the bottom of a row, for example in a <div>. To fix this, they will add the vertical-align:middle property to that <div> class. Unfortunately, the alignment needs to be specified on the element being aligned. Including this will ensure that you don't make this mistake. However, there are reasons to use different vertical-alignments depending on the content, so if this isn't useful it may be better to add specificity to avoid having conflicts with images later on.

    <img class = "vert" src="foo.png">

    .vert {

Changing the resize on textareas is done by default in the boilerplate CSS. This will keep the textarea from resizing horiztontally, which could break a grid or other percentage based layout. This is added because it is normally the functionality that is looked for, but may need to be removed to avoid conflicts if this isn't the functionality intended from the textareas.

    textarea {
        resize: vertical;

If you haven't used clearfix, it is a helpful hack to fix troubles with floating elements in a non-floating container simply by adding the class. It uses pseudo elements in order to clear both sides of the object without adding these properties to the element itself. If these aren't included in your current CSS already, the boilerplate has the most common convention for it.

    .clearfix:after {
        content: " "; /* 1 */
        display: table; /* 2 */

    .clearfix:after {
        clear: both;

     * For IE 6/7 only
     * Include this rule to trigger hasLayout and contain floats.

    .clearfix {
        *zoom: 1;

Responsive design is no doubt one of the driving forces of web design and development right now, and to use these techniques would be to understand the function of media queries. Included is the normal width-based media query

    @media only screen and (min-width: 35em) {
        /* Style adjustments for viewports that meet the condition */

but another query is also present that is less remembered. A print style sheet is a special set of style adjustments that are only used when the web page is to be printed. Considering many CSS attributes are missing from print styles (even background-color and images!), the look of your website that comes out of the printer can be much different than the one viewable on the screen. This can be extremely important especially when running a site that may have directions, menus, etc that could be printed.

Creating a stylesheet for print is easy, simply call the media query the same way you would for a normal width based one

    @media print {
        // Adjusted styles


The sample .htaccess file in the boilerplate is full of not only best practices but also fixes for common issues surrounded by fantastic explanations. Since developers tend to use a similar .htaccess for most sites and learn what to add as they go, reading through this is a nice way to see all the available options and note some things that may be useful.

Everyone has come across the Same Origin Policy at some point. As a security measure, browsers limit the interaction between resources on different servers through XMLHttpRequests. This is important because it keeps scripts originating on foreign sites from manipulating data. This can be an issue though when we have scripts on two of our own pages that we want to allow, but the same-origin policy keeps them from communicating. This is most common when fetching images or including AJAX requests from other sites.

Cross-Origin Resource Sharing is a technique that adds new HTTP headers that allow these resources to be passed to other domains. HTML5BP has examples of CORS for AJAX, images, and web fonts that you can apply to your .htaccess file.


<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"

# Images

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(gif|ico|jpe?g|png|svg|svgz|webp)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS

# Web fonts

<IfModule mod_headers.c>
    <FilesMatch "\.(eot|font.css|otf|ttc|ttf|woff)$">
        Header set Access-Control-Allow-Origin "*"

It's telling that the images and web fonts CORS isn't commented out in the boilerplate .htaccess, rather it is implied that this will be common practice. With the increase of using CDNs for serving images and web fonts like Google Fonts, Typekit, and Pictos (Server), it can be assumed that these will be helpful on the majority of modern sites. If the site is entirely self contained though, there isn't any reason to add unnecessary exceptions here and they can be avoided.

Error handling (like 404) can be controlled and modified through the .htaccess file. There are two inclusions in HTML5BP that handle these errors.

Options -MultiViews

Multiviews controls content negotiation. If a site needs support for alternate browser settings like languages, character sets, or direction of reading, adding this line will enable this functionality.

ErrorDocument 404 /404.html

If you want to make a custom 404 static HTML document instead of the default, this line can be used to point to that file.

Viewing CSS rollovers can sometimes cause screen flickers in Internet Explorer. If you are using the ExpiresByType directives above, you can add the following lines to eliminate this flicker.

BrowserMatch "MSIE" brokenvary=1
BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
BrowserMatch "Opera" !brokenvary
SetEnvIf brokenvary 1 force-no-vary

The BrowserMatch Directive sets the Apache-readable environment variables, changing behavior based on user agent string (browser information). HTML5BP includes this as a precaution against older browsers that sent possibly confusing strings. This may not be necessary anymore and can most likely be removed if the goal is to keep a lean .htaccess, but IE fixes are always nice to have.

A big chunk of the additional code in the boilerplate .htaccess is to ensure the correct MIME types are set for all the different filetypes you might be using. I would definitely recommend this is included even if you are trying to trim parts that aren't used much. You can see by the comments that these eliminate a few nagging errors.

<IfModule mod_mime.c>

  # Audio
    AddType audio/mp4                                   m4a f4a f4b
    AddType audio/ogg                                   oga ogg

  # JavaScript
    # Normalize to standard type (it's sniffed in IE anyways):
    # http://tools.ietf.org/html/rfc4329#section-7.2
    AddType application/javascript                      js jsonp
    AddType application/json                            json

  # Video
    AddType video/mp4                                   mp4 m4v f4v f4p
    AddType video/ogg                                   ogv
    AddType video/webm                                  webm
    AddType video/x-flv                                 flv

  # Web fonts
    AddType application/font-woff                       woff
    AddType application/vnd.ms-fontobject               eot

    # Browsers usually ignore the font MIME types and sniff the content,
    # however, Chrome shows a warning if other MIME types are used for the
    # following fonts.
    AddType application/x-font-ttf                      ttc ttf
    AddType font/opentype                               otf

    # Make SVGZ fonts work on iPad:
    # https://twitter.com/FontSquirrel/status/14855840545
    AddType     image/svg+xml                           svg svgz
    AddEncoding gzip                                    svgz

  # Other
    AddType application/octet-stream                    safariextz
    AddType application/x-chrome-extension              crx
    AddType application/x-opera-extension               oex
    AddType application/x-shockwave-flash               swf
    AddType application/x-web-app-manifest+json         webapp
    AddType application/x-xpinstall                     xpi
    AddType application/xml                             atom rdf rss xml
    AddType image/webp                                  webp
    AddType image/x-icon                                ico
    AddType text/cache-manifest                         appcache manifest
    AddType text/vtt                                    vtt
    AddType text/x-component                            htc
    AddType text/x-vcard                                vcf


Forgetting to ensure your files are being served in the correct text encoding can dramatically affect what your end user sees. UTF-8 is designed to be able to represent every Unicode character in the set. Adding the following will make sure that all of your text or HTML files are encoded correctly.

AddDefaultCharset utf-8

<IfModule mod_mime.c>
    AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml

One of the most common ways that we as developers start to delve into our .htaccess files is by creating rewrites. Whether you want to eliminate the "www" from the front of the domain name by default or redirect to a subdomain, rewrites many times can be essential to the way the website is viewed. The boilerplate uses the following snippet

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
  # Options +SymLinksIfOwnerMatch
    RewriteEngine On
  # RewriteBase /

You may already be familiar with RewriteEngine On and RewriteBase / from adding redirects. The first turns the engine on, and is required for any of the rewrites to work. RewriteBase / is normally redundant if left to itself, as it writes the root to the current root. As noted by in the comments though, some cloud hosts may require it.

Choosing whether to go with www or without is mostly cosmetic, but it is important that the decision is made. Avoiding having the same content at both address will eliminate duplicate content issues with search engines, along with giving you a solid domain to brand with.

# To **eliminate** the www by default, use

<IfModule mod_rewrite.c>
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

# If you want the www to be there by default (and be added if it isn't typed in manually), try

<IfModule mod_rewrite.c>
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
  RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Usually the first option is recommended, as the cleaner look combined with less possible hangups makes it generally more attractive.

If you have a lot of directories that don't have a default document (HTML, php, etc), these folders can still be viewable if navigated to directly. To avoid this, the boilerplate team suggests using the following code by default.

<IfModule mod_autoindex.c>
    Options -Indexes

This ensures that the only directories that can be opened through the browser are those with the default docs. Taking this further, they add another snippet that blocks hidden files like .git, .gem, etc.

<IfModule mod_rewrite.c>
    RewriteCond %{SCRIPT_FILENAME} -d [OR]
    RewriteCond %{SCRIPT_FILENAME} -f
    RewriteRule "(^|/)\." - [F]

There is one more snippet that keeps your non-public data and files secure. As noted, some text editors can produce security flaws by saving files like config and log. I don't have to explain why you wouldn't want these editable by people browsing to your site.

<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
    Order allow,deny
    Deny from all
    Satisfy All

I'm sure you'll notice plenty of extensions in there that are (accidentally or otherwise) added to your sites directories. Aside from the config and logs, I frequently store my PSDs in my local directories where they may accidentally be copied to my online directories either by poor aim in dragging to my FTP client or forgetting to set my .gitignore correctly while using Git. Also if you are still using Flash (anyone?), your FLA files will be safe as well.

Compression is a way great to decrease page load and save your mobile users some precious data. The boilerplate recommends compressing the headers as well as files with the MIME-types specified. You can do so with one code snippet.

    <IfModule mod_deflate.c>

        <IfModule mod_setenvif.c>
            <IfModule mod_headers.c>
                SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
                RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding

        <IfModule mod_filter.c>
            AddOutputFilterByType DEFLATE application/atom+xml \
                                          application/javascript \
                                          application/json \
                                          application/rss+xml \
                                          application/vnd.ms-fontobject \
                                          application/x-font-ttf \
                                          application/x-web-app-manifest+json \
                                          application/xhtml+xml \
                                          application/xml \
                                          font/opentype \
                                          image/svg+xml \
                                          image/x-icon \
                                          text/css \
                                          text/html \
                                          text/plain \
                                          text/x-component \


The mod_deflate module in Apache allows allows compression of files before being received by the client.


The inclusion of the humans text file stems from a project that pushes the idea of revealing the authors behind the site without adding intrusive comments. This can become an issue when a client doesn't like the idea of adding markup or comments with this information. Adding a humans.txt ensures that it doesn't interfere with the rest of the website while providing a common and recognizable file for other developers to look up.

# humanstxt.org/
# The humans responsible & technology colophon


    <name> -- <role> -- <twitter>




    HTML5, CSS3
    Normalize.css, jQuery, Modernizr