A Generic HTML5 Template

Jul 4 2014 by Jacob Gube | 21 Comments

This is boilerplate markup (a blank HTML document template) for HTML5-capable web pages.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="shortcut icon" href="">
</head>
<body>

<!-- Place your content here -->

<!-- SCRIPTS -->
<!-- Example: <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> -->
</body>
</html>

Download Source from GitHub

Copy-and-paste the code template above in a new HTML document and then fill out the blanks.

Commented Version

Read the highlighted comments to learn more about each item in the template:

<!DOCTYPE html>
<!-- Set a lang="" attribute value for
     the <html> tag for interoperability and accessibility
     See other global attributes for the HTML tag: 
     READ: http://www.w3.org/TR/html-markup/global-attributes.html -->
<html>

<head>

<!-- Tell Internet Explorer to use the most current layout engine available
     READ: https://www.modern.ie/en-us/performance/how-to-use-x-ua-compatible -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<!-- Declare a character set for web performance
     Do it through the HTTP header as the first option
     Make sure HTTP header and meta tag are the same
     READ: https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly -->
<meta charset="utf-8"> 

<!-- Specify web page title -->
<title></title>

<!-- Specify the web page description -->
<meta name="description" content="">

<!-- Specify the web page author -->
<meta name="author" content="">

<!-- Tell mobile browsers to use the device's width and scale -->
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Load stylesheets early in the HTML document
     to render visual content ASAP
     Specify the URI of stylesheets in href attribute -->
<link rel="stylesheet" href="">

<!-- Load htmlshiv and Respond.js for old IE versions so we can use
     HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<!-- Specify the URI of your favicon in href attribute -->
<link rel="shortcut icon" href="">

<!-- The commented-out markup below is for iOS/Android bookmarking icons-->
<!--
<meta name="mobile-web-app-capable" content="yes">
<link rel="icon" sizes="196x196" href="">
<link rel="apple-touch-icon" sizes="152x152" href="">
-->

<!-- Reference non-render-blocking scripts here
     and use async attribute if possible
     Example: <script src="" async></script> -->
</head>
<body>

<!-- Place your content here -->

<!-- Put render-blocking scripts here if possible
     and use async attribute if possible -->
<!-- SCRIPTS -->
<!-- Example: <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> -->
</body>
</html>

Explainer

This HTML5 template, in my opinion, is the bare minimum for a practical HTML5-capable document.

I’d like to elaborate on some of the decisions I’ve made with this template.

Placement of scripts

It’s best practice to place your render-blocking scripts near the end of your HTML document, right before the closing </body> tag (or choose not to use them in the first place).

Doing that allows the visual content, CSS and document object model to render first, improving the perceived speed and performance of your web pages.

But referencing scripts at the end isn’t always possible, so move your script references up the HTML document if you need to.

Also, as a form of progressive enhancement, you should preferentially use the HTML5 async attribute with your <script> references so that they can load asynchronously and in parallel, at least in web browsers that are able to.

Example:

<script src="my-script.js" async></script>

Important note: These two script-placement practices can seriously break your web pages if you’re not well-versed in how JavaScript is loaded, rendered, and executed by the browser. And the reason I know this is, indeed, because of the many web pages I’ve broken in the past.

The "viewport" meta tag

The following is small-screen-specific:

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

Without this meta tag, the web page might look like this:

Mobile Safari without viewport meta tag

As you can see above, Mobile Safari will try to render the page to its default width of 980px using the device’s native PPI.

However, with the "viewport" meta tag used in this template, we tell the browser to scale the content to match the device’s width instead. This results in the following:

Mobile Safari with viewport meta tag

The latter is easier to read.

Support of IE 9 and below

Despite commendable efforts from the Internet Explorer team to get their users to update to the most recent version of the browser, the reality is that there are still many people who use IE 9 and below.

To be able to render new HTML5 elements and media queries, this template has a conditional comment for serving html5shiv by Alexander Farkas and Respond.js by Scott Jehl. They’re going to be served through a reliable public CDN. The conditional comment will only load these scripts to users on IE 9 and lower.

