What follows is an excerpt from HTML5 & CSS3 for the Real World, by Alexis Goldstein, Louis Lazaris and Estelle Weyl.

As you learn HTML5 and add new techniques to your toolbox, you’re likely going to want to build yourself a blueprint, or boilerplate, from which you can begin all your HTML5-based projects. In fact, you’ve probably already done something similar for your existing XHTML or HTML 4.0 projects.

We encourage this, and you may also consider using one of the many online sources that provide a basic HTML5 starting point for you.[3]

In this project, however, we want to build our code from scratch and explain each piece as we go along. Of course, it would be impossible for even the most fantastical and unwieldy sample site we could dream up to include every new element or technique, so we’ll also explain some new features that don’t fit into the project. This way, you’ll be familiar with a wide set of options when deciding how to build your HTML5 and CSS3 websites and web apps, so you’ll be able to use this book as a quick reference for a number of techniques.

Let’s start simple, with a bare-bones HTML5 page:

<!doctype html>

<html lang="en">
  <meta charset="utf-8">

  <title>The HTML5 Herald</title>
  <meta name="description" content="The HTML5 Herald">
  <meta name="author" content="SitePoint">

  <link rel="stylesheet" href="css/styles.css?v=1.0">

  <!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>

  <script src="js/scripts.js"></script>

Look closely at the above markup. If you’re making the transition to HTML5 from XHTML or HTML 4, then you’ll immediately notice quite a few areas in which HTML5 differs.

The Doctype

First, we have the Document Type Declaration, or doctype. This is simply a way to tell the browser—or any other parsers—what type of document they’re looking at. In the case of HTML files, it means the specific version and flavor of HTML. The doctype should always be the first item at the top of all your HTML files. In the past, the doctype declaration was an ugly and hard-to-remember mess. For XHTML 1.0 Strict:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

And for HTML4 Transitional:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

Over the years, code editing software began to provide HTML templates with the doctype already included, or else they offered a way to automatically insert one. And naturally, a quick web search will easily bring up the code to insert whatever doctype you require.

Although having that long string of text at the top of our documents hasn’t really hurt us (other than forcing our sites’ viewers to download a few extra bytes), HTML5 has done away with that indecipherable eyesore. Now all you need is this:

 <!doctype html>

Simple, and to the point. You’ll notice that the “5” is conspicuously missing from the declaration. Although the current iteration of web markup is known as “HTML5,” it really is just an evolution of previous HTML standards—and future specifications will simply be a development of what we have today. Because browsers have to support all existing content on the Web, there’s no reliance on the doctype to tell them which features should be supported in a given document.

The html Element

Next up in any HTML document is the html element, which has not changed significantly with HTML5. In our example, we’ve included the lang attribute with a value of en, which specifies that the document is in English. In XHTML-based syntax, you’d be required to include an xmlns attribute. In HTML5, this is no longer needed, and even the lang attribute is unnecessary for the document to validate or function correctly.

So here’s what we have so far, including the closing </html> tag:

<!doctype html>

<html lang="en">


The head Element

The next part of our page is the <head> section. The first line inside the head is the one that defines the character encoding for the document. This is another element that’s been simplified. Here’s how you used to do this:

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

HTML5 improves on this by reducing the character encoding <meta> tag to the bare minimum:

<meta charset="utf-8">

In nearly all cases, utf-8 is the value you’ll be using in your documents. A full explanation of character encoding is beyond the scope of this chapter, and it probably won’t be that interesting to you, either. Nonetheless, if you want to delve a little deeper, you can read up on the topic on the W3C’s site.

note:Get In Early

To ensure that all browsers read the character encoding correctly, the entire character encoding declaration must be included somewhere within the first 512 characters of your document. It should also appear before any content-based elements (like the <title> element that follows it in our example site).

There’s much more we could write about this subject, but we want to keep you awake—so we’ll spare you those details! For now, we’re content to accept this simplified declaration and move on to the next part of our document:

<title>The HTML5 Herald</title>

<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">

<link rel="stylesheet" href="css/styles.css?v=1.0">

In these lines, HTML5 barely differs from previous syntaxes. The page title is declared the same as it always was, and the <meta> tags we’ve included are merely optional examples to indicate where these would be placed; you could put as many meta elements here as you like.

