0% found this document useful (0 votes)
52 views593 pages

Edx html5 1 - Code

Uploaded by

denilson.dlr
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views593 pages

Edx html5 1 - Code

Uploaded by

denilson.dlr
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Welcome!

The HTML5 course team is thrilled to guide you in your learning experience. We
are committed to teach you how to code Web pages, and how to do it the
correct way. With this W3Cx HTML5 Part 1 course, you will be able to test their
new skills through numerous interactive examples and multiple exercises. You
will be encouraged to create Web pages and apps and share them in the
discussion forums.

During this course, you will:

Learn the new simplified HTML5 tags, and how to use microdata
Play with the audio and video tags
Draw and animate fun Web graphics
Discover the newest HTML5 forms
Understand why accessibility is important
Test the basic APIs, such as Web storage and geolocation
Practice coding techniques thanks to multiple interactive examples
Outline of the HTML5 Part 1 course
About W3C and the Web (OPTIONAL)
About W3C
Why accessibility is important
Why internationalization is important
W3C tools

Course Introduction and practical information


Course syllabus
Getting around the course
Grading and due dates
Course tools
Welcome survey

Week 1: HTML5 Basics


1.1 Video introduction - Week 1
1.2 From HTML1.0 to HTML5
1.3 New structural elements
1.4 Other elements and attributes
1.5 Microdata
1.6 Exercises - Week 1

Week 2: HTML5 Multimedia


2.1 Video introduction - Week 2
2.2 Streaming multimedia content: the video and audio elements
2.3 Subtitles and closed captions
2.4 Enhanced HTML5 media players and frameworks
2.5 Webcam, microphone: the getUserMedia API
2.6 Exercises - Week 2

Week 3: HTML5 Graphics


3.1 Video introduction - Week 3
3.2 Basics of HTML5 canvas
3.3 Immediate drawing mode: rectangles, text, images
3.4 Path drawing mode: lines, circles, arcs, curves and other path drawing
methods
3.5 Colors, gradients, patterns, shadows, etc.
3.6 Exercises - Week 3

Week 4: HTML5 Animations


4.1 Video introduction - Week 4
4.2 Basic animation techniques
4.3 Canvas and user interaction (keyboard, mouse)
4.4 A glimpse of advanced canvas functionalities
4.5 Exercises - Week 4

Week 5: HTML5 Forms


5.1 Video introduction - Week 5
5.2 Introduction to HTML5 Forms
5.3 Accessible forms
5.4 New <input> types
5.5 New forms attributes
5.6 New elements related to forms
5.7 Form validation API
5.8 Exercises - Week 5

Week 6: HTML5 Basic APIs


6.1 Video introduction - Week 6
6.2 Introduction to HTML5 APIs
6.3 HTML5 Cache
6.4 The Web Storage API
6.5 The File API
6.6 The geolocation API
6.7 Final exam
Week 1
History of HTML versions
HTML stands for HyperText Markup Language, and it is the authoring
language used to create documents on the World Wide Web. HTML is used to
define the structure and layout of a Web page, how a page looks and any
special functions. HTML does this by using tags that have attributes. For
example <p> means a paragraph. As the viewer of a Web page you don't see
the HTML as it is hidden from your view - you just see the results. But you all
know that!

HTML 1.0
Below is a screenshot of Tim Berners-Lee's Browser Editor as developed in
1991-1992.

This was a true browser editor for the first version of HTML and ran on a NeXT
workstation. Implemented in Objective-C, this very first browser in Web
history made it easy to create, view and edit web documents. Hypertext
Markup Language (First Version of HTML) was formally published in June 1993.
HTML versions
HTML is an evolving language. For Web sites and pages created since 1991,
however, it is easy to find out which HTML version they use. A Document Type
Declaration, or DOCTYPE, is a piece of HTML code that states which version of
HTML is being used. This declaration must appear at the very top of every Web
page.
For example: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> tells
that the document uses the HTML4.01 version.

HTML Versions

1991
HTML

1993
HTML+

1995
HTML2.
0

1997
HTML3.
2

1999
HTML4.
01

2000
XHTML
1.0
October
HTML5 2014

For those of you who are curious, the W3C published a document laying down
the HTML5 Differences from HTML4 (the document was published in December
2014, shortly after the release of HTML5). Read also the history
section available in the HTML5.1 specification document.

What is HTML5?
On 28 October 2014, the W3C officially published HTML5 as a Web standard
(or recommendation of HTML5). HTML5 is the fifth major revision of the format
used to build Web pages and applications.

HTML5 contains powerful capabilities for Web-based applications with


more interaction, video support, graphics, more styling effects, and a full set of
APIs. HTML5 adapts to any device, be it a desktop, mobile, tablet, or
television device. HTML5 is an open platform developed under royalty free
licensing terms.

People use the term HTML5 in two ways:

to refer to a set of technologies that together form the future Open
Web Platform. These technologies include HTML5
specification, CSS3, SVG, MathML, Geolocation, XmlHttpRequest, Context
2D, Web Fonts (WOFF) and others. The boundary of this set of technologies is
informal and changes over time.
to refer to the HTML5 specification, which is, of course, also part of the
Open Web Platform.

Although it would be great if people used one term to refer to the specification
and another term to refer to the set of specifications, in practice people use the
term both ways.

When HTML5 became a Web standard, Tim Berners-Lee, Web inventor and
W3C Director said:

"Today we think nothing of watching video and audio natively in the browser,
and nothing of running a browser on a phone. We expect to be able to share
photos, shop, read the news, and look up information anywhere, on any device.
Though they remain invisible to most users, HTML5 and the Open Web Platform
are driving these growing user expectations."
The HTML5 logo
Here is the HTML5 logo! It has been unveiled on 18 January 2011, so way
before HTML5 became a Web standard. This logo represents HTML5, the
cornerstone for modern Web applications.

Please check out both the HTML5 logo home page and the FAQ page for more
information on how to use the logo, etc. You will notably find out that this logo
does not imply validity or conformance, and that you are welcome to be
creative and make it fit into your own designs.

Greater simplicity
Changes have been made to particular elements in
HTML5 making it simpler to use. In this section, we will
look at some examples highlighting these
improvements, including:
the new doctype definition;
the fact that the "type" attribute of elements such
as <link> or <script> are now optional;
the syntax constraints that have been relaxed;
the new structural elements that have been added, etc.

A minimal HTML5 document


1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Page Title</title>
6. <link rel="stylesheet" href="[Link]">
7. <script src="[Link]"></script>
8. </head>
9. <body>
10. ... <!-- The rest is content -->
11. </body>
12. </html>

Let's compare it to the HTML4 minimal document below


(source: [Link] Differences
have been highlighted in red:

1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"


"[Link]
2. <html lang="en">
3. <head>
4. <meta http-equiv="content-type" content="text/html" charset="utf-8">
5. <title>title</title>
6. <link rel="stylesheet" type="text/css" href="[Link]">
7. <script type="text/javascript" src="[Link]"></script>
8. </head>
9. <body>
10. ...
11. </body>
12. </html>

Simpler Character Set Definition


One word about the <meta charset="utf-8"> at line 4 in the HTML5 version: it
is good practice to declare the character set of your document to protect
against a serious security risk. For more details, please refer to the "Why
Internationalization is important" section in the Course Intro chapter.

No more complicated DOCTYPE definitions


The "Doctype", often called DTD (Document Type Declaration), is used by tools
such as HTML validators (i.e. the W3C validator), and specifies the rules used
by an HTML or an XHTML page. These rules are contained in special
documents called "Document Type Definitions" (also abbreviated as DTD),
written in a language that may seem a bit barbaric to humans (they are
intended to be read by software), and hosted by W3C.

DTDs are not used by current Web browsers to validate the structure of an
HTML page, as they "read" the code without using the DTD to decipher it,
using only "rules" contained in their own "HTML engine", but it is still preferable
to indicate the doctype as modern browsers have several rendering engines
that are chosen depending on the doctype.

Old HTML1 Web pages will not be rendered the same way as new HTML5
pages, since in the 90's some of them were written by hand and may contain
errors, embedded HTML elements, etc.

With HTML4, doctype definitions looked like this: <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"[Link] which was even more
complicated as one had to choose between three different possibilities
(doctypes could be transitional, strict, or frameset). Most of the time, the
doctype definition was copied and pasted from one document to another and
was nearly impossible to memorize.

With HTML5, there is only one way to indicate the doctype, and it's so simple
there is no reason to forget it:

1. <!doctype html>

The "TYPE" attribute is optional


With a rel="stylesheet" attribute, it is no longer necessary to
indicate type="text/css" (from the specification: "the default type for
resources given by the stylesheet keyword is text/css.")

The "type" attribute is not needed in HTML5, and even old browsers will use
text/css as the default type for stylesheets today. So, either way, you can omit
the "type" attribute altogether and use:

1. <link href="[Link]" rel="stylesheet"/>

instead of:
1. <link href="[Link]" rel="stylesheet" type="text/css"/>

We will not go into detail about the <link> element, but the fact that
the type attribute is becoming optional shows the current direction taken by
HTML5: towards greater simplicity.

Please see how to include a JavaScript file in our page:

1. <script src="[Link]"></script>

Here again, the type attribute has been omitted. Just as a reminder, the old
way to do the same thing:

1. <script type="text/javascript" src="[Link]"></script>

More flexible syntax constraints


If you look at the "minimal document" example, or at other examples in this
course, you won't find a lot of differences compared to the same code in
XHTML: attribute values are surrounded by quotes, all elements are written in
lower case, etc. This is because we are used to writing this way, but HTML5
also supports a simplified syntax:
Thanks to HTML5, you can omit quotes (not always, but most of the time) or
use uppercase, lowercase or a combination of the two.
Many elements no longer need a closing tag: </li>, </dt>, </dd>, </tr>,
</th>, </td>, </thead>, </tfoot>, </tbody>, </option>,
</optgroup>, </p> (in most cases), </head>, </body> and </html>. Older
browsers often add closing tags automatically at render time. We recommend,
however, closing tags that would naturally be closed: the ones that delimit a
particular zone in the document.

Attribute values only need to be quoted if they contain spaces or some non-
alphanumeric characters, instead of
writing <link rel="stylesheet" href="[Link]">, we could have
used <link rel=stylesheet href=[Link]> instead. However, for
compatibility with older browsers, it might be wiser to still use quotes...
New structural elements

History
As Web site layouts evolve, HTML5 structural elements such as lists,
paragraphs, tables, etc. show their limits. Today, many Web sites offer
navigation menus, tabbed panels, headers, footers, and so on. The way these
"parts"' are implemented relies heavily on <div> and <span> elements with
different id and class attributes, lots of CSS and lots of JavaScript code to apply
custom styles and behaviors.

However, there are some issues with this approach:

id and class names differ from one developer to another, from one country to
another, etc.
Even with the same ids and class names, the css rules may be different
JavaScript libraries have become increasingly heavy over the years
Web pages have become increasingly heavy over the years!
These elements can not be handled by the Web browser natively...
Even if differences exist between ids, classes and css/js implementations, they
also share common behaviors, layouts, and "ways of doing things" that could
be guessed at first glance by a human.

So various studies have been conducted in order to identify the most popular
ids, class names, widgets, etc. used on the Web:

According to [Link]
html5/, "During the creation of HTML5, Ian Hickson used Google's tools to mine
data from over a billion Web pages, surveying what ids and class names are
most commonly used on the real world Web. You can see one of the surveys
published at Google Code: Web Authoring Statistics: Classes. Opera did a
similar study of 3.5 million URLs, calling it MAMA ("Metadata Analysis and
Mining Application"). MAMA, as structural Web-paged search engine, had a
smaller URL set, but looked at a larger and wider variety of Web page statistics.
The articles published by Opera are no longer online but have been archived on
github, and still can be accessed using [Link], see MAMA common
attributes, MAMA's id list, and MAMA's class list. For more options, go to
the MAMA home page."

New elements added to the HTML5 set


The results of these surveys led to the addition of new structural elements in
HTML5. For example, the very popular <div class="header"> led to the
creation of a <header> element, <div class="aside"> to a<aside> element,
etc.

Finally, the 20 most popular ids and class names found in Hickson's and
Opera's surveys gave birth to these new elements (click on the element's name
to go to the W3C specification about this element):

HTML5 structural elements with descriptions.

HTML5 element Description

Introduction of "sectioning elements": an


article, a section, the entire document (header page).
<header> Typically the header of a Web site that appears on top
of each page, or a header of a long <article> or of a
long <section>
Contains the footer of a site, a long <article>, or a
<footer>
long <section>

Section that contains the main navigation links (within


<nav>
the document or to other pages).

Independent content, which can be individually


extracted from the document and syndicated (RSS or
<article>
equivalent) without penalizing its understanding.
Typically a blog post.

Generic section used to group different articles


for different purposes or subjects, or to define the
<section>
different sections of a single article. Generally used with
a header.

<time> Used for marking up times and dates.

Section whose content is not necessarily directly related


<aside> to the main content that surrounds it, but can provide
additional information.

<figure> and <figcaption Used to encapsulate a figure as a single item, and


> contains a caption for the figure, respectively.

The main element represents the main content of the


body of a document or application. The main content
area consists of content that is directly related to or
<main>
expands upon the central topic of a document or central
functionality of an application. There can be only
one <main> element in a document.

And there is no <content> element even though the <div


class="content"> was very popular. Instead, the HTML5 group decided that
anything not embedded in one of the elements from the above table is "default
content". If the content is of a type that corresponds to one of the elements
from the table, i.e. if the content is an article, it should be embedded
between <article> and </article>.
Read also at the end of this section about the new <main> element . This
element is part of the HTML5 recommendation and an integral part of the
HTML document structure.

External resources:

 VERY GOOD article: [Link]

importance-of-sections/

 [Link]

 [Link]
How to mix all the new structural elements together?

A blog example that uses the new structurAL elements

Let's study an example we put on JSBin (all examples we have cooked up

are available on the [Link] Web site and can be modified freely: you can

save your own version using the "Bins/create milestone" menu, share your

version with others in the forums, etc. Don't hesitate to play with the

source code, you will never break anything).


Use a <header> at the top of the blog
This is an example of one way to organize a blog. Here, we have designed

the HTML page using a <header> element that contains the "Simple

HTML5 blog" text that appears on top of the page.

HTML code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>Simple HTML5 blog</title>
5. </head>
6. <body>
7. <header>
8. <h1>Simple <span>HTML5</span> blog</h1>
9. </header>
10. ...

The CSS rules we used:

1. header {
2. color: #007e99;
3. font-size: 2.5em;
4. padding: 20px 50px
5. }
6. header span {
7. color: #722
8. }
Use a <nav> for the navigation menu just below the header

The navigation menu just below the header is a <nav> element. For the

purpose of this example we haven't provided any value for the hyperlinks...

HTML code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>Simple HTML5 blog</title>
5. </head>
6. <body>
7. <header>
8. <h1>Simple <span>HTML5</span> blog</h1>
9. </header>
10.<nav>
11. <ul>
12. <li><span>Blog</span></li>
13. <li><a href="">About</a></li>
14. <li><a href="">Contact</a></li>
15. </ul>
16.</nav>

And here is the CSS we used in this example for the <nav> element:

1. nav {
2. font-size: 1.5em;
3. margin: 5px 0;
4. padding: 20px 50px
5. }
6. nav li {
7. display: inline;
8. margin: 0 15px
9. }
10. nav li:first-child {
11. margin-left: 0
12. }
13. * html nav ul {
14. margin-left: -15px
15. }
16. nav span, nav a {
17. padding: 3px 15px 4px
18. }
19. nav span {
20. background: #722;
21. color: #fff
22. }

A <section> for each month and an <article> for each post in the blog

Now, we have one big <section> element that contains a set

of <article> elements...
HTML code:

1. <section>
2. <article>
3. ...
4. </article>
5. <article>
6. ...
7. </article>
8. <article>
9. ...
10. </article>
11. </section>

And here is the CSS:

1. section {
2. float: left;
3. padding: 35px 0;
4. position: relative;
5. width: 70%
6. }
7. section article {
8. margin: 0 50px 40px;
9. padding: 25px 0 0;
10. position: relative
11. }
12. section header {
13. font-size: 1em;
14. padding: 0;
15. }
16. section h2 {
17. font-size: 2.3em;
18. }

Note that the H2, article, article header, etc. will be styled using these

rules.

Add a <header> at the beginning of each <article>

Next, in each article in the section we have a header (to display the article

title), paragraphs (article content), and so on.

Example for the first blog article:

1. <section>
2. <article>
3. <header>
4. <h2><a href="">Information about this example</a></h2>
5. This example is a modified version of <a
6. href="[Link]
7. [Link]
8. </header>
9. <p>Try to move the mouse on different elements. The structure will be
10. highlighted and you will be able
11. to see the different inclusions of elements one in each other. If you
12. move the cursor to this sentence, it will be highlighted in dark
grey,
13. showing the presence of an &lt;article&gt; element, surrounded by a
14. &lt;section&gt; element (light grey), etc. So we have some articles in
15. a single section element. The page title at the top is
a &lt;header&gt;
16. element, while the tag cloud on the right is a &lt;aside&gt; element.
The
17. main menu on top (with Blog, About, Contact) is
a &lt;nav&gt; element.</p>
18. <figure>
19.
<img src="[Link]
20. alt="Example of HTML5 structural tags" />

21. <figcaption>
22. Fig. 1 : an example of how new structural elements could
23. be used. This page put a &lt;nav&gt; on top, and does not have
24. headers and footer for each article, like in this
figure,
25. but it could... By the way this is a
26. &lt;figcaption&gt; inside a &lt;figure&gt; element...
27. </figcaption>
28. </figure>
29. </article>
30. ...
31. </section>

Use <figure> and <figcaption> and embed <img> inside

Also note the way we included a figure using the new "HTML5" method,

using a <figure>..</figure> element that embedded a <img

src=.../> element together with a <figcaption> element.

Here is the CSS for the <figcaption> element we have used in the

example (we did not apply any style to the <figure> element):

HTML code:

1. <figure>
2. <img src="[Link]
3. alt="Example of HTML5 structural tags" />
4. <figcaption>
5. Fig. 1 : an example of how .....
6. </figcaption>
7. </figure>

CSS code:

1. figcaption {
2. font-style:italic;
3. font-size: 0.8em;
4. width: 100%
5. }

Use an <aside> element to display a tag cloud on the... side of the main

content

After the long <section> element that contains all the blog articles

displayed in the page, we added the HTML code for the tag cloud that is

displayed on the right of the page, "aside"! This is done using - you already

guessed it - an <aside> element:


1. <section>
2. .... all <article>... </article> here....
3. </section>
4. <aside>
5. <h2>Tag cloud</h2>
6. <ul class="tag-cloud">
7. <li><a href="" rel="tag" class="w2">ajax</a></li>
8. <li><a href="" rel="tag" class="w8">apple</a></li>
9. <li><a href="" rel="tag" class="w3">css</a></li>
10. ...
11. </ul>
12.</aside>
13. ...

We are not going to show the complete CSS here as it uses some tricks to

display the list as a "real tag cloud" that uses JavaScript for handling

events, etc. Those who are curious can look at the code of the online

example: [Link]

Here is the CSS for the <aside> element:


1. aside {
2. float: right;
3. padding: 70px 0 30px;
4. position: relative;
5. width: 25%
6. }
7. aside h2 {
8. color: #888;
9. font-size: 1.8em
10. }
11. aside .tag-cloud {
12. padding: 15px 35px 10px 0;
13. text-align: center
14. }
15. ...

We used a float:right CSS rule to put the tag cloud on the right... In a

following section we will provide several examples that explain how to

make a nice layout with the new structural elements, using simple CSS

rules.

Here is the result:


Add a <footer> at the end of the blog

Finally, we added a <footer> element (lines 12-14 below) after the tag

cloud definition, to display a page footer:

1. <html>
2. ...
3. <body>
4. ...
5. <section>
6. ...
7. </section>
8. <aside>
9. ...
10. </aside>
11. <footer>
12. <p>&copy; 2009 Some blog</p>
13. </footer>
14. </body>
15. </html>

With this CSS rule:

1. footer {
2. clear: both;
3. color: #777;
4. padding: 10px 50px
5. }

And here is the result at the bottom of the page:

More on <ARTICLE> and <SECTION>


Can an <article> contain
a <section>?
It may not be clear whether a <section> may
contain one or several <article> elements or if
an <article> may contain one or
several <section> elements.
The <article> element was designed for stand-alone parts of a document
that could eventually be syndicated in RSS streams.
<section> elements are used to cut a logical part into subparts.

An <article> may be cut into different <section> elements!

Example of a blog post defined as a long <article>, that is in turn cut into
smaller <section> elements:
1. <article id="id1">
2. <section id="id1part1">
3. <h2>Introduction</h2>
4. </section>
5. <section id="id1part2">
6. <h2>My travel to India</h2>
7. </section>
8. <section id="id1part3">
9. <h2>Return to France</h2>
10. </section>
11. </article>

The blog example from the previous part of the course, on the other hand, uses
a single <section> that contains several <article> elements.

Indeed, we can also have a <section> that regroups all blog posts per month,
each one being an <article>element.

A <section> may be cut into different <article> elements,

too!
CAN you PUT A <NAV> IN AN <ARTICLE>?
Yes you can, in case you would like to propose some navigation links with each
blog post, for example:
1. <article>
2. <header>
3. <h1>Blog post title</h1>
4. <p>Author: Michel</p>
5. </header>
6. <nav>
7. <ul>
8. <li><a href="...">Next post</a></li>
9. <li><a href="...">Previous post</a></li>
10. <li><a href="...">Contact author</a></li>
11. </ul>
12. </nav>
13. <p>Content...</p>
14. <footer>
15. <p>Posted by Michel, the <time datetime="2012-02-02">February
2,
16. 2012</time> </p>
17. </footer>
18. </article>

In that case, the <nav> element proposes navigation links to the next or
previous blog post, as well as a link to contact the author of the blog post.

Also note that we used in that example a <footer> element in the blog post.

WHAT ABOUT THE <DIV> ELEMENT ? IS IT STILL


USEFUL ?
The new elements have been primarily designed to better structure the code of
HTML pages such as those generated by blog or CMS software, however do not
forget that they add new semantics and will be taken into account by :
Browsers natively or browsers' extensions, i.e. for automatically generating a
table of contents, an outline view of the document, for applying default CSS
rules to these elements, etc. See for example the HTML5 outliner (Chrome
extension). More on that in the next section of the course.
Screen readers that vocalize document content,
see [Link] for an
interesting HTML5 blog post on this topic.
Web crawlers, etc.

You can use <div> elements in all cases where the proposed structural
elements do not fit your needs: for defining some content that should be
styled, for example.

This chart from the HTML5 Doctor Web site may help you decide whether or
not to use a <div>:
Headings and structural elements
We will now present some best practices for starting to use <section>,
<article>, <nav>, <aside>, in particular concerning the use of headings
(H1, H2, H3, H4, H5 and H6).

Use <H1>...<H6> for the headings, as you have


done with html4...
Since the very beginning, HTML has had heading elements: <h1>..<h6>. These
elements are used to display headings with different sizes by default, when no
CSS is used. The following example shows 6 sentences that are surrounded
by <h1>, <h2>, <h3>, <h4>, <h5> and <h6>:

This is a H1 heading

This is a H2 heading

This is a H3 heading

This is a H4 heading

This is a H5 heading

This is a H6 heading

These headings define a hierarchy, as shown by the default sizes given by the
browser. This hierarchy can also be used to define an outline of the document.
To illustrate this, we have used a browser extension. Here is the result for the
previous example:
In the above outline, note that we have only used H1...H6 elements, without
any new HTML5 structural elements such as <section> or <article>.

Here is a list of browser extensions you can try, for visualizing the outline of a
document: Google HTML5 outliner, or the HTML5 Outliner Opera
Extension or this Firefox extension.

Using headings and new sectioning elements


(section, article, aside, nav)
Definition of heading content and sectioning content
The <section>, <article>, <nav> and <aside> elements are
called "sectioning elements". They cut a document into slices we
call "sections".

The HTML5 specification says that "each sectioning element potentially has a
heading and has also an outline associated".

<h1>...<h6> are called headings, and define the header of a section (whether
explicitly marked up using sectioning content elements, or implied by the
heading content itself). This means that:

1. <body>
2. <h1>Title of my document</h1>
3. ...
4. </body>
... defines the header of a section implicitly, while:

1. <body>
2. ...
3. <section>
4. <h1>Title of my section</h1>
5. ...
6. </section>
7. </body>

... defines the heading of the explicit section (its parent element <section>).

Use multiple headings of different rank with sectioning


content
The first element of a heading content in an element of sectioning content
represents the heading for that section
(the <section><h1>...</h1></section> in the above example).

Subsequent headings of equal or higher rank start new (implied) sections,


headings of lower rank start implied subsections that are part of the previous
one. In both cases, the element represents the heading of the implied section.

Let's clarify this by looking at some example code:

1. <body>
2. <section>
3. <h1>This H1 is the heading of an explicit section</h1>
4. ...
5. <h2>This H2 is a subheading, part of the same section
6. (lower rank)</h2>
7. ....
8. <h1>This H1 starts an implicit new section in the explicit
9. section (equal or higher rank)</h1>
10. ...
11. <h2>This is a H2 heading in the new section that has
12. just started</h2>
13. ...
14. </section>
15. </body>
The corresponding outline is:

In the above example, please note two things:

[Link] outline shows an "Untitled body" at the root of the hierarchy,


[Link] default size for the H1 and H2 is the same (!). Indeed, when we start
a <h1> inside a <section> the browser lowers its default size automatically,
as if a new hierarchy level has been added artificially. We will discuss this
further in the following sections, as we introduce some best practices.

Best practices when using sectioning


elements
Best practice 1: always add a
heading to explicit sectioning
content
It's always better - mainly for accessibility
reasons - to include a heading (a <h1>,
<h2>...<h6>) in each sectioning element
(<section>, <article>, <nav>, <aside>),
but also after the <body> element (called a
"sectioning root").

Here are some examples:


Good (heading in each explicit section):

1. <section>
2. <h1>Blog post of April 2015</h1>
3. ...
4. </section>

Good (heading in a <header> does not change anything)

1. <section>
2. <header>
3. <h1>Blog post of April 2015</h1>
4. <p>Posted by Michel Buffa...</p>
5. </header>
6. ...
7. </section>

Bad (there is no Hx after the <section> -> no heading):

1. <section>
2. <header>
3. <p class="article title">Blog post of April 2015</p>
4. <p>Posted by Michel Buffa...</p>
5. </header>
6. ...
7. </section>

The last example is bad for accessibility reasons. A screen reader that vocalizes
the page will just say "Entering section", while in the previous two good
examples it would say "entering section with heading Blog Posts of April 2015".
You can also check if your headings and sectioning elements are ok by using a
browser extension that displays the outline of the document (just search for
"html5 outliner" in your browser's extension search engine).

For the course screenshots we used the Google Chrome HTML5


outliner extension.

The outline of the last example looks like this:


Notice that <body> is also a sectioning element. It's called a "sectioning root",
and would also need a heading.

Final good version:

1. <body>
2. <h1>Example Blog</h1>
3. <section>
4. <header>
5. <h2>Blog post of April 2015</h2>
6. <p>Posted by Michel Buffa...</p>
7. </header>
8. <p>Content of the blog post...</p>
9. </section>
10. </body>

In red, the sectioning root (<body>) and the sectioning elements


(<section> here...), each have a heading.

To sum up:

Always use a heading element after a sectioning element, for


example <section><Hx>...</Hx>...</section>, and after <body>,
where x can be 1..6,
Or, use a <header> element, like
in <section><header><Hx>...</Hx>.....</header>...</section>
More about the <header> element

The <header> element is just a container. It is not taken into account


for defining new sections of a document nor does it affect the
hierarchy levels.

You can use heading elements <h1>...<h6> in a <header> but be careful if you
use more than one, as the rules explained in the previous part of the
course will apply and may generate implicit "sections" in the header.

This example has two headings in the <header>:

1. <section>
2. <header>
3. <h1>Some text in a h1 in a header of a section</h1>
4. <h2>This a h2 in the header...</h2>
5. </header>
6. </section>

Here is the resulting table of contents, notice the two subsections that appear,
one for the H1, one for the H2:

Indeed, HTML does not have a dedicated mechanism for marking up


subheadings, alternative titles or taglines.

If you do not want the subtitles to be included in the table of contents, just use
standard markup, for example <p> elements, as shown in the next example. Of
course, CSS rules can be applied to change colors, sizes, etc.

1. <header>
2. <h1>HTML 5.1 Nightly</h1>
3. <p>A vocabulary and associated APIs for HTML and XHTML</p>
4. <p>Editor's Draft 9 May 2013</p>
5. </header>
Best practice 2: try not to rely on implicit sectioning,
use <section>, <article>, etc. instead of
just <h1>...<h6>
The example below defines several implicit "sections" by using <Hx> directly (at
lines 7 and 9):

Ok version (no explicit sections everywhere):

1. <body>
2. <h4>Apples</h4>
3. <p>Apples are fruit.</p>
4. <section>
5. <h2>Taste</h2>
6. <p>They taste lovely.</p>
7. <h6>Sweet</h6>
8. <p>Red apples are sweeter than green ones.</p>
9. <h1>Color</h1>
10. <p>Apples come in various colors.</p>
11. </section>
12. </body>

Better version (best practice): this example can also be written like
this:

1. <body>
2. <h1>Apples</h1>
3. <p>Apples are fruit.</p>
4. <section>
5. <h2>Taste</h2>
6. <p>They taste lovely.</p>
7. <section>
8. <h3>Sweet</h3>
9. <p>Red apples are sweeter than green ones.</p>
10. </section>
11. </section>
12.<section>
13. <h2>Color</h2>
14. <p>Apples come in various colors.</p>
15. </section>
16. </body>

Both of the examples above are semantically identical and produce the same
outline:

The third example is also semantically identical, and might be easier to


maintain (e.g. if sections are often moved around in editing), as it uses only
H1s right after sectioning elements. Be sure to read the warning message in
the explanations at the end of this page.

1. <body>
2. <h1>Apples</h1>
3. <p>Apples are fruit.</p>
4. <section>
5. <h1>Taste</h1>
6. <p>They taste lovely.</p>
7. <section>
8. <h1>Sweet</h1>
9. <p>Red apples are sweeter than green ones.</p>
10. </section>
11. </section>
12. <section>
13. <h1>Color</h1>
14. <p>Apples come in various colors.</p>
15. </section>
16. </body>

This final example would need explicit CSS style rules to be rendered well in
legacy browsers. Legacy browsers without CSS support would render all the
headings as top-level headings (same default size).

IMPORTANT WARNING ABOUT THE THIRD EXAMPLE JUST ABOVE!

As stated in the article HTML5 Document Outline and on the W3C HTML Wiki,
these days it is not recommended that you follow the third example, as many
browsers do not implement the outline algorithm that "sort of renumbers" H1s
when located inside sectioning content.

Embedding a table of contents


Here we propose a small piece of JavaScript code you can use in your
documents to display an embedded table of contents. This code comes from
the source code of the the HTML5 Outliner (h5o) Google Chrome extension.

This example is a simple document, with a hyperlink that, once clicked,


displays the table of contents in an <aside> element in the
main <section>. Just look at the source code and copy/paste the link into
your own HTML documents.

Online example: [Link]


Extract of source code:

1. <body>
2. <h1>This is an example of embedded table of content</h1>
3. <section>
4. <header>
5. <h1>First section of the document (this is a h1)</h1>
6. This is a subheading...
7. </header>
8. <h2>First subsection of the first section (a h2)</h2>
9. <p>Blah Blah...</p>
10. </section>
11. <section>
12. <h1>Second section of the document (a h1)</h1>
13. <h2>First subsection (a h2)</h2>
14. </section>
15. <aside>
16. <h3>Table of contents</h3>
17. <a href="javascript:(function(){...})();"
18. title="TableDeMatiere">
19. Click here to display the table of contents!
20. </a>
21. </aside>
22. </body>

Best practice: Visualizing the table of contents is


useful for debugging the structure of your page, and
checking the presence of headings after sectioning
content
Indeed, tools that generate the table of contents are a good way to debug the
structure of your page. Is the hierarchy correct? Is it what I wanted when I
designed my page?

They are also useful for checking the presence of headings in each sectioning
content. If some headings are missing, the table of contents will display some
"untitled entries". Remember that having a heading after each sectioning
content is a good practice in terms of accessibility.

What about the <MAIN> element that is


in the HTML5 specification?
If you use <nav> / <header> / <footer> etc.
to structure your document, you can also
use <main> to identify the main content of
the document. Doing so provides a navigable
document structure for assistive technology
users as well as styling hooks for devs.

We have seen the different sectioning


elements of HTML5, so why didn't we talk
about the <main> element earlier in this part
of the course? Shouldn't
<main>...</main> be used in place of <div
class="main">...</div>?

A document has been written by the HTML5 working group, which details the
different use-cases for this
element: [Link]
usecases#Introduction
The <main> element has been supported by major browsers since 2013.

This element is subject to some constraints:

There must not be more than one <main> element in a document,


It must not be a descendent of an <article>,<aside>, <footer>,
<header>, or <nav> element.

And finally here are some examples (from the HTML5 specification) that mix
the <main> element with the other sectioning elements already seen in the
course:

1. <!-- other content -->


2. <main>
3. <h1>Skateboards</h1>
4. <p>The skateboard helps kids to get around.</p>
5. <article>
6. <h2>Longboards</h2>
7. <p>Longboards are a type of skateboard with a longer
8. wheelbase and larger, softer wheels.</p>
9. <p>... </p>
10. <p>... </p>
11. </article>
12. <article>
13. <h2>Electric Skateboards</h2>
14. <p>These no longer require the propelling of the skateboard by
means of the feet; rather an electric motor propels the board, fed by an
electric battery.</p>
15. <p>... </p>
16. <p>... </p>
17. </article>
18. </main>
19.
20. <!-- other content -->

Here is another example (also from the specification). Here the <main> element
contains a <nav> element consisting of links to subsections of the main
content:
1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>Graduation Ceremony Summer 2022</title>
5. </head>
6. <body>
7. <header>The Lawson Academy:
8. <nav>
9. <h2>Click these links to navigate...</h2>
10. <ul>
11. <li><a href="[Link]">Courses</a></li>
12. <li><a href="[Link]">Fees</a></li>
13. <li><a>Graduation</a></li>
14. </ul>
15. </nav>
16. </header>
17.<main>
18. <h1>Graduation</h1>
19. <nav>
20. <h2>Please choose:</h2>
21. <ul>
22. <li><a href="#ceremony">Ceremony</a></li>
23. <li><a href="#graduates">Graduates</a></li>
24. <li><a href="#awards">Awards</a></li>
25. </ul>
26. </nav>
27. <h2 id="ceremony">Ceremony</h2>
28. <p>Opening Procession</p>
29. <p>Speech by Valedictorian</p>
30. <p>Speech by Class President</p>
31. <p>Presentation of Diplomas</p>
32. <p>Closing Speech by Headmaster</p>
33. <h2 id="graduates">Graduates</h2>
34. <ul>
35. <li>Eileen Williams</li>
36. <li>Andy Maseyk</li>
37. <li>Blanca Sainz Garcia</li>
38. <li>Clara Faulkner</li>
39. <li>Gez Lemon</li>
40. <li>Eloisa Faulkner</li>
41. </ul>
42. <h2 id="awards">Awards</h2>
43. <ul>
44. <li>Clara Faulkner</li>
45. <li>Eloisa Faulkner</li>
46. <li>Blanca Sainz Garcia</li>
47. </ul>
48.</main>
49. <footer>Copyright 2012 [Link]</footer>
50. </body>
51. </html>

Best practice
For accessibility matters, a best practice is to split your page content into
"regions" defined by the five 5 elements
(aside, footer, header, main and nav) learned this week.

We recommend this article written by Steve Faulkner: "Easy content


organisation with HTML5" (24 September 2015). Steve explains in details how
to organize an HTML document into "regions" based on the semantic markup
elements we have seen so far during Week 1 of this course.

External resources:
[Link]
[Link]
[Link]

Let's fix the blog example, taking into


account best practices
Let's go back to our blog example and see what can be improved:
Do we have a heading after each sectioning element?
Did we use sectioning elements or implicit sections?
Can we embed a table of contents?
The blog example is online at: [Link] let's see what
the Google Chrome HTML5 extension shows:

Also note that in this example, we used H1s after each sectioning element, and
we still get a hierarchy, some H1s are inside an <article> that is in
a <section> (this corresponds to the third example given in the "heading and
sectioning elements" part of the course):

1. <section>
2. <header>
3. <h1>Blog posts for April 2012</h1>
4. </header>
5. <article>
6. <header>
7. <h1><a href="">Information about this example</a></h1>
8. This example is a modified version
of <a href="[Link]
blog/[Link]">[Link]
9. blog/[Link]</a>
10. </header>
11. ...
12. </article>
13. </section>

With this technique, parts of the document can be moved more easily, or
integrated inside an RSS stream, without the need to renumber the headings.

Beware that this technique will require you to use some CSS styling, and may
confuse some screen readers that do not yet take into account this way of
computing the heading hierarchy. A simple fix is to use an H1 right after
the <body> and use only H2...H6 inside <section>, <article>,
<nav> and <aside>.

Let's fix the missing heading


We need to add a heading in the <nav> element. This will both fix the outline of
the document by removing the untitled entry, and will also make screen
readers happy as they will better vocalize the structure of the page (it will say
"entering nav" followed by the vocalization of the heading content).
1. <nav>
2. <header>
3. <h1>Navigation menu</h1>
4. </header>
5. <ul>
6. <li><span>Blog</span></li>
7. <li><a href="">About</a></li>
8. <li><a href="">Contact</a></li>
9. </ul>
10. </nav>

Here is the fixed result:


A common remark from Web designers is: "we do not want a heading content
displayed systematically after a <nav>, or an <aside> element..."

BEST PRACTICE 1: In order to NOT display the heading content on


screen the recommended technique is described in this article
by Steve Faulkner. Do not
use display:none or visibility:hidden in your CSS stylesheet, as
in that case the heading content will never be vocalized by screen
readers, and more generally by assistive technologies.

As an illustration of the recommended technique, see this JSBin


version of the blog example that hides the <h2>Navigation
menu</h2> from the <nav>...</nav> element, using the CSS
technique explained in the above link.
BEST PRACTICE 2: it is not advised to include interactive content
(links, controls etc) that is hidden offscreen (it is in fact a
violation of the W3C WCAG 2.0 Guidelines). All interactive content
must have a visible focus indicator (and be on screen when
focused).

Embedding a table of contents and adding


a <main> element
In the previous section we saw how to embed a table of contents using some
JavaScript code borrowed from the Google Chrome HTML5 outliner extension.

Let's add this piece of code (we removed the JS details from this extract):

1. <aside>
2. <h1>
3. <a href="javascript:(function(){...});"
4. title="TableOfContents">
5. Click here to display the table of contents!
6. </a>
7. </h1>
8. </aside>

We also added a <main> element to identify the main content of the page
composed of the big section with all blog posts:

1. <main>
2. <section>
3. <header>
4. <h2>Blog posts for April 2012</h2>
5. </header>
6. ...
7. </main>

Use H1 as top level headings only, use H2...H6 in


sectioning content
As explained in the article HTML5 Document Outline and by the W3C HTML
Wiki , it is risky to use nested H1s, as browsers do not correctly implement the
"outline algorithm".
The blog example uses nested H1’s. if you check it with the W3C conformance
checker, it will issues a warning: "Consider using the h1 element as a top-level
heading only (all h1 elements are treated as top-level headings by many
screen readers and other tools)."

So, while this is just a warning, we do prefer to use H1s only as top level
elements, and replace the H1s we had after <section>, <article>,
<nav> and <aside> elements respectively by a H2s and H3s.

Extract from source code:

1. <nav>
2. <header>
3. <h2>Navigation menu</h2>
4. </header>
5. ...
6. </nav>

Final, Fixed example


Full online example on JS Bin
Examples of classic page layouts
Introduction
In this section, we will show some "classic" CSS layout techniques for designing
an HTML page that uses the new sectioning elements.

We embed examples from this very good post about "Positioning


content": [Link] This is
recommended reading as it details how to use the CSS float property to
layout a Web page.

The examples below are given "as is" to give you some hints. There are lots of
other possibilities on using CSS to position elements.

External resources about the float and clear CSS properties


[Link]
[Link]
[Link]

Example 1: a <section> on the left and


an <aside> on the right, using
the floatand width CSS properTIES
This example uses the following HTML structure:
1. <header>
2. <code>&lt;header&gt;</code>
3. </header>
4.
5. <section>
6. <code>&ltsection&gt; <br> float: left;</code>
7. </section>
8.
9. <aside>
10. <code>&lt;aside&gt; <br> float: right;</code>
11. </aside>
12.
13. <footer>
14. <code>&lt;footer&gt;</code>
15. </footer>

Here we use the CSS rule float:left for the <section> and the CSS
rule float:right for the <aside>. When an element floats, it goes out of the
normal flow of the HTML element. Then by default it floats to the edge of its
parent; and its size depends on the elements it contains. So, in order to fill the
whole horizontal space, we prefer here to "force the width" by setting the
CSS width property with a percentage. So we took width: 63% for
the <section> on the left and width:30% for the <aside> on the right.

You can look at the complete CSS code in the interactive example below (click
on the CSS or HTML text in the menu bar below, or click "edit on codepen" to
change the code and see the results):
Example from the live coding video, a slight adaptation of
the technique described above:
Also available online at JSBin.
Example 2: three sections centered, of equal size,
also using the float and widthCSS properties
Here we show how to make a 3 column layout using the CSS float property.

HTML code:

1. <header>
2. <code>&lt;header&gt;</code>
3. </header>
4.
5. <section>
6. <code>&lt;section&gt; <br> float: left;</code>
7. </section>
8.
9. <section>
10. <code>&lt;section&gt; <br> float: left;</code>
11. </section>
12.
13. <section>
14. <code>&lt;section&gt; <br> float: left;</code>
15. </section>
16.
17. <footer>
18. <code>&lt;footer&gt;</code>
19. </footer>

Instead of having one element with a float:left and one element with
a float:right property, we instead use float:left for all three of them, and
we give a width:30% CSS property value to each <section>. We also set a
small margin so that the colums have a gap between them.

Look at the CSS code of the example below:


Example 3: Same result using the CSS flex property
This example uses the CSS flex property to achieve a result similar to the one
shown in Example 2. We recommend this tutorial on using the FlexBox module
from CSS3, written by David Storey.

Other tutorial links have been posted in the forums of the first version of this
course: Lynda Tutorial (check with your local library for a free membership!),
a screencast from [Link], a Podcast and an article on using FlexBox in
real world deployments.
Example 4: another example written by a student
(ROyRey), that uses the flex property
This example also uses all the structuring elements we saw: main, article,
section, etc. It uses only the simplest parts of the FlexBox CSS module, so it
should be easy to understand, even for CSS beginners:

The <details> and <summary> element


s
Introduction
These elements have been introduced for displaying a foldable zone in an
HTML document.

In the screenshot below, taken from the W3C specification page, the text next
to the horizontal arrow is a <summary> element, and the text displayed when
we click on the summary part, is the <details> element. This is a sort of
"accordion" with foldable content.
The <details> element generates a simple widget to show/hide element
contents, optionally by clicking on its child <summary> element.

Here is an example of what can be done using these


elements: [Link]
And here is what is displayed after clicking on the small arrow-shaped icon to
the left of the summary:

Here is the code of this example:

1. <!DOCTYPE html>
2. <html>
3. <body>
4. <details>
5. <summary>
6. How to beat the boss...spoiler alert !
7. </summary>
8. <p> Just aim to the red spots near his eyes</p>
9. <p>Keep shooting at these spots until the eyes open, then hit quickly both
eyes with your laser beam.</p>
10. </details>
11. </body>
12. </html>

The <summary>...</summary> is inside a <details>...</details> element.


By clicking on the icon at the left of the summary, the content of
the <details> value is displayed/hidden.
<details> blocks can be embedded inside one another, like in this
example: [Link]

Step 1: all folded:

Step 2: click on top level summary icon, the first "hidden" part appears...

Step3: click on embedded summary icon inside the part that has been
previously unfolded:

Source code of this example, see the summary/details inside another one:

1. <details>
2. <summary>
3. How to beat the boss...spoiler alert !
4. </summary>
5. <p> Just aim to the red spots near his eyes</p>
6. <p>Keep shooting at these spots until the eyes open, then hit quickly both
eyes with your laser beam.</p>
7. <details>
8. <summary>
9. Bonus and spoiler No 2: get a new weapon by cutting the tail of the
boss.
10. </summary>
11. <p>Before finishing him, try to cut his trail, you will get a new
weapon</p>
12. <p>Just try to stay behind him as long as you can, hitting his tail
with your melee weapon, after a few hits the trail will fall and you will get a
new bonus weapon, then finish the boss.</p>
13. </details>
14. </details>

CSS pseudo classes for styling summary icons


There are CSS pseudo classes to style this icon when it is in the open or closed
state. Support for these is still unofficial (works on Google Chrome).

Examples adapted from: [Link]


[Link] (trial available in French language).

Example1: [Link]

The color and background of the icon on the left are specified by the following
CSS rule, which uses the pseudo class ::-webkit-details-marker

In this example: red arrow, white background.

1. summary::-webkit-details-marker {
2. color:#FF0000;
3. background:#FFFFFF;
4. }

Once opened, the selector details[open] can style the icon


when <details> is unfolded. In this example: blue arrow, turquoise
background. Here is the corresponding CSS rule:

1. details[open] summary::-webkit-details-marker {
2. color:#0000FF;
3. background:#00FFFF;
4. }

It is also possible to change the icon itself using the CSS pseudo class :after

Example 2: [Link]

CSS rules used in this example:

Use a "+" shaped icon, pink, bold, etc... :

1. summary:after {
2. content: "+";
3. color: #FF00FF;
4. float: left;
5. font-size: 1.5em;
6. font-weight: bold;
7. margin: -5px 5px 0 0;
8. padding: 0;
9. text-align: center;
10. width: 20px;
11. }

Use a "-" shaped icon, white, when details are displayed:

1. details[open] summary:after {
2. content: "-";
3. color: #FFFFFF
4. }

Current support
Support as of October 2015:

You will find an up-to-date version of this table


at: [Link]
As you will have noticed, Internet Explorer (Edge support is partial) still does
not support <details>..<summary>. In the next section of this course, you will
see how to add retro-compatibility to a Web site that uses these elements, so
that they will be shown correctly even on browsers that do not support them.

Here is a version at JsBin of the last example, that includes a polyfill that
makes it work on nearly all browsers: IE, Microsoft Edge, which still do not
support summary/details as of May 2016. This version has been written
by jotlash, a student from the MOOC, after reading the next lesson about
polyfills.

How to add retro-compatibility: an


example
Introduction
A polyfill is a piece of JavaScript code you include in your HTML page, that will
emulate HTML5 features not yet implemented in browsers. Usually a polyfill
starts emulating a feature only when native support is not detected.

Do you know where the “polyfill” term is coming from? It was coined by
Remy Sharp, a British Web programmer who had been using a brand of
resin to fill holes in masonry.

You will find a list of polyfills on these Web


sites: [Link] or [Link] Or just do a search using
the keyword 'polyfill' with the name of the feature.

Some libraries, such as [Link] are useful for detecting features


supported by a given browser. It comes packed with some general purpose
polyfills (such as HTML5 shim for old IEs), and the wiki page of its github
repository comes with a huge list of available polyfills that can be loaded on
demand only when the browser is not supporting a native feature.

We recommend to watch these videos about polyfills and modernizr, if you


want to go deeper with polyfills (it's a [Link] tutorial):
How to use Modernizr

Example with <details> and <summary>


<details> and <summary> are still not supported by all browsers. How can we
use them in a Web site? The answer is: use a polyfill!
Version 1: no polyfill
We wrote a small contact manager application (just the layout - it does not
really work), composed of a form and a table for displaying contacts. The form
is in a <details>...<summary> elements.

Online version: [Link]

Result on Google Chrome (which does support summary/details):


On Internet Explorer the form is always visible,
as <summary> and <details> are not supported yet:
Version 2: with a light polyfill
Online version (try it now on Internet Explorer or Edge). It works as expected as
summary/details are at this time emulated by JavaScript
code): [Link]

Explanations: we used a light polyfill as indicated by [Link]


([Link]

The link points to the JavaScript code you must include in your Web page. But
in the comments of the polyfill page, you will find an online example at
[Link]:
You can follow the link to see a running example, or directly copy and paste the
code from the main page, then include it in your Web page using
the <script> element:

Either use <script src="[Link]"> (in this case put the polyfill in a
file [Link]>) or if you want to try it on [Link], just copy it into the
jsBin script tab, or include it directly between <script>...</script>. This is
what we did:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="UTF-8">
5. <title>Contact manager</title>
6. <script>
7. (function(e,t){function r(e){var t=null;... // POLYFILL CODE HERE!
8. ...
9. </script>
10. </head>
11. ...

Now the example works on browsers that do no support summary/details! This


is a screenshot taken with an old version of FireFox, that did not support these
elements:
Here is another example with a more complicated case (nested
summary/details), that shows that this polyfill does not handle 100% perfectly
nested elements.

Version 3: with a polyfill that is 100% accessible


The summary / details elements have also been designed to be accessible,
thus usable with a keyboard only. This example sent to me by Steve Faulkner is
99% correct in terms of functionality (small problem of alignment with nested
summary/details) and accessibility! It's the recommended choice!

Original example of use of the polyfill:


The contact manager form with this polyfill:

The <time> element


INTRODUCTION
The <time> element is useful for marking a time or
a duration in a document.

It provides both a human readable part (the part


between <time> and </time>) and a machine
readable part contained within a datetimeattribute. Dates are expressed
as YYYY-MM-DD.

The machine readable part adds semantics that can be used by search engines
for indexing, by browsers or by browser extensions, or by JavaScript code.
Useful scenarios include generating alerts for birthdays, automatically adding
dates or events that contain <time> elements in a calendar, etc.

External resources:

W3C specification: [Link]


time-element
Interesting article by Bruce Lawson: [Link]
of-time/

Example:

1. We open at <time>10:00</time> every morning.


2. I have a meeting the <time datetime="2012-02-
14">Monday 14/02/2012.</time>.
3. Blog posts from the year <time datetime="2012">2012</time>.
4. Archives, blog posts for <time datetime="2012-04">April 2012</time>
5. This recipe was published by Michel the <time datetime="2012-04-
16">April 16,2012</time>.

THE DATETIME ATTRIBUTE


The datetime attribute can be used for indicating a date/time or a duration.

Date/time values

Supports different specifications of time such as "a year", "a month in a year",
"a week in a year", "a time", etc...

Here are some examples:

Different syntaxes of the datetime attribute

datetime attribute values Interpretation


<time
The year 1905
datetime="1905">

<time datetime="1905-
November 1905
11">

<time datetime="11-
November 13th (any year)
13">

<time datetime="1905-
Week 21 from year 1905
W21">

<time datetime="1905-
November 13th year 1905, time = 9:00
11-13 09:00">

<time datetime="1905- Same as previous example, both syntaxes are supported,


11-13T09:00"> with and without the "T" between date and time.

<time
9:00 in the morning, GMT
datetime="09:00Z">

<time datetime="09:00-
9:00 in the morning, GMT minus 5 hours
05">

<time
9:00 in the morning, GMT plus 5 hours 45 minutes, (for
datetime="09:00+05:45"
example, Nepal is 5:45 ahead of GMT)
>

Duration values
Duration values use the prefix “P” for “period” as in <time
datetime="P4D"> (period = four days)...
So you start the attribute string value with a "P",
followed by a duration value that ends with
another letter indicating the unit used: "D" for
"days", “H” for hours, “M” for minutes and “S”
for seconds.

You can separate the different elements "P",


value and unit with spaces, but this is optional.
So <time datetime="P4D"> is a duration of 4
days, as is <time datetime="P 4 D">.

Using a “T” after the “P” marker allows you to indicate a more accurate
duration time: <time datetime="PT4H 6M 12.55S"> is a duration of 4 hours, 6
minutes and 12.55 seconds.

Alternatively, you could use also a duration time component.

From Bruce Lawson's article : "Whichever you choose, it’s represented


internally as a number of seconds. Because of this, you can’t specify a duration
in terms of months, because a month isn’t a precise number of seconds; a
month can last from 28 to 31 days. Similarly, a year isn’t a precise number of
seconds; it’s 12 months and February sometimes has an extra day.

You still can’t represent dates before the Christian era, as years can’t be
negative. Neither can you indicate date ranges. To mark up From “21/02/2012
to 25/02/2012″, use two separate <time> elements."

Examples:

1. <h2>Recipe:</h2>
2. <ul>
3. <li> Preparation time: <time datetime="PT30M">30 minutes</time> </li>
4. <li> Cooking time: <time datetime="PT10M">10 minutes</time> </li>
5. </ul>

<TIME> ELEMENT WITH NO ATTRIBUTES


Used without attributes, the value between the opening <time> and
closing </time> should follow the syntax given by the specification so that
machines can understand it (same syntax as the one presented for
the datetime attribute in the previous section). However it is recommended to
use a datetime attribute, as it gives more freedom in the way you can display
the date/time/duration in a human-readable form.

The <mark> element

The HTML <mark> tag is used for indicating text as marked or highlighted for
reference purposes, due to its relevance in another context.

Some use cases:

Display search results with search strings highlighted in the results.


Highlight important parts of a text, such as "quoting parts", etc.
Replace <strong> and <em> with <mark> when suitable.

Example1: [Link]

Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset=utf-8 />
5. <title>JS Bin</title>
6. </head>
7. <body>
8. <p>Project is due in <mark>.zip format</mark> next monday.</p>
9. </body>
10. </html>

Example 2:
Source code:

1. <body>
2. <pre>
3. <code><mark>var</mark> i = 3;</code>
4. </pre>
5. <p>The var keyword is used to declare a variable in JavaScript.</p>
6. </body>

CHANGE THE DEFAULT STYLE OF


THE <MARK> ELEMENT
If you don't like the default yellow background, you may use CSS to change the
style of the <mark> element:

For example:

Can be obtained with this CSS rule:

1. mark {
2. background-color: green;
3. color: yellow;
4. }

The new HTML5 DOWNLOAD attribute


for <A HREF>
External resources:
The W3C specification about "downloading resources"
Presentation by Eric Bilderman (a Chrome developer)
THE Old way to download files using HTML and HTTP
Everyone knows the classic way to make hyperlinks, using <a
href="...">some text</a>. What happens when you click on the hyperlink
depends on the MIME type received by the browser. If you link to a file the
browser knows how to render (an html page, a gif, jpg, or png image, etc.)
there is a good chance that the MIME type received by the browser will be
something like this:
1. Content-type: text/html, text/plain, image/gif, image/jpg, etc.

For example, HTML code such as this:

1. <a href="[Link]">
1. please right click this link to download
2. the [Link] picture</a>

...will ask the remote HTTP server to send back the [Link] file. The browser
will receive in the response HTTP header from the server (and by default the
browser will display the image in a new tab):

1. ...
2. Content-type: image/jpg
3. ...

However, if the link points to some PHP code, Java servlet code, or any kind of
script/application on the server side, this remote server code can send in its
HTTP response a Content-type that may force the browser to download the
image instead of rendering it.

It may also propose a name for the file to be downloaded that may be different
from the one that appears in the URL of the href attribute. This can be done by
generating, in addition to the Content-type line in the response HTTP header,
a Content-Disposition line that looks like this:

1. Content-Disposition: attachment; filename="[Link]";

Here are some extracts from a Java Servlet that generate a zip file and forces
the browser to propose downloading it using a specified name:

1. protected void doGet(HttpServletRequest request, HttpServletRespons


e response)
2. throws ServletException, IOException {
3. try {
4. // Build the zip file
5. String path = getServletContext().getRealPath("data");
6. File directory = new File(path);
7. String[] files = [Link]();
8. if (files != null && [Link] > 0) {
9. byte[] zip = zipFiles(directory, files);
10. ServletOutputStream sos = [Link]();
11. // generate a HTTP response that forces the download
12. [Link]("application/zip");
13. [Link]("Content-Disposition",
14. "attachment; filename=\"[Link]\"");
15. [Link](zip); [Link]();
16. }
17. } catch (Exception e) {
18. [Link]();
19. }
20. }

The above example will cause the browser that


invoked this server-side code to start the download of a file named "[Link]".

New way to download a file using an arbitrary name:


the download attribute
HTML5 proposes the use of a new attribute named download to download
resources rather than navigating to them. The example below shows how to
trigger the download of an image by the browser (instead of rendering it, which
is the default behavior) with a name different from the name of the resource.
1. <ahref="//[Link]/assets/courseware/v1/
aa323a9c005768df2c1e674c31002efb/asset-
v1:W3Cx+HTML5.1x+3T2016+type@asset+block/[Link]"
2. download="[Link]">
3. download a picture of Michel Buffa
4. </a>

Here is the result of this link (just click on it): download a picture of Michel
Buffa. NOTE from May 2016: this stopped working with the new version of edX
as now the different assets (images, videos) are hosted on a different domain
than [Link]. See the warning further in this page, about cross domain
restrictions.

This will indeed force the download of an image with a filename different from
its original filename on the server side. Here is a screen capture of the Web
browser while downloading the picture. We can see in the status bar the name
of the link (the image is "[Link]") and the downloaded file is
"[Link]":

Note: this attribute is not supported by IE or Safari yet, as of May 2016.

See [Link] for an up-to-date status.

WARNING: since 2015, and for security reasons, the image should be
located on the same domain as the HTML page that contains the
link (using a relative URL works well, for example, but linking a page on
another domain will not work - it will keep its original name).
Interesting applications: serverless download

Serverless download demo (by [Link])


This demo shows the use of the download attribute together with the HTML5
File, FileSystem and FileWriter APIs (to be studied later in this course) for
generating on-the-fly content from JavaScript code, and proposing downloading
it to a file.

We won't detail this demo here, but take a look if you are curious to see
what can be done with this new download attribute. As the FileWriter and
FileSystem APIs are still supported only by Google Chrome (other browsers
need polyfills), you will need Google Chrome to try it.

We have also put the simplified source code of this demo on [Link] for you
to play with: [Link] the original demo by [Link]
is at [Link]
The HTML5 TRANSLATE ATTRIBUTE
Introduction
HTML5 gives us a new translate attribute. This attribute is used to limit the
impact of translation tools such as Google Translate by prohibiting the
translation of certain content. In many cases some parts of a document should
not be translated.

Use cases include:

HTML pages that contain source code: you would certainly not like to see the
Java or PHP or whatever programming language parts of your page translated
into another spoken language!
Video game Web sites that propose cheat codes; the codes do not have to be
translated,
Street names, author names in an "about" page must not be translated,
etc.
Both Google translate and Microsoft online translation services already offer
the ability to prevent translation of content by adding markup to your content,
although they do it in (multiple) different ways. Hopefully, the new attribute will
help significantly by providing a standard approach.

Principle: give hints to translating tools


The W3C specification about the translate attribute tells us that
"The translate attribute is an enumerated attribute that is used to specify
whether an element's attribute values and the values of its Text node children
are to be translated when the page is localized, or whether to leave them
unchanged.

The attribute's keywords are the empty string, yes, and no. The empty string
and the yes keyword map to the yesstate. The no keyword maps to the no
state. In addition, there is a third state, the inherit state, which is the missing
value default (and the invalid value default)."

Example illustrating how to specify parts of an HTML


element that should not be translated:
1. <span translate="no" class="author">Michel Ham</span>

In the above example, a <span> element defines an author (of a blog, for
example) who is named Michel Ham. However, his family name is the same as
pork and would be translated to "Michel Jambon" in French, or Michel Jamón in
Spanish...

Using the translate="no" attribute should prevent this behavior...

1. <span translate="no" class="author">Michel Ham</span> is a professor


2. from the University of Nice,France.

Will be correctly translated into French by:

1. "Michel Ham est un professeur de l'Université de Nice, France."

...where all of the end of the sentence has been translated except the author's
name.
Inheritance between elements
When you define an element as not being translatable, its children inherit this
behavior and are themselves not translatable. The reverse is also true.
1. <p translate="no">This is a text in a paragraph element, that should not be
translated: the p element has a translate="no" attribute.<span> This part that
is in a span element embedded within the paragraph. It does not have a
translate attribute but inherits the translation-mode of the p and will not be
translated too</span>. This is the end of the paragraph...</ p>

To go further: External resources:


The W3C specification about the translate attribute,
Interesting blog post about Google translate, Microsoft translator and the
translate attribute
Using HTML's translate attribute

Microdata
Introduction
There are 3 ways to provide machine-readable content embedded in a classical
Web document: HTML+RDFa, microformats and microdata. In this section, we
will focus on microdata.

Adding microdata to Web pages helps search engines to better understand the
pages' content, their topics, etc. The main purpose of microdata is Search
Engine Optimization.

This information is not visible to humans: it is pure semantic information.


Popular kinds of microdata are events, a person's profile, the description of an
organization, the details of a recipe, a product description, a geographical
location, etc.

Quick example of microdata that describes a person:


1. <section itemscope itemtype="[Link]
2. <h1>Contact Information</h1>
3. <dl>
4. <dt>Name</dt>
5. <dd itemprop="name">Michel Buffa</dd>
6. <dt>Position</dt>
7. <dd><span itemprop="jobTitle">
8. Professor/Researcher/Scientist</span> for
9. <span itemprop="affiliation">
10. University of Côte d'Azur, France
11. </span>
12. </dd>
13. </dl>
14. <!-- SURFACE ADDRESS GOES HERE -->
15. <h1>My different online public accounts</h1>
16. <ul>
17. <li><a href="[Link]
18. itemprop="url">Twitter profile</a></li>
19. <li><a href="[Link]
20. itemprop="url">Michel Buffa's blog</a></li>
21. </ul>
22. </section>

We can also add another embedded data item in the middle, such as the
person's address:

1. ...
2. </dl>
3. <!-- SURFACE ADDRESS GOES HERE -->
4. <dd itemprop="address" itemscope
5. itemtype="[Link]
6. <span itemprop="streetAddress">10 promenade des anglais</span><br>
7. <span itemprop="addressLocality">Nice</span>,
8. <span itemprop="addressRegion">Alpes maritimes, France</span>
9. <span itemprop="postalCode">06410</span><br>
10. <span itemprop="addressCountry" itemscope
11. itemtype="[Link]
12. <span itemprop="name">France</span>
13. </span>
14. </dd>
15. <h1>My different online public accounts</h1>
16. ...
In the following sections, we will look more closely
at the itemprop, itemscope and itemtype attributes.

Data that can be processed, organized, structured,


or presented in a given context
Different use cases:
The browser, or a browser extension, may interpret the last example as an
address and may propose to send it to a map application,
A Web crawler may interpret this as an address and display it in its responses
using a dedicated presentation layout,
Some JavaScript code in the page can access this data,
With other types of microdata, for events, for example, the browser may pop
up a calendar application, etc.

Note: For advanced users, Microdata is very similar to microformats, which use
HTML classes, or to RDFa, which doesn’t validate in HTML4 or HTML5. Because
RDFa was considered to be too hard for authors to write (Google has conducted
research that finds that authors make 30% more mistakes with RDFa than with
other formats), microdata is HTML5's answer to the need to embed semantics
into html documents.

External resources
W3C's HTML Microdata Working Group Note
Very good Microdata paper from code{4}lib journal
Microdata and the microdata DOM API, article from [Link]
Interesting blog post about Microdata by one sencha developer
Chapter from Mark Pilgrim's book about microdata, very detailed introduction
about semantic metadata in general, contains full examples with explanations
about how to describe a Person, etc.
The reference about popular HTML5 microdata
vocabularies: [Link] (do not forget to visit the full list of
vocabularies), see also the [Link] blog for news and announcements
Testing tools
Google Rich Snippets and
Structured Data test tool
One of the most popular resources for testing
microdata (as well as microformats and RDFa) is the
Google page about rich snippets and structured data.
This page contains a link to a structured data testing
tool that you can use to see how Google recognizes
the semantic data you embed in your HTML code.
Testing a real interactive example with an "about page" for
Michel Buffa
Let's have a look now at a (small) example of an about page. It renders as a
very simple paragraph that explains who Michel Buffa is... But we embedded
Microdata, so it's interesting to see how a search engine sees it, and how it
may produce "augmented search results".

Online example at JsBin

Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset=utf-8 />
5. <title>Michel Buffa</title>
6. </head>
7. <body>
8. <div itemscope itemtype="[Link]
9. My name is <span itemprop="name">Michel Buffa</span>,
10. And I'm
a <span itemprop="jobTitle">professor/researcher</span> at
11. <a href="[Link] itemprop="affiliation">I3S
12. Laboratory</a> in the south of France, near the city of Nice. My
13. email
14. is : <span itemprop="email">micbuffa@[Link]</span>.
15. I live in the city of
16. <span itemprop="address" itemscope
17. itemtype="[Link]
18. <span itemprop="addressLocality">Biot</span>, in a region
named
19. <span itemprop="addressRegion">Alpes Maritimes</span>
20. </span>
21. </div>
22. </body>
23. </html>

Rendering of the page in a browser:

Here is what Google sees of the page. We just entered its URL
([Link] in the the Google page about rich snippets and
structured data:

Note that the address is a fully featured embedded object in the Person's
description.

Live Microdata
The Live Microdata Web site is a bit similar to the previous one except that it
shows the extracted metadata as JSON objects:
And the JSON view of the microdata:
Implementing microdata in your page /
the itemscope, itemtype and itempro
p attributes
Basic steps
Adding microdata to an HTML page is a really simple task and requires only
three attributes: itemscope, itemtype and itemprop.
1 - Define a container element by adding
an itemscope attribute
First, you need to add an itemscope attribute to an HTML element. This will
define the "global object" for which we will define properties. This element can
be of different types that we will describe later, but for now let us keep looking
at the same example we used in previous sections:
1. <section itemscope itemtype="[Link]
2. ...
3. </section>

We will look at the itemtype attribute later. Now that we have defined a global
wrapper object/element (a Person in this case), we can add properties inside
this element to define the first name, last name, etc.

2 - Specify the vocabulary used for your microdata with


the itemtype attribute of the container element
HTML5 proposes semantic elements for representing sections, articles,
headers, etc, but it does not propose any specific elements or attributes to
describe an address, a product, a person, etc.

We need a special vocabulary to represent a person or a physical address. With


microdata you can define your own vocabulary or better, reuse one of the
existing popular vocabularies, such as these: [Link]

Microdata works with properties defined as name/value pairs. The names are
defined in the corresponding vocabulary. For example, the vocabulary for
representing a Person, available at [Link] defines a set of
property names, as illustrated by the following screenshot:

As you can see in this small extract from the vocabulary (also called a
"schema"), a Person can have a name (some text), an Address (the type is
defined by another vocabulary named PostalAddress), an affiliation (defined by
another vocabulary named Organization) and so on.
We notice that one property, such as the address of a Person, may use another
vocabulary. Yes, a vocabulary may link to another vocabulary! There is also
inheritance between vocabularies! The above screenshot shows that the
Person vocabulary inherits from a Thing vocabulary, and the five first
properties of the table come from this vocabulary that describes things.

If you are a developer and if you are familiar with object oriented
programming, think of properties as class attributes and think of vocabularies
as classes.

Vocabularies are meant to be shared

If one of the existing vocabularies available at


the [Link] Web site fits your needs, you
should reuse it, as the most popular
vocabularies are becoming de facto standards
and will be taken into account by Web
crawlers, browsers, and browser extensions.

However, if you do not find a vocabulary


corresponding to your needs, keep in mind
that anyone can define a microdata vocabulary and start embedding custom
properties in their own Web pages. You need to define a namespace and put a
description of your vocabulary in a Web page that has the name of your
vocabulary. For example, if you own [Link], you may define a
vocabulary for describing Mech Warrior robots at
[Link] in the same way
as [Link] describes the properties of a person.

3 - Add properties using the itemprop attribute in HTML


elements inside the container
Basics:

Now that you have defined a container element, you may add properties to the
HTML inside:

1. <section itemscope itemtype="[Link]


2. <h1>Contact Information</h1>
3. <dl>
4. <dt>Name</dt>
5. <dd itemprop="name">Michel Buffa</dd>
6. <dt>Position</dt>
7. <dd><span itemprop="jobTitle">
8. Professor/Researcher/Scientist
9. </span> for
10. <span itemprop="affiliation">University of Nice,
11. France
12. </span>
13. </dd>
14. </dl>
15. <h1>My different online public accounts</h1>
16. <ul>
17. <li><a href="[Link]
18. itemprop="url">Twitter profile</a></li>
19. <li><a href="[Link]
20. itemprop="url">Michel Buffa's blog</a></li>
21. </ul>
22. </section>

In this example the container is a <section> that corresponds to a Person (we


have one clue here: the name of the vocabulary given by
the itemtype attribute), and each property defined inside this section is
identified by the value of the itemprop attribute of sub-elements.

The line:

1. <dd itemprop="name">Michel Buffa</dd>

...defines a property called "name" that has a value of "Michel Buffa" (the text
value between the opening and closing tags of the <dd> element)

Nesting microdata items:

As we saw with the Person/Address example at the beginning of this chapter, it


is possible to nest microdata items inside one another.

Give an element inside a microdata container its own itemscope attribute with
the recommended itemtypeattribute for indicating the name of the vocabulary
used by the nested microdata.

Again, look at the Person/Address example:

1. ...
2. </dl>
3. <!-- SURFACE ADDRESS GOES HERE -->
4. <dd itemprop="address" itemscope
5. itemtype="[Link]
6. <span itemprop="streetAddress">10 promenade des anglais</span><br>
7. <span itemprop="addressLocality">Nice</span>,
8. <span itemprop="addressRegion">Alpes maritimes, France</span>
9. <span itemprop="postalCode">06410</span><br>
10. <span itemprop="addressCountry" itemscope
11. itemtype="[Link]
12. <span itemprop="name">France</span>
13. </span>
14. </dd>
15. <h1>My different online public accounts</h1>
16. ...

The properties at lines 8-12 refer to the address nested microdata (they are
defined in the Address vocabulary, not the Person vocabulary), and "France"
(line 14) is a property that refers to the Country vocabulary.

Several properties with the same name but different values

It is possible to use the same property name several times in one microdata
object, but with different values:

1. ...
2. <h1>My different online public accounts</h1>
3. <ul>
4. <li><a href="[Link] itemprop="url">Twitter
5. profile</a></li>
6. <li><a href="[Link] itemprop="url">Michel
7. Buffa's blog</a></li>
8. </ul>

This will define the fact that Michel Buffa has two online accounts, and the two
properties have the name url, each with its own value.

It is possible to set more than one property at once, with the same
value
Here are some microdata that represent a song. In this example, at line 5 we
set two different properties: genre and keywords with the same value (see
the MusicRecording schema definition at [Link]

1. <div itemscope itemtype="[Link]


2. <h2>The song I just published</h2>
3. <ul>
4. <li>Name: <span itemprop="name">Please buy me on itunes, I need
money!</span></li>
5. <li>Band: <span itemprop="genre keywords">Punk, Ska</span></li>
6. </ul>
7. </div>

And so on...

Now let's see what elements are compatible with the itemprop attribute and
where the values of the properties are located, depending on each element
type.

The HTML elements compatible with


the itemprop attribute
Extract from : [Link]
overview/

If the itemprop attribute appears on a:

Elements that can be associated with microdata

HTML5 elements microdata value associated

<a> , <area> , <audi


o> , <embed> , <ifra
The data is the url in the element's href , src , or data attribute, as
me> ,
appropriate. For example, an image element inside a container of
<img> , <link> , <ob
personal contact information can be recognized as that person's
ject> , <source> ,
photo and downloaded accordingly.
or <video>
element

<time> element The data is the time in the element's datetime attribute. This lets
you, for example, just say "last week" in your text content but
still indicate exact date and time.

The data is whatever appears in the content attribute of


<meta> element the <meta> element. This is used when you need to include
some data that isn't actually in the text of your page.

anything else The data is whatever is in the text of the element.

For example, the value of a property defined in an <img> element will be the
value of the src attribute:
1. <img itemprop="image" src="[Link]" alt="A great
professor">

Or for a <time>, it will be the value of the datetime attribute:

1. <time itemprop="birthday" datetime="1965-04-16">April 16,


1965</time>

Or for an <a> element, the value will be the value of the href attribute:

1. <a href="[Link] itemprop="url">profile</a>

Microdata Tools
There are many tools available (most are free) that you can use for generating,
visualizing and debugging microdata. We list some of them in this page, but
feel free to share the tools you find / like in the forums.

Microdata generators
There are many free tools you can use to automatically generate microdata for
describing persons, restaurants, movies, products, organizations, etc. such as:
[Link]
[Link]
[Link]
Search for "microdata generators" using your favorite search engine, and you
will find lots!

Example with the first tool in the list:


Result:
Microdata visualization
[Link]
Browser extensions
There are many available, for all modern browsers. We have compiled an
exhaustive list of extensions (and online tools too) for the students from a
previous version of this course.

Examples of well structured pages with


Microdata
Here, we propose a few links to Web pages that were created by students of
previous editions of this course (from W3C's W3DevCampus classrooms).
The students had to create a Web page to introduce themselves, with some
information including: name, job, employer, location, etc., and of course enrich
the page with microdata. They also had to follow the best practices concerning
the new structural elements, headings, etc.

Click on these pages and look at the source code...

First example
Visit the online page: [Link]

Structure:

Microdata:
Second example
Visit the online page: [Link]
Week 2
The <video> element
Introduction
The <video> element of HTML5 is one of the two "Flash killers" (the other being
the <canvas> element). It was designed to replace horrible things like
embedded Flash objects that we used to encounter not so long ago.

Before HTML5, how did we embed videos in a web


page?
Answer: like this!
1. <object width="425" height="344">
2. <param name="movie"
3. value="[Link]
4. </param>
5. <param name="allowFullScreen" value="true"></param>
6. <param name="allowscriptaccess" value="always"></param>
7. <embed src="[Link]
8. type="application/x-shockwave-flash"
9. allowscriptaccess="always" allowfullscreen="true"
10. width="425" height="344">
11. </embed>
12. </object>

Indeed, until two years ago, this was the only way to embed a YouTube video
(fortunately, YouTube has changed that now). Furthermore, embedding a Flash
player made it impossible to watch videos on some mobile platforms
(especially Apple devices).

SINCE HTML5:
The new way of doing things is a lot better... (please open this live example at
JS Bin).

The source code of this example shows the typical usage of


the <video> element:
1. <video width="320" height="240" controls="controls">
2. <source src="movie.mp4" type="video/mp4" />
3. <source src="[Link]" type="video/ogg" />
4. Your browser does not support the <video> element.
5. </video>

Please note that:

The controls attribute indicates that a control panel with


play/stop/volume/progress widgets should be displayed;
Usually the browser will use the first format it recognizes (in this case, the
browser checks whether mp4 is supported, and if not, it will check for
the ogg format, and so on). Some browsers may use a different heuristic and
choose a "preferred" format.
The <video> element is a DOM member, so CSS styling can be applied, as
well as manipulation using the DOM API.

You will learn more about the different attributes of the <video> element later
on in the course...

Current BROWSER support FOR


the <VIDEO> ELEMENT
The <video> element has been supported by all major browsers since 2012.
Here is the compatibility table as of June 2015:
To get an updated version, see the support table from Can I Use...?

As you can see, with the exception of Opera mini and older versions of Internet
Explorer, nearly all browsers support the <video> element. Popular streaming
Web sites like YouTube and Dailymotion also support this element and
automatically switch from the Flash player to the HTML5 version, based on your
browser (whether or not it is mobile, supports Flash, etc.).

Restriction: you cannot embed a YouTube or


DailyMotion video using the <video>element
Help! <video src="my youtube video URL"></video> does not work!
BEWARE: you cannot directly embed videos from most of the popular social
Web sites such as YouTube, Dailymotion, Vimeo, etc. For commercial reasons,
and because advertising is automatically added to the videos, these Web sites
do not allow "regular" embedding of their videos.
While they use HTML5 to render their videos, these hosting sites (YouTube,
etc.) use rather complex techniques in order to prevent you from using them
with the <video> element. Instead, you often need to embed an <iframe> that
will render the HTML5 videos in your Web site, and of course, the advertising
that comes along with them.
Usually you have an "embed" button close to the videos that prompts you with
some HTML code that you can copy and paste for embedding.

An example using YouTube:

Here is the HTML code you need to copy and paste in order to embed a video
(in this case, a tutorial that tells you how to embed a YouTube video):

1. <iframe width="560" height="315"src="[Link]


embed/ZH1XOsv8Oyo" frameborder="0"allowfullscreen></iframe>

The YouTube video embedded in this page by the above code: it's HTML5 but
it's not a <video> element directly inserted in the HTML of this page, it's
an <iframe>:

CODEC SUPPORT
This is one of the main issues that the industry has had to solve during the last
few years: codec support was not the same from one browser to another, for
commercial/cost reasons. For example, Firefox only supported the ogg/oggm
format from 2010 to 2013. It did not natively support mp3/mp4 encoding for
audio/video, while Internet Explorer only supported the H.264 encoding. Since
2012, things have changed as browsers have been updated. In order to check
codec support, the best way is to try it yourself: just visit Video Format Support
from Microsoft IE (test works for all browsers).
You might also check external resources, such as this page from the Mozilla
Developer Network, but beware, it is very difficult to maintain such lists.

The recommended codec that works on most browsers, as of 2015:


H264/mp4
However, the recommended way of doing things, assuming you want to target
the largest possible audience with a large variety of browsers, is to encode
your videos in the major supported formats.

External resources
One excellent reference is in the online documentation of the Opera browser.
At the bottom of the page, you will find important references and links to many
relevant examples.
Check out this article about the state of HTML5 video as well, a must-read for
all of you!
Another very good reference is from Apple's developer site.
About DRM, and some HTML5 video features to come in HTML 5.1: "HTML5
Video in the Open Web Platform" is a talk by Philippe le Hegaret from W3C
(video + slides) (in April 2013).

The <audio> element


Introduction
HTML5 audio is composed of several layers:
The <audio> element is useful for embedding an audio player into a Web
page. It is dedicated forstreamed audio. It is very similar to
the <video> element, both in its use and in its API.
The "Web Audio API" is designed for musical applications and for adding
sound effects to games. This pure JavaScript API supports manipulation
of sound samples (loops, etc.), music synthesis and sound generation
(oscillators, etc.). It also comes with a set of predefined sound processing
modules (reverb, delay, etc.).
This course will focus on the <audio> element. Check for the HTML5-part 2
course, available on W3Cx, which cover the Web Audio API and other advanced
parts of HTML5.

The attributes, event set and JavaScript API of the <audio> element are just a
"reduced" version of the ones from the <video> element, and here we will only
address the differences and peculiarities.

The <audio> element, basic usage


The most simple basic example
Online example from JS Bin

Press play to stream the neigh of a horse:

As you can see, the code is very similar to the basic <video> element usage.

1. <html lang="en">
2. <body>
3. <audio controls="controls">
4. <source src="[Link]
5. type="audio/ogg" />
6. <source src="[Link]
7. type="audio/mp3" />
8. Your browser does not support the audio element.
9. Download the audio/video in
10.
<a href=”[Link]
a>
11.
or <ahref=”[Link]
a>
12. format.
13. </audio>
14. </body>
15. </html>

In this example, just as for the <video> element, we used


the controls attribute in order to render the play/stop, time, volume and
progress widgets.

Notice the other similarities: between the <audio>...</audio> tags, we added


a text message that is displayed if the Web browser doesn't support
the <audio> element, and we used several <source>...</source> elements
that link to different audio formats for the same file. The browser will use the
first format it recognizes.

Lines 8 - 12: we suggest downloading the audio files if the browser does not
support the <audio> element. This is also good practice!

Attributes of
the <video> and <audio> elements
Here are the attributes you can use with the <video> element. Most of them
are self explanatory...

We give them as a reference in the following table:

Attributes of the <video> element

Name Description

Source of the video.

src

Size of the video.

width If unspecified, the default width and height of the video will be used. If
and you specify one dimension but not the other, the browser will adjust the
size of the unspecified dimension to preserve the aspect ratio of the
height video.

If this boolean attribute is present, the browser displays its own controls
for video playback and volume.
controls

This attribute allows you to specify an image that the browser will use
while video is being downloaded, or until the user starts playing the
poster video.

If this attribute is not specified, the first frame of the video will be used
instead.
Name Description

This attribute asks the browser to start playing the video automatically as soon as the page
autoplay is ready.

The preload attribute is used when autoplay is not used. It tells the

preload browser what to do before a user plays a video. This attribute is a hint -
the browser may ignore it. While autoplay and preload are mutually
exclusive, if both are present, then preload is ignored.

Possible values:

 none: do nothing. This saves bandwidth, no video will be downloaded in


background before a user or a call to the play() method starts playing
the video.

 metadata: download metadata, such as length of the video or its format.

 auto (default value): the browser will decide. This will depend on the
implementation, and on the kind of connection: wifi, 3G, data roaming
etc.

Another boolean attribute that indicates to play the video in loop mode (and it starts again
loop when finished).

Be careful if you target mobile applications or if you have


multiple videos on the same page
The autoplay attribute is not recommended if your Web site targets mobile
applications, as it may consume bandwidth even if the user is not interested in
watching the proposed video. If you target mobile devices, we recommend
using preload=none as well, as the default value for this attribute is auto.

Best practice: do not use autoplay and add preload="none" if you target
mobile devices or if you have multiple audio/video on the same page. For
example, this page contains many audio elements and it does not make sense
to have them preload or autoplay.
About the poster attribute
If the poster attribute is missing, usually the first non-blank frame of the video
will be used as the image that is shown when the video is not playing.

while this is the expected behavior, Internet Explorer doesn’t actually do this, it
displays the first frame of the video as soon as it can regardless of the poster
value (see Ian Devlin's article about this).

About the autoplay attribute for general use


Do not abuse of the autoplay attribute. We talked earlier about mobile
applications, but even on desktop applications it's usually a bad idea to use it
(except for WebCams and for some animations with small video loops, without
sound, or for sites like YouTube, with just videos). This is the testimony of
a user in this course forum: "When I'm following the news, I open several
headlines in separate tabs. And then all of them start screaming at me with
some autoplays. I know this is supposed to make me watch the video, but for
me - it makes me close the loud tab and try another source."

Best practice: think twice before using the autoplay attribute, even for
desktop applications.

Attributes of the <audio> element


The attributes you can use with the <audio> element are a subset of those
available for the <video> element. Except for the poster attribute, they are
all recognized and have the expected meanings:
src: source of an audio stream.
controls: if this attribute is present, the browser displays its own controls for
audio playback and volume.
autoplay: tells the browser to start playing the audio stream automatically as
soon as the page is ready - please read details in the above table.
preload: tells the browser what to do before a user plays a sound - please read
details in the above table.
loop: indicates to play the audio stream in loop mode (start again when
finished).

As with the <video> element, the same best practice in regard to preload and
autoplay attributes should be followed.
Styling media players with CSS3
The <video> and <audio> elements are just like other HTML elements, so CSS3
can be used for styling, including CSS3 transitions, animations and transforms.
This was not possible with Flash technology.

An example of an audio player with some style


Add some decoration and styling
You can try this example online at JS Bin.

To add some styling to the basic example we saw when we introduced


the <audio> element, we just add a <figure> with two children: an <img> and
a <figcaption>. Inside the <figcaption> we add the <audio>element from
the previous example.

MOVE THE MOUSE POINTER OVER THIS PLAYER'S ELEMENTS!


HTML source code:

1. <figure id="figaudio1">
2. <img id="imghorse" width="200"
3.
src="[Link]
4. alt = "a horse"/>
5. <figcaption id="figcptionaudio1"> Press Play to hear the horse!
6. <audio controls="controls">
7. <source src="[Link]
8. type="audio/ogg" />
9. <source src="[Link]
10. type="audio/mp3" />
11. Your browser does not support the audio element.
12. Download the audio/video in
13.
<a href=”[Link]
a>
14.
or <ahref=”[Link]
a>
15. format.
16. </audio>
17. </figcaption>
18. </figure>

CSS source code:

1. #figaudio1 {
2. width : 420px;;
3. text-align:center;
4. padding : 6px;
5. background : white;
6. margin : 0 11px 0px 0;
7. border :solid 1px #888888;
8. border-radius : 8px ;
9. }
10.
11. #figcptionaudio1 {
12. font-size : .8em;
13. padding : 6px 8px;
14. background : #dddddd;
15. display :block;
16. text-align :center;
17. font-family : georgia, serif;
18. font-style : italic;
19. border-radius : 7px ;
20. }
21.
22. #figaudio1 > img {
23. background : #eeeeee;
24. padding : 5px;
25. border : solid 1px #444444;
26. }
27.
28. /* For audio and img transitions/animation */
29. audio, #figaudio1 > img {
30. transition:all 0.5s;
31. }
32.
33. #figaudio1 > img:hover {
34. box-shadow: 15px 15px 20px rgba(0,0, 0, 0.4);
35. transform: scale(1.05);
36. }
37.
38. audio:hover, audio:focus, audio:active {
39. box-shadow: 15px 15px 20px rgba(0,0, 0, 0.4);
40. transform: scale(1.05);
41. }
Changing the size of a video on the fly using CSS3
transforms
Resizing and rotating a video as the mouse pointer comes
over it
See this example online (where you can modify the code on the fly) or just play
the following video, and move the mouse pointer in and out of the video while
it's playing.

This example uses the pseudo CSS class :hover in order to track
the mouseover event. On mouseover, it uses a CSS3 transition property that
interpolates the changes in the scale and orientation of the video element
(done using a transform CSS property).

The corresponding HTML source code is:

1. <video id="w3devCampusVideo" autoplay controls>


2.
<source src=[Link]
3. type=video/webm>
4. <source src=[Link]
5. type=video/ogg>
6. <source src=[Link]
7. type=video/mp4>
8. </video>

... and the CSS source code is as follows:

1. #w3devCampusVideo {
2. width: 300px;
3. transition: all 0.5s ease-in-out;
4. }
5.
6. #w3devCampusVideo:hover {
7. width:400px;
8. transform:rotate(-5deg);
9. }
FullScreen video that resizes and maintains ratios. Uses
simple JavaScript to modify CSS properties
This is a trendy way of displaying videos (the PayPal Web site, as of June 2015,
used a small size video that looped and started playing as soon as the page
was loaded. One of the JsBin examples below uses this video. Note that as of
October 2015 PayPal removed the video and replaced it by a still image).

Below you will find two examples that show how to do this trick. The first is for
a "regular" video, using the <video> and <source> elements. This technique
can also be used on any YouTube embedded videos (see Example 2 below).

The interesting part is that we use a 100% standard (and really small and
simple) JavaScript code here to handle the window resize events and we just
set regular CSS properties width and height of the video element, to resize
the video.

Example 1: with a regular video

Online at JS Bin
Here is the HTML code. It's really simple, just notice the <body
onload="init();"> which calls the JavaScript init() function right after the
page is loaded.

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Full width video like PayPal site</title>
6. </head>
7. <body onload="init();">
8. <video id="myVideo" autoplay>
9. <source
10. src=[Link]
11. type=video/webm>
12. <source
13. src=[Link]
14. type=video/ogg>
15. <source
16. src=[Link]
17. type=video/mp4>
18. </video>
19. </body>

Here is the CSS (remove margins, remove padding, hide parts that could
overflow from the <body>):
1. body {
2. margin:0;
3. padding:0;
4. overflow:hidden;
5. }

And now the JavaScript code:


1. var video;
2.
3. function init() {
4. // function called when the page is loaded
5. video = [Link]("#myVideo");
6. // For initial value
7. [Link] = [Link];
8. [Link] = [Link];
9. // For dealing with window resize
10. [Link] = function() {
11. [Link] = [Link];
12. [Link] = [Link];
13. };
14. }

Example 2: with a YouTube video


 Online at JS Bin

The CSS and JavaScript codes for this example are exactly the same as in
Example 1.
Full screen video, pure CSS approaches (external resources)
Here is a JSBin with the video from the PayPal Web site, played full
screen using only very simple CSS.

In this example, the video does not rescale; it's just cropped if the browser
window is resized. Enlarge your browser and you'll see a man with a phone on
the right. Resize your browser and you'll see only part of the video.

Example on JsBin
CSS code:

1. body {
2. margin:0;
3. padding:0;
4. overflow:hidden;
5. }
6.
7. video {
8. width:100%;
9. height:auto;
10. }

Full screen video with CSS effects - example 2

This time the video is zoomed in so that it's much bigger than the browser's
window. When we resize the browser, the part of the video that is visible
adapts itself. It's not "real resize" of the video.

Try the example and read the explanation in an article by Dudley Storey. Also
available as a simplified JsBin example.
HTML code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="utf-8">
5. <title>Full screen video, example from [Link] by </title>
6. </head>
7. <body>
8. <header>
9. <video autoplay="" loop=""
10.
poster="[Link]
11. id="bgvid">
12. <source src="[Link]
13. type="video/webm">
14. <source src="[Link]
15. type="video/mp4">
16. </video>
17. </header>
18. <section>
19. <h1>[Link]
20. Background-Video</h1>
21. </section>
22. </body>
23. </html>

CSS code:

1. html, body{
2. color:white;
3. height: 100%;
4. }
5. header{
6. height: 100%;
7. background-image: url('[Link]
url('#');
8. background-repeat: repeat, no-repeat;
9. background-size: auto, cover;
10. background-position: center center, top left;
11. font-family: sans-serif;
12. color: #051a00;
13. }
14.
15. header video {
16. position:fixed;
17. top:50%;
18. left:50%;
19. min-width:100%;
20. min-height:100%;
21. width:auto;
22. height:auto;
23. z-index:-100;
24. transform:translateX(-50%) translateY(-50%);
25. }

The trick here is that:

[Link] video is in the header, and the header has a plotted transparent
background that is repeated in X and Y (see line 8 and 9).
[Link] video is positioned so that it's origin (top left corner) is away from the
visible surface (line 25), while it is set to take 100% of the surface (lines 20 and
21).

Full screen video that resizes and keeps its ratio, using the viewport
units (beware, not supported by old browsers)

Example on JsBin

This time we obtain the same result as with the first example that used
JavaScript and a resize event. The video resizes correctly and keeps its ratio.

CSS code:

1. body {
2. margin: 0;
3. }
4.
5.
6. video {
7. position: absolute;
8. width: 100vw;
9. height: 100vh;
10. object-fit: cover;
11. object-position: center center;
12. }

Discussion: why can't we achieve perfect resizing with only


CSS and the use of properties width=100% and height=100%?
Let's use the same video to compare the different approaches again:
[Link], using JavaScript - [Link] This solution works
on any browser, so we will focus on the two following methods, based on pure
CSS.
[Link] CSS 100% width and height properties (no JavaScript)
-[Link]
[Link] CSS viewport units for width and height (no JavasScript)
-[Link]

Resizing the browser window shows that #1 (JavaScript) and #3 (viewport


units) behave in the same way: the width or height of the video always fills the
window (whichever is smaller), and we always see the whole video.

Conclusion: we can get full size video without JavaScript by using viewport
units, unless we need to support some old browsers
(See [Link] for current support).

Setting the video to 100% width and height results in different behavior:

100% means 100% of the size of the <body> tag.


The body tag's width is 100% of the browser window width, so the video is
always full width.
The body tag's height, however, is determined by the size of its children: the
body tag's height grows and shrinks to accommodate the size of the children.
If the browser window is made wide and short, the video is full width, the
height is taller than the window, and part of the video is not visible. It seems
that just using % does not get us the same effect.
Control <audio> and <video> elements
from JavaScript
The <video> element has methods, properties/attributes and events that can
be manipulated with JavaScript. Using the DOM API it's possible to manipulate
an audio or video element as a JavaScript object that has:
Methods for controlling the behavior, such as play(), pause(), etc.;
Properties (duration, current position, etc.), either in read/write mode (such
as volume), or in read-only mode (such as encoding, duration, etc.);
Events generated during the life cycle of the element that can be processed
using JavaScript callbacks. It is also possible to send events to control the video
player.

Like any HTML element, the <video> element can be manipulated/created


using the DOM JavaScript API. Here is an example of
programmatically creating a <video> element:

1. var video = [Link]('video');


2. [Link] = 'video.mp4';
3. [Link] = true;
4. [Link](video);

This will create a complete video player for the file "video.mp4", with control
buttons, and will add it to the <body> element of the page.

Example that shows how to call play/pause or rewind


a video
Please look at this interesting example originally written by [Link] Hegaret from
W3C in 2008! (you can click on "edit in JS BIN" to view the source, but we will
give simpler and more detailed examples in the next section - this one is more
to show what can be done).
Note that in order to play the video, you must click on the "[Link]()" text. To
pause it, you click on the "[Link]()" text, and so on. Notice the text at the
top of the video, as well as the transparency. The text can be selected, since all
the elements displayed are pure DOM objects. You can zoom the page in and
out, etc. This was not possible with the Flash technology.

Conclusion: you can very easily change the look and feel of the standard
video player: use custom CSS and design your own control widgets. We can
find many examples of such video players that offer extended functionalities on
the Web. We will present some of them later in the course, but before that,
let's see a little more of what we can do using the JavaScript API of
the <video> element.
JavaScript API
of the <audio> and <video> elements
Methods, ProperTIES, AND EventS
The JavaScript API gives you powerful tools to manipulate the <video> element,
as the video object provides many properties, methods and events.

The complete list of events can be found at the W3C specification page, and
numerous examples of each event can be found on many Web sites such as
this one.

The complete list of properties can be found at the W3C HTML5 Video Events
and API page. This page is interesting for Web developers because it shows an
interactive view of the different values and events changing over time while
the video is playing within the page.

Click the picture to see it running online (or try the direct link), then
play with the different buttons and look at the table of events and
properties that will change in real time. The displayed names
show the properties, events, and methods from the API.
Here is a table that shows the most interesting
methods, properties, and eventsprovided by
the <video> element API
We provide this as a quick reminder - keep in mind that the complete list is
much longer!

Methods Properties Events

play() currentSrc play


pause() currentTime pause

load() startTime (readonly) progress

canPlayType() videoWidth error

videoHeight timeupdate

duration (readonly) ended

ended (readonly) abort

error empty

paused (readonly) emptied

muted waiting

seeking loadedmetadata

volume

height

width
seekable (readonly)

played (readonly)

Let's see now, through a set of examples, how to use the most important of
these properties, methods, and events...

Examples of the use of the video


element JavaScript API
The JavaScript API is useful for implementing playlists, making custom user
interfaces and many other interesting things. The "enhanced HTML5
multimedia players" presented further on the course rely heavily on this API.

Example 1 - how to use external buttons to control


the player's behavior
This example shows the first steps towards writing a custom video player. It
shows basic usage of the JavaScript API for adding custom buttons to
play/pause the video or to go back to the beginning by setting
the currentTime property to zero.

Try it online, and look at the source code.


Source code extract:

1. <video id="vid" controls>


2. <source src=[Link]
[Link]
3. type=video/webm>
4. ...
5. </video>
6. <p>Example of custom controls:</p>
7. <button onclick="playVideo();" style="cursor: pointer;">Play</
button>
8.
9. <button onclick="pauseVideo();" style="cursor: pointer;">Pause</
button>
10.
11. <button onclick="rewindVideo();" style="cursor: pointer;">
12. Back to beginning</button>
13. <script>
14. vid = [Link]("#vid");
15. function playVideo() {
16. [Link]();
17. }
18. function pauseVideo() {
19. [Link]();
20. }
21. function rewindVideo() {
22. [Link] = 0;
23. }
24. </script>

Lines 7, 9 and 11: we add a click listener to each button, in order to call a
JavaScript function when the button is clicked.
Line 14: using the DOM API we get the JavaScript object that corresponds to
the video element we inserted in the HTML document. This line is outside a
function, it will be executed when the page loads.
Lines 17 and 20: we call methods from the API for playing/pausing the video.
Line 24: we modify the currentTime property in order to rewind the video.
Note that [Link]() also rewinds the video, shows the poster image again,
but also pauses the video. By using currentTime=0 the playback does not
stop.

Example 2 - how to detect the end of a video and


START another one
This example listens for the ended event, and calls a callback function when
the video is ended.
1. <video src="[Link]" id="myVideo">
2. video not supported
3. </video>
4. <script type='text/javascript'>
5. var vid = [Link]('#myVideo');
6. [Link]('ended', playNextVideo, false);
7. function playNextVideo(e) {
8. // Whatever you want to do after the event, change the src attribute
9. // of the video element, for example, in order to play another video
10. }
11. </script>

Example 3 (application of the previous one) - how to


manage playlists
This example detects the end of a video then loads the next video, changes
the src attribute of the video element and plays the video (see the
online example).

To try this example: use the progress cursor to go near the end of the first
video that is being played and see how it continues with the next video.

1. <!doctype html>
2. <html lang="en">
3. <head>
4. <title>Sequential Movies</title>
5. <script>
6. var myVideo;
7. var currentVideo = 0;
8. var sources = [
9. "[Link]
10. "[Link]
P1120973_512kb.mp4"
11. ];
12. // Set the src of the video to the next URL in the playlist
13. // If at the end we start again from beginning (the modulo
14. // [Link] does that)
15. function loadNextVideo() {
16. [Link] = sources[currentVideo % [Link]]
17. [Link]();
18. currentVideo++;
19. }
20. // callback that loads and plays the next video
21. function loadAndplayNextVideo() {
22. [Link]("playing " + sources[currentVideo % [Link]])
23. loadNextVideo();
24. [Link]();
25. }
26. // Called when the page is loaded
27. function init(){
28. // get the video element using the DOM api
29. myVideo = [Link]("#myVideo");
30. // Define a callback function called each time a video ends
31. [Link]('ended', loadAndplayNextVideo, false);
32. // Load the first video when the page is loaded.
33. loadNextVideo();
34. }
35. </script>
36. </head>
37. <body onload="init()">
38. <video id="myVideo" controls></video>
39. </body>
40. </html>

 Line 8: the JavaScript array that contains the URLs of the


videos in the playlist. In this example, we've got only two of
them, but if the array is larger the example will still work.
 Line 42: When the page is loaded, an init() function is
called.
 Lines 32 - 38: we used the DOM to get the JavaScript object
corresponding to the video element, then define a listener
for the ended event. Each time a video will end,
the loadAndplayNextVideo() callback will be called. As the
video element has no src attribute by default, we also
preload the first video (call to loadNextVideo() at line 38).
 Lines 16 - 20: the loadNextVideo() function uses a variable
called currentVideo that corresponds to the index of the
current video. By setting [Link] = sources
[currentVideo % [Link]], we set the src of the
video element to sources[0], then to sources[1], and as we
increment the currentVideo index each time (line 19), if it
becomes greater than 1, the modulo (the "%" symbol is the
modulo in JavaScript) will make it "loop" between 0 and the
number of videos in the playlist. In other words, when the
last video ends, it starts back to the first one.
Extended examples
In this section, we propose six extended examples that use more JavaScript
and more complex CSS manipulation. They might be a little hard to understand
if you are a JavaScript beginner, but don't be afraid to try and test them, look
at the code, etc.

Some examples are given "as is", such as the custom video player that
uses SVG (at the end of the page); if you are interested, you may view the
code.

Example 1: A player showing the use of every type


of CSS3 transformATION
Please see this example online, originally written by Chris Heilmann, and tuned
by us ;) The editable source code is here at JS Bin.

Don't forget to click the JavaScript and CSS tabs at JS Bin in order to display the
JavaScript code that creates the buttons on the right of the video, and the CSS3
that processes the different clicks and applies CSS3 transforms.
This example shows a lot:

It uses the HTML5 elements <nav>, <footer>, <header>.


It shows the use of CSS3 2D transformations (scale, translate, and rotate).
It shows how to handle DOM events using JavaScript and how to modify CSS
properties of the <video>element from JavaScript.

Example 2: Applying CSS3 filters to a video in real


time
Please see this example online. Play the video and then click on the video while
it's playing. This will change in real-time the CSS class of the video element.
Each class uses the filter property with different values.
Note that CSS filters are not yet 100% supported by the major browsers. You
still need to use prefixed versions of the CSS properties, as shown below (this
table is taken from [Link]).

CSS filter support (green squares with a small yellow part in the top right
corner) means that a prefix is needed, like -webkit-filter, or -moz-
filter or -o-filter):

There is an up-to-date version of this table.

Below, you will find images obtained with different filter values:
Use <video class="blur"> for example, to obtain a blurry video.
This complete example changes the CSS class associated to the video
element, on the fly in a mouseclick listener callback.

Here, we define the CSS classes used in the example:

1. .blur {
2. filter: blur(3px);
3. }
4. .brightness {
5. filter: brightness(5);
6. }
7. .contrast {
8. filter: contrast(8);
9. }
10. .hue-rotate {
11. filter: hue-rotate(90deg);
12. }
13. .hue-rotate2 {
14. filter: hue-rotate(180deg);
15. }
16. .hue-rotate3 {
17. filter: hue-rotate(270deg);
18. }
19. .saturate {
20. filter: saturate(10);
21. }
22. .grayscale {
23. filter: grayscale(1);
24. }
25. .sepia {
26. filter: sepia(1);
27. }
28. .invert {
29. filter: invert(1)
30. }

This extract from the source code explains how to set a mouseclick listener
and how to change the value of a CSS class attribute on the fly:

1. <video id="output" controls autoplay>


2.
<source src=[Link]
3. type=video/webm>
4. <source src=[Link]
5. type=video/ogg>
6. <source src=[Link]
7. type=video/mp4>
8. </video>
9. <script>
10. var output = [Link]('output');
11. var idx = 0;
12. var filters = [
13. 'grayscale',
14. 'sepia',
15. 'blur',
16. 'brightness',
17. 'contrast',
18. 'hue-rotate', 'hue-rotate2', 'hue-rotate3',
19. 'saturate',
20. 'invert'];
21. function changeFilter(e) {
22. var el = [Link];
23. var effect = filters[idx++ % [Link]];
24. [Link] = effect;
25. // Do not propagate the event, prevent default behavior.
26. // By default, a click on a video element pauses/unpauses the video
27. // By stopping the propagation and canceling the default behavior,
28. // we stop the pause/unpause behavior when the video is clicked.
29. // Now a click just changes the CSS filter we apply on the video.
30. [Link]();
31. [Link]();
32. }
33. [Link]('click', changeFilter, false);
34. </script>
35. <style>
36. #output {
37. width: 307px;
38. height: 250px;
39. background: rgba(255,255,255,0.5);
40. border: 1px solid #ccc;
41. }
42. .blur {
43. filter: blur(3px);
44. }
45. .brightness {
46. filter: brightness(5);
47. }
48. ...
49. </style>

Notes about "prefixed CSS properties" and a good tool that


will add prefixes for you!
If you look at the previous CSS file, the CSS filter property is not prefixed (for
example, -webkit-filterinstead of filter), whereas some browsers still
require prefixes.

[Link] is a very practical tool. It's a simple library you can include in
your HTML page that will add prefixes on the fly when needed. It uses the
[Link] tables and also relies on the W3C specifications, so we
recommend it!

Typical use: just add some lines of code to the <head> element of your HTML
page.

1. <head>
2. <script src="[Link]
[Link]"></script>
3. <style type="unprocessed" id="AutoprefixerIn">%css%</style>
4. <style id="AutoprefixerOut"></style>
5. <script>
6. AutoprefixerSettings = ""; // Specify here the browsers you
7. // want to target or leave empty
8. [Link]("AutoprefixerOut").innerHTML =
9. autoprefixer(AutoprefixerSettings || null)
10. .process([Link]("AutoprefixerIn")
11. .innerHTML)
12. .css;
13. </script>
14. </head>
Example 3: how to track all possible events and
manipulate many properties
This example also shows how to handle failures. See the code and play with
this example online.

Here is an example of a piece of code for handling errors during video


playback:
1. ...
2. [Link]('error', function(evt) {
3. logEvent(evt,'red');
4. }, false);
5. ...
6. function logEvent(evt, color) {
7. switch ([Link]) {
8. ...
9. case 'error':
10. var error = [Link]('video').error;
11. switch ([Link]) {
12. case error.MEDIA_ERR_ABORTED:
13. [Link] = "fetching aborted at the user's request";
14. break;
15. case error.MEDIA_ERR_NETWORK:
16. [Link] = "a network error caused the browser to stop
fetching the media";
17. break;
18. case error.MEDIA_ERR_DECODE:
19. [Link] = "an error occurred while decoding the media";
20. break;
21. case error.MEDIA_ERR_SRC_NOT_SUPPORTED:
22. [Link] = "the media indicated by the src
23. attribute was not suitable";
24. break;
25. default:
26. [Link] = "an error occurred";
27. break;
28. }
29. break;
30. }
31. ...
32. }
Example 4: how to display a percentage of buffering
when using a slow connection
See the example online here too.

Note that on mobile phones, the video does not start until the user presses the
play control or clicks on the video picture. Using the "canplaythrough" event is
a trick to call a function that starts the video player as soon as the page is
loaded on desktop. This event is not supported by mobile devices, so if you
try this example on a mobile, the video will not start automatically.

As the Apple Developer Web site explains it: "The buffered property is
a TimeRanges object: an array of start and stop times, not a single value.
Consider what happens if the person watching the media uses the time
scrubber to jump forward to a point in the movie that hasn’t loaded yet—the
movie stops loading and jumps forward to the new point in time, then starts
buffering again from there. So the buffered property can contain an array of
discontinuous ranges. The example simply seeks the end of the array and
reads the last value, so it actually shows the percentage into the movie
duration for which there is data. "

1. <!doctype html>
2. <html lang="en">
3. <head>
4. <title>JavaScript Progress Monitor</title>
5. <script>
6. function getPercentProg() {
7. var myVideo = [Link]('video')[0];
8. var endBuf = [Link](0);
9. var soFar = parseInt(((endBuf / [Link]) * 100));
10. [Link]("loadStatus").innerHTML = soFar + '%';
11. }
12. // Will be called as soon as the page is ready on desktop computer,
13. // Only when a user clicks on play control or image on mobile
14. function myAutoPlay() {
15. var myVideo = [Link]('video')[0];
16. [Link]();
17. }
18. function addMyListeners(){
19. var myVideo = [Link]('video')[0];
20. [Link]('progress', getPercentProg, false);
21. // Calls autoplay only if the device is adapted
22. [Link]('canplaythrough', myAutoPlay, false);
23. }
24. </script>
25. </head>
26. <body onload="addMyListeners()">
27. <h1>Check progression of buffering before playing a movie. Useful
withy
28. slow connexion (3G, etc.)</h1>
29. <div>
30. <video controls>
31.
<source src=[Link]
32. type=video/webm>
33.
<source src=[Link]
34. type=video/ogg>
35.
<source src=[Link]
36. type=video/mp4>
37. </video>
38. <p id="loadStatus">Buffering...</p>
39. </div>
40. </body>
41. </html>

Example 5: how to use SVG elements as external


controllers
This is the ultimate way of doing a real custom player: redesign your own
controls using SVG shapes! This example is given "as is" for those of you
who may be curious. An SVG course from W3C might be available on W3Cx one
of these days. Stay tuned ;)
Try it online!

Example 6: A CUSTOM VIDEO PLAYER WRITTEN BY A


STUDENT WHO TOOK A PRECURSOR VERSION OF
THIS MOOC
This is more an example than a tutorial. Maurice, a student who followed the
precursor version of this MOOC at the [Link] Web site, had the
assignment to write a custom video player with playlist, video thumbnails,
custom play/pause/next/previous/volume controls, and present it in a Web
page that used a nice layout based on the new structuring elements seen
during Week 1.

Here is the online example on JS Bin, by Maurice Buiten.

We recommend looking at the source code; you will learn many things related
to the Week 1 course.

Screenshot:
This is the discussion forum dedicated to "streaming multimedia content". You
are welcome to post comments and share your creations here, and of course
ask questions.

Some topics of discussion and optional projects:

Suggested topics
Where do you host your video files (we are speaking about files that can be
used with the <video> element directly, not on YouTube, DailyMotion, etc.)?
Have you already tried some of the enhanced audio or video players? Would
you please share opinions or make a review of these players?
What tool do you use for encoding your audio and video files?

Optional projects
This might be useful: free videos
at [Link]

Here are a few ideas to play with the material learned in this section. Your
classmates and the team who prepared the course will be happy to look at
them and give feedback. Please post URLs of your work in this discussion
forum. These projects are optional, meaning that they won't be graded.

Project 1 (very easy): find the "enhanced HTML5 video players" described in
the course and try to use one of them to play a video. Do some customization
as well, such as adding a logo, choosing a theme, etc.

Project 2 (easy): try to write a video or an audio player with a few custom
buttons for play/stop/etc. When your custom player is done, please add a way
to play several videos one after another (what we call a playlist), etc.

Examples that can help you, created by students of earlier versions of this
MOOC:

A custom player with nice CSS and buttons


Another simple one with custom buttons for play/stop/volume up/volume
down...
Custom players with a small playlist composed of three songs by Queen
AWESOME custom player created by GeorgianaB, with playlist, progress bar,
CSS3 animations, etc. Check this out!

Project 3 (with JavaScript knowledge): play a video file or an audio file


with an external synchronization. Use the progress event and
the currentTime property from the audio and video objects you can
manipulate with the JavaScript API described in the course. For example, please
display some text aside the video, and/or display a Wikipedia page in an
iframe, and/or display a Google map if you know how to do it.
Add closed captions, subtitles, etc. to
your videos
Introduction
This section introduces the new HTML5 <track> element, useful for adding
closed captions, subtitles, descriptions, and metadata to your videos. It comes
with a new JavaScript API.

The WebVTT format used for describing a track file is also presented in this
chapter.

Most of the major desktop browsers now support HTML5


captioning
See this compatibility table for the up-to-date status of the different browsers.
Also, please check on [Link] for information about the <track> element
support by browsers.

Some definitions
closed captions describe all relevant audio present in the video (fire, rain,
birds, gun fights, etc.).
subtitles are only for spoken words.

The accessibility features of TV programs often propose both options for people
with hearing deficiencies.

Typical use: add a subtitle/caption track to


a <video> element
Important warning!!

The <track> element cannot be used with a file:// URL. Please


use http:// and a Web server. Your server must use a special MIME format for
the .vtt files: text/vtt;charset=utf-8 (set by default on most servers now).

Examples of the lines to add to an Apache Web server:

1. <Files [Link]>
2. ForceType text/vtt;charset=utf-8
3. </Files>
It might be worth mentioning that most browsers work fine with WebVTT even
if the MIME Type is not set, but Internet Explorer doesn’t: in fact it will
ignore WebVTT entirely unless the MIME Type is set correctly!
Here is an example of a video element that includes a <track> element in
the .vtt (WebVTT) format (line 7), original version
at [Link] and we also cooked a version that is
easier to study on jsbin: [Link]

As seen in this screenshot, the example uses a <track> element to insert


basic captions to the video: sounds and music are described, in addition to
standard subtitles that correspond to what the different movie characters say.

1. <video height="272" width="640"


2. poster="[Link]
3. crossorigin="anonymous"
4. controls>
5. <source src="[Link]
6. type="video/mp4">
7. <source src="[Link]
8. type="video/webm">
9. <track src="[Link]
10. kind="captions" label="Closed Captions" default>
11. </video>

Notice that the <track> element at line 9 has an attribute named kind that
indicates the type of the track that is included. Possible values
are: subtitles, captions, descriptions, chapters or metadata.

The <track> element also has an attribute default that indicates that we
want this track to be displayed by default when reading the video.

We also used an attribute named crossorigin that is necessary just to run


this demo, as it is required by the server that hosts the video from this
example.

Multiple tracks may be included in a video element


Multiple tracks are needed to support different langages, video captions for the
hearing-impaired, subtitles, etc.

Below is an example (from the specification) that includes


multiple <track> elements (subtitles for three languages and captions only for
English):

1. <video src="[Link]">
2. <track kind=subtitles src=[Link]
3. srclang=en
4. label="English">
5. <track kind=captions src=[Link]
6. srclang=en
7. label="English for the Hard of Hearing">
8. <track kind=subtitles src=[Link]
9. srclang=fr
10. lang=fr
11. label="Français">
12. <track kind=subtitles src=[Link]
13. srclang=de
14. lang=de
15. label="Deutsch">
16. </video>

Note the use of some new attributes in the <track> element:

label: the label value will be displayed in the GUI control that is included in
the default HTML5 video player,
srclang: gives the language for the text track data. The value must be a
valid BCP 47 language tag. This attribute must be present if the element's kind
attribute is in the subtitles state.

External resources (optional, if you wish to learn


more)
The W3C specification for the <track> element
The living W3C standard for the WebVTT format
Examples of text tracks with JavaScript scripting
HTML5 video with SRT subtitles
Creating and validating WebVTT subtitles
Silvia Pfeiffer's HTML5 Video Accessibility slides give more examples of
working with markup, as well as showing how to build chapter tracks for
navigation and description tracks for screen readers.

The WebVTT format


The W3C Web Media Text Tracks Community Group is working on the
"WebVTT: The Web Video Text Tracks Format" specification, a format used for
defining files that will contain text for captions and subtitles, and much more...
The WebVTT files are used with the src attribute of the <track> element, that
can be used inside a <video>...</video>.

In the example presented in the previous section (located


at [Link] we used a file called [Link]:

1. <video height="272" width="640"


2. poster="[Link]
3. crossorigin="anonymous"
4. controls>
5. ...
6. <track src="[Link]
7. kind="captions" label="Closed Captions" default>
8. </video>

And here is an extract of the corresponding [Link] file:

1. WEBVTT
2. [Link].000 --> [Link].042
3. (drumbeat)
4. [Link].167 --> [Link].025
5. (plaintive violin solo playing)
6. [Link].000 --> [Link].183
7. (wind whistling)
8. [Link].167 --> [Link].025
9. (orchestra music swells)
10. [Link].033 --> [Link].192
11. (weapons clash)
12. [Link].000 --> [Link].175
13. (gasps)
14. [Link].183 --> [Link].158
15. (grunts)
16. [Link].167 --> [Link].058
17. (groaning)
18. [Link].192 --> [Link].150
19. (blade rings)
20. [Link].158 --> [Link].008
21. (bellowing)
22. [Link].017 --> [Link].067
23. (grunting)
24. [Link].075 --> [Link].133
25. (panting)
26. [Link].108 --> [Link].125
27. (cries out in agony)
28. [Link].050 --> [Link].058
29. (panting)
30. [Link].092 --> [Link].142
31. (panting)
32. [Link].017 --> [Link].125
33. (orchestra plays ominous low notes)
34. [Link].058 --> [Link].133
35. (plaintive violin solo returns)
36. [Link].158 --> [Link].058
37. This blade has a dark past.
38. [Link].092 --> [Link].108
39. It has shed much innocent blood.
40. [Link].083 --> [Link].000
41. You're a fool for traveling alone
42. so completely unprepared.
43. [Link].100 --> [Link].033
44. You're lucky your blood's still flowing.
45. [Link].183 --> [Link].075
46. Thank you.

This format is rather simple, but we still recommend reading this excellent
article from Mozilla Developer Network that explains in detail all the different
options.

Each "element" in this file has a starting and ending time, plus a value (the text
that will be displayed), followed by a blank line (blank lines are separators
between elements).

Each element is called "a cue", and may optionally have an ID that will be
useful when using the track element JavaScript API, in particular
the getCueById() method of TextTrack objects. How to use these will be
taught in the "advanced HTML5" course, soon on W3Cx

Example of numeric IDs:

1. 9
2. [Link].000 --> [Link].000
3. to hear from <u>you</u>
4. 10
5. [Link].500 --> [Link].000
6. We want to hear what inspires you as a developer

IDs may also be defined as strings, and values can use HTML as well:

1. Opening
2. [Link].000 --> [Link].000
3. Welcome to our <i>nice film</i>

The displayed text can span multiple lines, but blank lines are not allowed, as
they would be interpreted as a separator:
1. [Link].083 --> [Link].000
2. <p>You're a fool for traveling alone</p>
3. <p>so completely unprepared.</p>

External Resource:
An unofficial webVTT format validator

Practical example: adding subtitles to a


video
Introduction
We will look at a simple example. First, you need a video on one of the
formats/codecs supported by the browsers you target. A recommended
codec is H264, but other formats, such as webm, may have some advantages if
the browser supports them. For example, webm allows the video to start playing
after a much shorter buffering time. In other words, try if possible to
provide the video encoded with more than one codec.

For this, use any sort of open source, free or commercial video encoding
software, such as Handbrake (free, open source) or Super (free). There are also
online video encoding services, and you can even upload your video to
YouTube, let it encode your video in several resolutions and codecs, and use a
browser extension such as VideoDownloadHelper (for Firefox) to download the
video in your chosen formats.

So, let's suppose you have a video like the one below (we included it on
YouTube for practical reasons). This video has subtitles (you can activate them
in the YouTube player), but the goal of this lesson is to explain how we made
them without using the YouTube embedded tools, which do not allow export
the subtitle file to be exported in the webVTT format.
And you've also got it in mp4/H264 and in webm formats. Here is how you can
embed it in your page using the video element:

1. <video id="myVideo" width=500 controls>


2. <source
3. src="videos/SameOldSongAndDanceRogerLathaudPart1MidRes.mp4"
4. type="video/mp4">
5. <source
6. src="videos/[Link]"
7. type="video/webm">
8.
9. <track src="videos/[Link]"
10. kind="subtitles" srclang="en" default>
11. </video>

At line 9, we added a <track> element to add English subtitles, as the guitar


teacher there is speaking in French. We will now explain how we created this
subtitle track.

Adding subtitles to the video


Now, we need to create a WebVTT file for this video. How can we synchronize
an English translation of what the guitar teacher says in French?
Many tools - both free and commercial - are available to add subtitles to a
video. Most are native applications you need to install on your computer.
However, a free and very practical tool is available for doing this 100% in a
Web browser: [Link] also known
as [Link]

Go to the above Web site, click on the "subtitle a video" link, then follow the
different tutorials/instructions. It will ask for a YouTube URL, so it's better to
first upload your video to YouTube (even in private mode). Once you have
entered the URL of your video, you will have an online subtitles/caption editor.
Enter your subtitles and sync them until you are happy with the results.
Once your subtitles/captions are ok, you will be able to upload them to
YouTube, or -this is what we wanted first- download them as WebVTT format:
Try your subtitled/captioned video

Styling and positioning the


captions/subtitles
Online example used in this section
In this section, we will look at different possibilities for positioning and styling
the text displayed as captions/subtitles while playing a video.

This video example shows each use case. We also "cooked" an easier version
to study on JS Bin (look at the HTML in JS Bin).

The screenshots below are taken from this video.


And here is the WebVTT file. Notice the new attributes that have been added
on the right end of the duration values:

1. WEBVTT
2. [Link].000 --> [Link].000
3. These captions test some features of the WebVTT formats
4. [Link].000 --> [Link].000 line:5%
5. This cue is positioned at the top of the video
6. [Link].000 --> [Link].000 position:5% align:start
7. This cue is positioned at the left side of the video.
8. [Link].000 --> [Link].000 position:95% align:end
9. And this one ate the right side.
10.[Link].000 --> [Link].000 size:33%
11. This cue is only a third of the width of the video, hence the multiple line
breaks.
12. [Link].000 --> [Link].000
[Link] cue contains <b>bold</b> text.
14. [Link].000 --> [Link].000
[Link] cue contains <i>italic</i> text.
16. [Link].000 --> [Link].000
[Link] cue contains <u>underlined</u> text.
18. [Link].000 --> [Link].000
[Link] cue contains <b><i><u>bold, italic, underlined</u></i></b> text.
20. [Link].000 --> [Link].000
21.<[Link]>This cue contains the class "myclass".
[Link] that support ::cue CSS should make it red.</c>
23. [Link].000 --> [Link].000
24. The following cue contains two voices.
25. Tarzan should be blue and Jane green.
26. [Link].000 --> [Link].000
27. <v Tarzan>Me Tarzan...
28. <v Jane>That would make me Jane!
29. bigtext
30. [Link].000 --> [Link].000
31. This cue has a unique id.
32. Using CSS, its font size should be 150%.
33. [Link].000 --> [Link].000
34. The <[Link].333>text <[Link].666>in <[Link].000>this <00:0
1:07.333>cue <[Link].666>should <[Link].000>grow
35. <[Link].333>one <[Link].666>word <[Link].000>at <[Link]
.333>a <[Link].666>time
36. [Link].000 --> [Link].000
37. That's it! For now...

How to Position the subtitles


The video example tests nearly all the possibilities for positioning
subtitles/captions, styling (using HTML element wrapping with <b>, <i>, etc.),
voicing (subtitles corresponding to different characters will be displayed in
different colors) and CSS styling.

It is possible to locate the cues in the video viewport using absolute or relative
values. The attributes that position the text are located on the same line as the
cue definition, like at line 9 of the previous WebVTT example file:

1. [Link].000 --> [Link].000 position:5% align:start


2. This cue is positioned at the left side of the video.

There are several possible values:

line:5% means "vertical position at a line 5% of the height of the video


viewport (it will be located at the top of the video, proportional to its vertical
size).
position:5% align:start means "regular location at the bottom of the
video, the start of the sentence will be located at 5% of the width of the video",
i.e., near the left side.
position:95% align:end means "regular location at the bottom of the video,
the end of the sentence will be at 95% of the horizontal width of the video".
size:33% The size of each line will be one third of the size of the video. Since
the sentence won't fit, it will be displayed in multiple lines.
And so on. Please look at the video as it is self-explanatory.

Use of <b>, <i>, <u> for styling subtitles / captions

Using CSS classes for styling


It is possible to style using CSS classes as part of a cue value,
using the <c> element. You can specify the CSS class that should be applied by
adding "." followed by the name of your CSS class. Here is an example:
1. <[Link]>This cue contains the class "myclass".
2. Browsers that support ::cue CSS should make it red.</c>

CSS rules used in this example:


1. <style type="text/css">
2. ::cue(.myclass) { color: red; }
3. ::cue(v[voice="Tarzan"]) { color: blue; }
4. ::cue(v[voice="Jane"]) { color: green; }
5. ::cue(#bigtext) { font-size: 150%; }
6. </style>

The ::cue pseudo element selector is used to match "cues" in the webVTT file.
You add parenthesis and a secondary CSS selector to match cues that have a
particular id, or a particular CSS class, etc. Look at the CSS above and at the
extract from the webVTT file, play the video, you will understand how
this works...

Support differs from one browser to another, see this compatibility table for
more info. Notice that most of the enhanced players presented further on in
the course will provide full support.

Using voicing for styling: the <v> element


Screenshot taken at 1:02 of this example online:

Using the <v> tag, you will distinguish different voices that should be displayed
in different colors (depending on the HTML5 video player implementation). See
the CSS presented in the previous section to see how to specify the colors for
the different voices.

Extract from the source code:


1. [Link].000 --> [Link].000
2. <v Tarzan>Me Tarzan...
3. <v Jane>That would make me Jane!

External resource:
Article from Mozilla Developer Network that details all the options you can use
in WebVTT cues.

Chapters: use another specific <track>


Adding chapters is very similar to adding subtitles/captions. Look at line 5,
where we use an extra <track>element with a kind="chapters" attribute.
1. <video poster="webvtt_talk.png" style="width:100%" preload="metad
ata">
2. <source src="webvtt_talk.webm">
3. <source src="webvtt_talk.mp4">
4. <source src="webvtt_talk.ogv">
5.
<track id="nav" src="webvtt_talk_navigation.vtt" kind="chapters"srclang
="en">
6. <track id="cc" src="webvtt_talk_captions.vtt" kind="captions"
7. label="captions" srclang="en" default>
8. </video>

Here is an example of WebVTT files with defined chapters. Each "CUE" at line 3,
7, 11 etc. can bear any name. We used "Chapter 1, Chapter 2, Ending, etc..."
but you are free to name them as you choose.

What makes them special is that the track has an attribute kind="chapters".
In 2015, the <video>elements rendered in standard browsers ignore chapters,
but enhanced HTML5 players such as SublimeVideo Player or JW Player take
them into account.

It's also easy to process them, and for example, to generate a custom
navigation menu, using the <track>JavaScript API (which is covered in
the HTML5 part 2 course available on W3Cx).

Example of a WebVTT file that defines chapters:


1. WEBVTT FILE
2.
3. Chapter 1
4. [Link].000 --> [Link].700
5. Title Slide
6.
7. Chapter 2
8. [Link].700 --> [Link].600
9. Introduction by Naomi Black
10.
11. Chapter 3
12. [Link].600 --> [Link].100
13. Impact of Captions on the Web
14.
15. Chapter 4
16. [Link].100 --> [Link].000
17. Requirements of a Video text format
18.
19. Ending
20. [Link].000 --> [Link].766
21. Simple WebVTT file
22.
23. Greetings 6
24. [Link].766 --> [Link].666
25. Styled WebVTT file

JW Player displays chapters:


SublimeVideo's player takes into account chapters:
Tools for creating WebVTT subtitles
and for reusing existing subtitles
Many tools are available to make and edit HTML5 video and caption/subtitles:
Tools for converting existing file formats to WebVTT files, such as
the .srt format, which is popular in the DivX/AVI/Mkv
scene. This article reviews 3 of them, but there are many more. Do a quick
Web search and you will get plenty of results.
Tools for creating subtitles/captions from scratch. Use these to
generate a WebVTT file. You can embed the <track> element in your own
videos, on your own Web pages, or upload the WebVTT file to YouTube. We
recommend Universal Subtitles. It's a free online tool that is very easy to use.
Check the "add subtitles/captions to your video" unit of this course.
Enhanced HTML5 video players that use the <video>,
<source> and <track> elements under the hood. They also provide many extra
features, including support for subtitle/caption formats other than
WebVTT (by converting on the fly).
JavaScript libraries for converting to the WebVTT format on the
fly, such as JS_videosub

The <track> JavaScript API


Introduction
The <track> element comes with a powerful API that is used to develop many
interesting features such as:
Dynamically building a navigation menu that shows the different chapters of
the video,
Synchronizing page content with timestamps in the WebVTT file (for example:
show a map next to the video, that shows the location corresponding to the
video content),
Displaying all the subtitles/captions at once as HTML in the page,
Making an app for creating on the fly subtitles/captions,
Etc.

How to do this will be taught in the "advanced HTML5" course, soon on W3Cx.
Examples of use
Add a navigation menu to start playing the video at given
chapters
This example shows a video with an enhanced progress bar that displays the
different chapters as small "clickable" squares. Furthermore, using the
JavaScript API of the <track> element, this Web site builds a navigation menu
(on the right of the video):

Sync video with Google Map and Google Street View


Check this demo by Sam Dutton: it shows a video that comes with a WebVTT
file that contains longitudes and latitudes. When the video plays, JavaScript
functions are called at given times and get the longitude and latitude. A Google
Map and a Google Street views are updated in real time.
Sync guitar tablatures and music score with a video
This example shows how we manage to render music scores in real time as the
video plays.

Some JavaScript code listens to the ontimeupdate event while the video is
playing. We use the currentTimeproperty of the video to know exactly where
we are in the video. Finally, we also rely on an external library to render in an
HTML5 canvas the bars corresponding to the current video explanations. We
render in real time guitar pro tablatures using the [Link] library.

Here is the discussion forum dedicated to "closed captions and subtitles". Do


not hesitate to post comments and questions, as well as to share your
creations here.

Some topics of discussion and optional projects:

Suggested topics
What tools do you use for adding subtitles to videos?
Did you have problems with encoding foreign languages?
What subtitle format do you use? WebVTT or .srt or something else?

Optional projects
Here are a few project ideas. Your classmates and the team who prepared the
course will all be glad to try them and give some feedback. Please post URLs in
this discussion forum. These projects are optional, meaning that they won't be
graded.
Project 1 (very easy): add some subtitles of your own on one of your videos.
Share your step by step experience. This will be a valuable resource for your
classmates.

See an example that might help:

Very simple example on JsBin with a video and subtitles hosted in the "public"
directory of a dropbox account. Note the use of the crossorigin attribute of
the <video> element. The subtitles were created by hand
with [Link]

Project 2 (easy): try to style some of the subtitles, set their position, etc.

Example that can help:

Try it on JSBin: Samurai Pizza Cat with subtitled lyrics grabbed from the
Wikiquote Web site, and synchronized using [Link]
A Queen song subtitled by Ann McCartney - the JSBin contains all the
explanations at the bottom of the page. Try it on JSBin.

Project 3 (with JavaScript knowledge): Please write a karaoke player with a


small list of songs for people to choose from.

Enhanced HTML5 video players


Introduction
There are numerous "enhanced" video players; most are free and open source,
some are commercial. They offer lots of features, which are listed below. Not all
of these features are available in every player, this list just illustrates what can
be added to the standard <video> element.

We call them "HTML5 enhanced video players" because on top of being based
on the <video> element, they come with custom features, custom look'n'feel,
chapters, etc., based on a JavaScript API that makes such
customizations possible.

An explanation of what enhanced video players can do, by the creators of the
popular JW Player.
Accessible players
For those of you interested in this particular topic, here is a very good resource
that compares most of the players presented in this section, in terms of
accessibility. This resource has links to players designed especially for people
with disabilities: accessible media player resources and demos.

Advantages and Disadvantages of using a custom


player
Advantages of enhanced video players:
Flash or ActiveX/Silverlight fallbacks to make the player work in old versions of
Internet Explorer
Support for all kinds of subtitle formats
Customizable look'n'feel (add your logo, custom themes, etc.)
Full screen mode without borders on old browsers (today's implementations of
the <video> element support full screen mode)
Consistent look'n'feel across browsers (menus for subtitles, etc.)
1.5x, 2x, 3x speeds for fast playback
Social buttons for sharing on Facebook, Twitter, etc.
Support for chapters
Support for scrub bar thumbnails
Extra features for better accessibility
And so on...

Advantages of relying only on the <video> element rather than on an


enhanced player:

Total control!
No need for external dependencies
Lightweight: no need to download lots of JavaScript and CSS code (also, Flash
fallbacks in some cases)

WhICH should I use? the <video> element and my


own customizations or an out of the box enhanced
player?
Either solution (basic player or enhanced player) is good and HTML5 compliant.

Popular players such as the Sublime video player (now bought by Dailymotion,
and no more officially supported, but still downloadable) and JW Player have
many explanations and examples on their Web sites, and are either free of
charge or come with free versions. The PayPal team open sourced an
"accessible video player" used on the PayPal Web site.

Interesting comparisons and reviews are available on the following


Web sites:

Comparison matrix of most of the existing video players


10 recent players compared

Example screenshots
Scrub Bar thumbnails (JW Player)

Custom look'n'feel and logo (Sublime video player):


Chapters and chapter thumbnails (JW Player):

PayPal accessible player:


LeanBack (says "free for non-commercial use", licensing is not very clear...):
[Link]: a framework for building your own custom
video player
Open source, and made for developers, [Link] comes with many plugins
(chapters, thumbnails etc.).
Enhanced HTML5 audio players
INTRODUCTION
In addition to enhanced video players, there are also enhanced audio players.
While there is room for lots of enhancements in a video player, the number of
features that can be added to audio players is rather limited. Usually
they come with support for playlists, shuffle mode, and a better look'n'feel
suitable for mobile Web applications.

Read this article about 10 enhanced HTML5 audio players, for example.

EXAMPLES
Chameleon audio player (commercial):

[Link]: an open source JavaScript library for creating an enhanced audio


player. Native JavaScript with fallbacks in Flash, etc.
HTML5 audio player by [Link]

SoundManager2, a free HTML5 audio player with flash fallback and a javaScript
API that makes it suitable to any kind of project.
Using the webcam video stream
Introduction to the getUserMedia API
The getUserMedia API is useful for controlling a webcam video stream. This
chapter presents the most interesting parts, related to
the <video> and <audio> elements.

While this API is one component of the WebRTC specification and therefore not
considered a "real" part of the HTML5 specification, we still consider it relevant
to the "multimedia" part of this course. The getUserMedia API, when dealing
with video streams, is always used in conjunction with the <video> element.

Typical use of the getUserMedia API WITH a Webcam


The main idea is to set the src attribute of a <video> element to the live video
stream object coming out of the webcam. To get this stream, you'll have to call
the [Link](params, onSuccess, onError) method from
the getUserMedia API.

The stream is passed as a parameter to the onSuccess() callback, as in this


typical example:
1. <video id="myVideo" autoplay>Fallback msg here.</video>
2. <script>
3. function onSuccess(stream) {
4. var output = [Link]('myVideo');
5. // use the default webcam if more than one are connected
6. [Link] = [Link]([Link]()[0]);
7. }
8. function onError() {
9. // getUserMedia API not supported, or another application is using the
webcam!
10. }
11.
12. if ([Link]) {
13. [Link]({video:true}, onSuccess, onError);
14. }
15. </script>

In fact, this example still does not work "as is". Prefixes need to be added to
the API function calls, due to limitations of current browser support.

HTTPS is mandatory: for getUserMedia to work, it is mandatory to access


the page that contains the JavaScript code through https:// otherwise you will
get an error message. Notice that all examples on jsbin use
[Link]

Current BROWSER Support (May 2016)


Since 2012, the getUserMedia API has been supported by Google Chrome,
Firefox and Opera, both on desktops and mobile devices, but you still need to
use the prefixed version of the API (i.e.
call webkitGetUserMedia or mozGetUserMedia instead of getUserMedia). While
Internet Explorer does not support it, it's supported by Microsoft Edge, IE's
successor.
Simple web camera display that works on all
browsers WITH support FOR the getUserMedia API

This example is available online: JS Bin example

It's similar to the first example above except that we use the prefixed versions
of getUserMedia(...). This example works on Opera/Chrome/Firefox on
Desktop and Mobile.

Another noticeable difference is the haircut of your instructor, but


that's another story :-)
Source code:

1. <html>
2. <head>
3. <meta charset="utf-8">
4. <title>JS Bin</title>
5. <script>
6. [Link] = ( [Link] ||
7. [Link] ||
8. [Link] ||
9. [Link]);
10.
11. if ([Link]) {
12. [Link] (
13. // constraints
14. {
15. video: true,
16. audio: false
17. },
18.
19. // successCallback
20. function(localMediaStream) {
21. var video = [Link]('video');
22. [Link] = [Link](localMediaStream);
23. },
24.
25. // errorCallback
26. function(err) {
27. [Link]("The following error occured: " + err);
28. }
29. );
30. } else {
31. [Link]("getUserMedia not supported");
32. }
33. </script>
34. </head>
35. <body >
36.
<video width=200 height=200 id="video" controls autoplay></video>
37. </body>
38. </html>

More on getUserMedia
Let's see some more examples of what we can do with the getUserMedia API:
start/stop the webcam, take a screenshot from the current video stream from
the webcam, and apply CSS effects in real time. And at the end, we give links
to some cool examples available on the Web.

How to stop/release the webCam

Online version at JS Bin


In order to stop the webcam and make the hardware "unlock it", you need to
call the stop() method of the video stream.

Modified version of the previous example:

1. <html>
2. <head>
3. <meta charset="utf-8">
4. <title>JS Bin</title>
5. <script>
6. [Link] = ( [Link] ||
7. [Link] ||
8. [Link] ||
9. [Link]);
[Link] webcamStream;
11.
12. function startWebcam() {
13. if ([Link]) {
14. [Link] (
15. // constraints
16. {
17. video: true,
18. audio: false
19. },
20.
21. // successCallback
22. function(localMediaStream) {
23. var video = [Link]('video');
24. [Link] = [Link](localMediaStream);
25. // We use the first webcam by default
26. webcamStream = [Link]()[0];
27. },
28.
29. // errorCallback
30. function(err) {
31. [Link]("The following error occurred: " + err);
32. }
33. );
34. } else {
35. [Link]("getUserMedia not supported");
36. }
37. }
[Link] stopWebcam() {
39. [Link]();
40.}
41. </script>
42. </head>
43. <body >
44.
<video width=200 height=200 id="video" controls autoplay></video>
45. <button onclick="startWebcam();">Start Webcam</button>

46. <button onclick="stopWebcam();">Stop Webcam</button>


47. </body>
48. </html>

Explanation:
Lines 6-9: set the [Link] method with the name that
works on the current browser. As some browsers only have experimental
implementations, this method needs to be prefixed by -webkitor -moz etc.
Then in the rest of the code, we can just
use [Link] without worrying about prefixes. If the browser
does not support this API at all, it will receive undefined.
Line 13: we test if [Link] is not defined (aka supported
by the current browser).
Lines 14-32: we call [Link]. We defined here (line 21 and
28) the callback functions directly between the parenthesis of the method call.
This is possible with JavaScript, and might confuse beginners:
Lines 15-19 define the first parameter of the call: a JavaScript object that
defines the "constraints", here we only want to capture the video.
Lines 22-27 define the function called in case of success, instead of having
just the function name here like in previous examples, we directly put the code
of the function. Lines 23-25 are executed when the webcam stream could be
opened. Line 25 we store the stream of the first available video stream (there
can be more than one webcam) in a global variable so that we can use from
another function (for stopping/starting the webcam...)
Lines 29-32 define a function called in case of error (the webcam cannot be
accessed).
Line 33: closing parenthesis of the [Link](...) method
call.
Lines 38-40: a function for stopping the webcam. We use the global
variable webcamStream here, that has been initialized when we started using
the webcam, line 25.

Other examples that mix in what we've SEEN in


previous chapters, but this time with a live video
stream
Applying CSS effects on a video element with a live webcam
Try this example that shows how to use the getUserMedia API - note the CSS
effects (click on the video to cycle from one effect to another). Works in
Chrome/Firefox/Opera: Online version at JS Bin
Taking a snapshot from the live webcam stream
The trick is to copy and paste the current image from the video stream into
a <canvas> element:
Online version at JS Bin
We will examine this example in greater detail next week when we look at
the <canvas> element. For the time being, just play with the example.
Impressive demonstrations available on the Web
WebCam pixelization! Fun!
A 3D rotating cube made with CSS3, that shows the webcam stream on the
facets.
A MUST TRY: Paul Neave's WebGL Camera Effects

Working with the microphone


Instead of using the getUserMedia API
with: [Link]({video:true}, onSuccess, onError), it is
also possible to use {audio:true} for the first parameter. In this case, only the
microphone input will be captured. Notice that {video:true, audio:true} is
also accepted, if you write a video conferencing system and need to capture
both the audio and the video (this is often the case when writing WebRTC
applications). The W3C WebRTC is another W3C specification, under
development, for P2P audio/video/data Real Time Communication.

Apart from videoconferencing, microphone input will be used for music Web
apps, from the WebAudio API. This API focuses on real time sound processing
and music synthesis. This API will be covered in the advanced W3Cx HTML5
course.

Do try some nice WebRTC applications like [Link] audio and video
conferencing tool. Also check out the WebAudio demonstrations written by
Chris Wilson, in particular the one called "Input effects".

Below is an example of real time audio processing of the microphone


input using getUserMedia and WebAudio APIs
[Link]: a free WebRTC video conferencing tool. It uses the getUserMedia API
for video and audio.
Week 3

About JavaScript and HTML5

HTML5 is composed of new elements, but it also comes with

many JavaScript APIs for controlling video and sound,

drawing and animating things in the new <canvas> element, for offline

applications, persistence, geolocation, orientation, etc.

So yes, during this course, in particular during Week 3 and 4, you will have

to do a bit of JavaScript. But, DON'T PANIC!

Here we provide a basic introduction to JavaScript. If you want to learn

more, many resources are available on the Web; this document is simply

here to give you a head start. Remember that one great thing about these

MOOCs courses is that everybody can help each other. Some students are

very good in JavaScript and are usually very happy to help others when

they encounter difficulties.


You will learn a lot by looking at examples, tweaking them,

cloning and modifying them, [Link] previous students who

were real JavaScript beginners managed to do all the assignments

(drawing and animating a monster with keyboard/mouse interaction)!

And they did this by just studying the provided examples.

External resources

 The book I used to learn JavaScript myself: Object Oriented JavaScript

by Stoyan Stefanov

 Mozilla Developper Network has a JS guide too.

Extracts from the forum posts:

 Video tutorials at Treehouse are very slick, this includes a basic JavaScript

course.
 Codecademy is also very good - very nice JavaScript introduction for

beginners. I recommend this for those with no JS knowledge as it starts

from scratch.

What do you need? How to debug? How to catch errors?

We will not look at the JavaScript syntax here, but more at "JavaScript in

the browser", how it works, how to start writing code, etc.

First of all, you need to find a way to debug your code and see errors. If

your work does not produce any results, you must know why!

For that you will use the dev. tools of your browser. Press F12 in

Windows or cmd-alt-i in Mac to open the dev. tools, then go to the

console tab: this is where errors will be displayed, or messages of

your own (use the [Link](string) JavaScript function in the


JavaScript code embedded in your html page). In the console, you will be

able to type any JavaScript command.

Let's look at this example on JS Bin:

1
2
3 <!DOCTYPE html>
4 <html>
5 <head>
6 <meta charset=utf-8 />
7 <title>Web Audio API</title>
8 <script>
9 [Link]("Some JavaScript code has been executed");
1 </script>
0 </head>
1 <body>
1 <h1>JavaScript debugging using the dev tool console</h1>
1 </body>
2 </html>
1
3

The simplest way to add JavaScript code in an HTML page, is by using

the <script>...</script> element.

The code in this example is executed sequentially when the page is

loaded: the JavaScript code is executed before the browser could see the
rest of the page (as the <script></script> is located before

the <body>).

The H1 element, for example, does not exist in the Document Object Model,

and has not yet been displayed when the JavaScript code is executed. If we

move the <script></script> at the end of the document, then the H1

would have been built before the JavaScript code is executed.

The only line of code we have is [Link]("Some JavaScript code

has been executed");

This means "display in the JavaScript console the message...". If we open

the console tab provided by [Link] in a dedicated tab (that redirects

all [Link]() messages), and re-execute the page (just type a space

at the end of a line, this will re-render the page and display the message in
the console), we see the message in the console tab, as well as in the dev.

tools console. This is illustrated by the image below:

It is also possible to use the "real dev. tool console", and for this I

recommend running the application in a single window, not in the JS

Bin editor. Press the black arrow on the top right of the output window -

this will render the page as a standalone Web page, then press F12. You

should see:
Ok, now, let's make an error:

change [Link]() into [Link](). Let's see what happens:


And if we run it standalone and use the dev. tool console:
And if we click on the line number in the right, the dev. tool shows the

source code centered on the line that caused the error:

Without such tools, debugging JavaScript code is impossible. So you need

to look at some basic tutorials on how to use the dev. tools of your

browsers, since they differ from one another in the way they work

- although the principles remain the same.


About the asynchronous nature of JavaScript

Some of you may not be used to "asynchronous programming", "callbacks"

etc. We recommend to read this article on WikiPedia and this thread on

StackOverflow.

Draw and animate graphics:


the <canvas> element
Introduction
The <canvas> tag is one of the "Flash killer" features of
HTML5. This course will focus on the fundamental drawing
capabilities of the HTML5 canvas.

The W3C HTML5 specification about


the <canvas> element states that "The canvas element
provides scripts with a resolution-dependent bitmap
canvas, which can be used for rendering graphs, game
graphics, or other visual images on the fly."

The canvas has been designed for pixel-based graphics, while SVG
(Scalable Vector Graphics, another W3C standard) is for vector-based
graphics.

Indeed, the canvas JavaScript drawing API supports different kind of shapes:
lines, rectangles, ellipses, arcs, curves, text, images. Some drawing styles need
to be specified that will affect the way shapes are drawn (color, drawing width,
shadows, etc.). An alpha channel for drawing in transparent mode is also
supported, as well as many advanced drawing modes and global filters (blur,
etc.).
The canvas is also used to do animations at 60 frames per second (useful for
games), to display videos with special effects, to display a webcam stream, and
so on.

Examples
Example 1
Foot Chinko, one of the most popular free HTML5 games (released in 2015):
Example 2
Data visualization with the HTML5 <canvas>:

Example 3
Love HTML5, a nice demo that shows 60 frames/s animation in a
canvas, (written in 2009)!
Performance is generally good today, since most Web browsers support
hardware acceleration or will add support soon. Back in 2009, this demo ran at
only a few images per second on some low-end computers (smartphones that
could run HTML5 demos, such as this one, did not exist at that time ) due to
the lack of hardware acceleration support in the browser's implementations of
the canvas API.

Note: 3D drawing using the WebGL API is also possible in a <canvas>, but will
not be covered in this course. For the most curious among you, please have a
look at the two popular libraries for doing 3D drawing/animation in
a <canvas>: BabylonJS and ThreeJS.
Current support by browsers (as of 2015)

An up-to-date version of this table is at: [Link]

Good external resources


[Link]
[Link]
[Link]
[Link]
How to make the HTML5 canvas
accessible to users with disabilities?
Introduction
The dynamic nature of the <canvas> element has made it difficult to use in
applications that need to be accessible to people with disabilities. To be
accessible, it must meet the following principles:
Providing alternative content for what is drawn on the <canvas>,
Exposing the location of shapes, paths, images drawn on the <canvas> to
assistive technologies,
Visually indicating whether or not a shape in the canvas had keyboard focus.

The W3C canvas task force


The Canvas Task Force of the W3C's HTML Working Group is working on
different features to be added to the HTML5.1 canvas specification in order to
address canvas accessibility. This is only preliminary work and browsers
implementations are not available yet.
Read more on this topic:
What the canvas element means for accessibility is an article written by Mark
Sadecki (ex-W3C, now working at edX).
From the W3C wiki: Canvas Element Accessibility Issues

Canvas cheatsheet with all API


methods and properties
This is a valuable resource, which we recommend either printing or
keeping open in a separate browser tab. The original version was located at
"[Link] but this
URL no longer works. Here, we share the mirrored versions (HTML and PDF
ones).
HTML version
Just follow this link: [Link]
[Link]

PDF version
The image links to a PDF - just click on it.
The canvas coordinate system
X axis is horizontal, directed to the right
Y axis is vertical, directed downwards
The coordinate system used for drawing in canvases is similar to the one used
by many drawing APIs like Java2D: the (0 , 0) is in the top left corner while the
X axis is going to the right and the Y axis to the bottom, as shown in the
following picture (author Mark Pilgrim):

Small errata about what I said in the above video: "So let's get the canvas

using the DOM API [Link]() or better,

use [Link]() that is a more recent method from the

DOM API"..
The part is bold is not correct: querySelector, technically, comes

from Selectors API. Just in case some people would like to go to the

specs...

Typical use of the <canvas> element

detailed explanation of the example shown in the video

Here are the different steps, in a little more detail, of the example

demonstrated in the above video:

1 - Add the <canvas> element into an HTML page

1. <canvas id="myCanvas" width="300" height="225">


2. Fallback content that will be displayed in case the web browser
3. does not support the canvas tag or in case scripting

4. is disabled.

5. </canvas>

Place code similar to the above somewhere in an HTML page. This

example defines an area of 300 by 225 pixels on which content can be

rendered with JavaScript.

Normally you should see nothing as a result; by default canvases are

"transparent".
Make it visible using CSS: A good practice when you are learning

to use canvases is to use some CSS to visualize the shape of the canvas.

This is not mandatory, just a good trick...

The three lines of CSS will create a border around the canvas

with id="myCanvas", of 1 pixel width, in black:

CSS code:

1. <style>
2. #myCanvas {
3. border:1px solid black;
4. }
5. </style>

2 - Select the <canvas> element for use from JavaScript

We can have more than one <canvas> in a single page, and canvases will

be manipulated with JavaScript like other elements in the DOM.

For example with:

1. var canvas = [Link]("myCanvas");

... or with the querySelector() method introduced by HTML5, that use

the CSS selector syntax for selecting elements:


1. var canvas = [Link]("#myCanvas");

3 - get a "2D context" associated with the canvas, useful for

drawing and setting drawing properties (color, etc.)

Once we have a pointer to the <canvas>, we can get a "context".

This particular object is the core of the canvas JavaScript API.

It provides methods for drawing, like fillRect(x, y, width,

height) for example, that draws a filled rectangle, and properties for

setting the color, shadows, gradients, etc.

Getting the context (do this only once):

1. var ctx=[Link]('2d');

Set the color for drawing filled shapes:

1. [Link]='red';

Draw a filled rectangle:

1. [Link](0,0,80,100);
Complete example that draws a filled rectangle in red

Try it online at JS Bin

Result:

Source code:

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <style>
5. #myCanvas {
6. border: 1px solid black;
7. }
8. </style>
9. <script>
10. var canvas, ctx;
11.
12. function init() {
13. // This function is called after the page is loaded
14. // 1 - Get the canvas
15. canvas = [Link]('myCanvas');
16. // 2 - Get the context
17. ctx=[Link]('2d');
18. // 3 - we can draw
19. drawSomething();
20. }
21. function drawSomething() {
22. // draw a red rectangle
23. [Link]='#FF0000';
24. [Link](0,0,80,100);
25. }
26. </script>
27. </head>
28. <body onload="init();">
29. <canvas id="myCanvas" width="200" height="200">
30. Your browser does not support the canvas tag.
31. </canvas>
32. </body>
33. </html>

Explanation

Only access elements when the DOM is ready:

Notice that we wrote an "init" function (line 12) that is called only when the

page has been entirely loaded (we say "when the DOM is ready"). There are

several ways to do this. In this example we used the <body

onload="init();"> method, at line 32.

It's good practice to have such a function, as we cannot access the

elements of the page before the page has been loaded entirely and before

the DOM is ready.


Another way is to put the JavaScript code at the end of the document

(between <script>...</script>), right before the </body>. In this case

when the JavaScript code is executed, the DOM has already been

constructed.

Start by getting the canvas and the context:

Before drawing or doing anything interesting with the canvas, we must first

get its drawing "context". The drawing context defines the drawing

methods and properties we can use.

Good practice is to get the canvas, the context, the width and height of the

canvas and other global objects in this "init" function.

After the context is set, we can draw, but first let's set the current

color for filled shapes:

The example shows the use of the fillStyle property at line 27 - useful

for specifying the way shapes will be filled. In our case this line indicates

the color of all the filled shapes we are going to draw:


1. [Link]='#FF0000';

The context property named fillStyle is used here. This property can

be set with a color, a gradient, or a pattern. We will see examples of these

later on in the course.

When we set it with a color, we use the CSS3 syntax.

The example says that all filled shapes will use the color "#FF0000",

which corresponds to a pure red color using the CSS RGB hexadecimal

encoding (we could also have used [Link]='red');

Then we can draw:

1. [Link](0,0,80,100);

This line is a call to the method fillRect(top left X coordinate, top

left Y coordinate, width, height), which draws a filled rectangle.

The way the rectangle will be filled depends on the current value of several

properties of the context, in particular the value of

the fillStyle property. So, in our case, the rectangle will be red.
Summary of the different steps

1. Declare the canvas, remembering to add an id attribute, and fallback

content:

<canvas id="myCanvas" width="200" height="200">

...fallback content...

</canvas>

2. Get a reference to the canvas in a JavaScript variable using the DOM

API:

var canvas=[Link]('myCanvas');

3. Get the context for drawing in that canvas:

var ctx=[Link]('2d');

4. Specify some drawing properties (optional):

[Link]='#FF0000';

5. Draw some shapes:

[Link](0,0,80,100);
Drawing principles
More about the "context" object
Before we go on, we should take some time to clarify the way we draw on
HTML5 canvases. We already mentioned that we use a graphic context for all
the main operations. Whenever a shape, a text, or an image is drawn, the
current values of the different properties of the graphic context are taken into
account. Some are relevant only for certain kinds of shapes or drawing modes,
but you must be aware that it is always the current values of these drawing
properties that are used.

Later on we'll see that there are ways to save and restore this whole set of
values, but for now, let's examine in greater detail some of the properties and
methods we've already encountered, and introduce new ones.

More about properties and methods of the context


object
fillStyle is a property of the context, similar in a way to a
CSS property.
Its value can be one of the following:
a color,
a pattern (texture), or
a gradient.

The default value is the color black. Any kind of drawing in "fill mode" will use
the value of this property to determine how to render the "filled part" of the
drawing: any filled rectangle will be filled black by default, any filled circle will
be filled in black, and so on.

As long as we don't modify the value of this property, all drawing commands
for filled shapes will use the current value.

Note that we will study in detail how to use colors, gradients and patterns later,
but for now we introduce some properties and values so that you can
understand the principles of canvas drawing.

fillStyle and the other context properties can be considered to be "global


variables" of the context.
fillRect(x, y, width, height): a call to this method draws
a filled rectangle.
The two first parameters are the coordinates of the top left corner of the
rectangle. This method uses the current value of the fillStyle property to
determine how to fill the rectangle.
1. [Link]='pink';
2. [Link](10,10,200,200);

Produces this result:

strokeStyle is a property of the context similar to fillStyle,


but this time for indicating how the shape's outline should
be rendered.
The possible values are the same as those for the fillStyle property: a color,
a pattern, or a gradient. This property will be taken into account when
wireframe shapes are drawn.
strokeRect(x, y, width, height): like fillRect(...), but
instead of drawing a filled rectangle the rectangle is drawn
in wireframe mode.
1. [Link]='blue';
2. [Link](10,10,200,200);

...produces this result:


Only the outline of the rectangle will be drawn, and it will be drawn using the
value of the strokeStyleproperty.

clearRect(x, y, width, height): a call to this method


erases the specified rectangle.
Actually it draws it in a color called "transparent black" (!) that corresponds to
the initial state of the rectangle as if no drawing had occurred.
1. [Link]='pink';
2. [Link](10,10,200,200);
3. [Link](50, 50, 20, 20);

The result is:


Let's see some simple examples...
Draw a wireframe red rectangle, width lineWidth = 3 pixels.
Interactive example available here at JS Bin

Extract from the source code (the part that draws the rectangle):

1. function drawSomething() {
2. // draw a red rectangle, line width=3 pixels
3. [Link]=3;
4. [Link]='red';
5. [Link](10,10,80,100);
6. }

Here, we used "stroke" instead of "fill" in the property and method names
(lines 4 and 5): strokeStyle instead of fillStyle, strokeRect(...) instead
of fillRect(...).

We also introduced a new property of the context, that applies only when
drawing in "stroke" mode, the lineWidth property (line 3), that is used for
setting the width of the shape outline. The value is in pixels.

Draw 2 filled red rectangles with a blue outline of 5


pixels and some text
Let's continue with another example. This time we will draw several shapes
that share the same colors - they will be filled in red, with a blue outline. We
also show how to draw a text message with a given font.
Online example on JS Bin

Source code extract:

1. function drawSomething() {
2. // set the global context values
3. [Link]=5;
4. [Link]='red';
5. [Link]='blue'
6. // font for all text drawing
7. [Link] = 'italic 20pt Calibri';
8. // Draw the two filled red rectangles
9. [Link](10, 30, 70, 150);
10. [Link](110, 30, 70, 150);
11. // Draw the two blue wireframe rectangles
12. [Link](10, 30, 70, 150);
13. [Link](110, 30, 70, 150);
14. // Draw a message above the rectangles
15. [Link]("hello", 70, 22);
16. }

This example shows the "global" nature of the context properties. Once you set
the filled color to red, any shapes you draw in filled mode will be red. This is
true for all the context properties. We set some of these properties in lines 3-7,
and all following calls to context methods for drawing rectangles or text will
depend on them. The two filled rectangles at lines 10-11 will be red, the two
wireframe rectangles drawn at lines 14-15 will be blue, etc.
Line 18 shows how to draw a text message at an X position of 70 and a Y
position of 22. The font is set at line 7 using the font property of the context.
The syntax is the same we use in CSS for using "system fonts".

If you would like to draw the filled text message in green, for example, you
should set the [Link] to "green" after you draw the
rectangles and before you draw the text (i.e just before line 18).

Summary of what we learned


"stroke" means "wireframe" or "outlined", it is a prefix for setting properties or
calling methods that will affect wireframe shapes, "fill" is a prefix for filled
shapes.
To set the properties of wireframe shapes use [Link]= ..., for
filled shapes use [Link]=... So far the values we have used are
colors, expressed as strings. Example: [Link] = 'blue';
To draw a wireframe rectangle use [Link](x, y, width, height),
to draw a filled rectangle use [Link](x, y, width, height);
To set the line width of wireframe shapes, use the [Link] property.
Example [Link] = 10; [Link](0, 0, 100, 100); will draw
a 100x100 rectangle in wireframe mode, with an outline width of 10 pixels.
To draw a text message use [Link](message, x,
y) or [Link](message, x, y), for wireframe text or filled text
respectively.
To set the character font use the [Link] property; the value is a font in CSS
syntax, for example: [Link] = 'italic 20pt Calibri';

2D transformations: changing the


coordinate system
Introduction
In this part of the course, we introduce the basics of 2D transformations, a
powerful tool that will make things easier as soon as you have to:
Draw complex shapes at given positions, with given orientations and sizes,
Draw shapes relative to one another.

Let's start with some simple examples before looking at how we use 2D
transforms.
Let's draw three rectangles!
If we draw three rectangles of size 100x200 in a 400x400 canvas, one at (0, 0)
and another at (150, 0), and a third at (300, 0), here is the result and the
corresponding code:

JavaScript code extract (see the online example at JS Bin for the
complete running code)

1. function drawSomething() {
2. [Link]='lightgreen';
3.
4. [Link](0,0,100,200);
5. [Link](150,0,100,200);
6. [Link](300,0,100,200);
7. }

Let's modify the code so that we can draw these


rectangles at any X and Y position
What if we wanted to draw these 3 rectangles at another position, as a group?
We would like to draw all of them a little closer to the bottom, for example...
Let's add some parameters to the function: the X and Y position of the
rectangles.

The full JavaScript code is (see online running example):

1. var canvas, ctx;


2. function init() {
3. // This function is called after the page is loaded
4. // 1 - Get the canvas
5. canvas = [Link]('myCanvas');
6. // 2 - Get the context
7. ctx=[Link]('2d');
8. // 3 - we can draw
9. drawSomething(0, 100);
10. }
[Link] drawSomething(x, y) {
12. // draw 3 rectangles
13. [Link]='lightgreen';
14. [Link](x,y,100,200);
15. [Link](x+150,y,100,200);
16. [Link](x+300,y,100,200);
17. }

At line 10, we called the drawSomething(...) function with 0 and 100 as


parameters, meaning "please add an offset of 0 in X and 100 in Y directions to
what is drawn by the function...

If you look at the code of the modified function, you will see that each call
to fillRect(...) uses the x and y parameters instead of hard coded values.
In this way, if we call it with parameters (0, 100), then all rectangles will be
drawn 100 pixels to the bottom (offset in y). Here is the result:
Ok, Now let's draw a small monster's head with
rectangles
Now we can start having some fun... let's draw a monster's head using only
rectangles (online version):
An extract of the JavaScript source code is:

1. function drawMonster(x, y) {
2. // head
3. [Link]='lightgreen';
4. [Link](x,y,200,200);
5. // eyes
6. [Link]='red';
7. [Link](x+35,y+30,20,20);
8. [Link](x+140,y+30,20,20);
9. // interior of eye
10. [Link]='yellow';
11. [Link](x+43,y+37,10,10);
12. [Link](x+143,y+37,10,10);
13. // Nose
14. [Link]='black';
15. [Link](x+90,y+70,20,80);
16. // Mouth
17. [Link]='purple';
18. [Link](x+60,y+165,80,20);
19. }

As you can see, the code uses the same technique, becomes less and less
readable. The Xs and Ys at the beginning of each call makes understanding the
code harder, etc.

However, there is a way to simplify this => 2D geometric transformations!

GEOMETRIC Transformations: changing the


coordinate system
The idea behind 2D transformations is that instead of modifying all the
coordinates passed as parameters to each call to drawing methods
like fillRect(...), we will keep all the drawing code "as is". For example, if
the monster of our previous example was drawn at (0, 0), we could just
translate (or rotate, or scale) the original coordinate system.

Let's take a piece of code that draws something corresponding to the original
coordinate system, located at the top left corner of the canvas:

1. function drawMonster(x, y) {
2. // head
3. [Link]='lightgreen';
4. [Link](0,0,200,200);
5. // eyes
6. [Link]='red';
7. [Link](35,30,20,20);
8. [Link](140,30,20,20);
9. // interior of eye
10. [Link]='yellow';
11. [Link](43,37,10,10);
12. [Link](143,37,10,10);
13. // Nose
14. [Link]='black';
15. [Link](90,70,20,80);
16. // Mouth
17. [Link]='purple';
18. [Link](60,165,80,20);
19. // coordinate system at (0, 0)
20. drawArrow(ctx, 0, 0, 100, 0, 10, 'red');
21. drawArrow(ctx, 0, 0, 0, 100, 10, 'red');
22. }

This code is the just the same as in the previous example except that we
removed all Xs and Yx in the code. We also added at the end (lines 25-26) two
lines of code that draw the coordinate system. The drawArrow(startX,
startY, endX, endY, width, color) function is a utility function that we will
present later. You can see it in the source code of the complete online example
on JS Bin: look in the JavaScript tab.

Note that the X and Y parameters are useless for now...

Result:

Translation using [Link](offsetX, offsetY)


Now, instead of simply calling drawMonster(0, 0), we will call
first [Link](100, 100), and look at the result (online
code: [Link]
JavaScript code extract:

1. [Link](100, 100);
2. drawMonster(0, 0);

Line 1 changes the position of the coordinate system, line 2 draws a monster in
the new translated coordinate system. All subsequent calls to drawing methods
will be affected and will work in this new system too.

Other transformations: rotate, scale


There are other transformations available:
[Link](angle), with angle in radians. Note that the order of
transformations is important: usually we translate, then rotate, then scale... If
you change this order, you need to know what you are doing...
[Link] (sx, sy), where scale(1, 1) corresponds to "no
zoom", scale(2, 2) corresponds to "zooming 2x" and scale(0.5,
0.5) corresponds to zooming out to see the drawings half as big as before. If
you do not use the same values for sx and sy, you do "asymmetric scaling",
you can distort a shape horizontally or vertically. Try changing the values in the
source code of the next online examples.
Here is the previous example, but this time we translated the coordinate
system, then rotated it with an angle equal to PI/4 , then we scaled it so that
units are half as big (see the example online):

And here is the code of the transformations we used, followed by the call to the
function that draws the monster:

1. [Link](100, 100);
2. [Link]([Link]/4);
3. [Link](0.5, 0.5);
4.
5. drawMonster(0, 0);

Line 1 does:
Line 2 does:

Line 3 does:
Line 4 draws the monster in this new translated, rotated, scaled coordinate
system:
BEWARE: all drawings to come will be in that
modified coordinate system!
If we draw two shapes at two different positions, they will be relative to this
new coordinate system.

For example, this code (online at [Link]

1. [Link](100, 100);
2. [Link]([Link]/4);
3. [Link](0.5, 0.5);
4. // Draw the monster at (0, 0)
5. drawMonster(0, 0);
6. // Draw a filled rectagle at (250, 0)
7. [Link](250, 0, 100, 100);

... gives this result:


How can we reset the coordinate system, how can
we go back to the previous one?
Aha, this is a very interesting question... we will give the answer very soon in
the section on saving/restoring the context :-)

Saving and restoring the context


There are two methods for saving and restoring the context
properties: [Link]()and [Link]().

What will be saved: fillStyle and strokeStyle, lineWidth, previous


coordinate system, etc., that is ALL properties that affect drawing!

A call to [Link]() will probably save the context property values in a


hardware register on your graphics card. Multiple contexts can be saved
consecutively and restored.

Contexts saved will be stacked, the last one that has been saved will be
restored by the next call to restore(), so it is very important to have one
restore for each save.

Best practice: save the context at the beginning of any function


that changes the context, restore it at the end of the function!
Example of a function that changes the context and
restores it after execution
Online example: [Link]
We took the last example we saw (the one with the monster, from the previous
page of the course), and slightly modified the function that draws the monster:

We added parameters for setting the position and orientation of the monster,
and added calls to [Link](x, y) and [Link](angle) in the
function.
We added parameters for the head color and eye color.
We saved the context at the beginning of the function (BEST PRACTICE),
We restored it at the end (BEST PRACTICE).

Source code extract of this function: notice at lines 3 and 26 how we


save/restore the context at the beginning/end. Right after saving the context,
we modify the coordinate system (lines 7-8). The rest of the code is nearly the
same as in the last version of the monster example.

1. function drawMonster(x, y, angle, headColor, eyeColor) {


2. // BEST PRACTICE : SAVE CONTEXT AND RESTORE IT AT THE END
3. [Link]();
4. // Moves the coordinate system so that the monster is drawn
5. // at position (x, y)
6. [Link](x, y);
7. [Link](angle);
8. // head
9. [Link]=headColor;
10. [Link](0,0,200,200);
11. // eyes
12. [Link]='red';
13. [Link](35,30,20,20);
14. [Link](140,30,20,20);
15. // interior of eye
16. [Link]=eyeColor;
17. [Link](43,37,10,10);
18. [Link](143,37,10,10);
19.
20. ...
21. // BEST PRACTICE!
22. [Link]();
23. }

Drawing rectangles - immediate


drawing mode
Introduction
In the previous sections, we learned how to draw filled or wireframe rectangles.

As soon as the [Link](x, y, width, height) or


the [Link](x, y, width, height) method is called, a rectangle is
indeed drawn immediately in the canvas.

While drawing rectangles with strokeRect or fillRect, drawing text or


drawing images, all these shapes will be drawn in immediate mode.
Another mode called "path mode" or "buffered mode" will be seen later in this
course, which will be useful for drawing lines, curves, arcs, and also rectangles.
Rectangles are the only shapes that have methods for drawing
them immediately and also other methods for drawing them in "path/buffered
mode".

Example: drawing rectangles in immediate


mode using good practice
We'll just give an example here that draws several rectangles, filled or
wireframe, with different colors and line widths.

Online example on JS Bin

Source code:

1. <!DOCTYPE HTML>
2. <html>
3. <head>
4. <title>Some rectangles drawn in immediate mode</title>
5. <style>
6. #myCanvas {
7. border: 1px solid #9C9898;
8. }
9. </style>
10. <script>
11. var canvas, ctx;
12.
13. [Link] = function () {
14. canvas = [Link]('myCanvas');
15. ctx = [Link]('2d');
16.
17. // black rectangle, default color (black)
18. [Link](10, 10, 100, 100);
19. // outlined rectangle, default color
20. [Link](150, 10, 100, 100);
21.
22. // outlined rectangle filled in red, outline blue
23. [Link] = 'red';
24. [Link] = 'lightBlue';
25. [Link] = 10;
26. [Link](100, 150, 150, 150);
27. [Link](100, 150, 150, 150);
28.
29. // A function that automatizes previous drawing
30. var angle = [Link] / 10;
31.
drawFilledRectangle(300, 150, 150, 150, 'pink', 'green', 10, angle);
32.
drawFilledRectangle(300, 150, 150, 150, 'yellow', 'purple', 10, angle +0.5);
33. };
34.
35. function drawFilledRectangle(x, y, w, h, fillColor, strokeColor, lw, ang
le) {
36. // GOOD PRACTICE: save if the function changes the context
37. // or coordinate
38. // system
39. [Link]();
40.
41. // position coordinate system
42. [Link](x, y);
43. [Link](angle);
44.
45. // set colors, line width...
46. [Link] = lw;
47. [Link] = fillColor;
48. [Link] = strokeColor;
49.
50. // draw at 0, 0 as we translated the coordinate
51. // system already
52. [Link](0, 0, w, h);
53. [Link](0, 0, w, h);
54.
55. // GOOD PRACTICE: a restore for a save!
56. [Link]();
57. }
58. </script>
59. </head>
60. <body>
61. <canvas id="myCanvas" width="578" height="400">
62. </canvas>
63. </body>
64. </html>

Drawing text
Introduction
The canvas API provides two main methods for drawing
text: [Link](message, x, y) and [Link](message, x, y).

It also provides a set of context properties for setting the character font and
style, for laying out the text, etc.
Typical use
Try this example online: [Link]

Source code extract:

1. [Link] = "60pt Calibri";


2. // .. set color, lineWidth, shadow etc.
3. // 10, 10 is the start of the baseline, bottom of left leg of the "H" in the
4. // "Hello World" example.
5. [Link]("Hello World!", 10, 10);
6. // Or
7. [Link]("Hello World!", 10, 10);

Look at the code from the example provided: [Link] -


change the position where the text is drawn, change font attributes, etc.

The [Link] property:


It is possible to draw text in a canvas using the font property of the context to
specify the font style (plain, bold, italic), the size, and the font name. Other
properties such as strokeStyle or fillStyle, as well as other properties
detailed in the next subchapters, will also be taken into account.

The font property is CSS-compliant, and accepts values like:

[font style][font weight][font size][font face]

Accepted values are:


font style: normal, italic, oblique, inherit
font weight: normal, bold, bolder, lighter, auto, inherit, 100, 200, 300, 400,
500, 600, 700, 800, 900
font size: a size in pixels or in points, such as 60pt, 20px, 36px, etc.
font face: Arial, Calibri, Times, Courier, etc. Some font faces may not work in
all browsers.

Examples:
[Link] = "60pt Calibri";
[Link] = "normal normal 20px Verdana";
[Link] = "normal 36px Arial";
[Link] = "italic bold 36px Arial";

The fillText() or strokeText() methods


The fillText(message, x, y) or strokeText(message, x, y) methods from
the context will actually draw a text message at the origin of the baseline
position. In the "Hello World" example, this is located at the bottom of the left
leg of the "H".

There is a fourth optional parameter maxWidth that forces the text to fit into a
given width, distorting it if necessary:

1. [Link]("Hello World!", x, y [, maxWidth]);


2. [Link]("Hello World!", x, y [, maxWidth]);

Example that uses the maxWidth parameter of


the strokeText() or fillText()methods:
Try it online: [Link]

Source code extract:

1. ...
2. [Link] = "60pt Calibri";
3. [Link] = 3;
4. [Link] = "blue";
5. [Link] = "red";
6. [Link]("Hello World!", 10, 100);
7. [Link]("Hello World!", 10, 100);
8. // Draw text with constrained width of 250 pixels
9. [Link]("Hello World!", 10, 160, 250);
[Link]("Hello World!", 10, 160, 250);
11. // Constrain width to 150 pixels
[Link]("Hello World!", 10, 220, 150);
[Link]("Hello World!", 10, 220, 150);

Measuring the width of a given text (bounding box)


Try this example online: [Link]

The [Link]() method can be used to get the current width in pixels
of a given text, taking into account the diverse properties involved such as
font, size, shadow, lineWidth, etc.

Source code extract from this example:

1. [Link] = "60pt Calibri";


2. [Link] = 3;
3. [Link] = "blue";
4. [Link] = "red";
5. [Link]("Hello World!", 10, 100);
6. [Link]("Hello World!", 10, 100);
7. var textMetrics = [Link]("Hello World!");
8. var width = [Link];
9. // Draw a text that displays the width of the previous drawn text
10. [Link] = "20pt Arial";
11. [Link]("Width of previous text: " + width + "pixels", 10, 150);
12. // Draw the baseline of the given width
13. [Link](10, 100);
14. [Link](width+10, 100);
15. [Link]();

The [Link] property: change the way


the text is horizontally drawn
Try this example at JS Bin (borrowed and adapted
from [Link]

The text baseline is important as it tells how the y parameter of


the fillText("some text", x, y) and strokeText("some text", x,
y) methods is interpreted.

The textBaseline property of the context is used to specify the different ways
one can position the baseline of a given text. The example above shows the
different possible values for this property and the corresponding results. The
default value is "alphabetic" and corresponds to what has been used in the
previous "Hello World" example.

Possible values:

Possible values for the textBaseline property

The text is aligned based on the top of the tallest glyph in the text.
top

The text is aligned based on the line the text seems to hang from. This is almost identical
hanging to top, and in many cases, you cannot see the difference.
The text is aligned according to the middle of the text.
middle

The bottom of vertically oriented glyphs, e.g. western alphabet like the latin.
alphabetic

The bottom of horizontally oriented glyphs.


ideographi
c

The text is aligned based on the bottom of the glyph in the text, that extends
bottom furthest down in the text.

Typical use (taken from the example above):

1. [Link] = "top";
2. [Link]("top", 0, 75);
3. [Link] = "hanging";
4. [Link]("hanging", 40, 75);
5. [Link] = "middle";
6. [Link]("middle", 120, 75);

Horizontal text alignment


Try this example online: [Link]
The textAlign property of the context tells how the x parameter will be used
when calling strokeText("some text", x, y) and fillText("some text",
x, y). For example, with textAlign="center", the x parameter gives the
position of the vertical center of the text, while
in textAlign="right", x corresponds to the rightmost position of the text.

Typical use (source code taken from the above example):

1. [Link] = "center";
2. [Link]("center", 250, 20);
3. [Link] = "start";
4. [Link]("start", 250, 40);
5. [Link] = "end";
6. [Link]("end", 250, 60);
7. [Link] = "left";
8. [Link]("left", 250, 80);
9. [Link] = "right";
10. [Link]("right", 250, 100);

Drawing images
Introduction
Load images in the background, wait for them to be loaded
before drawing!
Working with images is rather simple, except that we need the images to be
fully loaded into memory before drawing them. Loading images is
an asynchronous process we need to take care of. Working with multiple
images might also be difficult for beginners. Later on in this course, we will
present a multiple image loader.

It is also possible to draw images from a video stream, images corresponding


to another canvas content, or images that are defined by <img> HTML elements
in the page. We will see that as well in the following parts of this chapter.

But let's start with a basic example!


Example 1: drawing an image
Try this example online: [Link]

Source code:

1. <!DOCTYPE HTML>
2. <html>
3. <head>
4. <script>
5. [Link] = function() {
6. // It is necessary to wait for the web page to load before running this code.
7. var canvas = [Link]("myCanvas");
8. var context = [Link]("2d");
9. var imageObj = new Image();
10. // Callback function called by the [Link] = .... line
11. //located after this function
12. [Link] = function() {
13. // Draw the image only when we have the guarantee
14. // that it has been loaded
15. [Link](imageObj, 0, 0);
16. };
17.
18. // Calls the [Link] function asynchronously
19. [Link] =
20. "[Link]
21. };
22. </script>
23. </head>
24. <body>
25. <canvas id="myCanvas" width="512" height="512"></canvas>
26. </body>
27. </html>

Several things need to be explained here:


[Link] have to create a JavaScript Image object (line 10),
[Link] we set the src attribute of this object with the URL of the image file,
then an asynchronous request is sent in the background by the
browser. Loading a big image may take some time, so the rest of the
JavaScript code continues running. This is why we call it "asynchronous".
[Link] the image file has been loaded, the browser calls
the onload callback associated with the image (line 14).
[Link] draw the image only from inside this callback, otherwise we have
no guarantee that the image has been loaded and can be usable. The actual
drawing here is done line 17.

There are numerous variants of the drawImage(...) context


method at line 17:
drawImage(img, x, y): draws the image at position x, y, keeping the original
image size.
drawImage(img, x, y, sizeX, sizeY): same as before except that the
image drawn is resized.
drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh): for drawing sub-
images, (sx, sy, sw, sh) define the source rectangle, while dx, dy, dw, sh define
the target rectangle. If these rectangles don't have the same size, the source
sub-image is resized.

See picture below :


Example 2: show the different variants
of drawImage(...)
Online example: [Link]
Source code extract:

1. var imageObj = new Image();


2.
3. [Link] = function() {
4. // Try commenting/uncommenting the following lines to see the
5. // effect of the different drawImage variants
6. // Original, big image
7. // [Link](imageObj, 0, 10);
8. // Original image drawn with size = 100x100 pixels
9. [Link](imageObj, 0, 10, 100, 100);
10. // with size = 150x150
11. [Link](imageObj, 80, 10, 150, 150);
12. // with size = 200x200
13. [Link](imageObj, 210, 10, 200, 200);
14.
15. // draw the sub image at 0, 0, width = 512, height = 100
16. // at position 100, 250, with a width of 256 and a height of 50
17. [Link](imageObj, 0, 0, 512, 100, 100, 250, 256, 50);
18. };
19. [Link] = "[Link]
HTML5_Logo_512.png";
20. };

Example 3: draw an image defined in the page by


an <img src="..."> element
Sometimes, you may want to draw an image that is already declared in the
HTML document as an <img src="..."> element. Remember that when you
add an <img> in the document, the browser starts downloading it in
background.

WRONG => indeed, you could try drawing it using some code like this:

1. <body>
2. <canvas id="myCanvas" width="512" height="512"></canvas>
3. <p>Original image as an <img> element:</p>
4. <img id="logo"
5. src="[Link]
texture_85_by_voyager168-[Link]">
6. <script>
7. canvas = [Link]("myCanvas");
8. var ctx = [Link]("2d");
9. var logo = [Link]("#logo");
10. [Link](logo, 0, 0, 100, 100);
11. </script>
12. </body>

Although you will find many examples on the Web that do it this way, they will
only work most of the time with small images, or with images that are in the
browser's cache. Remember that you cannot draw an image that has not
been fully loaded!

If you try to draw an image that is not loaded or partially loaded, you will have
unexpected results!
Best practice: only draw an image that is fully loaded, use
the onload callback!
GOOD => the right way to do this is shown in this
example: [Link] that starts drawing only from
the onload callback function:
1. <!DOCTYPE HTML>
2. <html>
3. <head>
4. <script>
5. var canvas, context;
6. [Link] = function() {
7. canvas = [Link]("myCanvas");
8. context = [Link]("2d");
9.
10. draw();
11. };
12. function draw() {
13. var imageObj = [Link]("#logo");
14. [Link]("image is already loaded, we draw it!");
15. [Link](imageObj, 0, 10, 100, 100);
16. }
17. </script>
18. </head>
19. <body>
20. <canvas id="myCanvas" width="512" height="512"></canvas>
21. </p>
22.<img id="logo" src="[Link]
HTML5_Logo_512.png">
23. </body>
24. </html>

With large image files, this will not break nor produce unexpected
results: [Link]

The DOM Level 2 Events specs say :


The load event occurs when the DOM implementation
finishes loading all content within a document, all frames
within a FRAMESET, or an OBJECT element.
Results with a very large image (5160x3270 pixels):
Drawing images from a video stream
The drawImage(...) function can take a video element as its first parameter.
The image that will be drawn is the one currently played by the video stream.
This can be done at video frequency on most modern computers or mobile
devices.

Online example at [Link]

This example shows:

a <video> element on top, and four images drawn in a canvas below.


The images are drawn every XXX milliseconds using
the setInterval(function, delay) method.
Source code extract:

1. <script>
2. var video;
3. var canvas, ctx;
4. var angle = 0;
5.
6. function init() {
7. video = [Link]('sourcevid');
8. canvas = [Link]('myCanvas');
9. ctx = [Link]('2d');
10.
11. setInterval("processFrame()", 25); // call processFrame each 25ms
12. }
13.
14. function processFrame() {
15. [Link](video, 0, 0, 320, 180);
16. drawRotatingVideo(480, 90);
17. [Link](video, 0, 180, 320, 180);

18. [Link](video, 320, 180, 320, 180);


19. }
20.
21. function drawRotatingVideo(x, y) {
22. // Clear the zone at the top right quarter of the canvas
23. [Link](320, 0, 320, 180);
24.
25. // We are going to change the coordinate system, save the context!
26. [Link]();
27. // translate, rotate and recenter the image at its "real" center,
28. //not the top left corner
29. [Link](x, y);
30. [Link](angle += 0.01); // rotate and increment the current angle
31. [Link](-80, -45);
32.
33. [Link](video, 0, 0, 160, 90);
34.
35. // restore the context
36. [Link]();
37. }
38. </script>
39. </head>
40.
41. <body onload="init()" >
42. <p>This is a <video> element: </p>
43.<video id="sourcevid" autoplay="true" loop="true">
44. <sourcesrc="[Link]
BigBuckBunny_640x360.mp4"
45. type="video/mp4" />
46. <sourcesrc="[Link]
BigBuckBunny_640x360.ogv"
47. type="video/ogg"/>
48. </video>
49. <p>This is a <canvas> element: </p>
50.<canvas id="myCanvas" width="620" height="360"></canvas>
51. </body>

Line 11: the call to setInterval will make the browser execute
the processFrame function each 25ms.
Lines 15, 17 and 18: in processFrame, drawImage(...) is called 3 times with
the video element passed as first parameter.
Line 43: the video element declared at line 43
has autoplay=true and loop=true, it starts playing the video as soon as
possible and will loop it.
Line 21: We implemented a rotating video effect in
the drawRotatingVideo. The use of context save/restore is primordial as this
function changes the coordinate system at each call, translating and rotating it.
Notice the extra translation at line 31 that translates the coordinate system
backwards with half of the size of the image that is drawn. We did this in order
to make the image rotate around the center of the rectangle, instead of around
the top left corner at (0, 0) by default. Try commenting out this line in the
running example and you will see what we mean.

Immediate drawing mode vs path


drawing mode
Immediate mode = executing a call to a drawing
method means immediately drawing in the canvas
In the previous examples, we saw how to draw rectangles using
the fillRect(x, y, width, height) and strokeRect(x, y, width,
height) methods of the context.

We also learned how to draw a text message using the fillText(message, x,


y) and strokeText(message, x, y) methods that draws a text in filled and
wireframe mode, respectively.

These methods, along with


the drawImage(...) method already seen in section
3.3.3, are "immediate methods": as soon as they
are executed, the results are displayed on screen,
the drawings are performed, pixels on the canvas
area change their colors, etc.

Here is a code extract that will draw 1000 random


rectangles in a canvas, using immediate mode
rectangle drawing calls.

Online example: [Link]

1. var canvas, ctx, w, h;


2. function init() {
3. canvas = [Link]('myCanvas');
4. ctx = [Link]('2d');
5. w = [Link];
6. h = [Link];
7. [Link]("time to draw");
8. for(var i=0; i < 1000; i++) {
9. var x = [Link]() * w;
10. var y = [Link]() * h;
11. var width = [Link]() * w;
12. var height = [Link]() * h;
13. [Link](x, y, width, height);
14. }
15. [Link]("time to draw");
16. }

Lines 12-18 draw 1000 rectangles of random sizes in immediate mode. We also
measure the time using the
usual [Link](name_of_timer) and [Link](name_of_timer)
that will write in the browser console the time elapsed. Note
that [Link](...) and [Link](...) display results only in
the browser's console, not in the JS Bin console.

On a Mac Book Pro from 2015, the result is:

Path mode = fill a buffer then execute all buffered


orders at once to enable optimization and
parallelism
There is another drawing mode called "path drawing mode" where you first
send drawing orders to the graphics processor, and these orders are stored in a
buffer. Then you call methods to draw the whole buffer at once. There are also
methods to erase the buffer's content.

Path drawing mode allows parallelism: if you need to draw 10,000 rectangles,
it's better to store the orders in the graphics card, then execute the drawing all
at once, rather than doing 10,000 immediate calls to strokeRect(...) for
example. With the buffered mode, the Graphic Processing Unit (GPU) of the
graphics card hardware will be able to parallelize the computations (modern
graphics cards can execute hundreds/thousands of things in parallel).

Same example as before, this time using the buffered mode for drawing
rectangles: [Link]

Extract from source code (the part that draws the rectangles):

1. for(var i=0; i < 1000; i++) {


2. var x = [Link]() * w;
3. var y = [Link]() * h;
4. var width = [Link]() * w;
5. var height = [Link]() * h;
6. [Link](x, y, width, height); // store a rectangle in path/buffer
7. }
8. [Link](); // draws the whole buffer (the 1000 rectangles) at once

Instead of calling strokeRect(...) or fillRect(...), we just call


the rect(...) method of the context (line 7). This is how we can delay the
drawing of the rectangles. The 1000 rectangles are stored in a buffer in the
hardware.

The call to [Link]() (line 9) or to its sister method [Link]() will draw
the entire buffer contents in fill or stroke mode.

And here is what the timer gives: a slightly faster execution time. Changing
1000 to 100,000 will give even larger differences.

Path mode is faster than immediate mode!

Reset the path mode buffer


A call to [Link]() will reset the buffer (empty its contents). We will
see many more examples of using the Path drawing mode in another section
later on this week.
1. // start a new buffer / path
2. [Link]();
3. // all these orders are in a buffer/path
4. [Link](10, 10);
5. [Link](100, 100);
6. [Link](150, 70);
7. // Draw the buffer
8. [Link]();
Summary of Path mode principles
[Link] drawing methods that work in path mode, for example
call [Link](...) instead of [Link](...) or [Link](...)
[Link] [Link]() or [Link]() to draw the buffer's contents,
[Link] that the buffer is never emptied, two consecutive calls
to [Link]() will draw the buffer contents twice! Instead,
use [Link]() to empty it if needed.
[Link] is possible to empty the buffer by calling [Link]().
[Link] drawing is faster than immediate drawing (parallelization is possible).

Warning: you do not need to spend too


much time on each part of this sub-
section
You do not need to memorize or learn by heart all the examples in the
following pages. They are given as references. There will be no exercises about
curves as they are not often done "by hand", but are generated by tools such
as Adobe Illustrator or online generators.
You need to draw arcs? Then, please use the corresponding section as a
reference: you know you will find one or more examples, also available on JS
Bin, and a detailed explanation.
You need to draw lines? Arrows? Curves? Same thing: go to the
corresponding page and get a look at the examples!

Also, do not forget to use the cheatsheet provided at the beginning of the
course. You will find it very helpful when you start playing with the canvas.

Path drawing: lines


Introduction
We have been drawing rectangles so far.

Now let's go a bit further by introducing the notion of "path drawing". This
approach uses the [Link](x, y) method of the context, in conjunction
with other drawing methods that end in "To", such as [Link](x, y).

This makes it easier to draw multiple connected lines. Consecutive calls


to [Link](x, y) will store in the path/buffer a set of connected lines that
we will draw altogether by a single call to [Link]() or [Link]().
Here are the different steps:

[Link] the "pencil" somewhere with a call to [Link](x1, y1). This will be
the origin of the first line.
[Link] the [Link](x2, y2) method to draw a line from the previous
position (previous step) to the position passed as parameters to
the lineTo(...) method. This position will serve as the origin for the next line
to be drawn.
[Link] lineTo(x3, y3) again to draw a line that goes from (x2, y2) to (x3, y3).
This line will start at the end of the previous one.
[Link] step 3 to draw more connected lines.
[Link] the [Link]() or the [Link]() methods to draw the path defined
by the different lines.

Note the call to [Link]() or [Link]() will use the current values of
the strokeStyle or fillStyleproperties. It is possible to call [Link](x,
y) in the middle of steps 1 through 5 in order to move the pen somewhere else
without connecting to the last drawn line.

Here is an example that draws a grid: [Link]

1. var canvas=[Link]('myCanvas');
2. var ctx=[Link]('2d');
3. // Vertical lines
4. for (var x = 0.5; x < 500; x += 10) {
5. [Link](x, 0);
6. [Link](x, 375);
7. }
8. // Horizontal lines
9. for (var y = 0.5; y < 375; y += 10) {
10. [Link](0, y);
11. [Link](500, y);
12. }
13.
14. // Draw in blue
15. [Link] = "#0000FF";
16.
17. // Until the execution of the next line, nothing has been drawn!
18. [Link]();

In this example, the entire grid is drawn during the execution of the last line of
code, with the single call to [Link]().

Another example mixing filled and wireframe shapes


(and immediate and path modes)
Try this interactive example here: [Link]

1. var canvas=[Link]('myCanvas');
2. var ctx=[Link]('2d');
3. // a filled rectangle in immediate mode
4. [Link]='#FF0000';
5. [Link](0,0,80,100);
6. // two consecutive lines in path mode
7. [Link](0,0);
8. [Link](100, 100);
9. [Link](100,0);
10. // draws only the two lines in wireframe mode
11. [Link] = "#0000FF";
12. [Link]();
This example shows that filled and wireframe shapes should be drawn
differently (here a filled rectangle is drawn using a call to
the fillRect(...) method while a wireframe set of connected lines is drawn
using the stroke() method of the context).

Drawing a single path made with


disconnected lines / parts
Try this interactive example here: [Link]

1. var canvas=[Link]('myCanvas');
2. var ctx=[Link]('2d');
3. // first part of the path
4. [Link](20,20);
5. [Link](100, 100);
6. [Link](100,0);
7. // second part of the path, moveTo(...) is used to "jump" to another place
8. [Link](120,20);
9. [Link](200, 100);
10. [Link](200,0);
11. // indicate stroke color + draw the path
12. [Link] = "#0000FF";
13. [Link]();

In this example, we simply called the moveTo() method between each part of
the path. And we called stroke() only once to draw the whole path.
Drawing lines with different styles
Common mistake: drawing the same path twice
Let's look at the drawing from the last example of the previous section:

Imagine that we would like to draw them with different styles and colors: the
shape on the left will stay as it is now (blue, wireframe), while the shape on the
right will be filled, colored in pink. Let's look at how we can do this...

Drawing two paths with different styles: the WRONG


and the right way!
First, the wrong way!
In this example, we will draw the two parts of the path with different styles: the
first part in wireframe mode, and the second part in filled mode.

What we will try first is to call stroke() after the first half of the path, then
call fill() after the second half of the path (check this interactive example):

Here is the code:


1. var canvas=[Link]('myCanvas');
2. var ctx=[Link]('2d');
3. // first part of the path
4. [Link](20,20);
5. [Link](100, 100);
6. [Link](100,0);
7. // indicate stroke color + draw first part of the path
8. [Link] = "#0000FF";
9. [Link]();
10. // second part of the path
11. [Link](120,20);
12. [Link](200, 100);
13. [Link](200,0);
14. // indicate stroke color + draw the path
15. [Link] = "pink";
16. [Link]();

Hey - it does not work! Weirdly, the two parts of the path are filled in pink! But
we called stroke() after the first half of the path was drawn (lines 5-8). Then
we called fill() only after the second part of the path was specified (lines 14-
19)... so, what happened?

Remember that fill() or stroke() draws the whole path, even if it is


disconnected, and even if it has already been drawn!

What happened is:

[Link] call to stroke() has drawn the path corresponding to the lines 5-7.
Indeed, the first part of the path (on the left) has actually been drawn once in
wireframe mode, and in blue.
[Link], the call to fill() at line 20 has drawn the whole path again, but in
pink and in filled mode. But this time the path corresponds to lines 5-7 plus
lines 14-16 that make up the second shape on the right. So the path that has
been drawn this time is made of both of the triangles.
Important: If you do not want to draw parts of the same path several times,
you need to draw two different paths, using the [Link]() method, as
shown in the next example.
Now, the right way!
Online example: [Link]
Source code:

1. var canvas=[Link]('myCanvas');
2. var ctx=[Link]('2d');
3. // first part of the path
4. [Link](20,20);
5. [Link](100, 100);
6. [Link](100,0);
7. // indicate stroke color + draw first part of the path
8. [Link] = "#0000FF";
9. [Link]();
10.// start a new path, empty the current buffer
[Link]();
12. // second part of the path
13. [Link](120,20);
14. [Link](200, 100);
15. [Link](200,0);
16. // indicate stroke color + draw the path
17. [Link] = "pink";
18. [Link]();

This time, in order to draw the two shapes differently, we defined two separate
paths. The way to do this is just to call [Link]() to start a new path. In
this example, the first path has been drawn in wireframe mode, then a new
path has been started that is drawn in filled mode.
Drawing lines in immediate mode
Sometimes it might be useful to draw just one line without being in another
path.

It's interesting to see how we can write a single "draw line" function that takes
the start and end coordinates, the color, the line width, etc.

Here is the code:

1. function drawLine(x1, y1, x2, y2, color, width) {


2. [Link]();
3. // set color and lineWidth, if these parameters
4. // are not defined, do nothing (default values)
5. if(color)
6. [Link] = color;
7. if(width)
8. [Link] = width;
9. // start a new path
10. [Link]();
11. [Link](x1, y1);
12. [Link](x2, y2);
13. [Link]();
14. [Link]();
15. }

Notice the save/restore of the context at the beginning/end of the function.


This is a REALLY good practice to avoid affecting other functions' context.

Line 13 starts a new path so that the function will only draw what it is meant
to draw: a single line.
Lines 15-17 move the "pen" at (x1, y1) then draw a line to (x2, y2), and the
stroke at line 17 makes it appear on the screen.

Here is an example (see online example):

1. drawLine(0, 0, 100, 100);


2. drawLine(0, 50, 150, 200, 'red');
3. drawLine(10, 100, 100, 10, 'green', 10);
Result:

Practical example: drawing arrows


In this section, we present a function that draws arrows in a canvas, such as in
the illustration below:

You may find multiple implementations on the Web for drawing arrows in a
canvas, but the one we are presenting has the advantage of being rather
simple and enables you to set the color and line width of the arrows.

Let's see some examples of use:

1. // Adapted from : [Link]


canvas-tag
2. function drawArrow(ctx, fromx, fromy, tox, toy, arrowWidth, color){
3. //variables to be used when creating the arrow
4. var headlen = 10;
5. var angle = Math.atan2(toy-fromy,tox-fromx);
6.
7. [Link]();
8. [Link] = color;
9.
10. //starting path of the arrow from the start square to the end square
11. //and drawing the stroke
12. [Link]();
13. [Link](fromx, fromy);
14. [Link](tox, toy);
15. [Link] = arrowWidth;
16. [Link]();
17.
18. //starting a new path from the head of the arrow to one of the sides of
19. //the point
20. [Link]();
21. [Link](tox, toy);
22. [Link](tox-headlen*[Link]([Link]/7),
23. toy-headlen*[Link]([Link]/7));
24.
25. //path from the side point of the arrow, to the other side point
26. [Link](tox-headlen*[Link](angle+[Link]/7),
27. toy-headlen*[Link](angle+[Link]/7));
28.
29. //path from the side point back to the tip of the arrow, and then
30. //again to the opposite side point
31. [Link](tox, toy);
32. [Link](tox-headlen*[Link]([Link]/7),
33. toy-headlen*[Link]([Link]/7));
34.
35. //draws the paths created above
36. [Link]();
37. [Link]();
38. }

An arrow is made of one line (the arrow body) and three connected lines (the
arrow head).

As we modify some context properties in this function, we


call save() and restore() at the beginning and at the end of the function.

This function can be improved in many ways: adding shadows,


using fill() instead of stroke(), which gives strange results when the width
is too big, etc.

Examples
Online example that uses the above code: [Link]
1. drawArrow(ctx, 10, 10, 100, 100, 10, 'red');
2. drawArrow(ctx, 100, 10, 140, 140, 3, 'black');

Result:
Draw nicer arrows?
On the Web, you will find many different ways to draw arrows.

This Web site is worth


reading: [Link] It
details how to draw arrows with curved heads and different styles for the head.
Note, however, that you will need to modify some parts if you want it to
support different line widths, etc.

Screenshot from a demo available on the above Web site:

In a later part of the course dedicated to curve drawing in a canvas, we will


also show how to draw curved arrows, with very simple code (much simpler
than the one used for drawing the clock's hands above).

Closing a path
The [Link]() method indicates that we would like a closed path: draw
from the last point to the first.

Try this interactive example: [Link]


Source code:

1. var canvas=[Link]('myCanvas');
2. var ctx=[Link]('2d');
3. // Path made of three points (defines two lines)
4. [Link](20,20);
5. [Link](100, 100);
6. [Link](100,0);
7. // Close the path, try commenting this line
8. [Link]();
9. // indicate stroke color + draw first part of the path
10. [Link] = "blue";
11. [Link]();

Lines 5-7 corresponds to a path made of two consecutive lines. If we just


call stroke() after that, two lines will be drawn on the canvas.
Line 10 indicates that we would like a closed path. In this case, the call
to stroke() at line 14 will draw the two lines plus an extra line that connects
the last point of the path to the first one. It will draw a closed triangle!

Try commenting the line in the online example and see the results!

Drawing circles and arcs


The [Link](cx, cy, radius, startAngle, endAngle,
drawInverse) method is useful for drawing arcs of circles. It takes the center
of the circle/arc, its radius, the starting angle of the arc (turning clockwise), the
ending angle of the arc, and an optional parameter we will talk about later.
Note: figures borrowed
from [Link]

Typical usage
Typical usage for drawing an arc/circle/ellipse is:
1. [Link](centerX, centerY, radius, startAngle, endAngle); // clockwise
drawing
2. [Link](centerX, centerY, radius, startAngle, endAngle, false);

The angles are in radians (between 0 and 2*[Link]). The arc is drawn
clockwise. Beware that this may not seem natural if you're used to the
trigonometric order.

The last parameter is optional and has a value of false by default. If true,
instead of drawing an arc of circle that corresponds to the parameters, it will
draw its complementary. See the examples below to see the difference.

Example 1: drawing an arc with radius = 50, starting


angle = 0, end angle = PI/2
Try this example online: [Link]
1. [Link]();
2. // we ommited the last parameter
3. [Link](100, 75, 50, 0, [Link]/2);
4.
5. [Link] = 10;
6. [Link]();

Here is the result:

If we change the last parameter (we omitted it, so it took a value of false by
default):

1. [Link]();
2. // we omitted the last parameter
3. [Link](100, 75, 50, 0, [Link]/2, true);
4.
5. [Link] = 10;
6. [Link]();

Then, the result is the "complementary" of the previous arc:


Example 2: drawing a Full circle (filled + outlined)
Try this example: [Link]

Source code:

1. var canvas = [Link]("myCanvas");


2. var ctx = [Link]("2d");
3. var centerX = [Link] / 2;
4. var centerY = [Link] / 2;
5. var radius = 70;
6. [Link]();
7. // Add to the path a full circle (from 0 to 2PI)
8. [Link](centerX, centerY, radius, 0, 2*[Link], false);
9. // With path drawing you can change the context
10. // properties until a call to stroke() or fill() is performed
11. [Link] = "lightBlue";
12. // Draws the filled circle in light blue
[Link]();
14. // Prepare for the outline
15. [Link] = 5;
16. [Link] = "black";
17. // draws the path (the circle) AGAIN, this
18. // time in wireframe
[Link]();
20.// Notice we called [Link]() only once ! And drew it twice
21.// with different styles
Notice that we called [Link]() only once! And drew it twice, with different
styles, with calls to [Link]()and [Link](). Each call drew the defined
path in wireframe and in filled mode!

Proposed projectS
Project 1 - modify the previous example
on [Link] in order to get:

Project 2 - make a small program that draws a smiling head


like this (or make something better!)

Drawing rounded rectangles:


the arcTo(x1, y1, x2, y2,
radius) method
Introduction
There is another method called [Link](x1, y1, x2, y2, radius), which
is a bit complex to use, but very practical for drawing rounded rectangles.

In fact, the arcTo(...) method draws an arc of a circle depending on some


tangents. Let's look at these pictures for a better understanding (original
picture
from [Link]

Typical use
1. [Link](x0, y0);
2. [Link](x1, y1, x2, y2, radius);

This method can be confusing. It was defined mainly for drawing rounded
shapes like rounded rectangles. We used an excerpt here from the excellent
tutorial on the arcTo(...) method available at [Link]
[Link]/tutorials/canvas/[Link].

It works like this:

[Link] an imaginary line through (x0,y0) and (x1,y1), draw another


imaginary line through (x1,y1) and(x2,y2),
[Link] an imaginary circle of radius r, and slide it up between the two lines
until it just touches both lines. The two points at which the circle touches the
lines are called the tangent points.
[Link](x1, y1, x2, y2, r) will draw a line from the current
point (x0,y0) to the first tangent point on the line from (x0,y0) to (x1,y1),
[Link] will also draw an arc from that tangent point to the other tangent point on
the line from (x1,y1) to (x2,y2) along the circumference of the circle.
[Link], it adds the tangent point where the arc ends up, on the line
from (x1,y1) to (x2,y2) to the path as the new current point on the path.
Example 1: simple use

Try this interactive example: [Link]

1. [Link]();
2. [Link](0, 20);
3. [Link](100, 100, 200, 20, 50);
4. [Link] = 5;
5. [Link] = "#0000ff";
6. [Link]();

Example 2: draw A rounded rectangle


Try this interactive example: [Link]

Source code:

1. var roundedRect=function(ctx,x,y,width,height,radius,fill,stroke) {
2. [Link]();
3. // draw top and top right corner
4. [Link](x+radius,y);
5. [Link](x+width,y,x+width,y+radius,radius);
6. // draw right side and bottom right corner
7. [Link](x+width,y+height,x+width-radius,y+height,radius);
8. // draw bottom and bottom left corner
9. [Link](x,y+height,x,y+height-radius,radius);
10. // draw left and top left corner
11. [Link](x,y,x+radius,y,radius);
12. if(fill) {
13. [Link]();
14. }
15. if(stroke){
16. [Link]();
17. }
18. }
19. var canvas = [Link]('myCanvas');
20. var ctx = [Link]('2d');
21. [Link] = 'rgb(150,0,0)';
22. [Link] = 'rgb(0,150,0)';
23. [Link] = 7;
24. roundedRect(ctx, 15, 15, 160, 120, 20, true, true);

In this example, each call to [Link](...) draws a side plus a corner. This
makes us suspect that the arcTo() method has been designed primarily for
drawing rounded rectangles...

Example 3 comparison between lineTo and arcTo


This example at JS Bin is the same as the previous one, except that we added
at the end of the roundedRect function the same lines of code that draw
the rounded rectangle, but using lineTo instead of arcTo. Just take a look!

JS Bin example
Example 4: use the unrounded vertices in arcTo
For drawing a rounded square, this code also works:
1. [Link](x+radius, y);
2. [Link](x+width, y,x+width, y+height, radius);
3. [Link](x+width, y+height, x, y+height, radius);
4. [Link](x, y+height, x, y,radius);
5. [Link](x, y, x+width, y,radius);

which might be easier than trying to figure out where the arc will end like this:

1. [Link](x+radius, y);
2. [Link](x+width, y, x+width, y+radius, radius);
3. [Link](x+width, y+height, x+width-radius, y+height,radius);
4. [Link](x, y+height, x, y+height-radius, radius);
5. [Link](x, y, x+radius, y,radius);

This could be particularly helpful if you are dealing with something other than a
rectangle, like this rounded triangle (try the code at JsBin):
Quadratic curves

(Picture from: [Link]


quadratic-curves/)

Introduction
Quadratic curves are defined by a starting point (called a "context point"), a
control point, and an ending point. The curve fits the tangents between the
context and control points and between the control and ending points.

The context point may be defined by a call to the moveTo(x, y) method of the
context, or it may be the ending point of a previous path, if we're drawing a
path made of several shapes. For example, drawing a line and a quadratic
curve will make the endpoint of the line the context point for the quadratic
curve.

The control point controls the curvature - if we move the control point farther
we get a sharper curve.

External resource: an interactive example in which you can move the


different control points.

Typical use
1. [Link](contextX, contextY);
2. [Link](controlX, controlY, endX, endY);
3. // Optional : set lineWidth and stroke color
4. [Link] = 5;
5. [Link] = "#0000ff";
6. // Draw!
7. [Link]();

example 1: Quadratic curve


Try this interactive example: [Link]

Source code:

1. var canvas=[Link]('#myCanvas1');
2. var context=[Link]('2d');
3.
4. [Link]();
5.
6. [Link](100, 20);
7. [Link](230, 200, 250, 20);
8.
9. [Link] = 5;
10. [Link] = "#0000ff";
11. [Link]();

We set a starting point in line 6: moveTo(...), then set the control and ending
points with a call to quadraticCurve(...), at line 7, then set some properties
for color, thickness, and finally we call the stroke() method for drawing the
curve.

Example 2: lines connected with a quadratic curve


Try this interactive example: [Link]
Source code:

1. [Link]();
2. [Link](100, 20);
3. [Link](200, 80);
4. [Link](230, 200, 250, 20);
5. [Link](500, 90);
6. [Link] = 5;
7. [Link] = "#0000ff";
8. [Link]();

Practical example: use quadratics for


drawing curved arrows

Online example: [Link]

We propose a useful function for drawing curved arrows. The code is a modified
version of one that has been proposed by several contributors to this thread at
StackOverflow.
Source code of the function that draws a curved arrow:

1. function drawCurvedArrow(startPointX, startPointY,


2. endPointX, endPointY,
3. quadPointX, quadPointY,
4. lineWidth,
5. arrowWidth,
6. color) {
7. // BEST PRACTICE: the function changes color and lineWidth -> save context!
8. [Link]();
9. [Link] = color;
10. [Link] = lineWidth;
11.
12. // angle of the end tangeant, useful for drawing the arrow head
13.
var arrowAngle = Math.atan2(quadPointX - endPointX, quadPointY - endPoin
tY) + [Link];
14.
15. // start a new path
16. [Link]();
17. // Body of the arrow
18. [Link](startPointX, startPointY);
19.
[Link](quadPointX, quadPointY, endPointX, endPointY);
20. // Head of the arrow
21.
[Link](endPointX - (arrowWidth * [Link](arrowAngle - [Link] / 6)),
22. endPointY - (arrowWidth * [Link](arrowAngle - [Link] / 6)));
23.
24. [Link](endPointX, endPointY);
25.
26.
[Link](endPointX - (arrowWidth * [Link](arrowAngle + [Link] / 6)),
27.
endPointY - (arrowWidth * [Link](arrowAngle + [Link] / 6)));
28.
29. [Link]();
30. [Link]();
31. // BEST PRACTICE -> restore the context as we saved it at the
beginning
32. // of the function
33. [Link]();
34. }

This function takes as parameters the start and end points, the control point of
the curve, the arrow width, the width of the arrow head.

It computes the angle of the arrow at its endpoint (line 14) in order to compute
the rotated endpoints of the two lines of the arrow head (lines 24 and 29).

Notice that once again, as we modify the context properties (color, lineWidth)
in the body of the function, we save and restore the context at the beginning /
end of the function.

Bezier curves

(image from: [Link]


[Link])

Introduction
Bezier curves are interesting - used mostly for drawing "S" shapes or
asymmetric curves.
(Picture from : [Link]
bezier-curves/)

Bezier curves are defined by a context point, like quadratic curves, two control
points that define two tangents, and an ending point.

The first part of the curve is tangential to the imaginary line defined by the
context point and the first control point. The second part of the curve is
tangential to the imaginary line defined by the second control point and the
ending point.

The best way to understand how they work is to check out one of these
interactive applications:

[Link]
[Link]
[Link]
Nice video tutorial: [Link]

Typical usage of Bezier curves


Source code:
1. [Link](contextX, contextY);
2. [Link](controlX1, controlY1, controlX2, controlY2, end
X, endY);
3. // Optional : set lineWidth and stroke color
4. [Link] = 5;
5. [Link] = "#0000ff";
6. // Draw!
7. [Link]();
Example 1
Try this interactive example: [Link]

1. [Link]();
2. [Link](100, 20);
3. [Link](290, -40, 200, 200, 400, 100);
4. [Link] = 5;
5. [Link] = "#0000ff";
6. [Link]();

Example 2 with lines, quadratic, and bezier curves in


a path
Try this example online: [Link]

Extract from source code:

1. [Link]();
2. [Link](100, 20);
3. [Link](200, 160);
4. [Link](230, 200, 250, 120);
5. [Link](290, -40, 300, 200, 400, 150);
6. [Link](500, 90);
7. // TRY COMMENTING THIS LINE OUT
8. [Link]();
9. [Link] = 5;
10. [Link] = "#0000ff";
11. [Link]();

In this example we use the closePath() method to draw a line between the
last path point and the first path point (line 11), so that the drawing looks like a
pair of goggles.

Note how the different parts are linked together and make a "path":

Interesting, interactive tool for generating code that


draws bezier curves
This tool is available online: [Link] try it!

Screenshot:
Canvas context: colors
Introduction
In previous examples, we saw how to set the current color using
the strokeStyle and fillStyle properties of the canvas context object.

We will now look at color in a little more detail, and see how we can use
gradients or patterns/textures/images (in other words: fill shapes or fill the
outline of the shapes with some images that repeat themselves).

Colors and transparency


You can use the same syntax for colors that is supported by CSS3. The next
lines show possible values/syntaxes.
1. [Link] = 'red';
2. [Link] = "#00ff00";
3. [Link] = "rgb(0, 0, 255)";
4. [Link] = "rgba(0, 0, 255, 0.5)";

Note that:

All values are strings,


Line 4 defines a "transparent color", the "a" of "rgba" means "alpha channel".
Its value is between 0 and 1, where 0 means "completely transparent" and 1
means "opaque".

Here is an example that shows how to draw different filled rectangles in blue,
with different levels of transparency.

Try it online: [Link]

Linear gradients
It is possible to define the stroke or the fill style as a "gradient", a set of
interpolated colors, like in this example below (try it online
at: [Link]
The concept of linear gradient is seen as an "invisible" rectangle in which a set
of colors are interpolated along a line.

The gradient becomes visible when we draw shapes on top of the invisible
gradient, and when the fillStyleor strokeStyle property has for value this
gradient.

Here are the different steps needed:

Step 1: define a linear gradient


Syntax:
1. [Link](x0,y0,x1,y1);

... where the (x0, y0) and (x1, y1) parameters define "the direction of the
gradient" (as a vector with a starting and an ending point). This direction is an
invisible line along which the colors that compose the gradient will be
interpolated.

Let's see an example:

1. grdFrenchFlag = [Link](0, 0, 300, 0);

This line defines the direction of the gradient: a virtual, invisible line that goes
from the top left corner of the canvas (0, 0) to the top right corner of the
canvas (300, 0). The interpolated colors will propagate along this line.

If this gradient is going to be reused by different functions, it is good practice


to create/initialize it in a function called when the page is loaded and to store it
in a global variable.
Step 2: add a number of "color stops" to this gradient
We will add a set of "colors" and "stops" to this gradient. The stops go from 0
(beginning of the virtual line defined just above), to 1 (end of the virtual line). A
color associated with a value of 0.5 will be right in the middle of the virtual line.

Here is an example that corresponds to an interpolated version of the French


flag, going from blue to white, then to red, with proportional intervals. We
define three colors, blue at position 0, white at position 0.5 and red at position
1:

1. [Link](0, "blue");
2. [Link](0.5, "white");
3. [Link](1, "red");

Step 3: draw some shapes


First, let's set the fillStyle or strokeStyle of the context with this gradient,
then let's draw some shapes "on top of the gradient".

In our example, the gradient corresponds to an invisible rectangle that fills the
canvas. If we draw a rectangle of the canvas size, it should be filled with the
entire gradient:

1. [Link] = grdFrenchFlag;
2. [Link](0, 0, 300, 200);

The result is shown below: a big rectangle that fills the whole canvas, with
colors going from blue (left) to white (middle) to red (right).
Changing the direction of the gradient
If you modify the source code that defines the direction of the gradient as
follows...
1. grdFrenchFlag = [Link](0, 0, 300, 200);

... then you will define a gradient that goes from the top left corner of the
canvas to the bottom right of the canvas. Let's see what it does (online version
here: [Link]

Drawing shapes that do not cover the whole gradient


Instead of drawing a filled rectangle that covers the whole surface of the
canvas, let's draw several smaller rectangles.

Online example: [Link]


Note that the canvas has its default background color where we did not draw
anything. And where we have drawn rectangles, we can see "through" and the
colors from the gradient are visible.

Here is the code that draws the checkboard:

1. [Link] = grdFrenchFlag;
2. [Link](0, 0, 50, 50);
3. [Link](100, 0, 50, 50);
4. [Link](200, 0, 50, 50);
5. [Link](50, 50, 50, 50);
6. [Link](150, 50, 50, 50);
7. [Link](250, 50, 50, 50);
8. [Link](0, 100, 50, 50);
9. [Link](100, 100, 50, 50);
10. [Link](200, 100, 50, 50);
11. [Link](50, 150, 50, 50);
12. [Link](150, 150, 50, 50);
13. [Link](250, 150, 50, 50);

This code is rather ugly isn't it? It would have been better to use a loop...

Here is function that draws a chessboard (online example at JsBin):

1. // n = number of cells per row/column


2. function drawCheckboard(n) {
3. [Link] = grdFrenchFlag;
4. var l = [Link];
5. var h = [Link];
6.
7. var cellWidth = l / n;
8. var cellHeight = h / n;
9. for(i = 0; i < n; i++) {
10. for(j = i % 2; j < n; j++) {
11. [Link](cellWidth*i, cellHeight*j, cellWidth, cellHeight);
12. }
13. }
14. }
The two loops (lines 11-15) draw only one cell out of two (see the j = i % 2 at
line 12). i is the column number and if the column is odd or even, either we
draw or we do not draw a rectangle.

This code is much more complex than the previous one, taking 16 lines instead
of 13, but is much more powerful. Try to call the function with a value of 10,
20, or 2...

Drawing outlined shapes with gradients


Just as we used fillStyle and fillRect for drawing rectangles filled with a
gradient, we can also use strokeStyle and strokeRect in order to draw
wireframed rectangles. In the next example, which is just a variation of the
previous one, we have used the lineWidth property to set the outline of the
rectangles at 5 pixels: try this example at JsBin.

Extract from source code:

1. function drawCheckboard(n) {
2. [Link] = grdFrenchFlag;
3. [Link]=10;
4. ...
5. for(i = 0; i < n; i++) {
6. for(j = i % 2; j < n; j++) {
7. [Link](cellWidth*i, cellHeight*j, cellWidth, cellHeight);
8. }
9. }
10. }

What happens if we define a gradient smaller than


the canvas?
Let's go back to the very first example on this page - the one with the blue-
white-red interpolated French flag. This time we will define a smaller gradient.
Instead of going from (0, 0) to (300, 0), it will go from (100, 0) to (200,
0), while the canvas remains the same (width=300, height=200).
1. grdFrenchFlag = [Link](100, 0, 200, 0);

Like in the first example we will draw a filled rectangle that is the same size as
the canvas. Here is the online version: [Link] and here
is a screenshot of the result:

We notice that "before" the gradient starts, the first color of the gradient is
repeated without any interpolation (columns 0-100 are all blue), then we "see
through" and the gradient is drawn (columns 100-200), then the last color of
the gradient is repeated without any interpolation (columns 200-300 are red).

WHAT HAPPENS IF WE DEFINE A GRADIENT


bigger THAN THE CANVAS?
Nothing special; we will "see through the drawn shapes", and the parts of the
gradient that are located in the canvas area will be shown. You can try this
example that defines a gradient twice the size of the canvas:
1. grdFrenchFlag = [Link](0, 0, 600, 400);
And if we draw the same rectangle with the canvas size, here is the result:

The red color is beyond the bottom right corner.... we see only the top left
quarter of the gradient.

Draw shapes that share the same gradient as a


whole
This time, we would like to draw the chessboard with the gradient in each cell.
How can we do this with one single gradient?

We can't! At least we can't without recreating it for each cell!

It suffices to create a new gradient before drawing each filled rectangle, and
set it with the starting and ending point of its direction/virtual line accordingly
to the rectangle coordinates. Here is an online example and the resulting
display:
Extract from source code:

1. function setGradient(x, y, width, height) {


2. grdFrenchFlag = [Link](x, y, width, height);
3. [Link](0, "blue");
4. [Link](0.5, "white");
5. [Link](1, "red");
6. // set the new gradient to the current fillStyle
7. [Link] = grdFrenchFlag;
8. }
9.
10. // n = number of cells per row/column
11. function drawCheckboard(n) {
12. var l = [Link];
13. var h = [Link];
14.
15. var cellWidth = l / n;
16. var cellHeight = h / n;
17. for(i = 0; i < n; i+=2) {
18. for(j = 0; j < n; j++) {
19. var x = cellWidth*(i+j%2);
20. var y = cellHeight*j;
21. setGradient(x, y, x+cellWidth, y+cellHeight);
22. [Link](x, y, cellWidth, cellHeight);
23. }
24. }
25. }

We wrote a function setGradient(startX, startY, endX, endY) that


creates a gradient and set the fillStyle context property so that any filled
shape drawn will have this gradient.

In the drawCheckBoard(...) function we call it just before drawing rectangles.


In this way, each rectangle is drawn using its own gradient.
This flag does not really look like the French flag,
does it?
Indeed the French flag in these images is more accurate:

We slightly modified the examples of this chapter so that the flag looks more
like the French flag. Look at the modified versions below, and try to find out
what has changed in the gradient definitions:

[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]

Radial gradients
Basic principle / syntax: define two circles at
gradient creation
Radial gradients are for creating gradients that propagate/interpolate colors
along circles instead of propagating/interpolating along a virtual line, like linear
gradients.
Here is an example of a radial gradient that interpolates the color of the
rainbow. Online version: [Link]

The gradient is defined as follows:

1. var grd = [Link](150, 100, 30, 150, 100, 100);


2. [Link](0, "red");
3. [Link](0.17, "orange");
4. [Link](0.33, "yellow");
5. [Link](0.5, "green");
6. [Link](0.666, "blue");
7. [Link](1, "violet");
8. [Link] = grd;

The method from the context object createRadialGradient(cx1, cy1,


radius1, cx2, cy2, radius2) takes as the first three parameters the
"starting" circle of the gradient, and as the three last parameters, the "ending
circle".

In the above example, the gradients starts at a circle located at (150, 100),
with a radius of 30, and propagates to a circle with the same center as the first
(150, 100), but with a bigger radius of 100, as shown below:
We added color stops using a method similar to that used for linear gradients.

What happens if the circles are not located at the


same place?
You obtain some nice effects; here we set the second circle's center 60 pixels
to the right of the first circle's center (cx = 210 instead of 150). Online
example: [Link]
1. grd = [Link](150, 100, 30, 210, 100, 100);

And here is the result:


What happens if the gradient is smaller or larger
than the shapes we draw?
A gradient is an invisible shape on the screen: the radial gradient is made of
two circles: an inner and an outer circle. Between these two circles, colors are
interpolated.

We call the "first color" the color defined for the inner circle, the "last color" the
last color of the gradient, that corresponds to the outer circle:

The color inside the first circle will be the first color. In our example above,
the first color is red: and the small circle of the gradient in our example is filled
in red!
The color outside the outer circle will be the last color of the gradient - which
is not interpolated. The last color in our example is purple, and it fills the rest of
the filled rectangle area "after" the external circle of the gradient.
The colors between the two circles will be interpolated.

Painting with patterns


principle
The principle of "pattern" drawing is based on repeating an image (if the image
is smaller than the surface of the shape you are going to draw) for filling the
surface of objects to be drawn (either filled or stroked).

To illustrate this principle, in the next examples, we are going to draw


rectangles using this pattern:
There are a few steps we have to take before doing this:

[Link] a JavaScript image object

[Link] imageObj = new Image();


[Link] a callback function that will be called once the image has
been fully loaded in memory; we cannot draw before the image has been
loaded.

[Link] = function(){
2....
3.}
[Link] the source of this image to the URL of the pattern (in our example
with url of the pattern),

[Link] = "[Link]
[Link] soon as step 3 is executed, an HTTP request is sent in background by the
browser, and when the image is loaded in memory, the callback defined at step
2 is called. We create a pattern object inside, from the loaded image:

1.// callback called asynchronously, after the src attribute of imageObj is set
[Link] = function(){
3. // We enter here when the image is loaded, we create a pattern object.
4. // It is good practice to set this as a global variable, easier to share
5. pattern1 = [Link](imageObj, "repeat");
6.};
[Link] the callback function (or inside a function called from inside
the callback) we can draw.

1.// callback called asynchronously, after the src attribute of imageObj is set
[Link] = function(){
3. pattern1 = [Link](imageObj, "repeat");
4. // Draw a textured rectangle
5. [Link] = pattern1;
6. [Link](10, 10, 500, 800);
7.};

example 1: draw two rectangles with a pattern (one


filled, one stroked)
Online example: [Link]

Here we have two rectangles drawn using a pattern (an image that can be
repeated along the X and Y axis). The first is a filled rectangle while the second
is "stroked" with a lineWidth of 10 pixels.

HTML source code:

1. <!DOCTYPE html>
2. <html>
3. <body onload="init();">
4. <canvas id="myCanvas" width="500" height="400">
5. Your browser does not support the canvas tag. </canvas>
6. </body>
7. </html>

JavaScript source code:

1. var canvas, ctx, pattern1;


2.
3. function init() {
4. canvas = [Link]('#myCanvas');
5. ctx = [Link]('2d');
6. // We need 1) to create an empty image object, 2) to set a callback function
7. // that will be called when the image is fully loaded, 3) to create a
8. // pattern object, 4) to set the fillStyle or the strokeStyle property of
9. // the context with this pattern, 5) to draw something
10. // WE CANNOT DRAW UNTIL THE IMAGE IS FULLY LOADED -> draw
from inside the
11. // onload callback only !
12. // 1 - Allocate an image
13. var imageObj = new Image();
14.
15. // 2 - callback called asynchronously, after the src attribute of imageObj
16. // is set
17. [Link] = function(){
18. // We enter here only when the image has been loaded by the browser
19. // 4 - Pattern creation using the image object
20. // Instead of "repeat", try different values : repeat-x, repeat-y,
21. // or no-repeat, You may draw larger shapes in order to see
22. // different results
23. // It is good practice to leave this as a global variable if it
24. // will be reused by other functions
25. pattern1 = [Link](imageObj, "repeat");
26. // 5 - Draw things. Here a textured rectangle
27. [Link] = pattern1;
28. [Link](10, 10, 200, 200);
29. // ... And a wireframe one
30. [Link]=20;
31. [Link]=pattern1;
32. [Link](230, 20, 150, 100);
33. };
34. // 3 - Send the request to load the image
35. // Setting the src attribute will tell the browser to send an asynchronous
36. // request.
37. // When the browser gets an answer, the callback above will be called
38. [Link] = "[Link]
[Link]";
39. }

example 2: the repeatability of a pattern


To "better" see the repeatability of the pattern, here is the same example with
a 1000x1000 pixel wide canvas.

Online version here: [Link] and here is the result:


You can change the way the pattern is repeated by modifying the second
parameter of this method:

1. pattern1 = [Link](imageObj, "repeat");

Please try: repeat-x, repeat-y or no-repeat as acceptable values. Just


change this line in the online example and you will see live results.
Multiple image loader (for advanced
users, or just take it as it is: a utility
function you can reuse)
Below are 4 rectangles drawn with 4 different patterns.

Draw with multiple patterns? We need to load all of


them before drawing!
We said earlier that we cannot draw before the image used by a pattern is
loaded. This can become rapidly complicated if we need to draw using multiple
patterns. We need a way to load all images and then, only when all images
have been loaded, start drawing.

JavaScript is an asynchronous language. When you set the src attribute of an


image, then an asynchronous request is sent by the browser, and then after a
while, the onload callback is called... The difficult part to understand for those
who are not familiar with JavaScript is that these requests are done in parallel
and we do not know when, and in what order, the images will be loaded.

Solution: a multiple image loader that counts the


loaded images and calls a function you pass when
done!
The trick is to have an array of URLs that will be used by our multiple image
loader, then in the onload callback, this will be called once per image loaded,
so we can count the number of images effectively loaded.

When all images have been loaded, we call a callback function that has been
passed to our loader.

A complete example code that produces the result shown at the beginning of
this page is at: [Link]

Define the list of images to be loaded


1. // List of images to load, we used a JavaScript object instead of
2. // an array, so that named indexes (aka properties)
3. // can be used -> easier to manipulate
4. var imagesToLoad = {
5. flowers:
6. '[Link]
7. lion: '[Link]
8. blackAndWhiteLys: '[Link]
9. tiledFloor:
10.
'[Link]
O-zKk/s1600/symmetry:assymetry+repeatable+[Link]'
11. };

Notice that instead of using a traditional array, we defined this list as a


JavaScript object, with properties whose names will be easier to manipulate
(flowers, lion, tiledFloor, etc.).

The image loader function


1. function loadImages(imagesToBeLoaded, drawCallback) {
2. var imagesLoaded = {};
3. var loadedImages = 0;
4. var numberOfImagesToLoad = 0;
5. // get num of images to load
6. for(var name in imagesToBeLoaded) {
7. numberOfImagesToLoad++;
8. }
9. for(var name in imagesToBeLoaded) {
10. imagesLoaded[name] = new Image();
11. imagesLoaded[name].onload = function() {
12. if(++loadedImages >= numberOfImagesToLoad) {
13. drawCallback(imagesLoaded);
14. } // if
15. }; // function
16. imagesLoaded[name].src = imagesToBeLoaded[name];
17. } // for
18. } // function

This function takes as a parameter the list of images to be loaded, and a


drawCallback function that will be called only once all images have been
loaded. This callback takes as a parameter a new object that is the list of
images that have been loaded (see line 16).

We first count the number of images to load (lines 7-9), then for each image to
be loaded we create a new JavaScript image object (line 12) and set its src
attribute (line 19) - this will start to load the image.

When an image comes in, the onload callback is called (line 14) and inside, we
increment the number of images loaded (line 15) and test if this number is >=
the total number of images that should be loaded. If this is the case, the
callback function is called (line 16).

Example of use of this loader


1. loadImages(imagesToLoad, function(imagesLoaded) {
2. patternFlowers = [Link]([Link], 'repeat');
3. patternLion = [Link]([Link], 'repeat');
4. patternBW = [Link]([Link], 'repeat');
5. patternFloor = [Link]([Link], 'repeat');
6. drawRectanglesWithPatterns();
7. });
Line 1 is the call to the image loader, the first parameter is the list of images
to be loaded, while the second parameter is the callback function that will be
called once all images have been loaded.
Lines 2-5: in this callback we create patterns from the loaded images (note the
use of the property names [Link], etc. that makes the code
easier to read).
Line 7: then we call a function that will draw the rectangles.

Here is the function:

1. function drawRectanglesWithPatterns() {
2. [Link]=patternFloor;
3. [Link](0,0,200,200);
4. [Link]=patternLion;
5. [Link](200,0,200,200);
6. [Link]=patternFlowers;
7. [Link](0,200,200,200);
8.
9. [Link]=patternBW;
10. [Link](200,200,200,200);
11. }

Drawing shadows
Context properties to draw with shadows

There are 4 properties of the canvas context that are useful for indicating that
we want to draw shapes with shadows:
[Link]: color to use for shadows,
[Link]: blur level for shadows,
[Link]: horizontal distance of the shadow from the shape,
[Link]: vertical distance of the shadow from the shape
Example 1: Simple
Online example: [Link]

HTML source code:

1. <!DOCTYPE html>
2. <html>
3. <body onload = init();>
4. <canvas id="myCanvas" width="400" height =800>
5. Your browser does not support the canvas tag.
6. </canvas>
7. </body>
8. </html>

JavaScript source code:

1. var canvas, ctx;


2. function init() {
3. canvas = [Link]('myCanvas');
4. ctx = [Link]('2d');
5. // call to a function that will set the 4 context properties for shadows
6. setShadow();
7. // all drawings that will occur will cast shadows
8. // first green filled rectangle
9. [Link] = "#22FFDD";
10. [Link](20, 20, 200, 100);
11. // second stroked rectangle
12. [Link] = "purple";
13. [Link]=10;
14. [Link](20, 150, 200, 100);
15. }
16.
17. // We define the 4 properties in a dedicated function, for clarity
18. function setShadow() {
19. [Link] = "Grey"; // color
20. [Link] = 20; // blur level
21. [Link] = 15; // horizontal offset
22. [Link] = 15; // vertical offset
23. }

Lines 21-27: we set the 4 properties that define shadows in a dedicated


function, for better clarity.
Line 8: we called this function once before drawing the rectangles.
Lines 11-18: we draw a filled and a stroked rectangle. Both rectangles cast
shadows.

example 2: unwanted shadows!


Let's take a previous example: the one that draws a filled circle with an
outline: [Link]

Now, let's add a shadow to it, online example: [Link]

Here is an extract from the code:

1. ...
2. [Link]();
3. // Add to the path a full circle (from 0 to 2PI)
4. [Link](centerX, centerY, radius, 0, 2*[Link], false);
5. // With path drawing you can change the context
6. // properties until a call to stroke() or fill() is performed
7. [Link] = "lightBlue";
8. // add shadows before drawing the filled circle
9. addShadows();
10. // Draws the filled circle in light blue
11. [Link]();
12. // Prepare for the outline
13. [Link] = 5;
14. [Link] = "black";
15. // draws the path AGAIN (the circle), this
16. // time in wireframe
17. [Link]();
18. // Notice we only once called [Link]()! And drew it twice
19. // with different styles
20. ...
21.
[Link] addShadows() {
23. [Link] = "Grey"; // color
24. [Link] = 20; // blur level
25. [Link] = 15; // horizontal offset
26. [Link] = 15; // vertical offset
27. }

And here is the result:


Ah, indeed, the call to [Link]() casts a shadow, but the call
to [Link](), that paints the whole path again, casts a shadow too, and
this time the outline produces an unwanted shadow... How can we avoid this
effect, while using the same technique for drawing the path?

The trick is to save the context before setting the shadow properties, then draw
the filled circle, then restore the context (to its previous state: without
shadows), then draw the outlined circle by calling [Link]().

Correct version of the code: [Link]

1. ...
2. // save the context before setting shadows and drawing the filled
circle
3. [Link]();
4. // With path drawing you can change the context
5. // properties until a call to stroke() or fill() is performed
6. [Link] = "lightBlue";
7. // add shadows before drawing the filled circle
8. addShadows();
9. // Draws the filled circle in light blue
10. [Link]();
11.// restore the context to its previous saved state
12. [Link]();
13. ...

And here is the final result:


Styling lines
Several context properties can be used to set the thickness of the shape
outlines, the way line end caps are drawn, etc.

They apply to all shapes that are drawn in path mode (lines, curves, arcs) and
some also apply to rectangles.

Line style: change the line thickness


We have seen this before. This is done by changing the value (in pixels) of
the lineWidth property of the context:
1. [Link] = 10; // set the thickness of every shape drawn in
stroke/wireframe mode to 10 pixels

Here is a complete example where we draw with a lineWidth of 20 pixels. You


can play with the complete interactive example
here: [Link]

Source code:
1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>A simple example of lineWidth property use</title>
5. </head>
6. <body>
7. <canvas id="myCanvas" width="500">
8. Your browser does not support the canvas tag.
9. </canvas>
10. <script>
11. var canvas = [Link]('myCanvas');
12. var ctx = [Link]('2d');
13.
14. // first path
15. [Link](20, 20);
16. [Link](100, 100);
17. [Link](100, 0);
18.
19.
20. // second part of the path
21. [Link](120, 20);
22. [Link](200, 100);
23. [Link](200, 0);
24.
25. // indicate stroke color + draw first part of the path
26. [Link] = "#0000FF";
27. // Current line thickness is 20 pixels
[Link] = 20;
29. [Link](); // draws the whole path at once
30.
31. // Draws a rectangle in immediate mode
32. [Link](230, 10, 100, 100);
33. </script>
34.
35. </body>
36. </html>
Line style: changing the end caps for a line
The lineCap property of the context indicates the way line end caps are
rendered. Possible values are butt(default), round, square (from top to bottom
in the next illustration). Note that a value of "round" or "square" makes the
lines slightly longer than the default value "butt".

Try the next example interactively: [Link]


Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>A simple example of lineCap property use</title>
5. </head>
6. <body>
7.
8. <canvas id="myCanvas" width="500">
9. Your browser does not support the canvas tag.</canvas>
10. <script>
11. var canvas = [Link]('myCanvas');
12. var ctx = [Link]('2d');
13.
14. // first path
15. [Link](20, 20);
16. [Link](100, 100);
17. [Link](100, 30);
18.
19. // second part of the path
20. [Link](120, 20);
21. [Link](200, 100);
22. [Link](200, 30);
23.
24. // indicate stroke color + draw first part of the path
25. [Link] = "#0000FF";
26. // Current line thickness is 20 pixels
27. [Link] = 20;
28.
29.// Try different values: butt, square, round
[Link] = "round";
31.
32. [Link]();
33. // Draws a rectangle
34. [Link](230, 10, 100, 100);
35. </script>
36.
37. </body>
38. </html>

Note that in this example, the rectangle is not affected. It has no line ends
visible - all its sides meet. However, the next property we're going to look at
will have an effect on rectangles!

Line style: setting the type of corner when two lines


meet
The lineJoin property of the context indicates the way corners are rendered,
when two lines meet. Possible values are miter (the default) for creating sharp
corners, round, or bevel for "cut corners".

Try the next example interactively: [Link]


Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>A simple example of lineJoin property use</title>
5. </head>
6. <body>
7.
8. <canvas id="myCanvas" width="500">Your browser does not support
the canvas tag.</canvas>
9.
10. <script>
11. var canvas = [Link]('myCanvas');
12. var ctx = [Link]('2d');
13. // first path
14. [Link](20, 20);
15. [Link](100, 100);
16. [Link](100, 30);
17.
18. // second part of the path
19. [Link](120, 20);
20. [Link](200, 100);
21. [Link](200, 30);
22.
23. // indicate stroke color + draw first part of the path
24. [Link] = "#0000FF";
25. // Current line thickness is 20 pixels
26. [Link] = 20;
27.// Try different values : miter(default), bevel, round
[Link] = "round";
29. [Link]();
30. // Draws a rectangle
31. [Link](230, 10, 100, 100);
32. </script>
33.
34. </body>
35. </html>

Line style: specific case of lineJoin="miter", the


miterLimit property, a way to avoid looooooong
corners!
The miterLimit property value corresponds to the maximum miter length: the
distance between the inner corner and the outer corner where two lines meet.
When the angle of a corner between two lines gets smaller, the miter length
grows and can become too long.

In order to avoid this situation, we can set the miterLimit property of the
context to a threshold value. If the miter length exceeds the miterLimit value,
then the corner will be rendered as if the lineJoin property had been set to
"bevel" and the corner will be "cut".

You can try an interactive example here: [Link]

In the example, try different values for the miterLimit property. You'll see that
the way the corners are rendered changes at values around 2 and 3.

Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>A simple example of miterLimit property use</title>
5. </head>
6. <body>
7.
8. <canvas id="myCanvas" width="500">Your browser does not support
the canvas tag.</canvas>
9.
10. <script>
11. var canvas = [Link]('myCanvas');
12. var ctx = [Link]('2d');
13. // first path
14. [Link](20, 20);
15. [Link](100, 100);
16. [Link](100, 30);
17.
18. // second part of the path
19. [Link](120, 20);
20. [Link](200, 100);
21. [Link](200, 30);
22.
23. // indicate stroke color + draw first part of the path
24. [Link] = "#0000FF";
25. // Current line thickness is 20 pixels
26. [Link] = 20;
27. // Try different values : miter(default), bevel, round
[Link] = "miter";
29.// try to change this value, try 2, 3, 4, 5 et...
[Link] = 1;
31. [Link]();
32.
33. // Draws a rectangle
34. [Link](230, 10, 100, 100);
35. </script>
36. </body>
37. </html>
Week 4

History of HTML / JavaScript animation

PRINCIPLES OF ANIMATION
In order to perform an animation, we need to:
[Link] the content of the canvas: this can be done using
the [Link](0, 0, canvasWidth, canvasHeight) method;
[Link] some shapes: use any of the drawing methods we have seen so far;
[Link] the shapes: modify the position and/or orientation, size and color of the
shapes;
[Link] (go to step 1).

These are the basic steps for animating objects in a canvas. The order of the
steps can be changed (i.e. you can move the shapes before drawing them),
but, the principle is the same: clear-draw-move-repeat. Step 1 could be
avoided if you redraw the whole canvas content during step 2.

BEFORE HTML5
Even before HTML5 and the introduction of the canvas element, people created
HTML games. They used CSS backgrounds inside <div> elements, and used to
change the CSS top, left, width and height properties of the divs to
animate graphic images on the screen.

During the late 1990s and early 2000s, JavaScript became increasingly popular.
The community created a first 'umbrella term' describing a collection of
technologies used together to create interactive and animated Web sites
- DHTML (Dynamic HTML). For example, check the games developed at this
time by Brent Silby (they all use DHTML).

For animation,
the setInterval(function,
ms) and setTimeout(function,
ms) methods were the only
solutions. Both methods take a function
as the first parameter, and a number of
milliseconds as the second parameter.

The only difference is that the code


provided to setInterval will run every n
milliseconds whereas the code
in setTimeout will run only once after n
milliseconds (meaning that we will have to repeat a call to setTimeout at step
4 above).

AFTER HTML5
The methods described above are now completed by a new method that
comes with multiple advantages: the requestAnimationFrame API.

We will compare the old methods with the new one, and implement the same
example with each of them to highlight the differences.

Performing animation using the


JavaScript setInterval(...) function
The setInterval(...) function is still popular on the Web, and even though
this is not the recommended way to do 60 frames/second canvas animation, it
is worth understanding how it works.
Syntax: setInterval(function, ms);
The setInterval(...) function calls another function or evaluates an
expression at specified intervals of time (in milliseconds), and returns
the unique id of the action. You can always stop it by calling
the clearInterval(id) function with the interval identifier as an argument.

Basic example that shows how to animate a DIV


using the DOM API (this is how pre-HTML5 games
were written)
Please try it online: [Link] (open the html, JavaScript
and output tabs):

Extract from the source code:

1. <body>
2. <div id="animatedDIV">Animated DIV :-)</div>
3. <button onclick="start()">Start animation</button>
4. <button onclick="stop()">Stop animation</button>
5. <script>
6. var elm = [Link]("animatedDIV");
7. var requestId;
8. var x = 0;
9. function render(time) {
10. [Link] = x++ + "px";
11. }
12. function start() {
13. requestId = setInterval(render, 10);
14. }
15. function stop() {
16. if (requestId) {
17. clearInterval(requestId);
18. }
19. }
20. </script>
21. </body>

Here, we define a <div> element, (see the online source code for the CSS
properties involved), and we use the setInterval method (line 17) to call
every 10ms the render() method that will just increment the position of this
element. Notice that since we're using the DOM, the horizontal position of the
div is modified by changing its left CSS property.

The call to setInterval returns an id we can use to stop the animation, by


calling clearInterval (line 22).

Animate the monster in a canvas, using setInterval


Online example: [Link]
Source code:

1. <body onload="init();">
2. <canvas id="myCanvas" width="400" height="400">
3. Your browser does not support the canvas tag.
4. </canvas>
5. <p>
6. <button onclick="start()">Start animation</button>
7. <button onclick="stop()">Stop animation</button>
8. <script>
9. var canvas, ctx;
10. var monsterX=100, monsterY=100, monsterAngle=0;
11. function init() {
12. // This function is called after the page is loaded
13. // 1 - Get the canvas
14. canvas = [Link]('myCanvas');
15. // 2 - Get the context
16. ctx=[Link]('2d');
17. }
18. function animationLoop() {
19. // 1 - Clear the canvas
20. [Link](0, 0, [Link], [Link]);
21. // 2 Draw the monster using variables for pos, angle, etc.
22.
drawMonster(monsterX, monsterY, monsterAngle, 'green', 'yellow');
23. // 3 Move the monster (change pos, angle, size, etc.)
24. monsterX += 10;
25. monsterX %= [Link]
26. monsterAngle+= 0.01;
27. }
28. function drawMonster(x, y, angle, headColor, eyeColor) {
29. // BEST PRACTICE: SAVE CONTEXT AND RESTORE IT AT THE END
30. [Link]();
31. // Moves the coordinate system so that the monster is drawn
32. // at position (x, y)
33. [Link](x, y);
34. [Link](angle)
35. // head
36. [Link]=headColor;
37. [Link](0,0,200,200);
38. ...
39. // BEST PRACTICE!
40. [Link]();
41. }
42. function start() {
43. // Start the animation loop, change 20 for bigger values
44. requestId = setInterval(animationLoop, 20);
45. }
46. function stop() {
47. if (requestId) {
48. clearInterval(requestId);
49. }
50. }
51. </script>
52. </body>

Lines 52-61: The code for launching and stopping the animation is similar to
that from the previous example.
Lines 34-50: The code that draws the monster is that which we saw earlier
when we presented the 2D transformations. Best practice is to save and
restore the context at the beginning and end of each function that changes the
context.
Lines 21-32: The most interesting part is the animation loop that
implements the basic animation steps: clear-draw-move. In order to make a
shape "movable", we use some "state variables" for its position and angle, and
we modify them at each iteration (lines 29-32). We will see later on how to
modify the value of these variables on user interactions (keyboard, mouse,
etc.).

Problems with setInterval


Running several animations simultaneously
The setInterval function may become hard to debug, particularly if you run
several animations simultaneously. For example, if you have two intervals, one
running every 100 milliseconds, the other every second, and if you want to
debug the second one, the first one will constantly be run at regular intervals,
making step by step debugging really difficult.
A single animation may be interrupted by itself to become
two simultaneous animations
setInterval will execute the function passed as first parameter
every n milliseconds regardless of when the function was last called or how
long the function takes to execute. If the function takes longer than the
interval, then setInterval might queue too many function executions back to
back when the interval is too short, leading to unpredictable results.
BEST PRACTICE: AVOID using setInterval for animating in a canvas,
except for trivial cases (change a color every second).
Using setTimeout() instead
of setInterval()
Introduction
One thing you should always remember about using setInterval: if we set
number of milliseconds at - let’s say 20ms - it will call our game loop function
EACH 20ms, even if the previous one is not yet finished. This may lead to many
problems (incomplete rendering, etc.).

That's where we can use another function:

Syntax: setTimeout(function, ms);

This function works like setInterval(...) with one difference: it calls your
function ONCE and AFTER a given amount of time.

Example of the monster animated in a canvas


with setTimeout
Example of use: [Link] (open the JavaScript, console
and output tabs).
This is similar to the previous example except that we called
setTimeout(function, delay) instead of setInterval(function,
period). As setTimeout runs the function passed as the first parameter
only once, we also have to call it at the end of the loop.

Extract from source code:

1. function animationLoop() {
2. // 1 - Clear
3. [Link](0, 0, [Link], [Link]);
4. // 2 Draw
5. drawMonster(monsterX, monsterY, monsterAngle, 'green', 'yellow');
6. // 3 Move
7. monsterX += 10;
8. monsterX %= [Link]
9. monsterAngle+= 0.01;
10. // call mainloop again after 20ms
11. requestId = setTimeout(animationLoop, 20);
12. }
13.
14. function start() {
15. // Start the animation loop, change 20 for bigger
16. // values
17. requestId = setTimeout(animationLoop, 20);
18. }
19. function stop() {
20. if (requestId) {
21. clearTimeout(requestId);
22. }
23. }

This function is certainly more suitable for doing graphic animation, such as for
writing an HTML5 game. It will never interrupt an ongoing animation, even if
the instructions inside the animation loop take too long.

Problems with setInterval() and setTimeout()


setTimeout does not "wait" during the timeout period. It lets the rest of the
JavaScript code run. It schedules a new call to the function passed as first
parameter with a timer running in the background. This might cause it to take
slightly longer than the expected timeout period to start executing.

This problem also occurs with setInterval, the timing is not "very" reliable. If
you plan to run a function every 20ms, and if you measure precisely the real
timing, sometimes you will discover big differences between what is scheduled
and what is performed. This is because these methods were designed a long
time ago, when high precision timers and 60 frames per second animation
were not an option.

Here comes the requestAnimationFrame API, a very good companion to the


canvas API!

BEST PRACTICE: AVOID using setTimeout for animating in a canvas, except


for trivial cases.
For 60 frames/second animation, use requestAnimationFrame!

requestAnimationFrame() - 60
frames/second animation (best
practice)!

Introduction: advantages over previous methods


The new requestAnimationFrame(animationLoop) is very similar
to setTimeout:
It targets 60 frames/s: requestAnimationFrame asks the browser to
schedule a call to the animationLoop function passed as parameter in 1/60th
of a second (equivalent to 16.6ms). Keep in mind that most monitors cannot
display more than 60 frames per second (FPS). Note that whether humans can
tell the difference among high frame rates depends on the application, most
games are acceptable above 30 FPS, and virtual reality might require 75 FPS to
achieve a natural feel. Some gaming monitors go up to 144 FPS (pro players in
e-sport train themselves at Counter Strike with a 150 frames/s rate).
It calls the function only ONCE, so if you want a continuous animation, like
with setTimeout, you need to call again requestAnimationFrame at the end of
the animationLoop function.

It has, however, several advantages over setInterval and setTimeout:

The scheduling is much more accurate: if the code inside the function can
be executed in less than 16.6ms, then the average error between the
scheduled time and the real time will be much smaller than with the old
functions.
High resolution timer: even if this difference is small, the function that is
called after 16.6ms has an extra parameter that is a high resolution time, very
useful for writing games that do time-based animation. Time-based animation
will be studied in detail in the HTML5 Part 2 course at W3Cx. It is a technique
that comprises measuring the amount of time elapsed between two frames,
then computing the distance in pixels to move objects on screen so that the
visible speed for a human eye remains constant, even if the frame rate is not.
Multiple animations are merged: browsers can bundle animations
happening at the same time into a single paint redraw (thus happening
faster/with less CPU cycles), solving the problems that can occur with
simultaneous setInterval calls.
CPU/GPU optimization, battery saved on mobiles: if the JavaScript
execution is occurring in a tab/window which is not visible, it doesn’t have to be
drawn. However the animation loop is still executed (objects will be moved, not
drawn). This is the same when a mobile phone or tablet screen is black or if the
application is put in background.

Typical use
You will note that requestAnimationFrame(function) is used
like setTimeout(function, delay). A call to requestAnimationFrame just
asks the browser to call the function passed as a parameter ONCE, and the
target delay is fixed, and corresponds to a 60 frames/s frame rate (16.6ms).
Notice that an id is used for stopping an animation
with cancelAnimationFrame(id).

Source code:

1. <body onload="init();">
2. <script>
3. var canvas, ctx;
4. function init() {
5. // This function is called after the page is loaded
6. // 1 - Get the canvas
7. canvas = [Link]('myCanvas');
8. // 2 - Get the context
9. ctx=[Link]('2d');
10. // 3 - start the animation
11. startAnimation();
12. }
13.
14. var id;
15. function animationLoop(timeStamp) {
16. // 1 - Clear
17. [Link](0, 0, [Link], [Link]);
18. // 2 Draw
19. drawShapes(...);
20. // 3 Move
21. moveShapes(...);
22. // call mainloop again after 16.6ms (corresponds to 60 frames/second)
23. id = requestAnimationFrame(animationLoop);
24. }
25.
26. function startAnimation() {
27. id = requestAnimationFrame(animationLoop);
28. }
29. function stopAnimation() {
30. if (id) {
31. cancelAnimationFrame(id);
32. }
33. }
34. </script>
35. </body>

Example: Animate the monster


with requestAnimationFrame
Online example at JsBin
Extract from source code, compare to the previous example that
used setInterval()

1. function animationLoop(timeStamp) {
2. // 1 - Clear
3. [Link](0, 0, [Link], [Link]);
4.
5. // 2 - Draw
6. drawMonster(monsterX, monsterY, monsterAngle, 'green', 'yellow');
7.
8. // 3 - Move
9. monsterX += 10;
10. monsterX %= [Link]
11. monsterAngle+= 0.01;
12.
13. // call mainloop again after 16.6 ms (60 frames/s)
14. requestId = requestAnimationFrame(animationLoop);
15. }
16. function start() {
17. // Start the animation loop, targets 60 frames/s, this
18. // calls animationLoop only ONCE!
19. requestId = requestAnimationFrame(animationLoop);
20. }
21. function stop() {
22. if (requestId) {
23. cancelAnimationFrame(requestId);
24. }
25. }

Notice that calling requestAnimationFrame(animationLoop) at line 19, and


after that from within the loop at line 14, asks the browser to call
the animationLoop function so that the delta between calls will be as close as
possible to 16.6ms (this corresponds to 1/60th of a second).

Is the 16.6ms delay really accurate? Can we trust it?


This target may be hard to reach if:
The animation loop content is too complex,
The target device that runs the animation is a low end phone or an old
computer,
The scheduler may be a bit late or a bit in advance (even if this kind of error is
much smaller withrequestAnimationFrame than
with setInterval or setTimeout).

Many HTML5 games perform what we call a "time-based animation". For this,
we need an accurate timer that will tell us the elapsed time between each
animation frame.

Depending on this time, we can compute the distances that must be achieved
by each object on the screen in order to move at a constant speed (for a
human eye), independently of the CPU or GPU of the computer or mobile
device that is running the game.

The timeStamp parameter of the animationLoop function (line 1 in the above


code) is useful for exactly that: it gives a high resolution time. By measuring
deltas between two consecutive calls of the animationLoop, we will know
exactly, with a sub-millisecond accuracy, the elapsed time between two
frames.

Using time-based animation, and more generally, using the canvas element for
writing HTML5 games, will be a chapter of the HTML5 Part-2 course to come.

Current support
Current support (as of June 2016) is really good and all modern browsers
support this API.

Up-to-date version of this table +


details: [Link]
Input & output: how events work in Web apps & games

Introduction - event management in JavaScript

In JavaScript, we treat events made by

users as an input, and we manipulate the

DOM structure as an output. Most of the

time in games/animations, we will change

state variables of moving objects, such as

position or speed of an alien ship, and the animation loop will take care of

these variables to move the objects.

The events are called DOM events, and we use the DOM JavaScript API to

create event handlers.

There are three ways to manage events in the DOM structure.

First way: declare event handlers in the HTML code

You will often find this in examples on the Web:

1. <div id="someDiv" onclick="alert('clicked!');">


2. content of the div
3. </div>
Note: this is not the recommended way to handle events, even if it's very

easy to use. Mixing the 'visual layer' (HTML) and the 'logic layer'

(JavaScript) in one place is ok for small examples (we have used this in

some examples in this course) but is not the recommended way for full

scale applications where a clean separation is best.

Second way: add an event handler to an HTML element in

JavaScript

Here is an example:

1. [Link]('someDiv').onclick = function(evt) {
2. alert('clicked!');
3. }

This method is fine, but you will not be able to attach several listener

functions. If you need to do this, the preferred version is the next one.

Third way: register a callback to the event listener with

the addEventListener method

This is how we do it:

1. [Link]('someDiv').addEventListener('click', function(
evt) {
2. alert('clicked!');
3. }, false);

The third parameter is not important for now, just set it to false, or

simply do not add a third parameter.

The DOM event that is passed to the event listener function

When you create an EventListener and attach it to an element, an event

object will be passed as a parameter to your callback, just like this:

1. [Link]('click', function(event) {
2. // now you can use the event object inside the callback
3. }, false);

Depending on the type of event you are listening to, we will use different

properties from the event object in order to get useful information like:

"what keys have been pressed down?", "what is the position of the mouse

cursor?", "which mouse button is down?", etc.

We will now cover how to deal with the keyboard and the mouse. Some

experimental APIs like the gamePad API are on their way and supported
by some browsers (to be studied in the HTML5 Part-2 course to come at

W3Cx).

Source code for the Knowledge Check 4.3.1

Online example on JS Bin

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Click on button</title>
6. </head>
7. <body>
8. <button id="myButton">Click me!</button>
9. <script>
10. var button = [Link]('myButton');
11. // Define a click listener on the button
12. [Link]('click', processClick);
13. // callback
14. function processClick(event) {
15. [Link]("Button clicked");
16. // What is the event parameter?
17. }
18. </script>
19. </body>
20. </html>
Dealing with key events

Introduction
This has been a bit of a nightmare for years, as different browsers have had
different ways of handling key events and key codes (read this if you are fond
of JavaScript archeology: [Link] Fortunately it's
much better today, and we are able to rely on methods that should work on
any browser.

When you listen to keyboard related events (keydown, keyup or keypressed),


the event parameter passed to the listener function will contain the code of the
key that fired the event. Then it is possible to test what key has been pressed
or released, like this:

1. [Link]('keydown', function(event) {
2. if ([Link] === 37) {
3. //left arrow was pressed
4. }
5. }, false);

At line 2, the value "37" is the key code that corresponds to the left arrow. It
might be difficult to know the correspondences between real keyboard keys
and codes, so here are handy pointers:

Try key codes with this interactive


example: [Link]
And find a list of keyCodes (taken
from: [Link] below:
Example 1: adding a key listener to the window
object
A lot of people think that the canvas element is not able to get key events.
Many examples on the Web handle key events on canvas by adding a listener
to the window object directly, like this:

Online example: [Link]

Extract from source code:

1. <canvas id="myCanvas" width="350" height="200">


2. </canvas>
3.
4. <script>
5. function init() {
6. // This will work when you press a key, anywhere on the document
7. [Link]('keydown', handleKeydown, false);
8. }
9.
10.
11. function handleKeydown(e){
12. alert('keycode: '+[Link]);
13. return false;
14. };
15. </script>

Indeed this solution works well if you write a game, and want to detect events
wherever the mouse cursor is, and without worrying about what HTML element
has the focus, etc...

Move the monster with the keyboard


Online example at JS Bin

Extract from source code:

1. <script>
2. var canvas, ctx;
3. var monsterX=100, monsterY=100, monsterAngle=0;
4. var incrementX = 0;
5. function init() {
6. // This function is called after the page is loaded
7.
8. // 1 - Get the canvas
9. canvas = [Link]('myCanvas');
10.
11. // 2 - Get the context
12. ctx=[Link]('2d');
13.
14. // 3 add key listeners to the window element
15. [Link]('keydown', handleKeydown, false);
16. [Link]('keyup', handleKeyup, false);
17. // 4 - start the animation
18. requestId = requestAnimationFrame(animationLoop);
19. }
[Link] handleKeydown(evt) {
21. if ([Link] === 37) {
22. //left key
23. incrementX = -1;
24. } else if ([Link] === 39) {
25. // right key
26. incrementX = 1;
27. }
28. }
[Link] handleKeyup(evt) {
30. incrementX = 0;
31. }
32. function animationLoop() {
33. // 1 - Clear
34. [Link](0, 0, [Link], [Link]);
35.
36. // 2 Draw
37. drawMonster(monsterX, monsterY, monsterAngle, 'green', 'yellow');
38.
39. // 3 Move
40. monsterX += incrementX;
41.
42. // call again mainloop after 16.6 ms (60 frames/s)
43. requestId = requestAnimationFrame(animationLoop);
44. }
45. </script>
Example 2: What if I want to listen to key events
only in my canvas?
If you add a key listener to a canvas element, the problem is that it will get
events only when it has the focus. And by default, it will never have the focus!
The tabindex attribute of the canvas element makes it
focusable. Without it, it will never get the focus!
The trick is to declare the canvas like this:
1. <canvas id="myCanvas" width="350" tabindex="1" height="200">
2. </canvas>

And we force the canvas to get the focus with:

1. canvas=[Link]('myCanvas');
2. ...
3. [Link]();

Now, if we try an example with the above canvas declaration, we show when
an HTML element has the focus: a border is added to it, as shown
here: [Link]

Note that the line that forces the focus to the canvas is commented by default.
Try to click on the canvas, then press a key, then click out of the canvas, then
press a key: this time nothing happens!

Extract from the code:

1. var canvas;
2. function init() {
3. canvas=[Link]('myCanvas');
4.
5. // This will work only if the canvas has the focus
6. [Link]('keydown', handleKeydown, false);
7. // We can set the focus on the canvas like this:
8. //[Link]();
9. // ... but it will stop working if we click somewhere else
10. // in the document
11. }
12.
13.
14. function handleKeydown(e){
15. alert('keycode: '+[Link]);
16. return false;
17. };

Line 10 is useful to initially set the focus on the canvas, but this trick will not
work if we click somewhere else in the HTML page.

Example 3: A better way: set the focus when the


mouse cursor enters the canvas
A better way to manage key events on a canvas is to set the focus when the
mouse is over the canvas, and to un-focus it otherwise.

Here is a modified version of the "move monster example" seen earlier. This
time, you move the monster with the left and right arrow only when the mouse
cursor is over the canvas. We added two mouse event listeners on the canvas:
one for the mouseenter event and the other for the mouseout event.

When the mouse enters the canvas we call [Link]() to set the focus to
the canvas, and when the mouse cursor goes out of the canvas, we
call [Link]() to unset the focus.

Online example at JS Bin


Extract from the code:

1. function init() {
2. // This function is called after the page is loaded
3. // 1 - Get the canvas
4. canvas = [Link]('myCanvas');
5. // 2 - Get the context
6. ctx=[Link]('2d');
7. // 3 - Add key listeners to the window element
8. [Link]('keydown', handleKeydown, false);
9. [Link]('keyup', handleKeyup, false);
10. [Link]('mouseenter', setFocus, false);
11. [Link]('mouseout', unsetFocus, false);
12. // 4 - Start the animation
13. requestId = requestAnimationFrame(animationLoop);
14. }
15. function setFocus(evt) {
16. [Link]();
17. };
18. function unsetFocus(evt) {
19. [Link]();
20. incrementX = 0; // stop the monster if the mouse exists the canvas
21. };

The third parameter (false) of lines 12 and 13 means "we do not want to
propagate the event to the ancestors of the canvas in the DOM."

Mouse interaction, mouse events

Introduction
Detecting mouse events in a canvas is quite straightforward: you add an event
listener to the canvas, and the browser invokes that listener when the event
occurs.

The example below is about listening to mouseup and mousedown events (when
a user presses or releases any mouse button):

1. [Link]('mousedown', function (evt) {


2. // do something with to the mousedown event
3. });

The event received by the listener function will be used for getting the button
number or the coordinates of the mouse cursor. Before looking at different
examples, let's look at the different event types we can listen to.

The different mouse events


We saw in the last example how to detect
the mouseenter and mouseout events.

There are other events related to the mouse:

mouseleave: similar to mouseout, fired when the mouse leaves the surface of
the element. The difference between mouseleave and mouseout is
that mouseleave does not fire when the cursor moves over descendant
elements, and mouseout is fired when the element moved is outside of the
bounds of the original element or is a child of the original element.
mouseover: the mouse cursor is moving over the element that listens to that
event. A mouseover event occurs on an element when you are over it - coming
from either its child OR parent element, but a mouseenter event only occurs
when the mouse moves from the parent element to the child element.
mousedown: fired when a mouse button is pressed.
mouseup: fired when a mouse button is released.
mouseclick: fired after a mousedown and a mouseup have occured.
mousemove: fired while the mouse moves over the element. Each time the
mouse moves, a new event is fired, unlike with mouseover or mouseenter,
where only one event is fired.

the tricky part: accurately getting the mouse


position relative to the canvas
When you listen to any of the above events, the event object (we call it a "DOM
event"), passed to the listener function, has properties that correspond to the
mouse coordinates: clientX and clientY.

However, these are what we call "window coordinates". Instead of being


relative to the canvas itself, they are relative to the window (the page).

Most of the time you need to work with the mouse position relative to the
canvas, not to the window, so you must convert the coordinates between the
window and the canvas. This will take into account the position of the canvas,
and the CSS properties that may affect the canvas position (margin, etc.).
Fortunately, there exists a method for getting the position and size of any
element in the page: getBoundingClientRect().

The example that shows the problem is at: [Link]

WRONG code:

1. ...
2. [Link]('mousemove', function (evt) {
3. mousePos = getMousePos(canvas, evt);
4. var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
5. writeMessage(canvas, message);
6. }, false);
7.
8. ...
9. function getMousePos(canvas, evt) {
10. // WRONG!!!
11. return {
12. x: [Link],
13. y: [Link]
14. };
15. }

Here is the result, when the mouse is approximately at the top left corner of
the canvas:
Good version of the code: [Link]

1. function getMousePos(canvas, evt) {


2. // necessary to take into account CSS boundaries
3. var rect = [Link]();
4. return {
5. x: [Link] - [Link],
6. y: [Link] - [Link]
7. };
8. }

Result (the cursor is approximately at the top left corner):


GOOD Example that shows how to display the mouse
position, and the mouse button that has been
pressed or released
This example uses the previous function for computing the mouse position
correctly. It listens to mousemove, mousedown and mouseup events, and shows
how to get the mouse button number using the [Link].

Online example: [Link]

Extract from source code:

1. var canvas, ctx, mousePos, mouseButton;


2.
3. [Link] = function init() {
4. canvas = [Link]('myCanvas');
5. ctx = [Link]('2d');
6.
7. [Link]('mousemove', function (evt) {
8. mousePos = getMousePos(canvas, evt);
9. var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
10. writeMessage(canvas, message);
11. }, false);
12.
13. [Link]('mousedown', function (evt) {
14. mouseButton = [Link];
15. var message = "Mouse button " + [Link] + " down at position:
" + mousePos.x + ',' + mousePos.y;
16. writeMessage(canvas, message);
17. }, false);
18.
19. [Link]('mouseup', function (evt) {
20. var message = "Mouse up at position:
" + mousePos.x + ',' + mousePos.y;
21. writeMessage(canvas, message);
22. }, false);
23. };
24.
25. function writeMessage(canvas, message) {
26. [Link]();
27. [Link](0, 0, [Link], [Link]);
28. [Link] = '18pt Calibri';
29. [Link] = 'black';
30. [Link](message, 10, 25);
31. [Link]();
32. }
33.
34. function getMousePos(canvas, evt) {
35. // necessary to take into account CSS boudaries
36. var rect = [Link]();
37. return {
38. x: [Link] - [Link],
39. y: [Link] - [Link]
40. };
41. }

Example: move the monster with the mouse, rotate


it when a mouse button is pressed.
This example shows an animation at 60 frames/s
using requestAnimationFrame, were the monster is drawn at the mouse
position, and if a mouse button is pressed, the monster starts rotating around
its center. If we release the mouse button, the rotation stops.
Online example: [Link]

Extract from source code:

1. var canvas, ctx;


2. var monsterX=100, monsterY=100, monsterAngle=0;
3. var incrementX = 0;
4. var incrementAngle =0;
5. var mousePos;
6. function init() {
7. ...
8. // 3bis - Add mouse listeners
9. [Link]('mousemove', handleMousemove, false);
10. [Link]('mousedown', handleMousedown, false);
11. [Link]('mouseup', handleMouseup, false);
12.
13. // 4 - Start the animation
14. requestId = requestAnimationFrame(animationLoop);
15. }
[Link] handleMousemove(evt) {
17. // The mousePos will be taken into account in the animationLoop
18. mousePos = getMousePos(canvas, evt);
19. }
20. function handleMousedown(evt) {
21. // the increment on the angle will be
22. // taken into account in the animationLoop
23. incrementAngle = 0.1;
24. }
[Link] handleMouseup(evt) {
26. incrementAngle = 0; // stops the rotation
27. }
28. function getMousePos(canvas, evt) {
29. ... // same as before
30. }
31. ...
32. function animationLoop() {
33. // 1 - Clear
34. [Link](0, 0, [Link], [Link]);
35.
36. // 2 - Draw
37. drawMonster(monsterX, monsterY, monsterAngle, 'green', 'yellow');
38.
39. // 3 - Move
40. if(mousePos !== undefined) { // test necessary, maybe the mouse
is not yet on canvas
41. monsterX = mousePos.x;
42. monsterY = mousePos.y;
43. monsterAngle += incrementAngle;
44. }
45. ...
46.
47. // call again mainloop after 16.6 ms (60 frames/s)
48. requestId = requestAnimationFrame(animationLoop);
49. }
This example shows one very important good practice when doing animation
and interaction: if you want to achieve a smooth animation, set the state
variables 60 times/s inside the animation loop (lines 45-49), depending on
increments you set in event listeners (lines 23-31).

Example: draw in a canvas as if you were using a


pencil
Online example: [Link]

Source code:

1. ...
2. <script>
3. var canvas, ctx, previousMousePos;
4. ...
5. function drawLineImmediate(x1, y1, x2, y2) {
6. // a line is a path with a single draw order
7. // we need to do this in this example otherwise
8. // at each mouse event we would draw the whole path
9. // from the beginning. Remember that lines
10. // normally are only usable in path mode
11. [Link]();
12. [Link](x1, y1);
13. [Link](x2, y2);
14. [Link]();
15. }
16.
17. function handleMouseMove(evt) {
18. var mousePos = getMousePos(canvas, evt);
19.
20. // Let's draw some lines that follow the mouse pos
21. if (!started) {
22. previousMousePos = mousePos; // get the current mouse position
23. started = true;
24. } else {
25. // We need to have two consecutive mouse positions before drawing
a line
26. drawLineImmediate(previousMousePos.x, previousMousePos.y,
27. mousePos.x, mousePos.y);
28. previousMousePos = mousePos;

29. }
30. }
31. [Link] = function () {
32. ...
33. started = false;
34.
35. [Link]('mousemove', handleMouseMove, false);
36. };
37. </script>

We had to define a variable started=false; as we cannot draw any line before


the mouse moved (we need at least two consecutive positions). This is done
in the test at line 21.

Same example but we draw only when a mouse


button is pressed
Online example: [Link]
We just added mouseup and mousedown listeners, extract from the source code:

1. function handleMouseMove(evt) {
2. var mousePos = getMousePos(canvas, evt);
3.
4. // Let's draw some lines that follow the mouse pos
5. if (painting) {
6. drawLineImmediate(previousMousePos.x, previousMousePos.y,
7. mousePos.x, mousePos.y);
8. previousMousePos = mousePos;
9. }
10. }
11. function clicked(evt) {
12. previousMousePos = getMousePos(canvas, evt);
13. painting = true;
14. }
15.
16. function released(evt) {
17. painting = false;
18. }
19.
20. [Link] = function () {
21. canvas = [Link]('myCanvas');
22. ctx = [Link]('2d');
23. painting = false;
24.
25. [Link]('mousemove', handleMouseMove, false);
26. [Link]('mousedown', clicked);
27. [Link]('mouseup', released);
28. };

Responsive canvas, resizing a canvas

Introduction
Resizing a canvas can be tricky if we don't know a few rules that might not
be easily guessed:
[Link] the width or height property of a canvas in JavaScript erases its
content and resets its context,
[Link] percentages (%) in the CSS width and height properties of a
canvas does not change its number of pixels/resolution. Instead, it scales the
existing pixels without erasing the content, giving a blurry effect when a
canvas becomes larger, for example.

Before looking at how best to handle canvas resizing, let's see some
examples below:

Example 1: changing the size of a canvas on the fly


erases its content!

Online example: [Link]

1. <script>
2. ...
3. function resizeCanvas() {
4. [Link] = 300;
5. }
6.
7. </script>
8. ...
9. <button onclick="resizeCanvas();">
10. Click this button to resize the canvas and erase it!
11. </button>

Example 2 : resize a canvas using


CSS width and height properties with percentages
This time we are using a similar example as above, but we removed the button
for resizing it, and we set the size of the canvas to 100x100 pixels. Instead of
drawing inside, we draw two lines that join the diagonals.

Here is the online version : [Link]

Then, we added this CSS rule. Try it online (resize the windows, you will see
what happens): [Link]

It's the same example as before, just adding the CSS:

1. <style>
2. #myCanvas {
3. border: 1px solid black;
4. width:100%
5. }
6. </style>

And the result shows clearly that the resolution is still the same, only the pixels
are bigger!
Even bigger:

GOOD PRACTICE: never use CSS percentages on a canvas width or


height!

Example 3: a responsive canvas using a resize


listener + a parent element
This is the trick to create a really responsive canvas:
[Link] it in a <div> or in any parent container,
[Link] CSS with percentages on the width and the height CSS properties of
the parent,
[Link] a resize listener on the parent of the canvas,
[Link] the width and height properties of the canvas from the JavaScript
resize listener function (content will be erased),
[Link] the content, scaled accordingly to the size of the parent.

Yep, this is not a straightforward process...

HTML, CSS and JavaScript code

HTML code:

1. <div id="parentDiv">
2. <canvas id="myCanvas" width="100" height="100" ></canvas>
3. </div>

CSS code:

1. <style>
2. #parentDiv {
3. width:100%;
4. height:50%;
5. margin-right: 10px;
6. border: 1px solid red;
7. }
8.
9. canvas {
10. border: 2px solid black;
11. }
12. </style>

JavaScript code for the resize event listener:

1. function init() {
2. ...
3. // IMPORTANT: there is NO WAY to listen to a DIV's resize
4. // listen to the window instead.
5. [Link]('resize',
6. resizeCanvasAccordingToParentSize, false);
7. ...
8. }
9.
10. function resizeCanvasAccordingToParentSize() {
11. // adjust canvas size, take parent's size, this erases content
12. [Link] = [Link];
13. [Link] = [Link];
14. ...
15. // draw something, taking into account the new canvas size
16. }

Complete example: [Link]


Original window size:

We resize the window horizontally:


Example 4: the same example with the monster
Online example: [Link]

Initial size:

When the canvas is resized, its width became smaller than the monster's size.
We scaled down the monster (using [Link]!)
The code is very similar to the previous example, we just
replaced drawDiagonals() by drawMonster(...), and we added a test in
the drawMonster(...) function for scaling the monster if it's bigger than the
canvas width (look at lines 10-16), this is a common trick:

1. function drawMonster(x, y, angle, headColor, eyeColor) {


2. // GOOD PRACTICE: SAVE CONTEXT AND RESTORE IT AT THE END
3. [Link]();
4. // Moves the coordinate system so that the monster is drawn
5. // at position (x, y)
6. [Link](x, y);
7. [Link](angle);
8. // Adjust the scale of the monster (200x200) if the canvas
9. // is too small
10. if([Link] < 200) {
11. var scaleX = [Link]/200;
12. var scaleY = scaleX;
13. }
14. [Link](scaleX, scaleY);
15. // head
16. [Link]=headColor;
17. [Link](0,0,200,200);
18. ...
19. }
What you will learn about the canvas in
the HTML5 part-2 course
As seen in this course, the canvas API is a "big beast", and we have presented
all the essential techniques for drawing and animating. However, we could not
fit everything into this part of the course. Exotic features that are rarely used
by developers, or advanced techniques that require more than 20 lines of
JavaScript, have been put aside for the upcoming HTML5 part-2 course, which
will soon be available at W3Cx.

In that HTML5 part-2 course, you will learn:

Techniques useful for writing HTML5 games: time-based animation,


advanced user interactions (detecting multiple keys plus mouse plus gamepad
plus touch events all at the same time in a single version of the code), sprite
based animation, collision detections, particle animation;
Pixel-level operations: special FX like blue-screen videos and augmented
reality;
And many other things, such as: masking/clipping, stacking canvases in
layers, composition modes, saving and restoring canvas contents, saving
canvas content to disk client-side, drawing a canvas into a canvas, etc.

Examples studied in the HTML5 advanced course (all


audio for games will also be covered)
Small game framework / object oriented JavaScript / advanced event
handling / collision detection / time based
animation: [Link]
Sprite based animation: [Link] (this is ugly code
to demonstrate the principle - in the course we develop a clean, sprite
animation framework).
Week 5

Introduction

With HTML5, forms, which had shown little improvement since 1997, evolved
considerably. To achieve this, web developers relied on many popular
JavaScript frameworks for validating input formats, providing various input
GUIs, such as calendars for dates, sliders, etc. Frameworks such as jQueryUI,
Dojo, and Sencha all provide a widget set for improving forms. Furthermore, it
was time to take into account the specifics of mobile web applications, where
the GUI of a date chooser cannot be the same as a 400x400 pixel wide
calendar on a desktop. Contextual virtual keyboards provided the way forward
on smartphones and tablets thanks to Apple, Google and others.

HTML5 took all this into account and now provides:

A new set of input fields that include a validation API and visual feedback,
contextualized keyboards, etc. Of course the look and feel depends on the web
browser's implementations, but the HTML5 forms specification introduced 13
new <input type=.../> fields: email, tel, color, url, date, datetime,
datetime-local, month, week, time, range, number and search.
Built-in validation system: JavaScript API for custom validation, CSS pseudo
classes that are useful for changing an input field style depending on the
validity of the input.
Other goodies, such as the option to set an input field out of a <form>, new
elements such as<datalist> for autocompletion, <output> for feedback, etc.

Examples of contextual keyboards are shown above; they differ depending on


the type of <input> fields in the <form>. In the example we can see: email,
URL, and phone number. Look at the different keyboard layouts. The last
picture is a date picker from an IOS phone.

HTML5 form examples


Introduction
In this section, we will show you what can be achieved with
recent HTML5 additions for forms. Try the examples, enter erroneous values,
submit the forms, and see what happens.

There is a lot of course content covered this week, and before we get into all
the details of the elements and attributes introduced by
HTML5 we suggest playing with running examples of full featured forms.

The examples
These examples are creations by students from a previous version of this
course, when it was hosted at the [Link] Web site (the W3C e-
learning platform). They are given "as is". They use the geolocation API that
will be presented in Week 6 for auto-filling the address input fields. This part
will be explained next week.

Feel free to look at the source code, and do not hesitate to ask questions in the
forum if you need explanations.
Example 1 (by Steve K.)
Example 2 at JS Bin (by Mels Le N.)

Example 3 (by Guillaume D.)


This example uses video, very nice CSS layout/styling and HTML5 forms.
Example 4 (by Philipp K.)

Using input elements for a Web


application GUI
This page's video shows that input elements,
in particular the new elements introduced by
HTML5, can be used as widgets to control the
behavior of a Web application. In this
situation, they do not need to be inside a
<form> element. We just bind event
listeners to them and we use them as client-
side widgets.
Example 1: choose the color, line width and speed of
an animation
Bouncing rectangle without GUI (JS Bin)
Bouncing rectangle with GUI (see screenshot at the top right of this page)
Same example as above, on JS Bin, that uses polyfills for IE and
Safari ([Link] for making <input type=color> work, and a small JS
polyfill for making [Link]() work too...). This is a good example of using a
polyfill.

Example 2: data visualization


control
Simple chart without a GUI (JS Bin)
Simple chart with a GUI (see screenshot on
the right)
Final version with different types of charts
and a GUI (see screenshot below)
Example from the video
Example from the video, on JS Bin

Forms are a way to get user input which is sent to a remote server. This section
of the course focuses on the HTML5 additions to forms, and as such will only
cover the client-side part.

On the server side, you may have PHP, Java, C#, Ruby, Python, etc.
components. There are several ways to collect server-side data from a form in
a Web page: REST Web services, servlets, Microsoft ASP pages, etc.
On the client side, the forms indicate to which server and how the data should
be sent, using the action and method attributes respectively. A <button
type="submit"> or an <input type=submit> field is used to submit the form
content.

For example: <form action="[Link]"


method="POST">...</form>. Here, we set the URL of the server side code
([Link]), and the HTTP method that will be used by the browser for
sending the form content (POST).

Another approach is to use JavaScript for sending the form content with
Ajax. This will be covered in the HTML5 Part-2 course.

This week, we will study the new elements and attributes offered by HTML5,
and will also cover the new HTML5 form validation API.

The example in the video shows some best practices for writing accessible
forms and does some basic layout using CSS. The additional example below
(external resource) shows the same good practices but presents a more
complete form with CSS rules to make a nice layout.

Additional example
A more complete example is on JS Bin, adapted from this very good article
from the Mozilla Developer Network.
Creating accessible forms
Forms are commonly used to enable user interaction in Web sites and Web
applications. For example for login, registering, commenting, and purchasing.

Since HTML5 provides functionalities to assist with accessibility, developers


should make a concerted effort to mark up Web based forms. The following two
guidelines are to give you a good start to make your forms accessible:

[Link] every form field, ensure that a descriptive label is provided and use
the <label> element to identify each form control.
[Link] larger or complex forms, use the <fieldset> and <legend> elements to
respectively group and associate related form controls.

We will give usage examples for each of these two basic guidelines in the
following pages.

Further reading
The WAI Web site hosts a Forms tutorial where you will find more guidelines to
follow in order to make your forms truly accessible: Form Instructions,
Validating Input, User Notifications, Multi-Page Forms, and Custom Controls.

Why is this important?


Forms can be visually and cognitively complex and difficult to use. Accessible
forms are easier to use for everyone, including people with disabilities.
People with cognitive disabilities can better understand the form and how
to complete it, as making forms accessible improves the layout structure,
instructions, and feedback.
People using speech input can use the labels via voice commands to
activate controls and move the focus to the fields that they need to complete.
People with limited dexterity benefit from large clickable areas that
include the labels, especially for smaller controls, such as radio buttons and
checkboxes.
People using screen readers can identify and understand form controls
more easily because they are associated with labels, field sets, and other
structural elements.
Labeling controls
Labels need to describe the purpose of the form
control
Form fields and other form controls usually have visible labels, such as "E-mail
Address:" as the label for a text field (see figure below).

When these labels are marked up correctly, people can interact with them
using only the keyboard, using voice input, and using screen readers. Also, the
label itself becomes clickable, which enables a person who has difficulty
clicking on small radio buttons or checkboxes to click anywhere on the label
text.

Associating labels explicitly


Whenever possible, use the label element to explicitly associate text with
form elements. The for attribute of the label must exactly match the id of the
form control.
Example 1 (click on the label, not on the input field to see
the effect)

Source code:

1. <label for="first_name">Your First Name</label>


2. <input id="first_name" type="text" name="fname"/>

Alternative example 1
Note that you can also include the <input> element inside
the <label>...</label> element, and also add a <span lang="en"> for
example, to indicate the language used in the label. Sometimes, nesting labels
and inputs can also make CSS styling easier and produce better results with
screen readers.

Source code (with <input> inside the <label>):


1. <label for="first_name"><span lang=en">Your First Name</span>
2. <input id="first_name" type="text" name="fname"/>
3. </label>

Example 2 (click on the label "Subscribe to newsletter" to


see the effect)

Source code:

1. <label for="firstname">First name:</label>


2. <input type="text" name="firstname" id="firstname"><br>
3. <label for="subscribe">Subscribe to newsletter</label>
4. <input type="checkbox" name="subscribe" id="subscribe">

labeling buttons
The label of a <button> element is set inside the element and can include
markup. This allows advanced accessibility hints to be included, such as
marking up language change.

Example: <button>Mon <span lang="fr">bouton</span></button>, for a


button with a label in French.

When using the <input> element to create buttons, the label is set in
the value attribute of the element.

Example: <input type="submit" value="Please submit">, that will be


rendered as a button.

Source code for an example of "Submit" and "Cancel" buttons:

1. <button type="submit">Submit</button>
2. <button type="button">Cancel</button>
3.
4. <input type="submit" value="Submit">
5. <input type="button" value="Cancel">

These will produce the same results:


Lines 1 and 2 render as:

While lines 3 and 4 render as:

Labeling Text areas

Source code:

1. <label for="address">Enter your


address:</label><br> <textarea id="address"name="addresstext"></texta
rea>

Grouping controls
Groupings of form controls, typically groups of related checkboxes and radio
buttons, sometimes require a higher level description. Grouping related form
controls makes forms more understandable for all users, as related controls are
easier to identify.

Associating related controls with fieldset


Grouping needs to be carried out visually and in the code, for example, by
using the <fieldset> and <legend> elements to associate related form
controls. The <fieldset> identifies the entire grouping and <legend> identifies
the grouping's descriptive text.
Example 1 - Radio buttons
In the example below, there are three radio buttons that allow the user to
choose an output format. Radio button groups should always be grouped
using <fieldset>.
Source code:

1. <fieldset>
2. <legend>Output format</legend>
3. <div>
4. <input type="radio" name="format" id="txt" value="txt" checked>
5. <label for="txt">Text file</label>
6. </div>
7. <div>
8. <input type="radio" name="format" id="csv" value="csv">
9. <label for="csv">CSV file</label>
10. </div>
11. […]
12. </fieldset>

Example 2 - Checkboxes
In the example below, there are three checkboxes that are all part of an opt-in
function for receiving different types of information.

Source code:
1. <fieldset>
2. <legend>I want to receive</legend>
3. <div>
4. <input type="checkbox" name="newsletter" id="check_1">
5. <label for="check_1">The weekly newsletter</label>
6. </div>
7. […]
8. </fieldset>

Associating related controls with WAI-ARIA


WAI-ARIA provides a grouping role that functions similarly
to fieldset and legend. For example, a divelement can have role=group to
indicate that the contained elements are members of a group.

WAI-ARIA roles are very important in the accessibility world, and we invite you
to see an example provided in the associated WAI tutorial. This article by Oscar
Cao gives an Introduction to understanding WAI-ARIA 1.0 roles.

Thirteen new input types!


In this section, we briefly present the new
input types, attributes, and elements
related to the forms that came with HTML5.
Details will be given later, illustrated by
multiple interactive examples. We will not
focus on HTML4 forms, however.

HTML5 introduced 13 new input types,


covering most of the needs reported by
Web developers who until now had relied
on JavaScript frameworks. HTML5 packages
some of the "form best practices" in its specification. Web browsers providing
native implementation will give a boost in performance, and reduce the size of
JavaScript embedded in complex Web pages.

HTML4 HTML5

 color
 date
 button
 datetime
 checkbox
 datetime-local
 file *
 email
 hidden
 month
 image
 number
 password
 range
 radio
 search
 reset
 tel
 submit
 time
 text
 url
 week
* The "file" type is disabled on IOS as this operating system does not give access to a
filesystem.
Five HTML5 types are variants about choosing a date (in red)

Now, let's play with some small examples and use these new input types and
attributes.

<input type=color>
Introduction
For years we used hundreds of lines of JavaScript for selecting colors, but now
it's bundled in the browser.

Here is how it looks on a mobile device: the first screenshot is from Opera
mobile, the second with Chrome mobile, and the third on Blackberry. Note
that, although no screenshot is shown here, FireFox mobile also has support.
Typical use
Inserting a color chooser is as simple as:
1. <!DOCTYPE html>
2. <html>
3. <body>
4. Choose a color : <input type="color" value="#FF00FF"/>
5. </body>
6. </html>

Note: In this chapter we are simplifying the examples, as we usually embed


input elements in a <form>...</form>.
Try <input type="color"> online on this JS Bin example. Or do it here in your
browser: just click the purple square (and if you don't see a light purple square,
it means that you are using either Safari or Internet Explorer - see "current
support" below):

Here is the result on Google Chrome:

Example: changing the background color of the page


The <input type="color"> can fire change or input events. Here is an
example that changes the background color of the page when a color is
chosen. Try it online at JS Bin.
Source code:

1. <!DOCTYPE html>
2. <html>
3. <body>
4. Select a color : <input type="color" id="colorChooser"/>
5. <script>
6. var colorInputField = [Link]("#colorChooser");
7. [Link]('input', function(evt) {
8. [Link] = [Link];
9. }, false);
10.</script>
11. </body>
12. </html>

Propose a limited choice of colors


By default, the color selector offers many options that may either frighten
some users or just not be appropriate for the purpose of the application.
Good news: it is possible to restrict the choices, and also simplify the user
interface, by using a <datalist>with some <option> elements inside. This
feature is not yet (as at April 2015) supported by all browsers, check this
compatibility table.

Example: if you are using Opera or Chrome, click the black rectangle on the
right: . The following should be displayed:

Online example at JS Bin

Source code extract:

1. <input type="color" value="#333333" list="colors">


2. <datalist id="colors">
3. <option>#0000FF</option>
4. <option>#00FF00</option>
5. <option>#FF0000</option>
6. </datalist>

Note that the id of the <datalist> element should be the same as the value of
the list attribute of the input field.

Warning: color values must use the CSS hexadecimal notation; using
'blue', 'green' and 'red' does not work in current implementations.

Current support for <input type="color">


As at June 2016, Safari and Internet Explorer still do not support this input type,
as shown in the table below:
Check for mobile support.

Several polyfills are available


If you click on the link to the [Link] support table, you will find links to
polyfills. There are a few available on the Web, and some are included
in [Link] (a JavaScript library that detects HTML5 and CSS3 features in
the user’s browser).

Below is an example with the polyfill [Link]. See how it renders in Safari
(the same code renders natively on browsers that support <input
type="color">):

For those of you who would prefer using a CDN, here is another example that
uses this polyfill, directly on JS Bin. You just have to include two lines in the
HTML and your <input type=range> will work on Safari and IE too :-) Notice
that this polyfill does not fire the input event, only the change event, when a
color is picked.

Example on JS Bin

We just added these two lines inside the <head>..</head> element:

1. <script src="[Link]
2. <scriptsrc="[Link]
[Link]"></script>
3. <link rel="stylesheet" type="text/css"
4.
href="[Link]
>

Another example of this polyfill. This time we downloaded it and made our own
HTML page:
And here is the HTML code (note, you first need to download the lib from the
Web site):

1. <!doctype html>
2. <html>
3. <head>
4. <title>Spectrum polyfill example, for input type=color</title>
5. <link rel="stylesheet" type="text/css" href="../[Link]">
6. <script type="text/javascript" src="../docs/[Link]"></script>
7. <script type="text/javascript" src="../[Link]"></script>
8. </head>
9. <body>
10. <input type="color" onchange="alert([Link]);"></p>
11. </body>
12. </html>

the Main problems with this element


The main criticism that Web designers make about this element is related to its
default appearance being strongly dependent on the browser and its
underlying operating system. Changing the look and feel is not possible, except
with the use of the options we saw in the previous sections of this page. This
problem is also true for other input elements that renders as complex widgets,
like <input type="date"> and its variants.

Another problem is that there is no way to control where the dialog that
contains the color chooser will appear - no positioning via CSS or JavaScript is
possible. The specification does not say anything about how to position it over
the page, thus the result is vendor specific.

The solution proposed by the W3C and its contributors is called Web
Components, a new approach for designing HTML5 widgets, that will be
covered in the HTML5 Part-2 course.

Below are the different look'n'feels on different versions of different browsers.

In Google Chrome (screenshot from 2014):

June 2015 / Chrome / Mac OS X Yosemite:


In Opera:

In FireFox:
The <input type="date"> and its
variants (datetime, datetime-
local, time, month, week)
Introduction
For years, date and time pickers in
HTML forms made Web developers
rely heavily on JavaScript based
widgets. The process is simpler in
HTML5, which provides a special
control to handle this specific kind of
data natively. All mobile browsers
support<input type="time"> and <input type="date">, while support on
desktop computers is not yet as good.
Below are a few screenshots of the HTML5 date picker on several mobile
devices. Note that the native date pickers of the operating systems are used:

The problem is different on a desktop. While it's great to have native support
for a date picker, Web developers would sometimes prefer 100% control over
the look and feel of the date picker widget. For this purpose, the
solution undoubtedly lies with the new Web Components (a way to make
custom reusable widgets in HTML/CSS/JS), that will be detailed in the HTML5
Part-2 course.

In this course, we will focus on native implementations. Desktop support is


currently not 100% (see the "current support" section below), so it is better to
try the following examples with Opera or Chrome.
Why don't you try it yourself? Just click on this input field:

With Google Chrome desktop, it shows this date picker widget:

On non-supported browsers, it defaults to an <input type="text"> input field.

Typical use of <input type="date">


Default use
The default usage is something like:
1. <label for="birthday">Choose birthday party date: </label>
2. <input type="date" id="birthday">

Result:

Most of the time you will add other attributes to give some restrictions (choose
a date in the past, in the future, only on a Saturday, etc.).

Restrict choice to an interval of dates:


attributes min, max and value
The <input type="date"> comes with several useful attributes. In particular
the value, min and maxattributes are used to propose a default date, a min and
a max date, or for defining an interval of acceptable values.

Try this example: just click the next input field: , or try it online on JS Bin if you
want to tweak the source code:
Errata: the online example is correct, but the above screenshot shows a year
equal to "2014" for the maxattribute, which is incorrect.

Source code:

1. ...
2. <input type="date"
3. id="birthdayParty"
4. value="2015-06-20"
5. min="2015-06-20"
6. max="2015-06-30">
7. ...

Choosing one day in a given week, etc. with the step:


attribute
Using the value attribute for setting a date, and using step=7 for example, will
make acceptable only the day of the week that corresponds to the value's day
(e.g.: only Mondays). Using step=2 will make acceptable only every other day,
etc.

Example: we want to celebrate birthday parties only on Saturdays, check this


on JS Bin!
Errata: the online example is correct, but the above screenshot shows a year
equal to "2014" for the max attribute, which is incorrect.

Extract from source code:

1. <input type="date"
2. id="birthdayParty"
3. value="2015-06-20"
4. min="2015-06-20"
5. max="2015-06-30"
6. step="7">

Combining with the <datalist> element to restrict the


choice of possible values
This feature is not yet (in 2015) supported by all browsers, check this
compatibility table.

Online example at JS Bin


Extract from source code:
1. <input type="date"
2. id="birthdayParty"
3. list="birthdayPartyPossibleDates"
4. value="2015-06-20">
5. <datalist id="birthdayPartyPossibleDates">
6. <option label="Best for me">2015-06-20</option>
7. <option label="Ok for me too ">2015-06-27</option>
8. <option label="This one is a sunday, hmmm">2015-06-28</option>
9. </datalist>

The list attribute of the input element must match the id attribute of
the datalist element.

If you use the min, max, or step attributes with a list attribute, it may
filter the restricted list even more. Check this example on JS Bin (tested
with Google Chrome), that has a restricted list of three elements, one of
which is filtered because it is not in in the min/max range.
responding to date changes, trying date/time and
other variants
Listening to the input event
Here is an interactive example at JS Bin where you can change the type of
date/time chooser. It also shows how to listen to the input event when a
date/time is chosen.

Source code:

1. <!DOCTYPE html>
2. <html>
3. <body>
4. Testing the new date input field. So far works only in Chrome and Opera
browsers.<p>
5. Choose a date/time : <input type="date" id="date" /></p>
6. <p>
7. You picked: <span id="pickedDate"></span>
8. </p>
9. After you have tried the first example, change the value of the "type" attribute
to:
10. <ul>
11. <li>datetime</li>
12. <li>datetime-local</li>
13. <li>time</li>
14. <li>week</li>
15. <li>month</li>
16. </ul>
17. And see the result.
18. <script>
[Link] field = [Link]("#date");
20. var result = [Link]("#pickedDate");
[Link] = function(evt) {
22. var date = [Link];
23. [Link] = "<b>"+date+"</b>";
24. }
25. </script>
26. </body>
27. </html>

Lines 20-26 show how we can detect a date change using JavaScript.

Checking if the chosen date is in the past or in the future


using the valueAsDate property
The object returned to the input event handler has a useful property
named valueAsDate. This is a JavaScript date object that can be compared to
other JavaScript date objects, in particular to the date of the day we can get
with var date = new Date();

The following example at JS Bin shows how to ascertain whether a date is in the
past or in the future:

While if we enter a date in the future:


Extract from source code:

1. <body>
2. <label for="birthDate">Enter your birth date: </label><p>
3. <input type="date" id="birthDate" >
4. <p>
5. You picked: <span id="pickedDate"></span><p>
6. <span id="pastFuture"></span>
7. </p>
8. <script>
9. var field = [Link]("#birthDate");
10. var result = [Link]("#pickedDate");
11. var pastFuture = [Link]("#pastFuture");
[Link] = function(evt) {
13. var date = [Link];
14. [Link] = "<b>"+date+"</b>";
15. if([Link] <= new Date()) {
16. [Link] = 'green';
17. [Link] = "<b>Date in the past, ok!</b>"
18. } else {
19. [Link] = 'red';
20. [Link] = "<b>Date in the future, you're not even
born!</b>"
21. }
22. }
23. </script>
24. </body>
Lines 17-23 show how we can compare the date picked in the calendar widget
with the current date. Note that we can compare any given dates using
JavaScript. To check that the chosen date is before 2000 we would do this:

1. if([Link] <= new Date(2000,1,1)) {


2. ...
3. }

HTML 5.1: <input type="datetime">, "week",


"month", "datetime-local", etc.
The HTML5 specification indicates that we can use <input
type="date"> and <input type="time"> while for some years (before the
specification became a frozen standard in October 2014), other variants were
also present, such as type=datetime, datetime-local, month and week.

These variants have been moved to the HTML 5.1 specification (still a work in
progress) because so far they have only been implemented by Chrome and
Opera.

Here is an interactive example at JS Bin where you can change the type of date
chooser and try all the different possible values for the type attribute of date
pickers.

Some screenshots from Opera desktops and Safari IOS:

<input type="time">:
<input type="datetime">
<input type="datetime-local">

<input type="week">:
<input type="month">:
Current support
These new input types are not yet supported by all browsers in their
desktop versions (while mobile support is 100% for major browsers).

Managing dates in different languages/formats is a difficult task that browser


developers have had to address. Furthermore, Web designers do not like the
fact that you cannot really control the look and feel of this element (the same
criticism as for the <input type="color"> element, see previous section).
These are undoubtedly the reasons why browser implementers did not make
the implementation of these widgets high priority.

However, for simple date picking (especially on mobiles), these elements are
very practical as is, and many polyfills are available, bringing compatibility to
browsers that do not yet support it.

There is also a growing set of Web Components for picking date/time. For
example, see [Link] and enter the "date" keyword in the
search field.
So far, as at early 2015, Safari, Internet Explorer and FireFox desktop browsers
still do not support this input type, as shown in the table below:

See the up-to-date version of the above table and check for the mobile support.

Polyfills / alternative solutions


Many polyfills are available. Remember that including a polyfill means that if
the target browser supports the native implementation, the polyfill will be
ignored and the native implementation will be used instead. Polyfills use
alternative JavaScript based widgets only as a fallback.
Here is a running example on JS Bin, that works with all browsers (including IE
and FireFox), easy to reproduce, that uses Webshim and jQuery:
Other popular polyfills are:

[Link] a solution that


uses Yepnope, Modernizer and the JQuery UI,
Web Experience Toolkit date polyfill, open sourced by the Canadian
government,
Jon Stipe’s polyfill,
Others are available, just use your favorite search engine :-)
<input type="email">, <input type="tel">, <input type="URL">

and <input type="search">

<input type="email">

This input type is relatively straightforward to use. In mobile applications,

this new input type pops up a keyboard layout adapted to email input. Note

the "@" key, the "." key, etc.


This input type is very interesting as it provides default validation

behaviors:

 If the value entered looks like an email address (contains a "@"...), the field

is valid, and gets the pseudo CSS class :valid

 If the value entered does not contain an "@", and does not look like

an email address, the field isinvalid and gets the pseudo CSS

class :invalid

See the next example to see this in action. More details will be presented

in a later section dedicated to form validation.

Typical use

Online example at JS Bin

Try it on your browser:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="utf-8">
5. <title>Example of input type=email</title>
6. <style>
7. input:invalid {
8. background-color:pink;
9. }
10. </style>
11. </head>
12. <body>
13. <label for="email">Enter your email </label>
14.<input type="email" id="email">
15. </body>
16. </html>

Note the CSS rule that turns the background color of the email input field

to pink if a user enters an invalid address (lines 7-8). Also note that the

validation is based only on matching a regular expression (the address

should contain a "@", a ".", etc.). It does not check if the address is an

existing one.

Current support: all browsers, on mobile or desktop versions, since 2012.

<input type="tel">

This input field is really useful on smartphones and tablets, as it makes the

browser pop up a keyboard layout suitable for entering phone numbers:


This input type is often used with the

new placeholder and pattern attributes that are detailed in

another section of this course. It is supported by all recent major Web

browsers, on mobile devices and desktops.

Online example at JS Bin

Try it in your browser (we used the same CSS for changing the background-

color when the input value is invalid):

Source code:

1. <!DOCTYPE html>
2. <html>
3. <body>
4. <head>
5. <title>Example of input type=tel</title>
6. <style>
7. input:invalid {
8. background-color:pink;
9. }
10. </style>
11. </head>
12. <body>
13. <label for="tel">Enter a telephone number:</label>
14.<input type="tel" id="tel"
15. placeholder="(555) 555-5555"
16. pattern="^(?\d{3})?[-\s]\d{3}[-\s]\d{4}.*?\)"/>
17. </body>
18. </html>

<input type="URL">

This input field is really useful on smartphones and tablets, as it makes the

browser pop up a keyboard layout suitable for entering URLs:


This field is also compatible with the validation API (more on this in

another section).

Here is an online example that shows the use of

the placeholder and pattern attributes for entering only URLs that start

with ftp:// or http:// . Check it at JS Bin!

Or try it here in your browser:

Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>Example of input type=url</title>
5. <style>
6. input:invalid {
7. background-color: lightPink;
8. }
9. </style>
10. </head>
11. <body>
12. <label for="url1">Enter a URL (default validation):</label>
13.<input type="url1" id="url"/>
14. <p>
15. <label for="url2">Enter a URL (custom validation, must start with http,
https or ftp):</label>
16. <input id="url2" type="url" placeholder="[Link]
17. pattern="(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.\/]*"/><p>
18. </body>
19. </html>

Lines 16-17 show the use of a pattern attribute with a JavaScript regexp

that accepts only URLs starting with http, https or ftp. More details on

the pattern attribute are given in the section that presents the new

HTML5 form attributes.

<input type="search">

The search type is used for search fields (i.e., for a search engine). A search

field behaves like a regular text field, except that it may provide some

feedback GUI for stopping the current request and emptying the search

field, or it may provide a drop-down list of recent search results.

The specification does not state what the GUI should look like, so current

implementations show variations in the look and feel.


Mobile (left blackberry, right Safari IOS):

Typical use:

1. <label for="search1">Simple search: </label>


2. <input type=search id="search1">
3. <p>
4. <label for="search2">Search with
attribute <code>results=5</code> (try with Safari): </label>
5. <input type=search id="search2" results=5>

Results on Chrome and Opera desktop - notice the small cross on the right

when one enters a value:


Same example with Safari desktop, this time the second line with an

attribute results=5 shows a small icon on the left:

Example that shows a drop down list of recent searches (Safari

screenshot borrowed from this excellent site about HTML5 forms that is

worth reading):
Source code for the Knowledge check below

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="utf-8">
5. <title>Example of input type=email</title>
6. <style>
7. input:? {
8. background-color:pink;
9. }
10. input:?? {
11. background-color:lightGreen;
12. }
13. </style>
14. </head>
15. <body>
16. <label for="email">Enter your email:</label>
17. <input type="email" id="email">
18. </body>
19. </html>

<input type="number">

This input field is useful for

entering numerical values

(integer or float), but not for

entering zip codes. On desktop


implementations and on some mobile implementations, it provides a user

interface with small vertical arrows for incrementing/decrementing the

current value, while on mobiles it will display a numeric keyboard.

For zip codes, a <input type="text" pattern="......"> is preferable.

See examples given in the pattern attribute section of this course.

Example: <input type="number" value="25" min="0" step="

5" max="500"/>

Screenshot examples taken with mobile devices (left: IOS, right: Android)
Examples on desktop (the width will be adjusted depending on

the min and max attributes):

Typical usage

<input type="number" value="25" min="0" step="5" max="50

0"/>

This field accepts specific attributes max, min, step, value (default

displayed value).

This input type is very interesting as it provides default validation

behaviors:

 If the value entered using a keyboard is not a valid number, or is not in the

range defined by the min andmax attributes, the field is invalid and gets

the pseudo CSS class :invalid.


 If the difference between the value you enter and min is a multiple of step,

then it gets the CSS pseudo class :valid, otherwise it will

be invalid. Example: if min=1 and step=5, the field will be valid

with value=1, 6, 11, 16 etc. if min=0, with value=0, 5, 10, 15 etc.

WARNING 1: Using a step attribute with an integer value will

make the arrows increment/decrement the current value with

the step value, and make the input field valid only when the

difference between the value you enter and min is a multiple

of step.

WARNING 2: by default, omitting the step attribute is

equivalent to step="1", so for entering float values, it is

necessary to use step="any" or step equal to a floating point

value such as step="0.1".

With step="any", floating point values are valid, but vertical


arrows will increment/decrement the value by one.

If step="0.1", arrows will increment/decrement by0.1, etc.

Online example at JS Bin: (try changing the attribute values,

use step="any" and try float values, etc).

Or, do it here in your browser (Manually enter a value that is not in the

range, or not a multiple of 5, try the up and down arrows, etc.):

Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <style>
5. #number:invalid {
6. background-color:pink;
7. }
8. #number:valid {
9. background-color:lightGreen;
10. }
11. </style>
12. </head>
13. <body>
14. Example of <code><input type=number></code>:<p>
15. <label for="number">Quantity (between 0 and 500, should be a
multiple of 5 otherwise it's invalid): </label>
16.<input type="number" id="number" value="25" min="0" step="5"
max="500"/>
17. <p>
18. Change the different values for attributes step, max, min, value. Don't
forget to try step="any" for float values...
19. </body>
20. </html>

Source code for the knowledge check

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Example type=number</title>
6. <style>
7. #myField:valid {
8. background-color:lightGreen;
9. }
10. #myField:invalid {
11. background-color:pink;
12. }
13. </style>
14. </head>
15. <body>
16. <label for="myField">Please enter a number between 0 and
30: </label>
17.
<input type="number" id="myField" min="0" step="5" max="30"/>
18. </body>
19. </html>

<input type="range">

This input type renders as a slider. It accepts the same attributes as the <input
type="number"/> : min, max, step and value.

Example of rendering on a desktop:

And on mobile devices: (left IOS, right Android)


Typical use
The basic use is to specify at least the value, min and max attributes, and
eventually the step attribute, too - like this:
1. <input id="slider6" type="range" min="0" max="10" step="2" value
="5">

But most of the time, you will need a visual feedback that shows the current
value selected by the slider.

This online example at JS Bin shows how to add a visual feedback using a very
short JavaScript function and an <output> element. The result is shown in the
first screenshot of this page, and can be tried here live in your browser, just
click and drag the small cursor of the slider (or use up and down arrow keys
when the field has the focus):

Source code:
1. <!DOCTYPE html>
2. <html>
3. <head>
4. <style>
5. #rangeValue1 {
6. border:1px solid black;
7. padding:2px;
8. }
9. </style>
10. <script>
11. [Link] = function() {
12. // Called when the page is loaded, for displaying initial value in the
output
13. printValue('slider1','rangeValue1');
14. }
15. function printValue(sliderId, outputId) {
16. var x = [Link](outputId);
17. var y = [Link](sliderId);
18. [Link] = [Link];
19. }
20. </script>
21. </head>
22. <body>
23. <form >
24. <label for="slider1">Select a value:</label>
25. <input id="slider1" type="range"
26. min="100" max="500" step="10" value="150"
27. oninput="printValue('slider1','rangeValue1')"/>
28. <output id="rangeValue1"></output>
29. </form>
30. <br/>
31. Play with attributes: value, min, max, step...
32. </body>
33. </html>
34.
Snapping behavior and
the step attribute
When you click and drag the slider,
it "jumps" to some snap points corresponding to the integer values of the range
defined by the min and max attributes, and the "size of the jumps" depends on
the value of the step attribute.

Try these examples and look at their behavior (complete online version is also
available at JS Bin):

value=5 min=0, max=10 step=1:

value=12 min=10, max=50 step=4:

Note that in the previous example, the default value displayed is 14, not 12
(the value just above minplus an integer step value). 12 is not possible so it's
been "snapped" to 14.
value=5 min=0, max=10 step="0.5":
In the previous example, it's necessary to add quotes for
setting step="0.5" (while HTML5 authorizes not using quotes for setting
integer values to attributes).
value=5 min=0, max=10 step="any":

WARNING: Using a step attribute with an integer value will make


the slider jump corresponding to the step value. By default,
omitting the step attribute is equivalent tostep="1", so for
accepting float values, it is necessary to use step="any", or step
equal to a floating point value, such as step="0.5".

Adding "ticks" to the range slider using


a <datalist> element

Using the <datalist> element, it's possible to display "ticks" above the range
slider, at given positions.
This feature is not yet (in 2015) supported by all browsers, check this
compatibility table.

1. <label for="slider2">value=5 min=0, max=10 step=1, ticks at 2, 4, 6,


8 and 10:</label>
2. <input id="slider2" type="range"
3. list="ticks2"
4. min="0" max="10" step="1" value="5"/>
5. <datalist id=ticks2>
6. <option>0</option>
7. <option>2</option>
8. <option>4</option>
9. <option>6</option>
10. <option>8</option>
11. <option>10</option>
12. </datalist>

Here is a complete online example at JS Bin that shows multiple


possibilities. You can try this using the sliders below:

value=5 min=0, max=10 step=1, ticks at 2, 4, 6, 8 and 10:

value=20 min=10, max=50 step=5, ticks at 0, 10, 20, 30, 40 and 50:

value=5 min=0, max=10 step="0.5", ticks at 0, 0.5, 1, 2, 4, 8:

value=5 min=0, max=10 step="any", ticks at 0, 5 and 10:

External resource
A script with the code from the above resource, that automatically generates
ticks, depending on the min, max and step attributes, codepen demonstration
here: see the Pen Auto-Generated HTML5 range input Ticks by Dudley Storey
(@dudleystorey) on CodePen.

Styling the sliders


You can use CSS for "standard" styling (size, color, background color, etc), and
special pseudo classes that depend on browser vendors for styling the cursor.
Here are some examples of what can be done:
Example at JS Bin

Or try it here:

value=0.5 min=0, max=1 step="0.1":

HTML:

1. <p>
2. <label for="sliderVolume">value=0.5 min=0, max=11 step="0.1":
3. </label><p>
4. <input id="sliderVolume" type="range" min="0" max="11" step="0.
1" value="0.5"
5. oninput="printValue('sliderVolume','volumeValue')" class="custom"/>
6. <output id="volumeValue"/>
7. </p>

CSS:

1. .custom { // horizontal rectangle of the slider


2. width: 60%;
3. height:15px;
4. border-radius: 8px;
5. box-shadow: inset 0 0 5px #333;
6. background-image:linear-gradient(to right, lightGreen, blue 100%, orange);
7. transition: background 450ms;
8. }
9.
10. /* Change the Slider Button Color Webkit (Opera, Chrome, Safari) */
11..custom::-webkit-slider-thumb {
12. -webkit-appearance: none !important;
13. background-color: #AAA;
14. background-image:
15. linear-gradient(to bottom, #EEE, #AAA);
16. border: 2px solid #999;
17. height:30px;
18. width:30px;
19. border-radius: 15px;
20. }
21. /* Change the Slider Button Color FireFox */
22..custom::-moz-range-thumb {
23. background-color: #AAA;
24. background-image:
25. linear-gradient(to bottom, #EEE, #AAA);
26. border: 1px solid #999;
27. height:30px;
28. width:30px;
29. border-radius: 15px;
30. }

JavaScript (just for changing the linear gradient of the CSS background color,
the CSS transition (line 7 of the above code) makes the color change
animated/smooth:

1. function setVolume(sliderID, textbox) {


2. var x = [Link](textbox);
3. var y = [Link](sliderID);
4. [Link] = [Link];
5. volumeListener(sliderID);
6. }
7.
8. function volumeListener(id) {
9. var slider=[Link](id);
10. var val = ([Link] - [Link]) / ([Link] - [Link]);

11. val *= 100; // val is between 0 and 1, values of the min and max
attributes
12. // We scale this to appropriate values for a gradient
13. var cssProp = 'linear-gradient(to right , lightGreen, blue '+val +'%,
red)';
14. [Link] = cssProp;
15. }

External resources with very impressive slider


stylings
A must see: Ana Tudor's custom range sliders
Some of her CodePens:
HTML4 and HTML5 input attributes
In this chapter, we will look at the new form attributes that have been
introduced by HTML5.
HTML4 HTML5

 form
 readonly
 autocomplete
 name
 autofocus
 disabled*
 list
 type
 pattern
 maxlength
 required*
 readonly
 placeholder
 size
 multiple
 value
 list
 alt
 min
 src
 max
 height
 step
 width
 formaction
 checked*
 formenctype
 align **
 formmethod
 formtarget
 formnovalidate

* pseudoclasses CSS target with :disabled and :checked or :required selectors


** align is deprecated, CSS rules should be used instead

We have already
seen the use of
pseudo CSS classes
used together with
the input field and
form validation
(pattern attribute,
input:invalid CSS
rule). We also
briefly looked at the
use of the placeholderattributes for displaying a helper message in the input
field.

In this section, we will cover the rest of the new attributes and provide further
examples of using the previously discussed attributes.

Another part of the course, about form validation and visual feedback using
CSS, will examine some of the most useful attributes in even greater detail.

The form attribute


This attribute is useful for putting input fields
outside the form itself. The form attribute of an
external input field must share the
same value as the id of the form the field
belongs to. This is useful when
using <fieldset> elements for making the
page/form layout easier.

Typical use
Try this interactive example in JS Bin, or try it directly in your browser:

Source code:
1. <!DOCTYPE html>
2. <html>
3. <body>
4. <label for="yourName">Enter your name:</label>
5. <input type="text" id="yourName" name="yourName" form="form1"/>
6. <p>
7. <form id="form1" action="[Link]" method="post">
8. <fieldset>
9. <legend>Choose option</legend>
10. <label for="free">Free registering</label>
11. <input type="checkbox" id="free"/>
12. <label for="premium">Premium</label>
13. <input type="checkbox" id="premium"/>
14.
15. <button type="submit">Send form</button>
16. </fieldset>
17. </form>
18. </body>
19. </html>

Line 5 and 7 shows the form attribute. Make sure that its value matches
the id of the form!

The autocomplete attribute


This attribute applies either to
the <form> element or on
individual <input> elements. It specifies
when input fields must autocomplete the
user's input based on the user's typing history.

Possible values of this attribute: on/off.

If applied to the <form> element, all input fields attached


to the form (inside or linked to it using
the form attribute), will have auto-completion set by
default to the value of the autocomplete attribute of the
form.

This default behavior can be overridden by setting it


individually to any input field inside. In other words: it
is possible to have autocomplete "on" for the form, and "off" for specific input
fields, or vice-versa.
Sometimes this autocomplete behavior is disabled by default in some Web
browsers, and will need to be adjusted in the preferences/settings.

This attribute targets most input types (those that allow typing in them).

Typical use
Online example: [Link]

Try it in your browser here if you prefer:

autocomplete attributeautocomplete=off, this overrides the

form's autocomplete=onattribute):

autocomplete=on by inheritance of the

form's autocomplete=onattribute):
To see auto-completion in action: enter something in both fields and

submit the form. Then enter the same thing: you will see that only

the second input field offers auto-completion.

Source code extract:


1. <form submit="[Link]" method="post" autocomplete="on">
2. ...
3. <label for="address">Enter your address (autocomplete off, overrides the
4. form's autocomplete=on attribute):</label>
5. <input type="text" id="address" autocomplete="off">
6. <p>
7. <label for="address1">Enter your address (autocomplete on by
inheritance of
8. the form's autocomplete=on attribute):</label>
9. <input type="text" id="address1">
10. <p>
11. <button type="submit">Submit</button>
12. ...
13. </form>

The autofocus attribute

This attribute is useful for transferring the focus to a field other than the

first field in a page/form (by default the first input field has the focus).
Attention: there must not be more than one element in the document

with the autofocus attribute specified!

This online interactive example at JS Bin illustrates the use of

the autofocusattribute: the focus is put on the second input field of the

page. It also shows the use of

required, placeholder and pattern attributes.

The required attribute makes the input field invalid if kept empty.

Here is the result in your browser:

autofocus attribute

autofocus attribute):

Notice that the focus in on the second input field, thanks to

the autofocus attribute.

Extract from source code:

1. <form>
2. ...
3. <input type="text" id="test"/><p>
4. ...
5. <input id="name" name="inputName"
6. placeholder="6 to 9 chars please..."
7. pattern="\w{6,9}"
8. required
9. autofocus
10. type="text"/>
11. ...
12. </form>

Note about Boolean attributes syntax

Important: : For "Boolean" attributes, such

as autofocus, required, optional, etc., you are able to either

write autofocus="autofocus", or just use the attribute name

"autofocus" without setting a value.

Read these explanations for a complete description of the syntax of

Boolean attributes.

Source code for the knowledge check 5.5.4

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <title>Example for a knowledge check</title>
5. </head>
6. <body>
7. <form>
8. <label for="studentID">Student ID (disabled field, cannot type in
it): </label>
9. <input type="text" value="S134356" id="studentID" disabled/><p>
10. <label for="name">First name: </label>
11. <input type="text" id="firstName"
12. placeholder="John"
13. autofocus
14. />
15. <label for="lastName">Last name: </label>
16. <input type="text" id="lastName"
17. placeholder="Smith"
18. autofocus
19. />
20. </form>
21. </body>
22. </html>

The list attribute


This attribute works together with the
new <datalist>element we already
studied when we saw the color and
date input fields.

This attribute's value must match


the id of a <datalist>element. It is
useful for providing local auto-
completion to some input fields, or
for restricting the possible values
on some others like <input
type=date> or <input type=color>.

Here is a small code extract from a more complete example shown in the
section about the new <datalist> element (see next unit).
Online example at JS Bin

Please try it in your browser (Type "F", "E",


"O", C" etc., or just click inside the field and
use the drop down menu). Note that you can
also enter any value; if it does not start with
one of these letters it will be accepted but will
not trigger auto-completion.

Source code extract:


1. <form>
2. ...
3. <input list="browsers" id="mybrowser" />
4. <datalist id="browsers">
5. <option value="Internet Explorer">
6. <option value="Firefox">
7. <option value="Chrome">
8. <option value="Opera">
9. <option value="Safari">
10. </datalist>
11. ...
12. </form>

At lines 3 and 5, the value of the list attribute of the input field must match
the one of the id of the <datalist> element.
The pattern attribute
Cartoon from xkcd #1171: Perl Problems

The pattern attribute enables the validation of the user's input on the fly (also
at submission time), based on regular expressions. It applies to
the text, search, url, tel, email, and password input types.

The pattern attribute follows the syntax of JavaScript regular expressions.

MUST READ: a good catalog of ready-to-go patterns is available at


[Link], an excellent Web site that proposes plenty of
JavaScript patterns for the pattern attribute of HTML5 forms. The left
hand menu proposes categorized patterns for postal codes, phones, URLs
for popular sites, etc.

You can also try this online JavaScript RegExps tester, and follow this
tutorial about "using JavaScript RegExps" that has step by step exercices
and explanations.

Typical use
Just add a pattern attribute
with a value that is the
JavaScript regular expression
that must match the entire
string entered in the field.
Note that the empty string is
valid by default (except if the required attribute is used - this makes empty
fields invalid).

It's best practice to systematically add a titleattribute with a value


that indicates what constitutes a valid entry. More on this in the section
of this course dedicated to form validation.

1. <input type="text" name="country_code"


2. pattern="[A-Za-z]{3}"
3. title="3 letter country code"
4. />

Online example at JS Bin

Or try it directly in your browser here:

With the previous example, until the value of the input field is equal to 3
alphabetic characters, the field is invalid.

As seen in the previous examples, we used some CSS pseudo classes for
automatically setting the background-color of the input field as we type.

Complete source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="utf-8">
5. <title>Example of the pattern attribute</title>
6. <style>
7. input:invalid {
8. background-color: lightPink;
9. }
10. input:valid {
11. background-color: lightGreen;
12. }
13. </style>
14. </head>
15. <body>
16. <label for="code">Please enter a 3 letter country code:</label>
17. <input type="text" name="country_code"
18. pattern="[A-Za-z]{3}"
19. title="3 letter country code"
20. id="code"/>
21. </body>
22. </html>

Another example that mixes several other attributes


with the pattern attribute
Online at: [Link]

Try it in your browser:

Attributes used: placeholder (for displaying a ghost example

value), pattern, required (empty field = invalid)...

Complete source code:


1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>Example of use of new HTML5 input field attributes</title>
5. <style>
6. input:focus:invalid { background-color: lightPink;}
7. input:valid { background-color:lightGreen; }
8. input:required {border: 2px solid red; }
9. input:optional {border: 2px solid green; }
10. </style>
11. </head>
12. <body>
13. <p>Attributes used: placeholder (for displaying a ghost example value),
pattern, required (empty = invalid)...
14. <p>
15. <label for="inputID">Enter a pseudo (6-12 characters): </label>
16. <input id="inputID" name="Name"
17. placeholder="Name"
18. pattern="\w{6,12}"
19. required
20. title="6-12 characters allowed please"
21. type="text" />
22. </body>
23. </html>

Another example that uses an <input


type="url"> element with a patternattribute
allowing only certain protocols
Online example at JS Bin

Try it in your browser:

Source code extract:


1. <input
2. id="website"
3. name="url"
4. type="url"
5. placeholder="[Link]
6. title="http, https or ftp allowed"
7. pattern="(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.\/]*"
8. />
The min, max and step attributes
These attributes are useful for
several input types such
as number, range, date and time (a
nd other variants).

The min and max attributes are used


to set ranges to input fields that
accept numerical values or a
date/time.

Their detailed use with these input fields has already been explained
in the different sections of this course dedicated to these particular
input field types.

Typical use
1. <input id="mydate" name="mydate"
2. type="date"
3. min="2012-01-01"
4. max="2013-01-01"
5. value="2012-01-01"
6. />
7.
8. <input name="time" id="time" type="time"
9. min="09:00"
10. max="17:00"
11. value="12:00"
12. />
13.
14.<input id="range" name="range" type="range" min="0" max="100" ste
p="5"/>

The multiple attribute


The multiple attribute is used
with email and file input
types. It's a Boolean attribute,
so here are the different syntax
possibilities:

<input type="email|file"
multiple>
<input type="email|file" multiple="multiple">
<input type="email|file" multiple="">

With <input type="email">


With the <input type="email">, this attribute enables the user to enter a set
of addresses, separated by a comma instead of a single address. Entering
several addresses will keep the input field valid.

Online example at JS Bin

Or try it below in your browser: type in a list of email addresses separated by a


comma, then look at the input field background color (pink = invalid, green =
valid), and then submit:

This form uses: <input type="email" name="myemail" multiple>

iple attribute

This form does not use the multiple attribute:

Complete source code:


1. <!DOCTYPE html>
2. <html>
3. <style>
4. input:invalid {
5. background-color: lightPink;
6. }
7. input:valid {
8. background-color: lightGreen;
9. }
10. fieldset {
11. border:1px solid;
12. padding:20px;
13. }
14. </style>
15. <body>
16. <p>This form uses: <code><input type="email" name="myemail">
17. <b>multiple</b></code></p>
18. <form>
19. <fieldset>
20. <legend>With the multiple attribute </legend>
21. <label for="emailmultiple">Enter several email addresses: </label>
22. <input type="email" name="myemail" id="emailmultiple"
23. title="enter multiple emails addresses, separated by a comma"
24. multiple/>
25. <button>Submit</button>
26. </fieldset>
27. </form>
28. <p>
29. <p>This form does not use the multiple attribute:</p>
30. <form>
31. <fieldset>
32. <legend>Without the multiple attribute </legend>
33. <label for ="secondemail">Enter several email addresses: </label>
34. <input type="email" name="myemail" id="secondemail"
35. title="only one address please!"/>
36. <button>Submit</button>
37. </fieldset>
38. </form>
39. <p>
40. Type in a list of email addresses separated by a comma. Look at the
input field background color (pink = invalid, green = valid), and then
submit. <p/>
41. </body>
42. </html>

Best practice: add a title attribute indicating what you expect


as a valid entry (lines 25 and 38). If you enter bad values and submit,
you will see in the error message the string value of the title attribute.

With <input type="file">


With this type of input field, multiple files can be chosen (whereas before
HTML5, only a single file could be chosen).

Typical use: <input type=file multiple>

Try these in your browser, look at the small variations (text in the buttons,
messages):

Example with <input type=file multiple>

Example without the multiple attribute:

Use the standard key modifiers (shift, control, command) for selecting multiple
files when the file chooser dialog pops up.
Warning about the next attributes
presented
In the following pages, we present a set of rarely
used attributes introduced by HTML5. There will be
no questions about them in the exercises at the end
of the week.

You might just glance at them and/or try the


examples. The next pages cover their usage and
you are welcome to use them for future reference (for those of you who like to
cover the topics completely).

The formaction and formmethod attrib


utes
These attributes are targeted to the <input type="submit"> input fields. They
are rarely used, so there will be no questions about them in the quizzes at the
end of the week.
1. <input type="submit"
2. formaction="[Link]" formmethod="get" value="Preview">

When you use an <input type="submit"> field with


the formaction attribute, the action attribute value of
the form is overridden. The form will be submitted to the
URL / value of the formaction attribute of the <input
type="submit"> field.

The formmethod attribute does the same with the


POST/GET method attribute of the form. If an <input
type="submit"> has a formmethod attribute, it overrides
the value of the method attribute of the form.

Typical use
1. <form action="[Link]" method="post">
2. <input type="submit"
3. formaction="[Link]" formmethod="get"
4. value="Preview">
5. <input type="submit" value="Send">
6. </form>

Line 3 overrides the values set in line 1.

Examples
Here are two online examples at JS Bin:
Example 1
Example 2

The first shows a form with two submit buttons:

the first button submits to the default URL specified by the action attribute of
the form,
the second button submits to another action specified by
its formaction attribute.

The second example shows a form with two submit buttons:

the first button submits using a GET,


the second button using a POST:
The formnovalidate attribute
The formnovalidate attribute is targeted to
the <input type="submit"> input fields. This
attribute is rarely used, so there will be no
questions about it in the end of the week's
exercises.

This atrribute allows the submission of a form


even if it contains invalidfields. For example: a
form that has an <input type="email"> field
or a field required and which are not filled.

In general, such forms have two submit


buttons, one with the formnovalidate attribute set to a non null value and one
without.

Typical use (online example at JS Bin):

1. <form action="[Link]">
2. <fieldset>
3. <legend>Example of formnovalidate attribute</legend>
4. <label for="email">E-mail:</label>
5. <input type="email" name="email" id="email"/><br>
6. <input type="submit" value="Submit" /><br>
7. <input type="submit"
8. formnovalidate
9. value="Submit without validation" />
10. </fieldset>
11. </form>

Try this code it in your browser:


Enter a bad email address, then submit - you should see an error

message. Using the other submit button will submit the form anyway.

formnovalidate attribute

The formtarget attribute


The formtarget attribute is targeted to
the <input type="submit">input fields. This
attribute is rarely used, so there will be no
questions about it in the exercises - Week 5.

This attribute's value indicates where the


response from the form submission should be
displayed.

Typical use
1. <input type="submit"
2. formtarget="_blank"
3. value="Submit but show results in a new window/tab">

Possible values for the formtarget attributes are:


_blank: the response is displayed in a new window or tab
_self: the response is displayed in the same frame (this is default)
_parent: the response is displayed in the parent frame
_top: the response is displayed in the full body of the window
framename: the response is displayed in a named iframe
Complete example
Online example at JS Bin

Try it in your browser:

First name:

Last name:

Source code:
1. <form action="[Link]">
2. <label for="firstName">First name:</label>
3. <input type="text" name="firstName" id="firstName"><br>
4. <label for="lastName">Last name:</label>
5. <input type="text" name="lastName" id="lastName"><br>
6. <input type="submit" value="Submit as usual">
7. <input type="submit"
8. formtarget="_blank"
9. value="Submit but show results in a new window/tab">
10. </form>

The formenctype attribute


A word about the enctype

attribute of

the <form> element

The enctype attribute existed before HTML5. It is often used together

with forms that contain file input fields. For sending files to a remote server,

we use "multipart" forms. This special encoding of forms needs to be

specified using the enctype attribute, as shown in the example below:

Online example at JS Bin

1. <!DOCTYPE html>
2. <html lang="en">
3. <body>
4. <form action="[Link]" method="post" enctype="multipart/form-
data">
5. First name: <input type="text" name="fname"><br>
6. Last name: <input type="text" name="lname"><br>
7. <input type="submit" value="Submit">
8. </form>
9. </body>
10. </html>
Note that when you send form content using Ajax, this attribute is not

needed, as you will specify the type of data sent to the remote server in

JavaScript, using for example the new FormData object.

Used as an attribute of the <input type="submit"

enctype=...> element

Since HTML5, this attribute can also be used in <input

type="submit"> input fields.

If an <input type="submit"> field has this attribute, then, when

submitted using method=POST, the browser will send the form

content encoded with the method specified by the formenctype attribute.

And this overrides the value of the enctype attribute specified in

the <form enctype=...> element (or its default value, if not present).
Typical use

1. <form action="[Link]">
2. ...
3. <input type="submit" formenctype="multipart/form-data"
4. value="Submit as Multipart/form-data">
5. </form>

The possible values for this field are:

 application/x-www-form-urlencoded: all characters are

escaped/encoded before submission, for example, spaces become "+",

accentuated characters are transformed into hexadecimal, etc.

 multipart/form-data: encoding is not done. Usually we use this

value for submitting binary data such as images, files, etc.

 text/plain: some encoding is done on standard characters like

space (that becomes a "+"), nothing is done for special characters.


Example

Try this online example at JS Bin

Source code:

1. <!DOCTYPE html>
2. <html>
3. <body>
4. <form action="[Link]" method="post"
5. enctype="application/x-www-form-urlencoded">
6. <label for="firstName">First name:</label>
7. <input type="text" name="firstName" id="firstName"><br>
8. <label for="lastName">Last name:</label>
9. <input type="text" name="lastName" id="lastName"><br>
10. <input type="submit" value="Submit">
11. <input type="submit"
12. formenctype="multipart/form-data"
13. value="Submit as Multipart/form-data">
14. </form>
15.
16. <p><b>Note:</b> The formenctype attribute is not supported by all
browsers.</p>
17. </body>
18. </html>

Explanations and how to see the difference between the two

submissions

If you run this example in the JS Bin standalone mode (click the black arrow

on the top right of the output tab, in JS Bin), you should see this:
Then, open the devtools and go to the "Network" tab, click on the POST

request. Once done, click on the right on the "Header" tab to see the HTTP

headers, and scroll down, you should see the form-data entries in the

header, like in this screenshot:


And if you start again and click on the left submit button, the one without

the formenctype attribute, you should see that the form content has been

submitted "normally" (default value is "urlencoded", spaces are replaced by

"+", etc.). Here is a screenshot of what you should see:

New HTML5 tags/form elements


In this chapter, we will look at the new HTML5 elements related to forms.

HTML4 HTML5

 <form>  <datalist>
 <fieldset>

 <legend>

 <textarea>
 <output>
 <label>
 <meter>
 <select>
 <progress>
 <option>
 <keygen> *
 <optgroup>

 <input>

 <button>

* Not really useful for most


developers.

In the following sections, we will specifically look at the <datalist>,


<output>, <meter> and <progress>elements.

The <output> element


The output element represents the result of a
computation or user action. You can see it as a
"specialized <div> or <span>" for displaying
interactive results.

Typical use / interactive examples


Do not hesitate to play with the source code of these examples online at JS Bin.
Example 1
1. <form oninput="[Link]=[Link]*[Link]">
2. <input type="number" name="a" id="a" value="2"> x
3. <input type="number" name="b" id="b" value="3"> =
4. <output for="a b" name="o">6</output>
5. </form>

The oninput event handler directly uses the <output> element using the value
of its name attribute.

Result (do change the input field values):

x =

Explanation about the attributes specific to the <output> element:


for: a space-separated list containing the elements' ids whose values went
into the calculation.
name: the name of the element.
form: associates the <output> element with its form owner. The value must
be the id of a form in the same document. This allows you to place
an <output> element outside of the <form> with which it is associated.

Example 2

+=

Source code:

1. <form >
2. <input name="a" value="50" type="range"
3. oninput="[Link] = [Link] + [Link];
4. [Link] = [Link];"/>
5. <output id="y">50</output> +
6. <input name="b" value="50" type="number" /> =
7. <output name="x" id="x" for="a b"></output>
8. </form>

HTML5 has introduced new input field


properties: valueAsNumber and valueAsDate. The last example is similar to
the previous one except that we use an addition instead of a multiplication.
As input field values are considered as strings by JavaScript, using [Link] =
[Link] + [Link] would result in a string concatenation instead of an
addition. That's why we use the valueAsNumber property.

This is why we used the valueAsNumber property also introduced by HTML5 for
some input fields such as <input type="range"> and <input
type="number">, we also encountered the valueAsDate properties when we
studied <input type="date">.

The <meter> element


The <meter> element displays colored bars to
represent numeric values.

It can be useful to display a colored gauge to


show disk usage, to highlight the relevance of a query
result, or the fraction of a voting population
that favours a particular candidate, etc. This element
is often used with the <input type="range"> field as
an instant feedback indicator.

The <meter> element should not be used to indicate progress. You should
instead use a <progress> element.

This element is supported by all major browsers, on desktop and mobile


devices, except Internet Explorer (Microsoft Edge supports it) and IOS/Safari, as
in November 2015.
Typical use
1. Storage space
used: <meter value=75 min=0 low=20 high=80 max=100 optimum=
50></meter>

The <meter> element uses the easy-to-


understand value, min, max, low, high and optimum attributes. The optimum
attribute, along with min, low, high and max attributes will affect the color of
the bar, and of course the constraint min < low < high < max should be
respected.

More explanations about the colors and the meaning of the optimum attribute
will come further in this lesson.

Interactive example
Try the next example online at JS Bin or just play with it in your browser by
dragging the slider below:

<meter value=75 min=0 low=20 high=80 max=100

optimum=19></meter>

Grades:

Source code of the example:


1. <p>Grades: <meter id="meter2" value="75" min="0" low="20" high
="80" max="100"></meter>
2. <input min="0" max="100" value="75" id="meter2range"
3. oninput="effect('meter2', 'meter2range')" type="range">
4. <output id="meter2val" for="meter2range"></output></p>
5. <script>
6. function effect(meter, meterrange) {
7. var currVal = [Link](meterrange).value;
8. [Link](meter).value = currVal;
9. [Link](meter+ "val").innerHTML = currVal;
10. }
11. </script>

Explanations:

The color of the gauge changes depending on the


attribute's values
Note: thanks to jyorme, a student of this course, for helping improving this part
of the course!

The optimum attribute indicates the optimal numeric value and gives an
indication where along the range is considered preferable. Just think of
the <meter> ranges as follows:

Range 1: between min and low


Range 2: between low and high
Range 3: between high and max

... and depending on the value you set to optimum attribute, one of the ranges
above becomes the "good (optimum)" range.

So in the previous example, with the value of the optimum attribute set to 19, a
number between min and low(not inclusive), the Range 1
(between min=0 and low=20) becomes the "good (optimum)" range (displayed
in green), the Range 3 (between high=80 and max=100) becomes the "bad"
(displayed in red color) range, and the Range 2, in the middle, will be displayed
in yellow (not optimum, not bad).

So, a <meter> element used for displaying blood pressure might be a good
candidate for setting the optimumvalue to "Range 2", and a <meter> element
used for displaying memory usage might be a good candidate for setting
the optimum value to "Range 1", meaning that a low memory usage is "good".

External resources
A good article about <meter> is to be found on the css-trick Web site. It shows
how to use proprietary CSS pseudo classes to style the element.
How to use and style the meter element, good blog post.

The <progress> element


The <progress> element is similar to <meter> but it is used for progress bars
(i.e., the percentage of a file being uploaded, etc.):
1. <progress id=pr value=50 min=0 max=100>

Gives:

The browser calculates the percentage corresponding to


the value, min and maxattributes and adjusts the length of
the progress bar accordingly.

If no value attribute is set, the progress bar will display an


"indeterminate look", that may vary among different browser
implementations. Chrome, Opera, Safari and Firefox display indeterminate
progress as an animated stripe. In IE 11, it's styled as animated dots.

This element is supported by all major browsers, on desktop and mobile


devices.
Typical use
Here is an online example at JS Bin, or try it below in your browser:

This example uses some JavaScript to simulate a download progress

by changing in real time the value attribute.

The progress below is defined like this:

<progress id=pr value=100 min=0 max=1000>

Download progress:

Source code:

1. Download progress: <progress id=pr


value=100 min=0 max=1000></progress>
2. <script>
3. var i=0;
4. setInterval(function () {
5. i = (i+1) %1000;
6. [Link]('pr').value = i;
7. },1);
8. </script>

The <datalist> element


The <datalist> form element is useful for linking a list of choices to an input
element.
We have already seen this element in action with different <input> elements,
such as <input type="color">, <input type="date">, or <input
type="range">.

It is often "linked" to input fields either for restricting the value set that can be
proposed (i.e., restricted set of colors or possible dates, or for displaying slider
ticks, as shown above), but it may also be used in a more general way,
for providing client-side auto-completion without the need to use
JavaScript.

It works with the new list attribute of input fields introduced by


HTML5. The id of the <datalist> must match the value of
the list attribute in the input field. A datalist can be shared by
several input [Link] suffices that their list attribute matches the id of the
datalist element.
The input field is related to the datalist that will propose auto-completion based
on <datalist> values.

Typical use for auto-completion


Here is an online example at JS Bin, or try it here in your browser (type the
name of your favorite browser):

What is your favorite browser:

Source code of this example:


1. <form action="demo_form.asp" method="get">
2. <input list="browsers" name="browser" />
3. <datalist id="browsers">
4. <option value="Internet Explorer">
5. <option value="Firefox">
6. <option value="Chrome">
7. <option value="Opera">
8. <option value="Safari">
9. </datalist>
10. <input type="submit" />
11. </form>

As you can see at lines 2 and 4, the id and list attributes


match. The <datalist> element is wrapped around a set of <option> that are
available for selection by another form control (in this example the input
field from line 2).

Current support
All major browsers support this element except Safari (as of June 2015).
See [Link] for details and polyfills.
Validation, CSS pseudo class feedback,
and custom validation API
In this section of the course,
we will look at CSS pseudo
classes that are useful for
giving instant feedback
when the user's input is not
valid. We will also look at
the new JavaScript API introduced by HTML5 for validating forms and form
elements.

In the following pages, we will first illustrate the concept of form validation with
the <input type="email"/>field. It can be generalized to all kind of input
types, such as url, number, etc. Some form attributes, such as pattern, will
also affect input field validity!

As of June 2015, form validation is supported by the following browsers:


Polyfills for Safari and old Internet Explorer versions
Webshim is a polyfill library that enables you to reliably use HTML5 features
across browsers, even if native support is lacking.
There are other polyfills that do not target all missing features. These will be
introduced in the following sections, as some only target particular parts of the
specification.
CSS3 pseudo classes provide automatic
visual feedback while typing
Most modern browsers propose default
behavior for validating input fields and forms.

The built-in validation system that comes with


HTML5 automatically adds a CSS pseudo class
to all input fields. Invalid fields (i.e. a badly
worded email address in an <input
type="email"> input field), will inherit
the :invalid pseudo class, valid fields will
inherit the :valid pseudo class.

A first step to improve your HTML form is to add some CSS rules to your input
fields. This will add visual feedback to the validity of input fields values - while
the user is typing - such as changing the color of the border of input fields, or
green/red icons on the right of the field, as shown in the small picture at the
top right of this page.

Also, at the time of submitting the form, some extra messages may be
displayed as pop up text bubbles.

The default bubble message and visual


feedback differ from one
implementation to another, but they
may be customized, with some
limitations that will be explained later.

For example, Firefox 15+ provides default feedback on the input field's border
(red = invalid, green = ok). This default behavior can be overridden by CSS
rules as illustrated in the section about new input type attributes.

Example 1: styling "required", "valid" and" invalid"


fields using CSS3 pseudo-classes
Here is an online example at JS Bin, or try it below in your browser:
Source code extract:
1. <html>
2. <head>
3. <title>CSS3 pseudo-classes for form validation visual feedback</title>
4. <style>
5. input:invalid { background-color: lightPink;}
6. input:valid { background-color:lightGreen; }
7. input:required {border: 2px solid red;}
8. input:optional {border: 2px solid green;}
9. fieldset {
10. border:1px solid;
11. padding:20px;
12. }
13. .formLabel { display: inline-block; width: 140px; text-
align: right; }
14. </style>
15. </head>
16. <body>
17. <form>
18. <fieldset>
19. <legend>Type invalid values and see the result</legend>
20. <label for="myEmail" class="formLabel">E-mail:</label>
21. <input type="email" id="myEmail" required/><br>
22. <label for="myURL" class="formLabel">Homepage (URL):</label>
23. <input type="url" id="myURL" required/><br>
24. <label for="myPhone" class="formLabel">Phone number:</label>
25. <input type="tel" id="myPhone"
26. pattern="[0-9]{3}-?[0-9]{3}-?[0-9]{4}"
27. placeholder="e.g. 416-555-1234" required/>
28. <br>
29. <button>Submit form</button><br />
30. </fieldset>
31. </form>

Try the online example with different Web browsers, both with and without the
CSS rules. See the differences between FireFox/Chrome/Opera in the default
visual feedback behavior. Don't worry: all default behavior can be overridden if
you provide your own CSS rules.

Best practice: except for FireFox, no other browser provides


default CSS styling for
valid/invalid/optional input fields. We recommend that you
ALWAYS provide default CSS rules that give visual feedback to
the user's input.

Safari and old browsers will still need a polyfill as of June 2015 (see the
different polyfills at the end of this page).

a Neat trick: add CSS transitions + an icon/marker to


the right of the input fields
Try this online example at JS Bin or try it here in your browser. This example
adds a small icon that changes depending on the validity of the input field:

Source code extract:


1. .myForm input:focus {
2. padding-right:70px;
3. }
4. .myForm input {
5. transition: padding .25s;
6. }
7. .myForm input:required:valid {
8. background:url('[Link] no-repeat right top;
9. }
10..myForm input:required {
11. background:url('[Link] no-repeat right top;
12. }

This time we just added an attribute class="myForm" to our form, in order to


avoid interfering with the other examples on this page, and we tweaked the
CSS rules a little.

The rule at line 1 says that any time we click on an input field, it will enlarge
itself to the right, while the rule at line 4 will make it animated.

The rules at lines 8 and 11 target the input fields with a required attribute.
They will change the background by displaying a small green or red icon,
corresponding to the valid/invalid status of the input field.

USE THE TITLE ATTRIBUTE FOR SPECIFYING A


CUSTOM MESSAGE
You can simply use the input's title attribute to provide a message for
pattern-mismatches, and more generally for all validation errors. This solution
is really neat and doesn't require JavaScript!

Try the online example at JS Bin, or try it here in your browser (type invalid
values and look at the custom messages):
Extract from source code:
1. <form class="myForm">
2. <fieldset>
3. <legend>Type invalid values and see the result</legend>
4. <label for="myEmail" class="formLabel">E-mail:</label>
5. <input type="email" id="myEmail"
6. title="You don't know what an email address looks like, do you?"
7. required/><br>
8. ...
9. <button>Submit form</button><br />
10. </fieldset>
11. </form>

Beware: browser implementations differ. Chrome, IE, Opera (as of June 2015)
will display the title attribute value in error message bubbles when the form
is submitted, while Safari and FireFox (desktop and mobile) will simply ignore
it.

You must also take care of the different languages, otherwise you will get error
message bubbles that show some parts in the local language, and the message
from the title attribute "as is".

Google Chrome on a French computer:

Same example on FireFox, the title attribute is ignored:


The built-in validation system is an improvement on what existed
before HTML5 (i.e., nothing), but additional work is required if
you want fully localized, hand-made validation feedback.

We will show solutions in the last section of this week's course.

How to style the validation messages displayed in


the bubbles?
Try the examples from this page on different browsers. You may notice
differences (from left to right: Chrome, FireFox and IE):

How can we change the style of these bubbles (for example, to unify the look
and feel between different browsers)? Unfortunately we can’t.

Chrome used to provide a series of vendor prefixed pseudo-elements (::-


webkit-validation-bubble-*), but they were removed with Chrome 28 and later
versions. However, there are possibilities that involve the use of the HTML5
form JavaScript API. At the end of this section, we propose solutions that
work well.
external resources (not mandatory reading)
For those really interested in HTML5 forms, we recommend following
the tutorial below, which shows how to give a super look'n'feel to an HTML
form, as well as visual feedback using HTML5 new attributes, CSS pseudo
elements and form validation API. This tutorial also gives some nice JavaScript
tricks and explains HTML4/CSS2 classic enhancements:
Bring Your Forms Up to Date With CSS3 and HTML5 Validation, tutorial from
the [Link] Web site.

However, beware! While this tutorial shows some very good tricks about the
look'n'feel, it also unfortunately shows a very common mistake:

The "for" attribute of a <label> has to match the "id" attribute of the related
input, not the "name" attribute!

Apart from this, it has good content.

Polyfill for browsers that do not fully support the new


attributes required, pattern, etc. (this includes the
current Safari version)
We recommend using the [Link] library together with some external
polyfills. These articles are worth reading for those of you who need retro-
compatibility:
Cross Browser Styling of HTML5 Forms — Even In Older Browsers
Creating Cross Browser HTML5 Forms Now, Using modernizr, webforms2 and
html5Forms
There is also a small JavaScript based polyfill that offers compatibility with
Safari, just for the missing attributes. Note that a new version is on the way
(read the message at the end of the GitHub page of the project).

The HTML5 JavaScript form validation


API
There is a JavaScript API for form
validation. This API will let you
use your own validation
algorithm (i.e. check that you
have entered the same
password in two different input
fields), and customize error
messages. Also, together with
some HTML/CSS/JavaScript you
will be able to make your own message bubbles.

Typical use
Example of password checking at JS Bin, be careful to try this example in JS
Bin standalone mode (click the small black arrow on the top right of the output
tab).

Or you may try it here in your browser:

Extract from source code:


1. <html>
2. <head>
3. <title>Example of using the validation API</title>
4. <style>
5. .myForm input:invalid { background-color: lightPink;}
6. .myForm input:valid { background-color:lightGreen; }
7. .myForm input:required {border: 2px solid red;}
8. .myForm input:optional {border: 2px solid green;}
9. .myForm label { display: inline-block; width: 140px; text-align: right; }
10. </style>
11. </head>
12. <body>
13. <form class="myForm">
14. <fieldset>
15. <legend>Example use of the validation API</legend>
16. <label for="password1" >Password:</label>
17.
<input type="password" id="password1" oninput="checkPasswords();"r
equired>
18. <p>
19. <label for="password2">Repeat password:</label>
20.
<input type="password" id="password2" oninput="checkPasswords();"r
equired>
21. <p>
22. <button>Submit</button>
23. </fieldset>
24. </form>
25.
26. <script>
27. function checkPasswords() {
28. var password1 = [Link]('password1');
29. var password2 = [Link]('password2');
30. if ([Link] != [Link]) {
31. [Link]('Passwords do not match!');
32. } else {
33. [Link]('');
34. }
35. }
36. </script>
37. </body>
38. </html>

Explanations: the validity API proposes a setCustomValidity() method


available on input DOM objects. This method allows you to customize error
messages. It takes a string parameter. When this string is empty, the element
is considered valid, when the string is not empty, the field is invalid and the
validation error message displayed in the bubble will be equal to that string.

At lines 17 and 20 we added an input event listener: each time a key is typed,
the checkPasswords()function is called.
Lines 28 and 29 get the input fields' values, and lines 31-35 check if the
passwords are the same and set the validity of the field using the validation
API's method setCustomValidity(error_message).

The validity property of input fields


The validity property of input fields helps to get error details when the field
is invalid. This property tests the different types of validation error.

Here is how to get the validity property of an input field:

1. var input = [Link]('IdOfField');


2. var validityState_object = [Link];

The possible values for the validity property are:

valueMissing
typeMismatch
patternMismatch
tooLong
rangeUnderflow
rangeOverflow
stepMismatch
valid
customError

Here is an example at JS Bin that shows how to test the different types of
validation errors, or you may try it here in your browser (enter bad values, too
big, too small, enter invalid characters, etc.):

Note that testing it in Chrome/Opera/Firefox does not produce the same


results. So far Opera has the most advanced implementations, however,
entering "21" for example in the <input type="number" max="20"/>input
field may yield some unexpected results depending on the browser. Test it
yourself.

Source code:
1. <!DOCTYPE html>
2. <html>
3. ...
4. <body>
5. <script>
6. function validate() {
7. var input = [Link]('b');
8. var validityState_object = [Link];
9.
10. if(validityState_object.valueMissing) {
11. [Link]('Please set an age (required)');
12. } else if (validityState_object.rangeUnderflow) {
13. [Link]('Your value is too low');
14. } else if (validityState_object.rangeOverflow) {
15. [Link]('Your value is too high');
16. } else if (validityState_object.typeMismatch) {
17. [Link]('Type mismatch');
18. } else if (validityState_object.tooLong) {
19. [Link]('Too long');
20. } else if (validityState_object.stepMismatch) {
21. [Link]('stepMismatch');
22. } else if (validityState_object.patternMismatch) {
23. [Link]('patternMismatch');
24. } else {
25. [Link]('');
26. }
27. }
28. </script>
29. <form class="myForm">
30. <label for="b">Enter a value between 10 and 20: </label>
31.
32. <input type="number" name="text" id="b" min="10" max="20"
33. required oninput='validate();'/>
34. <button>Submit</button>
35. </form>
36. </body>
37. </html>
The validationMessage property
It is also possible to get the validation error message, using
the validationMessage property of input fields.
1. var input = [Link]('b');
2.
3. [Link]("Validation message = " + [Link]);

This will be useful for making custom error messages. More about this topic in
the next section of the course.

Custom validation: changing the


default behavior, aggregating error
messages, removing bubbles, etc.

Criticism of the default behavior of HTML5 built-in


validation
The techniques we have seen so far for enhancing HTML forms are powerful
and provide interesting features, but are also criticized by Web developers:
Browser support is still not 100% complete (Safari and Internet Explorer still
lack several important features),
It is not possible to aggregate error messages. On submission, browsers show
an error bubble next to the first invalid field, and there is no built-in way
to display all error messages for all invalid fields at the same time,
You cannot style the bubbles.
However, the validation API gives enough power to make your own
validation behavior, overriding the default when necessary.

Here is an adaptation of work presented at the [Link] Web site.


This link is really worth reading, as it presents different approaches and gives
external references for those who would like to go further.

Example that shows aggregation of error messages


+ overriding default behavior
Try the online example at JS Bin, or try it here in your browser: enter invalid
values and submit with one or two invalid fields.

Complete source code:


1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset="utf-8">
5. <title>Aggregating error messages</title>
6. <style>
7. input:invalid { background-color: lightPink;}
8. input:valid { background-color:lightGreen; }
9. input:required {border: 2px solid red;}
10. input:optional {border: 2px solid green;}
11.
12. .error-messages {
13. display: none;
14. margin: 0 10px 15px 10px;
15. padding: 8px 35px 8px 30px;
16. color: #B94A48;
17. background-color: #F2DEDE;
18. border: 2px solid #EED3D7;
19. border-radius: 4px;
20. }
21. fieldset {
22. border:1px solid;
23. padding:20px;
24. }
25. </style>
26. </head>
27. <body>
28. <form>
29. <fieldset>
30. <legend>Submit with one or two invalid fields</legend>
31. <ul class="error-messages"></ul>
32. <label for="name">Name:</label>
33. <input id="name" name="name" required>
34. <p>
35. <label for="email">Email:</label>
36. <input id="email" name="email" type="email" required>
37. <p>
38. <button>Submit</button>
39. </fieldset>
40. </form>
41.
42. <script>
43. function replaceValidationUI(form) {
44. // Suppress the default bubbles
45. [Link]("invalid", function (event) {
46. [Link]();
47. }, true);
48.
49. // Support Safari, iOS Safari, and the Android browser — each of
which

50. // do not prevent form submissions by default


51. [Link]("submit", function (event) {
52. if (![Link]()) {
53. [Link]();
54. }
55. });
56.
57. // Container that holds error messages. By default it has a CSS
58. // display:none property
59. var errorMessages = [Link](".error-messages");
60.
61. var submitButton = [Link]("button:not([type=button]),
62. input[type=submit]");
63.
64. [Link]("click", function (event) {
65. var invalidFields = [Link]("input:invalid");
66. var listHtml = "";
67. var errorMessagesContainer = [Link](".error-
messages");
68. var label;
69.
70. // Get the labels' values of their name attributes + the validation
error
71. // message of the corresponding input field using the
validationMessage
72. // property of input fields
73. // We build a list of <li>...</li> that we add to the error message
container
74. for (var i = 0; i < [Link]; i++) {
75.
label = [Link]("label[for=" + invalidFields[ i ].id + "]");
76. listHtml += "<li>" +
77. [Link] +
78. "" +
79. invalidFields[ i ].validationMessage +
80. "</li>";
81. }
82.
83. // Update the list with the new error messages
84. [Link] = listHtml;
85.
86. // If there are errors, give focus to the first invalid field and show
87. // the error messages container by setting its CSS property
display=block
88. if ([Link] > 0) {
89. invalidFields[ 0 ].focus();
90. [Link] = "block";
91. }
92. });
93. }
94.
95. // Replace the validation UI for all forms
96. var forms = [Link]("form");
97. for (var i = 0; i < [Link]; i++) {
98. replaceValidationUI(forms[ i ]);
99. }
100. </script>
101. </body>
102. </html>

Explanations:

Line 32: we added an empty unnumbered list (<ul>..</ul>) to the form, with
the CSS class="error-messages". We will use this class attribute for styling,
and hiding by default, the error messages using CSS (see lines 12-20, line 13
hides the messages by default).
Lines 97-102 look at all forms in the document and call a function that will
replace the default validation behavior for all of them:
the replaceValidationUI(form) function.
This function first disables all default behavior (no more display of
bubbles during form submission), this is done at lines 45-57.
Line 66: we add a click listener to the submit button of the current form.
Line 67 gets all invalid input fields for that form,
Lines 76-83: For each invalid field, we get the value of the name attribute of
the corresponding label, we also get the validation error message, and we build
a list item(<li>...</li>).
Line 86: Then we add this list element (a formatted error message
corresponding to an invalid input field) to the error message container.
Lines 90-93: The focus is given to the first invalid field that shows an error
message.
Week 6

HTML5 JavaScript APIs


We have already studied some of the HTML5 JavaScript APIs, including:
The canvas API,
The form validation API,
The audio and video elements API, the getUserMedia API (also related to audio
and video elements),

However, HTML5 also comes with several APIs that are not
directly related to HTML elements, namely: the Orientation API;
the Geolocation API; most APIs related to client-side persistence;
the Web Storage API; the Web Workers API; and some other APIs
that are not in the HTML5 specification, but are related to it,
such as the GamePad API, the Web Audio API, etc.

This week, we will look at some of the most useful APIs. Others will be covered
in the HTML5 Part-2 course:

The HTML5 Cache API for making Web sites and Web applications
work offline.
The "Web Storage" API, sort of "super cookies", for storing pairs of
key/values client side. This API is useful for enabling Web sites to
save/restore their state, or for writing serverless applications. You will see a
small contact manager that stores its data locally, without the need for a
remote Web server.
The File API, that enables Web applications to work with local files.
For example, a picture editor, or media player that can work with your music
and video files - the ones on your phone or your hard disk! With this API you
will also be able to preview image files directly in your page - there is no need
to send them to a remote server.
The Geolocation API for obtaining
data such as longitude, latitude,
altitude (when available),
and speed. You will learn how to write
applications in combination with
interactive maps. You will also learn how
to guess the address of a user, for
example for pre-filling a registration
form with the city, country, and zip code that corresponds with the current
location.
Happy learning!

HTML5 cache / offline applications


Introduction
Even back in the 90's, long before
HTML5 existed, all
browsers implemented a native
way of caching files. However, the
implementations and heuristics
differed from one browser to
another, and there was no easy
way to control (at the application
layer) which parts will be cached.

The HTML5 specification introduces


a new way to handle caching. As stated in the "offline Web
applications" section of the document: "In order to enable users to continue
interacting with Web applications and documents even when their network
connection is unavailable — for instance, because they are traveling outside of
their ISP's coverage area — authors can provide a manifest which lists the files
that are needed for the Web application to work offline and which causes the
user's browser to keep a copy of the files for use offline."

By "offline applications", this means:

[Link] a Web site can be browsed while no internet connection is


available. But it also says that:
[Link] Web page may be an "application", not just a static page.

Meaning, it may be a video game that usually retrieves data from a Web
server, saves high scores, etc. It may be a mail application (like Gmail) that
shows the most recent emails, checks for new ones, and has features for
composing and sending new emails, etc.

In these cases, having a controllable "cache API" helps implement things like:

When offline, you can read and compose emails, but you cannot receive or
send new emails.
A more complex behavior would be that, when offline, you can write emails
that will be stored locally on the client side and sent only when connectivity is
available.
Or, in a static Web site, everything can be retrieved from the cache, so that a
user is able to read the Web site offline, but the login page will not be
available... instead, a disclaimer page will be displayed, etc.

The HTML5 cache tries to address aspects of these needs, and is pretty useful
for mobile Web applications, where connections are not always
available/reliable.

Note: Native mobile applications developers often push the following


argument that "a Web app cannot run offline". This is a false statement!

Using the HTML5 cache is both useful for mobile applications, as these device
can often be offline, and for traditional Web developers who do not specifically
target mobile devices. Any Web site (even comprised 100% of static
pages/images/videos/etc.) can benefit from being intelligently cached, as the
HTML5 cache can dramatically decrease the load time for any given site,
especially if the same browser/person visits the Web site regularly, as
illustrated by these pictures below (borrowed from a MSDN blog post about
offline applications that is worth reading):

Current support
Current support is very good, as stated by the [Link] Web site. All major
browsers - desktop or mobile - have supported the HTML5 cache since 2012.
External resources (optional, if you wish to learn
more about this topic)
Tutorials
The W3C specification about Offline Web Applications / cache
Article from [Link] about the cache API
Appcache facts: good resume of the cache
API + best practices

Tools
Cache manifest validator tool
ManifestR bookmarklet, a tool for
automatically generating a cache manifest file

The HTML5 cache manifest file


HTML5 introduced a "manifest file" as an attribute to the <html>element. This
file will tell the browser what to cache, what not to cache, and some other
goodies we will see in this section.

Below is an example of the inclusion of a manifest file (it is best


practice/recommendation to use the .appcache suffix):

1. <html manifest="[Link]">
2. ...
3. </html>

You must include the manifest attribute on every page for which you
want to cache resources (images included in the page, JavaScript files, CSS
files). The manifest file will contain lines that will dictate which image/js/css
needs to be cached, which must never be cached, etc.

The page with the manifest is de facto included in the list of files that
will be cached. This means that any page the user navigates to that
includes a manifest will be implicitly added to the application cache.

The browser does not cache a page if it does not contain the manifest
attribute. The default cache behavior, prior to HTML5, will be used (depending
on the browser versions). If you want a Web site or a Web app to work
offline, then please include a manifest in every HTML page!
The manifest attribute value is a relative path (relative to the page URL), but
an absolute URL can be used (not recommended) if it respects the same origin
policy.

The manifest file must be served with the correct


MIME Type
The HTTP server that serves your files must be configured so
that .appcache files are served with the MIME type text/cache-manifest. For
example, with the Apache server, this line must be added in the [Link]
configuration file (or in the .htaccess files):
1. AddType text/cache-manifest .appcache

What do we put in the manifest file?


First example: cache an HTML page that displays the current time (clock). It
uses three pages: HTML, CSS and JavaScript. This example is taken from the
W3C specification, you can try the online example here.

The manifest file is:

1. CACHE MANIFEST
2. [Link]
3. [Link]
4. [Link]

Lines 2-4 show that a given HTML page, in which this manifest is included, asks
the browser to cache three files: the HTML page itself ([Link], cached by
default, but the specification recommends adding it to the manifest as best
practice), a CSS file [Link] and a JavaScript file [Link].

Note that the first line "CACHE MANIFEST" is mandatory.

Pitfalls to avoid when using the HTML5 cache


PITFALL #1 : When a file is available in the cache and on the remote
HTTP server, it will always be retrieved from the cache! An upcoming
section is dedicated to "updating the cache", and we will explain how to control
this and update the files in the cache.
PITFALL #2: If one file cannot be retrieved and cached, zero files will
be updated in the cache. There is no such thing as "partial update". A best
practice is to always validate your manifest file using one of the tools listed at
the end of this chapter.

The first time you run this in Chrome, you may see the cache content with the
dev. tools (F12):

With the same example, Firefox asks if you agree to cache some data (the
sentence is in French here but it says: "This Web site would like to save data on
your computer for offline use. Authorize? Never? Just for this time?"):
Let's have a look at another example of [Link] (this one comes
from the [Link] Web site), that does a little more:

1. CACHE MANIFEST
2. CACHE:
3. #images
4. /images/[Link]
5. /images/[Link]
6. #pages
7. /pages/[Link]
8. /pages/[Link]
9. #CSS
10. /style/[Link]
11. #scripts
12. /js/[Link]
13. FALLBACK:
14. / /[Link]
15. NETWORK:
16. [Link]

This time, notice a few additional things:

It's possible to add comments starting with #


There are three different sections in capital letters: CACHE, FALLBACK and
NETWORK
These three sections are optional - we did not have them in the first example.
But as soon as you indicate one of them, you must indicate the others. (CACHE
was defaulted in the first example as we had no explicit section declarations).

The CACHE section specifies the URLs of the resources that must be
cached (generally relative to the page, but they can also be absolute and
external, for example for caching jQuery from a Google repository, etc.). These
resources will be 1) cached when online, and 2) available from the cache when
offline.

The NETWORK section is the contrary of the CACHE section: it is useful


for specifying resources that should NOT be cached. These resources 1)
will not be cached when online, and consequently 2) will not be available when
the user is offline. EVEN IF THE BROWSER HAS CACHED THEM IN ITS OWN "PRE
HTML5" cache! In the previous example, at line 23, the [Link] file (the one
with the login/password form...) is never cached. Indeed, entering
login/password and pressing a "login/connect/signup" button is useless if you
are offline.

Using a wildcard * in this section is also common practice; this means "do not
cache all files that are not in the CACHE or FALLBACK section":

1. NETWORK:
2. *

Partial URLs may also be used in this section, such as "/images", which means,
all URLs that end with images/*... should not be cached. Notice that wildcards
and partial URLs are not allowed in the CACHE section, where all individual
files must be explicitly specified.

The FALLBACK section specifies resources that will be displayed when


the user requests a resource that is not available when offline. For
example, a [Link] file must not be cached, nor be available when offline.
In this case, accessing [Link] will cause [Link] to be
displayed (and this file will be cached, this is forced by being in the FALLBACK
section). The "/ /[Link]" in the FALLBACK section of the example says
that for any resource that is not available in the cache (here, "/" means "any
resource"), show the [Link] page.

Partial URLs can be used too. For example:

1. /images/ /images/[Link]
... tells us that all images in the sub-directory "images" relative to the Web
page that includes the manifest, if unavailable in the cache when the browser
is offline, will be replaced by an image named "[Link]".

What to cache?
Do you need to cache resources included by your
CSS/JavaScript files, etc.?
If your CSS files use @import or include some external pictures, you need to
explicitly add them one by one to the manifest file. The same applies to your
JavaScript files: if they include other files, and you want them to be added to
the cache, you must add them one by one to the manifest file. This can be
tricky, so fortunately there are several tools to help you generate a manifest
file. More on these in the next unit of this course section.

What about cross domain/external domain files? Can


we cache them too?
Normally yes, you can. Imagine a Web site that uses jQuery or any other
common JS/CSS addons: you will need to have all the required files in the
cache, otherwise the site will not run properly offline.

So, all external resources referenced through http:// URLs will be


cached without restrictions.

However, the specification, , says that for Web sites accessible only
through https:// secure connections, the same origin policy should apply.
Only resources from the same domain, when referenced by [Link] should
be cached.

In fact, some browsers, such as Google Chrome, do not adhere to this part of
the specification and also cache resources referenced by [Link] It has been
argued that the single origin policy for https is too restrictive in the real world
for app caching to be of genuine value.
Useful tools for generating or validating
a manifest file

ManifestR: a manifest file


generator
manifestR is a bookmarklet, meaning that you are
able to drag it to your bookmarks bar. Then, when
you visit a page, you will click on the manifestR
button, and it will create an HTML5 appcache
manifest file for that page. See the live coding at
section 6.3.2 to see it in action!
[Link]: multi purpose command line tools
[Link] is a small script library that uses PhantomJS 1.2 (or later) to analyze
Web pages. Currently it can perform the following tasks:
Generation of an appcache manifest for a Web app
Simple performance analysis of a Web page and its resources
List of CSS properties used on the page
Cache validators
Manifesto is an HTML5 Offline Application Cache verification bookmarklet. Go to
their Web site, drag an icon to the toolbar of your browser, and when you visit
an HTML page that has a manifest file, click the manifesto bookmarklet. This
will generate a report. The Web site proposes several links to try it out with
valid and invalid manifest files.
The [Link] Web site accepts URLs of manifest files, or
pasted content. It will validate the file. It also proposes a Chrome extension and
a TextMate addon.
Updating the cache
Do you Remember how the cache works?

When a resource is in the cache, it will ALWAYS be retrieved from the


cache, even if you are online, and even if a more recent version is
available on your Web server.

So how do we force the update of the cache?


Best practice: update the manifest file on your server!

Updating the manifest file server side will


update the files cached by browsers: the
easiest way to make the browser update
the cache is to update the manifest file
itself.

A best practice is to add a comment with the


last modification date of your Web site in the
manifest file. If you update any file on your
site, also update this comment. Your manifest last modified date will be
changed, and the browser will check all files in the CACHE section of the
manifest for modification, and update the cached version if necessary.

Clear the cache on the client side?


Clearing the cache using the browser dev. tools/options will also regenerate the
cache at the next connection. It's not common to manually clear the cache.
Usually Web developers do this when debugging.
Cache size limitations
Introduction
For traditional Web sites of normal size, there is no
problem. Just create a manifest file as we've shown
you (in the "make your Web site run offline" unit),
and your Web site should work offline!

On today's (2015) desktop browsers, the available


cache size is generally sufficient per domain, and
there is no need to worry.

If a user visits your Web site and if this Web site asks
to be cached, and if there is no more free space
available, the browser will find some (in general by
asking the user permission to increase the cache size
limit for the current domain - see screenshots-, or by
clearing least recently used data). On mobile devices, the cache size limits are
lower but reasonable.

With some atypical applications that need to cache large amounts of data
(images, videos), there may indeed be inadequate space in the cache. In this
case, the browser prints an error message in the console. It's also possible to
use a JavaScript API to detect this situation and show the user an error or a
warning message in the page "Sorry, this Web site will not be available offline
as we could not cache it due to size limitations...". This advanced part will not
be covered in this course.
Anyway, if you wish to find out more about size limits and what the various
HTML5 persistence mean, please read the rest of this page. As such, there will
be no exercises related to the optional content material below!

For traditional Web pages


There is a size limit, but it varies depending on many
parameters!
There are size limitations,
but they vary from one
browser to another. And
they also vary
depending on
whether your
browser is running
on a mobile
or desktop device.
Finally they may
vary depending on
the size of the hard
disk or the size of
the memory of the
device the browser
is running on!

For example, with Chrome there is no maximum size limit for cached data (it is
computed depending on the configuration and on the current amount of data
already persisted). But if you use the LocalStorage persistence for storing
data, (see next section of this course), then, for this special kind of data,
Chrome applies a 10Mbytes per domain limit. And this is completely different
on FireFox, on Safari, etc. The W3C specification recommends at least 5Mbytes
per domain with support for at least 20 domains.

We recommend reading this article from HTML5 rocks (January 2014). The
author wrote a Web application that tries to fill all available space and "guess
how the different persistent storage spaces" are managed by different
browsers. He tried with all major browsers on mobile devices and on desktop.

On the right: a screenshot of some of the resulting measures (extract from the
above article).
Also, for greater detail, see this paper about "Managing HTML5 offline storage".

A quota management
JavaScript API exists!
In order to make Web
applications aware of the free
space available for persisting
their data, a Quota Management
API is being developed. Note that this API specification is under active
discussion and is subject to change in the future. It's still experimental.

Try this example on JS Bin that shows the available disk space for all HTML5
persistence means (cache, localStorage, IndexedDB, etc.). Try it with Google
Chrome: as of June 2015, it is the only browser that implements the Quota API.

Source code extract:

1. function showFreeSpace() {
2. //the type can be either TEMPORARY or PERSISTENT
3. [Link]([Link],
4. onSuccess, onError);

5. }
6.
7. function onSuccess(usedSpace, remainingSpace) {
8. var displaySpace = [Link]("#space");
9. [Link] = "Used space = " + usedSpace + ", remaining
space = "
10. + remainingSpace;
11. }
12.
13. function onError(error) {
14. [Link]('Error', error);
15. }
Applications from stores or applications that run on a
Web-based operating system
A note about "non traditional Web applications"

Finally, the amount of


free storage space is
managed differently if
your Web application is
not a "traditional HTML
page" loaded in a
browser, i.e. using
a http:// or https:// U
RL. It may be a browser
extension, a browser
application (coming from
a store such as Chrome
store, Windows store,
FireFox OS store, etc), it may run on a Playstation 4 or on a Xbox One.

In these cases, HTML5 applications can get more privileges such as


reading/writing to your hard disk and benefit from a large disk space. Imagine
that they are similar to applications you install on your smartphone: you accept
that they use XXX megabytes, use your GPS without asking for permission, etc.
This course will not cover this type of application, but only focuses on
traditional Web pages and applications.
Checking that the browser is
online/offline
The new HTML5 persistence APIs are
very often used with the
[Link] property, part of
the DOM API. This feature is available
on all browsers.
The [Link] property
returns true or false depending on
whether or not the application has
network connectivity.

Beware that a browser may be


"online", but if your applications talk to a remote server, which does not
answer, or if your DNS server is down, being online does not mean that your
application fully works. Gmail, for example, detects when the remote service is
down and displays a message "trying to connect in 30s...".

Important: if the browser is offline, this means that your application


should work in "degraded, offline mode". If it's online, it should work,
but there is no guarantee that your remote server is up and running,
that the DNS server is operational, etc.

Check connectivity: online example on JS Bin

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset=utf-8>
5. <title>HTML5 Demo: Online connectivity monitoring</title>
6. </head>
7. <body>
8. <header>
9. <h1>Online connectivity monitoring</h1>
10. <style>
11. #status {
12. color: #FFFFFF;
13. padding: 5px;
14. }
15. .online {
16. background: green;
17. }
18. .offline {
19. background: red;
20. }
21. </style>
22. </header>
23. <article>
24. <p>Current network status (try to disconnect wifi or unplug
25. your ethernet cable):
26. <span id="status">checking...</span>
27. </p>
28. <ol id="state"></ol>
29. </article>
30. <script>
31. var statusElem = [Link]('status'),
32. var state = [Link]('state');
33. function online(event) {
34. [Link] = [Link] ? 'online' : 'offline';
35. [Link] = [Link] ? 'online' : 'offline';
36. [Link] += '<li>New event: ' + [Link] + '</li>';
37. }
38. [Link]('online', online);
39. [Link]('offline', online);
40. // call the online function so that it refreshes display when
41. // the page is first loaded
42. online({ type: 'ready' });
43. </script>
44. </html>
Usually, one checks if the application is running in online or offline mode (in the
latter case, data may be retrieved from the client side using one of the various
methods presented in this week's course). Instead of displaying messages
(lines 41-42 in the code source shown above), you should use an
implementation like this:

1. [Link]('online', function(e) {
2. // Re-sync data with server.
3. }, false);
4. [Link]('offline', function(e) {
5. // Queue up events for server, store them on the browser side
6. }, false);

Practical example 1: save form's content as


you type
Bookmark this page

Example 1: a form that never loses what you entered, even if you reload

the page, or press "backspace" by mistake

You can start filling this form and

come back another day and

complete it. It doesn't matter if

you closed your browser before coming back.


In this example, we use the most simple way to use localStorage:

 Save with the [Link] = value syntax. For

example, [Link] = 'Michel' will save the value

"Michel" with the access key being 'firstName'

 Restore with the var value = [Link] syntax. For

example, var fn = [Link]; will set fn with the value

'Michel' if this value has been previously saved as in the example from the

line above.

Saving the form content on the fly

Open this online example at JS Bin, and use F12 or cmd-alt-i (Mac OS) to

look at the dev. tools. As you type in the different input fields, their content

is updated in the localStorage.


We just added input event listeners to each input field. For example, in

order to save the first name input field's content, we just added:

1. oninput="[Link]=[Link];"

Where firstName in red is the key and [Link] the current value of

the input field.

In the same way, we added an input listener to all the input fields in this

example's form.
Restoring the form content on page load/reload

This time, we want the form content to be restored on page load/reload. We

will add a restoreFormContent() function in the JavaScript code that will

be called each time the page is loaded. In this function, we will read the

saved data and set the input fields' values.

Complete example on JS Bin: enter data and press reload at any time. The

form content is restored!

Source code extract (only addition to the previous example):

1. // Called when the page is loaded


2. [Link] = restoreFormContent;
3.
4. function restoreFormContent() {
5. [Link]("restoring form content from localStorage");
6. if([Link] !== undefined)
7. [Link]("firstName").value = [Link];
8. if([Link] !== undefined)
9. [Link]("lastName").value = [Link];
10. if([Link] !== undefined)
11. [Link]("email").value = [Link];
12.
13. if([Link] !== undefined)
14. [Link]("age").value = [Link];
15. if([Link] !== undefined)
16. [Link]("date").value = [Link];
17. }

The tests at lines 7, 10, 13, etc., verify that data has been saved, before

trying to restore it. Without these tests, it would put the "undefined" string

as the value of input fields with no corresponding data to restore.

More methods from


localStorage/sessionStorage
This time we will look at another example
that uses new methods from the API:
[Link](...),
[Link](...),
[Link](...),
[Link]().

Getting/setting values using


the getItem(key) and setIte
m(key, value)methods
If you want to keep a simple counter of the number of times a given user has
loaded your application, you can use the following code (just to show how to
use setItem/removeItem methods):
1. var counter = [Link]("count") || 0;
2. counter++;
3. [Link]("count", counter);

As you can easily guess from the above, we use var value = getItem(key) to
retrieve a key's value and setItem(key, value) to set it. This is similar to
what we saw in the examples of the page above, except that this time:

The key can contain spaces, for example we can


write: [Link]("Instructor's name", "Michel"); and var
name = [Link]("Instructor's name");, whilevar name =
[Link]'s name; will not work!
In a loop or in an iterator, sometimes we need to set/get localStorage values
using this syntax, for example:
1. var inputField = [Link]("firstName");
2. saveInputFieldValue(inputField);
3. ...
4. function saveInputFieldValue(field) {
5. [Link]([Link], [Link]);
6. }

Deleting a key with removeItem(key), or all keys


with clear()
Deleting a key can be performed through removeItem(). And if you wish to
reset the entire store, simply call [Link]().

Note that it will probably only be the rare occasion that you will want the entire
store to be cleared by the user in production software (since that effectively
deletes their entire data). However, it is a rather a common operation needed
during development, since bugs may store faulty data the persistence of which
can break your application, since the way you store data may evolve over time,
or simply because you also need to test the experience of the user when first
using the application.

One way of handling this is to add a user interface button that


calls clear() when clicked, but you must then remember to remove it when
you ship! The recommended approach to use (whenever possible) is to simply
open the dev. tool's console and type [Link]() there — it's safer
and works just as well.
Iterating local stores
Local stores (localStorage or sessionStorage) can also be iterated through in
order to list all the content that they contain. The order is not guaranteed, but
this may be useful at times (if only for debugging purposes!). The following
code lists everything in the current store:
1. for (var i = 0, n = [Link]; i < n; i++) {
2. var k = [Link](i);
3. [Link](k + ": " + localStorage[k]); // get the ith value, the one with a
key that is in the variable k.
4. }

Observant students will note that something seems a bit off in the example
above: instead of calling [Link](k), we simply
access localStorage[k]. Why? Because keys in the local store can also be
accessed as if the store were a simple JavaScript object. So instead
of [Link]("foo") and [Link]("foo",
"bar"), one can write [Link] and [Link] = "bar". Of
course there are limitations to this mapping: any string can serve as a key, so
that [Link]("one two three") works, whereas that string
would not be a valid identifier after the dot (but it could still work
as localStorage["one two three"]).

Example that
shows all the
methods of the
local storage API in
action
Online example at JS Bin, run
it, then click on the first
button to show all key/values
in the localStorage. Open
the URL in another tab, and
see that the data is shared between tabs, as local stores are attached to an
origin.

Then click on the second button to add data to the store, click on the third to
remove data. Finally, the last one clears the whole data store.
Source code:

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset=utf-8 />
5. <title>Example of localStorare API use</title>
6. <script>
7. // Using localStorage
8. var counter = [Link]("count") || 0;
9. counter++;
10. [Link]("count", counter);
11. function getCountValue() {
12. // retrieve data
13.
[Link]("#counter").innerHTML = [Link];
14. }
15. function seeAllKeyValuePairsStored() {
16. // clear list first
17. [Link]('#list').innerHTML="";
18. for (var i = 0, n = [Link]; i < n; i++) {
19. var key = [Link](i);
20. var value = localStorage[key];
21. [Link](key + ": " + value);
22. var li = [Link]('li');
23. [Link] = key + ": " + value;
24. [Link]('#list').insertBefore(li, null);
25. }
26. }
27. function resetStore() {
28. // erase all key values from store
29. [Link]();
30. // reset displayed list too
31. [Link]('#list').innerHTML="";
32. }
33. function addSomeData() {
34. // store data
35. [Link] = "Buffa";
36. [Link] = "Michel";
37. // refresh display
38. seeAllKeyValuePairsStored();
39. }
40. function removeSomeData() {
41. // store data
42. [Link]("lastName");
43. [Link]("firstName");
44. // refresh display
45. seeAllKeyValuePairsStored();
46. }
47. </script>
48. </head>
49. <body onload="getCountValue()">
50. <h1>Number of times this page has been seen on this
browser: <spanid="counter"></span></h1>
51. <button onclick="seeAllKeyValuePairsStored()">Show all key value
pairs stored in localStorage</button><br/>
52. <output id="list"></output>
53.
54. <button onclick="addSomeData()">Add some data to the
store</button><br/>
55. <button onclick="removeSomeData()">Remove some
data</button><br/>
56. <button onclick="resetStore()">reset store (erase all key/value
pairs)</button>
57. </body>
58. </html>

You can check in the Chrome dev. tools user interface that the content of
the localStorage changes as you click on the buttons.
Practical example 2: save/restore
user's preferences
Introduction
Local stores are also useful for saving/restoring user preferences of Web
Applications. For example, the JS Bin tool you have been using since the
beginning of this course uses localStorage to store the list of tabs you open,
and their width:

In this way, the next time you come back to JS Bin, "it will remember your last
settings".
Another example is a guitar FX processor / amp simulator your instructor is
writing with some of his students. It uses localStorage to save/restore presets
values:

Practical example: save/restore preferences of an


example you have already
seen
Original example on JS Bin: we can change
the color, size and speed of the animated
rectangle. However, each time we come back to the page, default values are
restored.

We would like to save the current values and find them back as they were
when we come back to the page.

Here is a modified example that saves/restores its state, you can try it at JS
Bin. In this modified version of the animated rectangle example, you can set
the color, size, speed, etc. And if you reload the page, the state of the different
input field is restored, but also the internal variables. Check the source code in
the JS Bin example and read the following explanations.

We used the same generic code for saving/restoring input fields' values we saw
in the first example that used localStorage. The only difference is that we
renamed the two generic functions so that they correspond better to their role
here (instead of saveFormContent we called the
function restorePreferences).

The function initPreferences is executed when the page is loaded.

Source code extract:

1. function initPreferences() {
2. [Link]("Adding input listener to all input fields");
3. // add an input listener to all input fields
4. var listOfInputsInForm = [Link]("input");
5. for(var i= 0; i < [Link]; i++) {
6. addInputListener(listOfInputsInForm[i]);
7. }
8. // restore preferences
9. restorePreferences();
10. applyGUIvalues(); // Use the input fields' values we just restored to set
internal
11. // size, incX, color, lineWidth variables
12. }
13.
14. function addInputListener(inputField) {
15. // same as before
16. }
17.
18. function restorePreferences() {
19. // same as old restoreFormContent
20. }
21.
22. function applyGUIvalues() {
23. // Check restored input field content to set the size of the rectangle
24. var sizeWidget = [Link]("size");
25. size = [Link](incX)*parseInt([Link]);
26. // also update the outline element's value
27. [Link]("sizeValue").innerHTML = size;
28. // Check restored input field content to set the color of the rectangle
29. var colorWidget = [Link]("color");
30. [Link] = [Link];
31. // Check restored input field content to set the speed of the rectangle
32. var speedWidget = [Link]("speed");
33. incX = [Link](incX)*parseInt([Link]);
34. // also update the outline element's value
35. [Link]("speedValue").innerHTML = [Link](incX);
36. // Check restored input field content to set the lineWidth of the
rectangle
37. var lineWidthWidget = [Link]("lineWidth");
38. [Link] = parseInt([Link]);
39. }

Practical example 3: example 1 on


steroids
Try the example!
Online example at JS Bin

This time, using


the setItem and getItem method we
saw earlier in the course, we could write
some generic functions for saving/restoring
input fields' content, without having
advance knowledge about the number of fields in the form, their types, their
ids, etc.

Furthermore, we removed all input listeners in the HTML, making it cleaner (no
more oninput="[Link] = [Link];'...)

Define listeners + restore old values after the page


is loaded, use generic functions
We start writing an init() function that is called when the page is loaded. This
function will:
[Link] input listeners for all input fields
[Link] the last saved value for each input field, if present.

Source code:

1. // Called when the page is loaded


2. [Link] = init;
3.
4. function init() {
5. [Link]("Adding input listener to all input fields");
6. // add an input listener to all input fields
7. var listOfInputsInForm = [Link]("input");
8. for(var i= 0; i < [Link]; i++) {
9. addInputListener(listOfInputsInForm[i]);
10. }
11. // restore form content with previously saved values
12. restoreFormContent();
13. }

And here is the addInputListener(inputField) function. It takes an input


field as parameter and attaches an oninput listener to it, that will save the
field's content each time a value is entered. The key will be the id of the input
field (line 3):

1. function addInputListener(inputField) {
2. [Link]('input', function(event) {
3. [Link]([Link], [Link]);
4. }, false);
5. }

Note that at line 2 we use addEventListener (that is not using


the oninput property here). addEventListener will not replace
existing oninput definitions and keep all existing listeners unchanged.

Restore all input fields' content using a generic


function
We have seen how to save all input fields' content on the fly. Now, let's see
how we can restore saved values and update the form. This is done using the
function restoreFormContent():
1. function restoreFormContent() {
2. [Link]("restoring form content from localStorage");
3. // get the list of all input elements in the form
4. var listOfInputsInForm = [Link]("input");
5. // For each input element,
6. // - get its id (that is also the key for it's saved content
7. // in the localStorage)
8. // - get the value associated with the id/key in the local
9. // storage
10. // - If the value is not undefined, restore the value
11. // of the input field
12. for(var i= 0; i < [Link]; i++) {
13. var fieldToRestore = listOfInputsInForm[i];
14. var id = [Link];
15. var savedValue = [Link](id);
16. if(savedValue !== undefined) {
17. [Link] = savedValue;
18. }
19. }
20. }

In this function, we first get the list of input fields (line 5), then iterate on it
(line 14). For each input field, we get its id, which value is the key
in localStorage for the previous data saved for this field (lines 15-16). Then if
the value is not undefined, we restore it by setting the value of the input field
(lines 19-20).
These generic functions can be used in many
different projects
Indeed, if you look carefully, you will see that these functions are really useful.
You may easily embed them in your own projects, or perhaps adapt them for a
particular need (i.e. for saving input type="checkboxes" that work a bit
differently), etc. Later in the course, we will show how to reuse them with
another example: the animated red rectangle.

Size limitation,
security, localStorage or sessionSto
rage?
We have already talked about client-side storage limits when we studied the
HTML5 cache. We saw that the limit varies depending on various parameters.
However, it's good to recall a few things from the specification:
User agents (browsers) should limit the total amount of space allowed for
storage areas.
User agents may prompt the user when quotas are reached, allowing the user
to grant more space to a site. This enables sites to store many user-created
documents on the user's computer, for instance.
User agents should allow users to see how much space each domain is using.
A mostly arbitrary limit of five megabytes per origin is recommended
(translation: give at least 5Mb per origin).

In many cases, local storage is all that your application will need for
saving/loading data on demand. More complex ways to do it exist, such as
IndexedDB, a No SQL database, that proposes transactions and usually
comes with far more available space than local storage. IndexedDB usage is for
advanced users and will be covered in the HTML5 part-2 course.

Additionally, there will be a limit on the amount of data that you can store
there. Browsers enforce quotas that will prevent you from cluttering your users'
drives excessively. These quotas can vary from platform to platform, but are
usually reasonably generous for simple cases (around 5MB), so if you are
careful not to store anything huge there, you should be fine.

Finally, keep in mind that this storage is not necessarily


permanent. Browsers are inconsistent in how they allow for it to be wiped, but
in several cases it gets deleted with cookies — which is logical when you think
of how it can be used for tracking in a similar fashion.

For serious applications, you might want to synchronize existing data with the
server on a regular basis, in order to avoid data loss (and in general, because
users enjoy using the same service from multiple devices at once). This is a
rather complex feat, and frameworks such as Firebase can help. Such
techniques are beyond the scope of this course and will not be covered.

sessionStorage key/values instead of cookies?


Note that if all you need is to store session-based data in a manner that is more
powerful than cookies, you can use the sessionStorage object which works in
exactly the same way as localStorage, but the lifetime is limited to a single
browser session (lifetime of your tab/window).

Also note that in addition to being more convenient and capable of


storing more data than cookies, it has the advantage of being scoped
to a given browser tab (or similar execution context).

Cookies' big danger: if a user has two tabs open to the same site, they will
share the same cookies. Which is to say that if you are storing information
about a given operation using cookies in one tab, that information will leak to
the other side — this can be confusing if the user is performing different tasks
in each.

By using sessionStorage, the data you store will be scoped and


therefore not leak across tabs!

toring more than strings? Use JSON!


Introduction
Storing strings is all well and good, but it quickly becomes limiting: you may
want to store more complex data with at least a modicum of structure.

There are some simple approaches, such as creating your own minimal record
format (e.g. a string with fields separated with a given character, using join()
on store and split() upon retrieval) or using multiple keys (e.g.post_17_title,
post_17_content, post_17_author, etc.). But these are really hacks. Thankfully,
there's a better way, [Link]() and [Link]() methods.

JSON provides a great way of encoding and decoding data that is a really good
match for JavaScript. You have to be careful not to use circular data structures
or non-serializable objects, but in the vast majority of cases, plugging JSON
support into your local store is straightforward.

Typical usage
1. [Link] = [Link](object); // or...
2. [Link](key, [Link](object));

Let's try a simple toy example (online at JS Bin). The example below saves a
JavaScript object in JSON, then restores it and checks that the object properties
are still there!
Source code:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <meta charset=utf-8 />
5. <title>Storing JSON Objects with Local Storage</title>
6. <script>
7. var personObject= {'firstName': 'Michel', 'lastName': 'Buffa'};
8. // Store the object as a JSON String
9. [Link]('testObject', [Link](personObject));
10. // Retrieve the object from storage
11.
var retrievedObject = [Link]([Link]('testObject'))
;
12. [Link]([Link] + "
" + [Link]);
13. // then you can use [Link],
[Link]...
14. </script>
15. </head>
16. <body>
17. </body>
18. </html>

Explanations:

Line 7: we built a JavaScript object that contains a person.


Line 10: we store it in localStorage as a JSON string object, with a key equal
to testObject.
Line 13: we restore it from localStorage as a string, and
the [Link] methods turns it back into a JavaScript object.
Line 15: we print the values of the object properties.

More complete example that shows how we can


save a form's content in JSON
Online example on JS Bin that saves in localStorage an array of contacts in
JSON
More complete example: a form and a table that
displays the contacts stored in localStorage
Example on JS Bin (uses summary/details, so use a browser that supports it or
add a polyfill, as seen in Week 1).

Add contacts using the form, see how the HTML table is updated. Try to reload
the page: data are persisted in localStorage.

Examine the localStorage:


The source code for this example is a bit long, and we suggest that you
examine it in the JS Bin tool. We extensively commented it. It uses:

Well structured page with the new elements seen during Week 1 (section,
article, nav, aside, etc.)
HTML5 form elements with builtin and custom validation (the date cannot be
in the past, the firstName and lastName fields do not accept &, #, ! or $
characters),
localStorage for saving / restoring an array of contacts in JSON
It shows how to use the DOM API for dynamically updating the page content
(build the HTML table from the array of contacts, add a new line when a new
contact is submitted, etc.)
The File API
Introduction
The objective of this chapter is to provide an overview of the File API.

Before HTML5, file


management was limited
to multipart forms and to
Ajax for
sending/requesting files
to/from a remote Web
server.

Possible actions were


limited, both for the
developer and the user. However, HTML5 now comes with an API called "File"
that holds features for accessing file metadata (name, size, type) from client-
side JavaScript. The API also has methods for reading file contents directly in
the browser. This is particularly interesting for displaying preview of images
before uploading them, or - and this is much more interesting - for developing
Web applications that work with local files without the need for a server.
Imagine a multimedia player that accesses (in read-only) your file system,
reads your audio and video files, etc., such as the Remo Audio player below
(Google Chrome extension written in HTML5), or an application that edits the
audio content of local mp3 files, for example, the HYA-WAVE sound
editor (screenshot above).
External resources
The W3C specification about the File API
Article on [Link] about the file API (and drag'n'drop)
Article from [Link] about the file API

ource code of the example shown in the video


Example on JS Bin

Source code:

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Example of using readAsDataURL</title>
6. </head>
7. <body>
8. <input type="file" multiple onchange="readImagesAndPreview([Link]
s);">
9. <p>
10. <div id="thumbnails"></div>
11. <script>
12. var container = [Link]("thumbnails");
13. function readImagesAndPreview(files) {
14. for(var i=0; i < [Link]; i++) {
15. var f = files[i];
16. var reader = new FileReader();
17. [Link] = function(e) {
18. var img = [Link]("img");
19. [Link] = [Link];
20. [Link] = 100;
21. [Link](img);
22. }
23. [Link](f);
24. }
25. }
26. </script>
27. </body>
28. </html>

Getting
details
about a
file:
reading
metadata
Imagine you have an input field like this:
1. Select one or more files: <input type="file" id="input"/>

This will render as a "select files" or "browse files" button. If you select one file
in the file chooser dialog that has popped up, before HTML5 you couldn't do
anything with it in the client-side: no access from JavaScript. With the File API,
you can read what we call "file metadata": name, size, type and last
modification date.

Look at the the code below: the file API defines a files property on the DOM
node corresponding to the <input type="file".../> input field. This property
is an array.

In the example below, we get in the selectedFile variable, the metadata


related to the first selected file:
1. var selectedFile = [Link]('input').files[0];
2. // do something with [Link], [Link], [Link]
3. // [Link]
4. ...

Example 1: read metadata of the first selected file


Here is a complete example on JS Bin that uses the code above to get details
about the first selected file. Please try it below on your browser (click on the
button and choose one file):

Select one or more files:

 File name:

 File size:

 File type:

 File last modification date:

Complete source code:


1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset=utf-8 />
5. <title>Reading file metadata</title>
6. <script>
7. function displayFirstSelectedFileMetadata() {
8. var selectedFile = [Link]('input').files[0];
9.
[Link]("#singleName").innerHTML = [Link];
10.
[Link]("#singleSize").innerHTML = [Link] +"
bytes";
11. [Link]("#singleType").innerHTML = [Link];
12.
[Link]("#singleDate").innerHTML = [Link]
fiedDate;
13. }
14. </script>
15. </head>
16. <body>
17. Select one or more files: <input type="file" id="input"
18. onchange="displayFirstSelectedFileMetadata();"/>
19. <p>
20. <ul>
21. <li>File name: <span id="singleName"></span></li>
22. <li>File size: <span id="singleSize"></span></li>
23. <li>File type: <span id="singleType"></span></li>
24. <li>File last modification date: <span id="singleDate"></span></li>
25. </ul>
26. </body>
27. </html>

Example 2: display metadata of multiple files, use a


filter on the file type
This example is a bit more complicated, as it will display details about all files
selected (not only the first) and allows only images to be selected, using
the accept attribute of the input field: <input type="file"
accept="image/*".../>.

Example on JS Bin, or try it in your browser: click on the button, and select
multiple image files. Notice that in the file selector, files that are not images
will be greyed and non selectable.

Select several images:

...

Source code extract:


1. Select several images: <input
type="file" accept="image/*" multipleonchange="filesProcess([Link]
s)" name="selection"/>
2. <p>
3. <div id="result">...</div>
4. <script>
5. function filesProcess(files) {
6. var selection = "<table><tr><th>Name</th><th>Bytes</th><th>MIME
Type</th>
7. <th>Last modified date</th></tr>";
8. for(i=0; i<[Link] ;i++){
9. file = files[i];
10. selection += "<tr><td>"+[Link]+"</td><td style=\"text-
align:right\">"
11. +[Link]+"</td><td>"
12. +[Link]+"</td><td> "+[Link]+"</td></tr>";
13. }
14. selection += "</table>";
15.
16. [Link]("result").innerHTML = selection;
17. }
18. </script>

Explanations:

Line1: we used the multiple attribute to allow the selection of multiple files in
the file chooser (using shift or control keys). The accept="image/*" attribute
is a filter that restricts selection to images only. Finally, the onchange listener
will call the filesProcess(...) function, passing as parameter the list of
selected files for the current element ([Link]).
Lines 7 and 12: we prepare the HTML code for building a <table> with the
results.
Line 10: this for loop builds all the rows that compose the table, adding HTML
code to the selectionstring variable. At the end of the loop, this variable
contains all the HTML code that corresponds to the table of results.
Line 18: the table is added to the page. We use the innerHTML attribute of the
DOM element corresponding to the <div id="result"> in order to insert the
table as its child in the DOM tree. As such, the table appears on the page
dynamically.
Blob and File: what are they?
The HTML5 File API specification introduces several
new Interfaces
The FileList interface (we already met it:
the files property is aFileList),
the File interface that is useful for getting
details about a file (thefile variable in
the for loop of the last example illustrates
this) .
the Blob interface helps read binary data
(only) that is accessed slice by slice (as
chunks of data, each one being a "Blob"),
and a FileReader interface for reading file
content (we will see how to use it in the next
section of the course),

We will not use all of these new interfaces,


but let's explain the difference
between Blob and File, as most of the
methods exposed by theFileReader interface
take indiscriminately a Blob or a File as parameter.

The Blob object


An object of type Blob is a structure that represents binary data
available as read-only. Most of the time, you will only encounter these
objects when you handle files.

Blob objects have two properties, namely:size and type, which respectively
retrieve the size in bytes of the data handled by the Blob and their MIME type.

There is also a method called slice(), but this is not used in common
applications. If you are curious, check the "slicing a file" section of this
"Reading files in JavaScript using the File APIs" article.
The File object
File objects are useful for
manipulating... files! They
inherit the properties and
methods of Blob objects, and
have two additional properties
that are name, for the file name,
and lastModifiedDate to get the
date of the last modification of
the file (in the form of a
JavaScript Date object,
obviously) .

Most of the time, we will work with File objects. Blobobjects will have real
interest when the Filesystem API is widely available (at the moment there is
only an experimental version in Chrome), or when you download binary files
using Ajax (see example below). This last API will be covered in the HTML5
part-2 course.

[Advanced] If you are interested in seeing how Blob objects can be used, here
is an example "as is" that shows how to download an image using Xhr2 (Xml
Http Request version 2). The examples uses a <progress>element to show the
download progress, and uses [Link] = 'blob'; to indicate that
the file we are going to download is a binary file (a blob). Try the example, then
comment the line with responseType='blob'. In this case, you will notice that
the image file is not properly decoded by the browser and is not displayed in
the page. Xhr2 will be covered in the HTML5 part-2 course.

Reading file content


Introduction / typical use
Step1: create a FileReader object
The file API proposes several methods for reading file content,
each taken from the FileReaderinterface. Here is how you create
a FileReader object:
1. var reader = new FileReader();
Steps 2 & 3: first call a method of the FileReader object for
reading the file content, then get the file content in
an onload callback
There are three different methods available for reading a file's
content: readAsText, readAsArrayBuffer for binary data and also
as readAsDataURL (the content will be a URL you will use to set the src field of
an <img src=...>, <audio>, <video>, and also with all existing
methods/properties that accept a URL).

All these methods take as a unique parameter a File object (for example, a file
chosen by a user after clicking on a <input type=file> input field). Below, we
use, as an example, the readAsText method:

1. function readFileContent(f) {
2. // Executed last: called only when the file content is loaded, [Link]
is
3. // The content
4. [Link] = function(e) {
5. var content = [Link];
6. // do something with the file content
7. [Link]("File " + [Link] + " content is: " + content);
8. };
9. // Executed first: start reading the file asynchronously, will call the
10. // [Link] callback only when the file is read entirely
11. [Link](f);
12. }

The above code shows how a file can be read as text. The function is called, for
example by clicking on the button corresponding to a <input type="file"
id="file" onchange="readFileContent([Link])"/>, and by choosing
a file.

Line 12 is executed first, and asks the Reader object to read the file f as text.
As this takes some time, it's an asynchronous operation that will be executed
by the browser in the background. When the file is read,
the [Link] callback function is called.
Line 4 is executed after line 12, and is called only when the file content is
available. This callback takes an event e as a unique parameter,
and [Link] is the file content.
Try a variation of the above code in your browser, that displays the file content
in a text area. This example is detailed further in the course. Click and select a
text file below:

In following next course sections, we will look at different examples that read
file contents as text, dataURL and binary.

Practical examples: reading file content


as text
example 1: read a single file's content
Example at JS Bin, or try it here in your browser

Choose a text file :

Complete source code:


1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Example of use of FileReader with a text file</title>
6. </head>
7. <body>
8. <label for="files">Choose a text
file:</label><input type="file" id="file"
9. onchange="readFileContent([Link])"/><br/>
10. <p>
11. <textarea rows=15 cols=50 id="fileContent"></textarea>
12. <script>
13. function readFileContent(files) {
14. [Link]("In readFileContent");
15. var reader = new FileReader();
16. // Executed last: called when the file content is loaded, [Link] is
17. // The content
18. [Link] = function(e) {
19. // display content in the textarea with id="fileContent"
20. [Link]("fileContent").value= [Link];
21. };
22. [Link]("Reading file:" + files[0].name);
23. // Executed first: start reading the file asynchronously , will call the onload
24. // callback when the file is read
25. [Link](files[0]);
26. }
27. </script>
28. </body>
29. </html>

This example is the one at the end of the previous page. This time, we show
the complete source code above. Remember that the instruction at line 29 is
executed first, then when the file is read, the browser will call asynchronously
the onload callback at line 20.

Example 2: a variation of the previous one, using


multiple files
Example on JS Bin, or try it below in your browser. This time, please select
multiple text files (using shift for multiple selection):

Source code:
1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <meta charset="utf-8">
5. <title>Example of use of FileReader with a text file</title>
6. </head>
7. <body>
8. <label for="files">Choose multiple text files:</label>
9. <input type="file" id="files"
10. multiple onchange="readFilesAndDisplayAsText([Link]);"/><br/>
11. <p>
12. <textarea rows=30 cols=50 id="filesContent"></textarea>
13. <script>
14. var filesContent = [Link]("filesContent");
15. function readFilesAndDisplayAsText(files) {
16. [Link]("dans read files");
17. // Loop through the FileList
18. for (var i = 0, f; f = files[i]; i++) {
19. var reader = new FileReader();
20. // Add an onload listener to the reader
21. addOnLoadListener(reader, [Link]);
22. // start reading, will call the listener later, when the file f is read
23. [Link](f);
24. }
25. }
26. function addOnLoadListener(reader, name) {
27. // Add an onload listener that will be able to print the name of the
28. // file...
29. [Link] = function(e) {
30. [Link] += "###### READING FILE " + name + "
######";
31. [Link] += [Link];
32. };
33. }
34. </script>
35. </body>
36. </html>

Explanations:

This example is similar to the previous one, except that this time we read
multiple files.

Line 20: this is the for loop that will iterate on the files object passed as
parameter by the onchangelistener declaration at line 10
Line 25: instead of declaring the onload listener with a [Link] =...
directly in the loop, this time we preferred to write a separate function that will
do this. This technique is useful when you want the listener to work with extra
variables computed in the loop (in our case, the name of the file).

About character encoding


Note that you can optionally indicate the encoding of the file you are going to
read (default is UTF-8):
1. [Link](file, 'UTF-8');
2. [Link](file, 'ISO-8859-1');
3. ...

Read file content as binary

Introduction

This method is rarely used, except for loading "raw" binary data. For

images you would like to see in your HTML page using the <img src=

tag> or for drawing in a canvas, or for audio and video files that you

would like to play using the <audio> or <video> elements, it would be

preferable to use the readAsDataURL method presented on the next page

of the course.
readAsArrayBuffer is often used for purposes such as reading audio

samples that should be loaded in memory and played using the WebAudio

API, or for loading textures that you will use with WebGL for 3D animations.

Example 1: read a local audio file and play it with the WebAudio API

The WebAudio API is useful for reading audio sound samples from memory

(no streaming), and has been designed for music application and games.

This example shows how a local audio file can be read and played directly

in the browser, without the need for a server!

Example on JS Bin (does not work on IE, as it does not support the

WebAudio API). We could not embed it here on the edX platform as it

prevents code that uses Ajax to run in its pages.


Source code extract:

1. // User selects file. Read it as an ArrayBuffer and pass to the API.


2. var fileInput = [Link]('input[type="file"]');
3. [Link]('change', function(e) {
4. var reader = new FileReader();
5. [Link] = function(e) {
6. initSound([Link]);
7. };
8. // THIS IS THE INTERESTING PART!
9. [Link]([Link][0]);
10. }, false);

Explanations:

 Line 2: we get a pointer to the file selector, the variable fileInput.

 Line 4: we define a change listener. In this example, we use an anonymous

function directly included in the listener definition (the listener is

the function(e) {...}).

 Line 11: when a user chooses a file, the listener will be executed. Line 11

will start the reading of the file content, as a binary file (this is

what readAsArrayBuffer means: read as binary!). Once the file will be

entirely read, the onload callback will be asynchronously called by the

browser.
 Line 7 is the onload callback, executed when the file content is loaded in

memory. We pass the file content to the initSound function (see JS Bin

example for complete source code) that uses WebAudio to decode it (it

may be a compressed file - an mp3 for example - and WebAudio works

only with uncompressed audio formats in memory), and to play it.

Read file content as data URL


Introduction to a data URL
What is a data URL?

A data URL is a URL that includes type and content at


the same time. It is useful, for example, for inlining
images or videos in the HTML of a Web page (on mobile
devices, this may speed up the loading of the page by
reducing the number of HTTP requests).

Here is an example of a red square, as a data URL. Copy


and paste it in the address bar of your browser, and you
should see the red square:

1. data:image/
png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHEl
EQVQI12P4//8/
w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

This data URL in a browser address bar should look like this:
If we set the src attribute of an image element <img
src="data:image/png...."> with the data URL of the above screenshot, it will
work exactly as if you used a URL that started with http://

In your browser, you will see a small red circle rendered by this source code:

1. <img src="data:image/
png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
2. AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
3. 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red square" width=50
height=50/>

And here is the result:

This dataURL format enables file content to be stored in a base64 format (as a
string), and adds the MIME type specification of the content. The dataURL can
therefore store a file as a URL readable with modern browsers. It is becoming
more commonly used on the Web, especially for mobile applications, as inlining
images reduces the number of HTTP requests and makes the Web page load
faster.

You will find lots of Web sites and tools for generating dataURL from files, such
as the DataURL maker Web site (screenshot below):
With the above example, you can copy and paste the characters on the left and
use them with an <img src="...">. Just set the src attribute with it!

Notice that you can encode any type of file as dataURL, but this format is most
frequently used with media files (images, audio, video).

Example of HTML5 logo embedded in a document without


any real image, just a dataURL and CSS
Try it at JsBin
Example 1: read images as data URL and display
previews in the page
Example 1 is useful for forms that allow the user to select one or more pictures.
Before sending the form, you might want to get a preview of the pictures in the
HTML page. The [Link] method is used for that.

Example on JS Bin or try it below in your browser:


Preview of selected images:

Source code extract:


1. <label for="files">Choose multiple files:</label>
2. <input type="file" id="files" multiple
3. onchange="readFilesAndDisplayPreview([Link]);"/><br/>
4. <p>Preview of selected images:</p>
5. <output id="list"></output>
6.
7. <script>
8. function readFilesAndDisplayPreview(files) {
9. // Loop through the FileList and render image files as thumbnails.
10. for (var i = 0, f; f = files[i]; i++) {
11.
12. // Only process image files.
13. if (![Link]('image.*')) {
14. continue;
15. }
16.
17. var reader = new FileReader();
18.
19. //capture the file information.
20. [Link] = function(e) {
21. // Render thumbnail. [Link] = the image content
22. // as a data URL
23. // create a span with CSS class="thumb", for nicer layout
24. var span = [Link]('span');
25. // Add an img src=... in the span, with src= the dataURL of
26. // the image
27. [Link] = "<img class='thumb' src='" +
28. [Link] + "' alt='a picture'/>";
29. // Insert the span in the output id=list
30. [Link]('list').insertBefore(span, null);
31. };
32. // Read in the image file as a data URL.
33. [Link](f);
34. }
35. }

Explanations:

Line 35: starts the reading of the file f. When f is read, the onload callback
will be called.
Lines 25-31: we build, using the DOM API, a <span
class="thumb">...</span> and inside we add an<img src=the data
url> element with its src attribute equal to the url of the image that has been
read (the image content as dataURL is in [Link]). Finally, at line 31,
we insert the span in the document before the current children of the <output
id="list"> element (declared at line 5).

Example 2: read a single local image file and use it


with drawImage in a canvas
Try it on JS Bin
Errata: the above screenshot says "choose multiple files", but the example only
works with a single file.

Source code extract:

1. function drawImage(imageFile) {
2. var reader = new FileReader();
3.
4. //capture the file information.
5. [Link] = function(e) {
6. // For drawing an image on a canvas we
7. // need an image object
8. var img = new Image();
9. // Even if the file has been read, decoding
10. // the dataURL format may take some time
11. // so we need to use the regular way of
12. // working with images: onload callback
13. // that will be called after setting the src attribute
14. [Link] = function(e) {
15. // draw the image!
16. [Link](img, 0, 0, 400, 400);
17. }
18. // [Link] is the dataURL, so we set the
19. // src if the image with it. This will call
20. // asynchonously the onload callback
21. [Link]= [Link];
22. };
23. // Read in the image file as a data URL.
24. [Link](imageFile);
25. }
26. function readFileAndDraw(files) {
27. drawImage(files[0]);
28. }

Explanations:

Remember how we worked with images on a canvas. We had to create an


empty image object (line 8), set the src attribute of the image object (line 23),
then use an [Link] callback (line 15), and we could only draw from
inside the callback (line 17). This time, it's exactly the same, except that the
URL comes from [Link] in the [Link] callback (line 23).

Example 3 (advanced): an instagram-like photo filter


application
Another very impressive example, has been developed by @GeorgianaB, a
student of the first iteration of this course (see her other creations/examples
at [Link] This Web application reads local image files, draws
them into a canvas element and proposes different filters. This example is
given "as is" for those of you who would like to go further. Just click on the link
(or on the image below) and look at the source code.

Try this example online on gitHub (or click the screenshot below)
The Geolocation API
Let's start with an example!
Click the button to get your position and display a map as a picture.

This may take some time, or fail, if a geolocation is not available with

the device and connection you are using (e.g. at work, beyond a

proxy). Try it anyway!

This example will be explained later on in the course...

Introduction
This chapter presents the new Geolocation API
and illustrates its use with several examples.

The Geolocation HTML5 JavaScript API is implemented by most modern Web


browsers, and uses different means to get the current location: GPS, GSM/3G
triangulation, Wifi, IP address, etc.

It is possible to prompt the user to activate the GPS (this is what most GPS
navigation software does on mobile phones), or ask for a particular mean
among those available. It is also possible to track the current position when it
changes. This is useful for writing a navigation application or for tracking in real
time the position of different participants in the case of an application that
involves several persons at the same time (using WebSockets, for example).

Current support is excellent


As at April 2017, support for this API is excellent, both on mobile and on
desktop devices.
To get an updated table, check [Link]

Typical use
1. [Link](showPosition, onError);
2.
3. function showPosition(position) {
4. [Link]("latitude is: " + [Link]);
5. [Link]("longitude is: " + [Link]);
6. }
7.
8. function onError(err) {
9. [Link]("Could not get the position");
10. }

This online example at JS Bin shows how to get the current longitude and
latitude and display them in an HTML page. Try it below in your browser:

Click the button to get your coordinates:


Note that the first time you execute this example, for privacy reasons, the
browser will ask if you agree to share your position with the application.

Source code of this typical example:

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <title>Basic example of use of the geolocation API</title>
5. </head>
6. <body>
7. <p id="msg">Click the button to get your coordinates:</p>
8. <button onclick="getLocation()">Where am I ?</button>
9. <script>
10. var displayCoords=[Link]("msg");
11. function getLocation() {
12. if ([Link]) {
13. [Link](showPosition);
14. } else {
15. [Link]="Geolocation API not supported by your
browser.";
16. }
17. }
18. function showPosition(position) {
19. [Link]="Latitude: " + [Link] +
20. "<br />Longitude: " + [Link];
21. }
22. </script>
23. </body>
24. </html>
Explanations:

Line 14 checks if the Web browser supports the geolocation API by testing the
[Link]. If not null, then the geolocation API is
supported.
Line
15 calls [Link](showPosition) passin
g a callback function as a parameter (in this example we did not specify a
callback in case of error). When a current position is available, the
callback function will be called asynchronously, and the input
parameter of this callback function will be the current position, like in
the function showPosition(position) of the example.
Line 22: the position objects has a coords property that is the object that
holds the longitude and thelatitude.

External resources:
The W3C specification about the geolocation API (in Recommendation status,
aka, Web standard)
Good article from the Opera dev Web site
Excellent tutorial on the Google Maps API. Some examples in this part of the
course are illustrated using Google Maps.

The different properties of the coords


object
In the previous example, we used the coords property of the position passed
as an input parameter to the callback function. This coords object has many
properties:

Properties of the coords object


latitude The latitude of the position

longitude The longitude of the position

altitude The altitude of the position

accuracy The accuracy of the measure of the longitude and latitude (in
meters)

altitudeAccurac The accuracy of the measure of the altitude (in meters)

heading gives the orientation relative to north, in degrees

speed current speed in meters/second

Not all these values may be available in all Web browsers. When one of these
properties is null, it means that it is not available.

Geolocation error codes


In the last example, we used
the [Link](showPosition) with only
one callback function (in the case of success), but it is also possible to pass a
second parameter that is another callback function called in the case of error.
This example on JS Bin shows how to properly check against the different
possible errors, it's just a slightly different version of the previous example. Try
it, then turn your WiFi off or unplug your Ethernet cable (or turn off GPS and
3G/4G on a mobile phone). You should see an error message:

Source code of the example:

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <title>Basic example of use of the geolocation API</title>
5. </head>
6. <body>
7. <p id="msg">Click the button to get your coordinates:</p>
8. <button onclick="getLocation()">Where am I ?</button>
9. <script>
10. var displayCoords=[Link]("msg");
11. function getLocation() {
12. if ([Link]) {
13.
[Link](showPosition, errorPositio
n);
14. } else {
15. [Link]="Geolocation API not supported by your
browser.";
16. }
17. }
18. function showPosition(position) {
19. [Link]="Latitude: " + [Link] +
20. "<br />Longitude: " + [Link];
21. }
22. function errorPosition(error) {
23. var info = "Error during geolocation: ";
24. switch([Link]) {
25. case [Link]:
26. info += "Timeout !";
27. break;
28. case error.PERMISSION_DENIED:
29. info += "Permission denied, geolocation could not be obtained...";
30. break;
31. case error.POSITION_UNAVAILABLE:
32. info += "Location could not be obtained though the available
means...";
33. break;
34. case error.UNKNOWN_ERROR:
35. info += "Unknown error";
36. break;
37. }
38. [Link] = info;
39. }
40. </script>
41. </body>
42. </html>
Tracking a position in real time
Introduction
In order to track the current position, the geolocation API provides a method
similar to the getCurrentPosition(onSuccess,
onError) named watchPosition(onSuccess, onError).

When getCurrentPosition gives a position when called, watchPosition does


the following:

It gets the callback function only when the current position changes.
If you stay in the same location, the callback function won't be called
regularly.
It returns an id so that you can use the clearWatch(id) method to stop the
current tracking.

Typical use
1. // get an id of the current tracking, the showPosition callback is like the one we
saw in earlier examples.
2. var watchPosId = [Link](showPosition);
3. ...
4. // stop the tracking
5. [Link](watchPosId);

As an exercise, you may just try to


change getCurrentPosition to watchPosition in the previous examples, and
try this code using a mobile phone or tablet, walk for 20 meters and see the
position changing.

External resource
An article on [Link] that shows how to write a simple trip meter
using the geolocation API: in particular, you will find a JavaScript function that
computes the distance (in meters) between two positions defined by their
longitude and latitude.
Options available when using the geolocation API, in
particular real time tracking
Several options are available when using HTML5 geolocation. We can pass a
third parameter to the getCurrentPosition and watchPosition methods, that
will hold one or several of the following options:

Properties of the coords object

enableHighAccurac A boolean (true/false) which indicates to the device that you


wish to obtain its most accurate readings. in other words: use
y the GPS please! (However, this parameter may or may not
make a difference, depending on your hardware, GPS
availability, etc.)

maximumAge The maximum amount of time (in milliseconds) the position


may remain in the cache (this is appropriate as the device may
cache readings to save power and/or bandwidth).

timeout The maximum time (in milliseconds) for which you are
prepared to allow the device to try to obtain a Geo location.
After this timeout value has elapsed, the onError callback is
called.

2. [Link](onSuccess, onError,
3. {enableHighAccuracy:true});
4. // maximumAge = 10 mins, the position can be cached for 10 mins,
5. // useful when in tunnels...When the device tries to get
6. // a position, if it does not succeed, then go on error
7. // immediately
8. [Link](onSuccess, onError,
9. {maximumAge:600000, timeout:0});
10. // Position will never come from the cache (maximumAge: 0), and
11. // if after 0.1s the position could not be computed, then go on
12. // error
13. [Link](onSuccess, onError,
14. {maximumAge:0, timeout:100});
15. // Ask for GPS, cache for 30s, 27s before going on error...
16. watchId=[Link](onSuccess, onError,
17. {enableHighAccuracy:true, maximumAge:30000, timeout:27000});

Practical examples: use the geolocation


API together with Google Maps
This section presents some examples of how to get a static map (a picture),
using the Google Static Map API, how to display an interactive map using the
Google Map JavaScript API and even how to get an estimation of a physical
address from the longitude and latitude, using the Google Reverse Geocoding
JavaScript API.

The following three examples increase in complexity, but most of the code is
reused and adapted without even reading the Google documentation about the
different APIs.

Example 1 (easy): how to get a static image map


centered on your longitude and latitude
Online example available on JS Bin, or try it here in your browser:

Click the button to get your position:

It also illustrates the use of the error callback from the previous section. The
Google Map API is used to get an image centered at the longitude and latitude
collected with the HTML5 Geolocation API.

Source code extract:

1. <!DOCTYPE html>
2. <html>
3. <body>
4. <p id="demo">Click the button to get your position:</p>
5. <button onclick="getLocation()">Try It</button>
6. <div id="mapholder"></div>
7. <script>
8. var x=[Link]("demo");
9.
10. function getLocation() {
11. if ([Link]) {
12. [Link](showPosition,showError);
13. } else{
14. [Link]="Geolocation is not supported by this browser.";
15. }
16. }
17.
18. function showPosition(position) {
19. // Google map API needs the latitude and longitude separated by a
comma
20. var latlon=[Link]+","+[Link];
21. // Google map API URL that returns an image centered on the longitude
and latitude
22. var img_url="[Link]
center="
23. +latlon+"&zoom=14&size=400x300&sensor=false";
24. [Link]("mapholder").innerHTML="<img
src='"+img_url+"' />";
25. }
26.
27. function showError(error) {
28. ...
29. }
30. </script>
31. </body>
32. </html>

The magic occurs at line 23, where we use the Google Static Map API.
Example 2 (a bit more complicated...) that shows
how to display an interactive Google map centered
on the current position
This example is just given "as is", as there are so many possibilities for
rendering a map with the Google Map API. However, we think having such a
basic example might be useful.

Online example at JS Bin

Source code of the example:

1. <!doctype html>
2. <html>
3. <head>
4. </head>
5. <body>
6. <!-- for position display -->
7. <div id="myposition"></div>
8.
9. <!-- for gmap display -->
10. <div id="map" style="width:640px;height:480px"></div>
11.
12. <!-- get gmap API -->
13. <script src="[Link]
script>
14.
15. <script>
16. // Default position
17. var centerpos = new [Link](48.579400,7.7519);
18.
19. // default options for the google map
20. var optionsGmaps = {
21. center:centerpos,
22.
navigationControlOptions: {style: [Link]
},
23. mapTypeId: [Link],
24. zoom: 15
25. };
26.
27. // Init map object
28. var map = new [Link]([Link]("map"), o
ptionsGmaps);
29.
30. if([Link]) {
31.
32. // callback function, called by getCurrentPosition() in case of success
33. function drawPosition(position) {
34. var infopos = "Got position : <br>";
35. infopos += "Latitude : "+[Link] +"<br>";
36. infopos += "Longitude: "+[Link]+"<br>";
37. infopos += "Altitude : "+[Link] +"<br>";
38. [Link]("myposition").innerHTML = infopos;
39.
40. // Make new object LatLng for Google Maps
41. var latlng = new [Link]([Link],
42. [Link]);
43.
44. // Add a marker at position
45. var marker = new [Link]({
46. position: latlng,
47. map: map,
48. title:"You are here"
49. });
50. // center map on longitude and latitude
51. [Link](latlng);
52. }
53.
54. // callback function, called by getCurrentPosition() in case of error
55. function errorPosition(error) {
56. ...
57. }
58. [Link](drawPosition,errorPosition);
59. } else {
60. alert("Geolocation API not supported by your browser");
61. }
62. </script>
63. </body>
64. </html>

Example 3 (advanced) shows how to get a physical


address from the longitude and latitude
This is another example that obtains an address from longitude and latitude. It
uses the Google Reverse Geocoding JavaScript API. For those of you who are
really interested to know how this API works, please read the Google
documentation and tutorials.

Without going into detail, the below example might be useful to


copy/paste/adapt for trying to pre-fill a form where one is asked for an address.
Geolocation is useful for guessing the country, city, zip code, street, etc. Some
examples that use this feature will be given in the next section of the course.

Online example at JS Bin.

Source code of the example:

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4. <script src="[Link]
v=[Link]&sensor=false"></script>
5. <script>
6. // p elements for displaying lat / long and address
7. var displayCoords, myAddress;
8. // used with the google apis
9. var geocoder;
10. var map;
11. var infowindow = new [Link]();
12. var marker;
13. // Called when the page is loaded
14. function init() {
15. displayCoords=[Link]("msg");
16. myAddress = [Link]("address");
17. geocoder = new [Link]();
18. // In order to show something even before a user clicks on the button
19. var latlng = new [Link](34.0144, -6.83);
20. var mapOptions = {
21. zoom: 8,
22. center: latlng,
23. mapTypeId: 'roadmap'
24. }
25.
map = new [Link]([Link]('map_canvas'), ma
pOptions);
26. } // end of init()
27. // Called when the button is clicked
28. function getLocation() {
29. if ([Link]) {
30. [Link](showPosition);
31. } else {
32. [Link]="Geolocation API not supported by your
browser.";
33. }
34. }
35. // Called when a position is available
36. function showPosition(position) {
37. [Link]="Latitude: " + [Link] +
38. "<br />Longitude: " + [Link];
39. // Display the map
40. showOnGoogleMap(new [Link]([Link],
41. [Link]));
42. }
43. function showOnGoogleMap(latlng) {
44. // Ask google geocoder for an address once we get a longitude and
45. // a latitude. In fact, the reverse geocoder sends back an array of
"guesses"
46. // i.e. not just one address object, but several. Each entry in this array
47. // has several properties such as street, city, etc. We use the
"formatted_address"
48. // one here, but it might be interesting to get the detailed properties in
other
49. // applications like a form with street, city, zip code etc.
50. [Link]({'latLng': latlng},reverseGeocoderSuccess);
51. function reverseGeocoderSuccess(results, status) {
52. if (status == [Link]) {
53. if (results[1]) {
54. [Link](11);
55. marker = new [Link]({
56. position: latlng,
57. map: map
58. });
59. [Link](results[1].formatted_address);
60. [Link](map, marker);
61. // Display address as text in the page
62. [Link]="Adress:
" + results[0].formatted_address;
63. } else {
64. alert('No surface address found');
65. }
66. } else {
67. alert('Geocoder failed due to: ' + status);
68. }
69. } // end of reverseGeocoderSuccess
70. } // end of showOnGoogleMap
71. </script>
72. </head>
73. <body onload="init()">
74. <title>HTML5 + Geolocalisation + Google Maps API Reverse
Geocoding</title>
75. <p id="msg">Click the button to get your coordinates:</p>
76. <p id="address"></p>
77. <button onclick="getLocation()">Where am I ?</button>
78. <div id="map_canvas" style="width: 500px; height: 300px"></div>
79. </body>
80. </html>

Example: fill a form's address fields


automatically
Introduction
In the previous example, we used the results returned by the Google reverse
geocoding service, without going into detail.

In this section, we will see how we can get the different parts of the responses
(city, street, zip code, country, etc.) The reverse geocoding service tries to
guess what is the "best" address that matches the longitude and latitude, but
sometimes the first guess is not the best one.

How to parse the Google reverse geocoding results?


What are the Google reverse geocoding results exactly?
A common question is: how to have a robust code for parsing the Google
reverse geocoding, to properly get the city, street, country, etc.

Depending on your location/country and on the geolocation method used by


your browser (GPS on phone, IP, WiFi, 3G, etc.), some of the data might not be
available (i.e., no street). So, there is no guarantee that all candidate addresses
will get the same defined properties. For example, the first result may give a
defined city, but the third result may not.

Look at this line of code from the last example from the previous page - the
example that showed the address when you clicked on the button:

1. // Display address as text in the page


2. [Link]="Adress: " + results[0].formatted_address;
At line 2, we get the first address returned by the Google reverse geocoding
service, and use the formatted_address property. Let's suppose that it
contained the best address, formatted as a string. We chose to use it and
showed it in the page by setting [Link] with its value
(myAddress pointed to the <p id="address"></p> element in the page).

Let's examine the detailed results


We add a [Link](results) in the code, to see a structured view of
the results in dev. tools console:
Once we get the results, we can get the different parts:
Here is an example of how we can parse such a field. Notice that each field is
tested to see if it exists. The results are stored in the variables defined at line
1.
1. var country, postalCode, state, route, streetNumber, locality, areaLvl
1, areaLvl2;
1. function parseResult(result) {
2. for(i in result){
3. [Link]("type = " + result[i].types[0] + " long_name = " +
4. result[i].long_name);
5. if(result[i].types[0] == 'postal_code')
6. postalCode = result[i].long_name;
7. if(result[i].types[0] == 'country')
8. country= result[i].long_name;
9. if(result[i].types[0] == 'street_number')
10. streetNumber= result[i].long_name;
11. if(result[i].types[0] == 'route')
12. route= result[i].long_name;
13. if(result[i].types[0] == 'locality')
14. locality= result[i].long_name;
15. if(result[i].types[0] == 'state')
16. state= result[i].long_name;
17. if(result[i].types[0] == 'administrative_area_level_2')
18. arealLvl2= result[i].long_name;
19. if(result[i].types[0] == 'administrative_area_level_1')
20. areaLvl1= result[i].long_name;
21. }
22. // added this for debugging in the console
23. [Link]("postalCode = " + postalCode);
24. [Link]("country = " + country);
25. [Link]("streetNumber = " + streetNumber);
26. [Link]("route = " + route);
27. [Link]("locality = " + locality);
28. [Link]("Administrative area level 1 " + areaLvl2);
29. [Link]("Administrative area level 2 " + areaLvl1);
30. }
A form that auto fills the address input fields
Example at JS Bin

It's very hard to create a single code that will work in all situations and in all
countries, since postal addresses are formatted differently depending on the
country. A decoder that works well 99% of the time in the UK may be wrong for
Australia, for instance. So, it's just a "guess system", and in real life, if you
create a Web site and would like to help the user with completing a form, just
fill in the country, city, postal code, and suggest the rest, propose a small icon
for deleting the street input field content, etc. You could also add a drop down
menu that offers not only the first guess but the second and third, etc.

Source code extract:

1. function showOnGoogleMap(latlng) {
1. ...
1. // Display address as text in the page
2. [Link]="Adress: " + results[0].formatted_address;
3. // Call the function that parses the results and fills
4. // the input fields
5. parseResult(results[0].address_components);
6. ...
7. }
8. var country, postalCode, state, route, streetNumber, locality, areaLvl
1, areaLvl2;
9. function parseResult(result) {
10. for(i in result){
11. // Let's print all the data we can collect from the reverse geocoder,
12. // Look at the debug console to see what we get...
13. [Link]("type = " + result[i].types[0] + " long_name = " +
14. result[i].long_name);
15.
16. if(result[i].types[0] == 'postal_code')
17. postalCode = result[i].long_name;
18. ...
19. // fill input fields now, check if variables are undefined
20. if((route != undefined) && (streetNumber != undefined)) {
21. [Link]("let's fill the street");
22. [Link]("#address1").value = streetNumber + "
" + route;
23. }
24. if(locality != undefined) {
25. [Link]("let's fill the city");
26. [Link]("#address2").value = locality;
27. }
28. if(country != undefined) {
29. [Link]("let's fill the country");
30. [Link]("#country").value = country;
31. }
32. ...
33. }
34. }
35. </script>
This example is rather long and we have only shown an extract of the source
code. Take your time and look at the online example.

You might also like