In addition, this markup template has the following meta tag:

<meta http-equiv="X-UA-Compatible" content="IE=edge">

This explicitly instructs Internet Explorer to use the most current layout engine available in the user’s machine.

As we move forward to the future and the use of outdated IE browsers is no longer an issue, I’d love to be able to remove these browser-specific items from the template. Many will argue with me that browser-specific markup doesn’t belong in a generic boilerplate, but I’m favoring practicality/pragmatism over semantics in this instance.

A bit of extra markup and conditionally serving two tiny scripts only those that require it is a reasonable compromise for being able to use HTML5 elements and media queries.

Android and iOS home screen icons

About 36% of this HTML5 template is already for the sake of supporting a specific browser family,  so I’ve decided not to include the home screen icon references by default.

However, it’s a good idea to add Android and iOS home screen icons for your web pages because these are two very popular mobile operating systems. Here’s my suggested markup for that:

<meta name="mobile-web-app-capable" content="yes">
<link rel="icon" sizes="196x196" href="">
<link rel="apple-touch-icon" sizes="152x152" href="">

The above will have you covered for the Android Homescreen and iOS Home screen (from the lowest-resolution iOS device up to iPad with Retina display). For now.

Note: Don’t forget to fill out the blank href references to point to the URI of your icons.

For more information on what dimensions your icons should be, read these docs:

As an aside, I hope in the near-future that we can all agree on a non-proprietary way of including bookmarking icons that use an open-source image format.

HTML indentation style

My preference for HTML documents is to start the indentation at the first child element within the <body> element. This is more practical and readable as a developer because after the boilerplate items are set, they will rarely change while we’re developing the front-facing markup.

However, what does change quite often while we’re developing the front-end is the stuff inside the <body> element.

For example, I tend to update element hierarchies, element types and nested structures quite frequently while I’m building out the layout and content structure.

If I were to start the indentation at the <head> element, which would be the semantic thing to do, by the time I get to the meat of the document, I’m already at the second tab stop.

<!DOCTYPE html>
	<head>
		<title></title>
		<!-- etc. -->
	</head>
	<body>
		<! -- 2nd tab stop -->
		<nav id="top">
			<ul>
				<li><a>Link 1</a></li>
				<li><a>Link 2</a></li>
				<li><a>Link 3</a></li>
			</ul>
		</nav>
	</body>
</html>

Working with deep hierarchies, a lot of nesting, and tons of content, those two extra tab stops add up to quite a lot of re-indenting. In addition, I work on a small screen sometimes, and having that type of indentation schema makes code hard to read and scroll through.

Instead, this is what I prefer doing:

<!DOCTYPE html>
<head>
<title></title>
<!-- etc. -->
</head>
<body>

<nav id="top">
	<! -- Start indent at the first child element -->
	<ul>
		<li><a>Link 1</a></li>
		<li><a>Link 2</a></li>
		<li><a>Link 3</a></li>
	</ul>
</nav>

</body>
</html>

This HTML5 template is geared for the above markup-indenting style. This style allows me to tune out the boilerplate stuff as well as to make it easier to work with the elements still being developed.

If you’re bothered by my indentation style — and I completely understand if you are, because these types of things bother me too — you can easily customize this template to implement your preferred source-formatting system. Or, better yet, use Grunt in conjunction with libraries that can automate indentation or minification for you before pushing to production.

Improvements?

If you have suggestions for improving or fixing this template, please let me know. And thank you in advance for doing so!

License: Public Domain Dedication

No need to ask permission if you want to use this HTML5 template (but please email me any time you have other questions besides this). To be even more explicit: The template is free of any copyright restrictions. You can use, sell, modify, and distribute the template all without asking permission, providing attribution, or any other requirement. The HTML markup is under CC0 1.0 Universal. Note: I don’t own the external scripts referenced in the template so the public domain dedication only refers to the markup I wrote.

View Source on GitHub

Related Content

About the Author

Jacob Gube is the founder of Six Revisions. He’s a front-end web developer by profession. If you’d like to connect with him, head on over to the contact page or follow him on Twitter: @sixrevisions.