The key part of this chunk of markup is the stylesheet, which is included using the customary link element. At first glance, you probably didn’t notice anything different. But customarily, link elements would include a type attribute with a value of text/css. Interestingly, this was never required in XHTML or HTML 4—even when using the Strict doctypes. HTML5-based syntax encourages you to drop the type attribute completely, since all browsers recognize the content type of linked stylesheets without requiring the extra attribute.

Leveling the Playing Field

The next element in our markup requires a bit of background information before it can be introduced.

HTML5 includes a number of new elements, such as article and section, which we’ll be covering later on. You might think this would be a major problem for older browsers, but you’d be wrong. This is because the majority of browsers don’t actually care what tags you use. If you had an HTML document with a <recipe> tag (or even a <ziggy> tag) in it, and your CSS attached some styles to that element, nearly every browser would proceed as if this were totally normal, applying your styling without complaint.

Of course, this hypothetical document would fail to validate, but it would render correctly in almost all browsers—the exception being Internet Explorer. Prior to version 9, IE prevented unrecognized elements from receiving styling. These mystery elements were seen by the rendering engine as “unknown elements,” so you were unable to change the way they looked or behaved. This includes not only our imagined elements, but also any elements which had yet to be defined at the time those browser versions were developed. That means (you guessed it) the new HTML5 elements.

At the time of writing, Internet Explorer 9 has only just been released (and adoption will be slow), so this is a bit of a problem. We want to start using the shiny new tags, but if we’re unable to attach any CSS rules to them, our designs will fall apart.

Fortunately, there’s a solution: a very simple piece of JavaScript, originally developed by John Resig, can magically make the new HTML5 elements visible to older versions of IE.

We’ve included this so-called “HTML5 shiv”[4] in our markup as a <script> tag surrounded by conditional comments. Conditional comments are a proprietary feature implemented by Microsoft in Internet Explorer. They provide you with the ability to target specific versions of that browser with scripts or styles.[5] This conditional comment is telling the browser that the enclosed markup should only appear to users viewing the page with Internet Explorer prior to version 9:

<!--[if lt IE 9]>

<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>

It should be noted that if you’re using a JavaScript library that deals with HTML5 features or the new APIs, it’s possible that it will already have the HTML5 enabling script present; in this case, you could remove reference to Remy Sharp’s script. One example of this would be Modernizr, a JavaScript library that detects modern HTML and CSS features—and which we cover in Appendix A, Modernizr. Modernizr includes code that enables the HTML5 elements in older versions of IE, so Remy’s script would be redundant.

note:What about users on IE 6-8 who have JavaScript disabled?

Of course, there’s still a group of users who won’t benefit from Remy’s HTML5 shiv: those who have, for one reason or another, disabled JavaScript. As web designers, we’re constantly told that the content of our sites should be fully accessible to all users, even those without JavaScript. When between 40% and 75% of your audience uses Internet Explorer, this can seem like a serious concern.

But it’s not as bad as it seems. A number of studies have shown that the number of users that have JavaScript disabled is low enough to be of little concern.

In one study conducted on the Yahoo network, published in October 2010, users with JavaScript disabled amounted to around 1% of total traffic worldwide. Another study indicated a similar number across a billion visitors. In both studies, the US had the highest number of visitors with JavaScript disabled in comparison to other parts of the world.

There are ways to use HTML5’s new elements without requiring JavaScript for the elements to appear styled in nonsupporting browsers. Unfortunately, those methods are rather impractical and have other drawbacks.

If you’re still concerned about these users, it might be worth considering a hybrid approach; for example, use the new HTML5 elements where the lack of styles won’t be overly problematic, while relying on traditional elements like divs for key layout containers.

The Rest is History

Looking at the rest of our starting HTML5 template, we have the usual body element along with its closing tag and the closing </html> tag. We also have a reference to a JavaScript file inside a script element.

Much like the link element discussed earlier, the <script> tag does not require that you declare a type attribute. In XHTML, to validate a page that contains external scripts, your <script> tag should look like this:

<script src="js/scripts.js" type="text/javascript"></script>

Since JavaScript is, for all practical purposes, the only real scripting language used on the Web, and since all browsers will assume that you’re using JavaScript even when you don’t explicitly declare that fact, the type attribute is unnecessary in HTML5 documents:

<script src="js/scripts.js"></script>