21 Comments

regan.leah

July 4th, 2014

I’m on my tablet right now, but you need a pull request to move your meta http-equiv. It’s needs to be the first meta tag to work properly.

Jacob Gube

July 4th, 2014

@regan.leah: Thank you for the input!

In this Microsoft article it says:

If you are using the X-UA-Compatible META tag you want to place it as close to the top of the page’s HEAD as possible. Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version’s engine. This is a performance hit because the browser must stop and restart analyzing the content.

This is confirmed by a neoswf on StackOverflow.

The X-UA-Compatible meta tag must appear straight after the title in the element. No other meta tags, css links and js scripts calls can be placed before it.

I’ll move it up. Thanks regan!

Daniel Lo Nigro

July 5th, 2014

Three different CDNs? That’s going to be terrible for performance because each one of those is a separate DNS lookup (exacerbated by the fact that two of the scripts are for old IE which doesn’t handle DNS lookup parallelism very well)

If you’re going to use jsdelivr for one of the scripts, why not use it for all of them for consistency?

Chris

July 7th, 2014

Just a heads-up but the link for the Android icon dev resource is invalid… should just be https://developer.chrome.com/multidevice/android/installtohomescreen but you mashed it with the apple link.

Jacob Gube

July 7th, 2014

@Daniel Lo Nigro: I’ve thought of DNS look-ups. I’ll reply soon, I just have to gather my thoughts and stats on public CDNs (perf and primed-cache potential). I managed to find a public CDN that has both Respond.js and html5shiv, but I would like to test performance first. I’ll respond when I have more data at hand.

@Chris: Thanks so much for catching my error. I’ve updated the post.

Taryn Cafferty

July 7th, 2014

@Jacob, I use an indenting scheme very similar to yours. My personal preference is to separate major elements with a line break and only indent the minor elements. For me, it is much easier to read when searching through the template for a particular element.

This is probably nit-picking, but I’ve always declared the document’s charset in the very first meta element due to W3C saying it should be declared within the first 1024 bytes of the document. Since MS says to place the X-UA-Compatible meta tag as close to the top as possible, I would consider declaring it after the charset, then follow it with the title element. What are your thoughts?

joy

July 8th, 2014

very useful stuff for newbies Jacob, HTML5 is what newbies love to learn. Thanks for sharing!

Jacob Gube

July 8th, 2014

@Taryn Cafferty: Thanks so much for the feedback!

You know, since last weekend, I’ve been thinking about that subject too (5 days now).

For reference, Taryn is talking about section 4.2.5.5 of the HTML5 specifications. It says:

The element containing the character encoding declaration must be serialized completely within the first 1024 bytes of the document.

These are the debates I’ve been having with myself:

  • There’s little chance that at line 4 the first bytes of the document exceed 1024. The only way this will happen is to have a super-edge-case long title value.
  • On the other hand, why not play it safe and move it up before the <title> tag to eliminate any potential of an issue with edge-cases? The only reason I’ve chosen to have the <title> tag where it is now is for development convenience and readability (<title> tag changes or might be neglected during development if it’s buried late in the <head>).

The conservative developer in me says to move it up right below the X-UA-Compatible meta tag (like you’ve suggested) and above the <title> tag because that’s the first variable element in the template, and it could potentially push the first byte size over 1024 (but like I said I’m not sure how long titles are negotiated by browsers).

What adds to this debate is I don’t quite understand how browsers interpret the value of the <title> tag related to the size of the first byte of the document. I know, in practice, browsers have a character limit for <title> tag. (Some resources I’ve read say there’s a 400-character length limit in some browsers, even if HTML specifications doesn’t specify a character limit). I need to test this first to be sure.

Testing to see how browsers read the first 1024 bytes is in my to-do list. I’m not super worried about it right now because ultra-long <title> are edge-cases. Most good <title> values should be short (for good interoperability with external web services like Google search and Facebook shares).

You’ve brought attention to a wonderful point, and I hope others can chime in too!

Miguel

July 9th, 2014

You refer to this URL when commenting the line:

https://developers.google.com/speed/docs/best-practices/rendering#SpecifyCharsetEarly

But what that page says is this:

“To avoid these delays, you should always specify the character encoding in the HTTP response headers. Note that, while it is possible to specify a character set using a meta http-equiv tag, doing so disables the lookahead downloader in Internet Explorer 8. Disabling the lookahead downloader can substantially increase the amount of time it takes to load your page. Microsoft notes: “we continue to strongly recommend that web developers specify the CHARSET in the HTTP Content-Type response header, as this ensures that the performance benefit of the Lookahead Downloader is realized”.

The HTTP response headers is not the HEAD element. What Google recommends (also in their page speed tests) is using this HTTP response header instead of the element:

Content-Type text/html; charset=UTF-8

I know it’s not a big issue (only IE8- are affected), just wanted to point it out.

Thanks for the template and comments!

Al Phillips

July 9th, 2014

For accessibility, a document should include a language declaration.
E.g.
see http://www.w3.org/TR/WCAG20-TECHS/H57.html

Also I note that you’re not including an open element but do have a closing one. I know that the element is not mandatory but why a closing one?

Al Phillips

July 9th, 2014

Oops. e.g. <html lang=”en”>

Jacob Gube

July 10th, 2014

@Al Phillips: Language declaration was intentionally left out on purpose. It is definitely a good idea to declare one though for accessibility and interoperability (e.g. it could help out language translation web services).

Could I request that you kindly elaborate on the question about an open element? I don’t think I understand the question. Thanks.

brent

July 10th, 2014

Ah your blog is filtering out special chars.

I think I can answer for Al Phillips.

Your boilerplate has no open <html> element.

It has a </html> and <!DOCTYPE html> a but no <html>

Interestingly it still passes validation at validator.nu
didn’t know that worked.

ionut marinescu

July 10th, 2014

for cdn why not use maxcdn
the same as bootstrap see here the basic template
http://getbootstrap.com/getting-started/

ionut marinescu

July 10th, 2014

or even better try this one http://www.jsdelivr.com

Al Phillips

July 10th, 2014

Thanks Jacob. Sorry I didn’t use character entities so the <html> didn’t show.

What I mean is that the boilerplate looks
<!DOCTYPE html>
<head>
</head>
<body>
</body>
</html>

rather than this:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>

I was wondering if there is a reason there is no opening <html> but there is a closing </html> element.

Jacob Gube

July 10th, 2014

@Al Phillips: I added an opening <html> tag and in the commented version I included a suggestion about declaring a lang attribute in the <html>tag. Another good option is the dir attribute especially if the language is not ltr. Thanks!

@brent: Brent, first, sorry for the poor usability and UX of this comment section. I’ll do something about it pronto. The commenting system here is not conducive for discussing HTML markup because it eats them up without any warning.

Secondly, I really appreciate that you’ve taken the time to use escape entities and then proceeded to leave a comment again – I know this takes extra time and effort!

The closing HTML tag in this template is my error. I meant not to include the HTML tags because under most circumstances the <html> tags are optional. It validates through an automated service because of this.

However, I’ve decided to include the HTML tags because it’s a good place to set global attributes such as lang and dir, which I’ve been thinking about since after pushing the first version of this template out. @Al Phillips‘ comment pushed me in the right direction.

Jacob Gube

July 10th, 2014

@ionut marinescu: Correct me if I’m wrong, but Respond.js is not available on jsdelivr.com.

Josh Habdas

July 11th, 2014

Thanks for sharing this. The minutiae detail of META tag ordering seems a bit much to me – it feels like a browser concern not worth making humans reason about. Here’s what I use as a nuts and bolts starting point for single-page HTML5 apps which others may find useful: https://github.com/trunkclub/brunch-with-panache/blob/master/app/assets/index.html. It’s similar, but cuts away more of the fat which could be added in later. Note that there would be NO script tags in the template other than what is necessary to bootstrap the application, as the app itself – not the document – would handle loading any other dependencies.

Jacob Gube

July 12th, 2014

@Daniel Lo Nigro: Thanks. I missed that.

Leave a Comment

Subscribe to the comments on this article.