We’ve put the script element at the bottom of our page to conform to best practices for embedding JavaScript. This has to do with the page loading speed; when a browser encounters a script, it will pause downloading and rendering the rest of the page while it parses the script. This results in the page appearing to load much more slowly when large scripts are included at the top of the page before any content. This is why most scripts should be placed at the very bottom of the page, so that they’ll only be parsed after the rest of the page has loaded.

In some cases (like the HTML5 shiv) the script may need to be placed in the head of your document, because you want it to take effect before the browser starts rendering the page.

[3] A few you might want to look into can be found at http://www.html5boilerplate.com/ and http://html5reset.org/.

[4] You might be more familiar with its alternative name: the HTML5 shim. Whilst there are identical code snippets out there that go by both names, we’ll be referring to all instances as the HTML5 shiv, its original name.

Want more? Check out the book and buy it online at HTML5 & CSS3 for the Real World, by Alexis Goldstein, Louis Lazaris & Estelle Weyl. Download the free sample chapters, access the book’s code archive, check on updates and errata or join the conversations on the SitePoint Forums.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like HTML5 & CSS3 For the Real World.

Comments on this article are closed. Have a question about HTML5? Why not ask it on our forums?

Start building your own HTML5 websites from scratch! Our latest book, Jump Start HTML5, is free to read on a Learnable trial.

Tags: CSS3, HTML5 Dev Center, HTML5 Tutorials & Articles
Louis is a dev blogger at Impressive Webs, author, and is currently SitePoint's HTML and CSS editor. He loves all things front-end, and curates Web Tools Weekly, a newsletter for front-end developers primarily focused on tools.

Free Guide:

How to Choose the Right Charting Library for Your Application

How do you make sure that the charting library you choose has everything you need? Sign up to receive this detailed guide from FusionCharts, which explores all the factors you need to consider before making the decision.

  • Alek Davis

    Good explanation. Thanks. One questions: What’s the purpose of “?v=1.0″ in the CSS link?

    • Louis Lazaris

      It just adds a version number to the CSS file. Sometimes you can update the CSS file and a user will visit your site and something will be broken because the browser has cached the old CSS file.

      You can prevent the CSS file from caching by giving it an updated version number. So if you change something, you can also change the version number to 1.1.

      This way, the CSS file will always be cached unless you manually change the version number, which forces the browser to get the new version since it thinks it’s a new file altogether.

      There are probably some more efficient ways to do this on the server side, but this is just a quick and dirty way for the front end.

      • Helen Natasha Moore

        I understand that this was a version number thing. I wanted to know how you do that. Do you change the CSS file name to include the numbers at the end? Or …?

      • Louis Lazaris

        No, you don’t need to change the file name. The file just has to be called “styles.css”. In fact, you are not allowed to change a file name to include a question mark, so you couldn’t do it anyhow! :)

        Everything after a question mark in*any* URL is what’s called the query string. The query string does not affect the actual file being requested; it is used to pass variables to the URL.

        Normally query strings are used for more elaborate things, but this is just a sort of hack to get the browser to think you’re requesting a different file, when you’re actually requesting the same one. In other words, every time you change the value of the query string, the browser will fetch the most recent file. If you leave the value, then it will try to get the cached file first.

        Of course, I’m no super-expert when it comes to browsers and caching, so if anyone else wants to chime in here and correct me on anything, please feel free. :)

      • Helen Natasha Moore

        Gosh, Louis, I’m embarrassed you thought I meant to include the query string in the file name! Ouch.

        I just meant that because I’ve seen this:

        … and I’ve also seen this:

        … that maybe there’s a bit of code somewhere that calls the latter from the former or something.

        Anyway ….. I get it now. You’re just adding a random value to the query string to trick the browser into fetching the file again. Thank you! :-)

      • BrenFM

        I came up with a rather simple way of looking at it:

        Every time you change the version number, that little variable on the end causes the user’s browser to say “Hay I’ve got a cached file called style.css?v=1.0, but you’re asking for a file called style.css?v=1.1. I’d better download that now and use it instead.” (copied from our work Tumblr account).

        When I’m dev’ing a site now and making lots of changes to a stylesheet or js file (prelaunch) I’ll whack a timecode on the end of it – something like:

        “style.css?v=<?php echo time(); ?>”

        This saves me from having to hard refresh everytime I make a change. Just pays to remember to remove it when you launch so as not to completely bypass caching!!

      • Helen Natasha Moore

        Now, that’s cool, BrenFM! :-)

      • IT Mitică

        Remove “style.css?v=” and put “styles.css?v=1.0″ instead, as to have a mechanism to completely bypass caching of files, when needed, after official launch.

      • BrenFM

        Thanks for the feedback, Helen! Appreciate it!

      • Louis Lazaris


        I was actually going to mention the timecode thing, but I didn’t want to encourage bad practice. :)

        But you’re right — that would certainly be a good thing for when you’re making constant updates locally. Good tip.


        Sorry I misunderstood your original question, but it looks like you now understand what the purpose of the query string value is. :)

  • Michael Tuck

    Not shilling for SitePoint, but I so want this book. :)

  • Joe Twumasi

    Nice tuts.

  • Heidi Helen

    A very useful article, thanks.

  • trilefile

    I too was wondering about the purpose of “?v=1.0″ in the link to the stylesheet.
    Thanks for a great article.

  • Brian Temecula

    I’d say having a template is a step in the right direction, but I can’t think of any website I’ve worked on in the last year or more that wasn’t utilizing a php framework, in which such HTML templates are a mere stepping stone to a view in which all other views are nested.

    • Louis Lazaris

      Naturally, I would never build any website or web app today unless it was built on some kind of back-end framework.

      This is just an HTML template that you would integrate into your back-end framework.

      Of course, this particular one is more for educational purposes, to learn the new HTML5 features, and thus is pretty minimal. For a really serious project, I suggest using HTML5 Boilerplate or something similar, which again, would be integrated with whatever back-end framework you’re using.

  • BrenFM


    Just read your bit in there about WHERE to put the HTML shiv… (i.e. before the stylesheet declaration). I’d been putting Modernizr in the bottom of the body… GUH! Goober!

    SO! Thanks a million for that little snippet of wisdom!

  • Michael Hall

    Thanks very much for the template with explanations, i saw a similar article here not to long ago. I particulary like the comment tip about adding a php snippet to append a random time to the query string.

    I’m using this template for sure.

  • Birger J. Nordølum

    I see a lot of where there should be gode. Something is wrong with the code highlighter.
    I’m using Chrome 12, if that can be of useful information.
    Thank you for the article :)

  • xhtmlcoder

    It’s interesting for a ‘standalone’ document to be referencing; proprietary hacks, live URL and scripting language just to function. So it cannot be considered a ‘backwards compatible’ document. Though I suppose people are well aware that is another major drawback of HTML5 adoption but then again it is non normative so in constant flux. Other than minor those points this article seems informative.

  • Rudie

    Love this:

    > “A number of studies have shown that the number of users that have JavaScript disabled is low enough to be of little concern.”

    How about blind people? There are only a few of those, right? Yeah, screw em! (I seriously think so, but I guess that’s not PC.)

    (PS. There’s something wrong with this preview function.)
    (PS. What kind of markup does these comments use? Markdown? Textile? HTML?)

    • _ michael

      CSS handles the _visual_ styling of the markup. Blind people and their screen readers will not really care if the CSS is not being applied.

  • Stijn

    But you can (generally) choose whether to enable Javascript or not. If you choose to disable it then probably you don’t care about things breaking. Being blind is not a choice.

    About the template, I want to point out that I think that you should never make a script element with a source attribute that points to the trunk of a source repository, as the tag including the html5shiv script in this template does. The problem with that is that whenever John changes his script, you will automatically get his new version, immediately. You are on the beta, no alpha, no development version of the script if you do this.

    I would recommend copying the script to your own server, or at least make it point to a specific version. Unfortunately John did not create any tags for his script so in this case you best copy it.

  • Michael Hall

    just to clarify…

    is the html5 shiv included to make the html5 tags/elements and user defined elements visible to older browsers like IE 8 or lower?

    also is their a shiv that will allow IE to use css3 properties yet?

    i’m running IE7(at work, not at home) and the following css does not work… anyway to get IE to conform? i think IE9 supports css3

    ul li:last-child { border-bottom: 1px solid #DDD; }
    ul li:nth-child(even) { background: #EEE; }

Special Offer
Free course!

Git into it! Bonus course Introduction to Git is yours when you take up a free 14 day SitePoint Premium trial.