This site was created based on the edX course HTML5 Coding Essentials and Best Practices by W3C.
The course did not have a main project that you built on throughout it so I created my own. I decided to summarize the course contents in this format while using the concepts presented in the course to create it.
There is some cool optional projects in the course which are listed below.
HTML5 has a simpler DOCTYPE definition and many attributes and end tags are optional. It also has several new structural elements. A minimal HTML5 document is shown below.
New Structural Elements
HTML5 has many new structural elements. These elements are <header>, <footer>, <nav>, <article>, <section>, <time>, <aside>, <figure>, <figcaption> and <main>.
You can have multiple elements of most of these and can nest most of them inside each other. You can only have one main. Below is a code tree that shows the basic structure of this site. As you can see, there is a header and footer in the body as well as each article. There are several sections and each section has several articles. It only has one aside but you could have one for each article or section if it made sense. Each section or article can have its own nav etc.
Sectioning Elements and Headings
Headings <h1> to <h6> implicitly section a document while the new tags section, article, nav and aside explicitly section a document.
The HTML5 specification says that "each sectioning element potentially has a heading and has also an outline associated".
There are many browser extensions that will show an outline of your document as seen in the image below. Just search for HTML5 outliner.
The image is for this page as it was when this was written. There are some duplicate section and article names as temporary placeholders. More important to note is is the "Untitled" ASIDE. It shows that way because the aside did not have a <h1>..<h6> tag at the time and thus needed one added.
You may notice that the nav bar has a title and that it is visible. Sometimes you will not want a nav to have a visible heading and it is recommended to position it off screen rather that using display: none or visibility: hidden. This is a better option for assistive technologies. See this article.
<details> and <summary> Elements
Accordian content is not a new thing but the <details> and <summary> elements make it easy. Here is an example that only contains text but it could contain a form, images and more.
This is the summary.
This is the additional content.
Here is the code that created the above accordian.
As of this writing Edge and some older browsers do not support this and here is one of the many polyfills you can add to the head of your document to add support.
The <time> element is useful for marking time or durarion in a document. It has a human readable part and a machine readable part. The dates on these articles use it. Check it out on w3schools.
The <mark> element highlights part of your document like a highlighter and can be styled with CSS. Check it out on w3schools.
download and translate Attributes
The download attribute can be used to force a link to be downloaded rather than displayed. Example below.
The translate attribute can be set to yes or no and can be used so that translation tools do not translate certain parts of your document. One example is that it would not make sense to translate code blocks like on this page.
I could manually add this attribute to all code blocks but I figured it would be easier and more interesting to use javascript. Here is the code.
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 although it can be used for other purposes as well.
These articles are supposed to be brief introductions and not full tutorials. Hopefully the articles will give you a taste and make you want to search out more information. A proper covering of microdata would be way too long so I present you this page as one option.
At the time of writing this I have not added any microdata to this page.
HTML5 Multimedia
The <video> Element
The <video> element allows you to embed video in your page without complex code or Flash. The video below is the first minute of Big Buck Bunny used under the Creative Commons Attribution 3.0 license.
Sample code. Providing multiple sources is good as some browsers only support certain formats. The poster is an optional image to display when loaded. The controls attribute is to display controls to play, stop, etc.
The preload attribute can be set to none, metadata or auto. It is only valid if the autoplay attribute is not used. I used none here so it did not delay loading of other items. Notice the time does not show a duration.
Note: You cannot directly embed videos from most social web sites such as YouTube, Dailymotion etc. They have different embed scripts.
The <audio> Element
The <audio> element is similar to the <video> element without the video related attributes like poster.
The above element was done using the below code. Notice how it is very similar. The controls attribute was given a value in this one but it will work the same with any value or no value. Also note that there are download links provided in case the <audio> element is not supported.
In this example I used the metadata value for preload thus it knows the duraion. I also used the loop attribute so the audio continuously loops when playing.
You can style the <video> and <audio> elements using CSS and JS. Here are some links to some examples.
The <track> element allows you to add captions, subtitles, descriptions and metadata to your videos. The WebVTT format is used for describing a track file.
The <track> element has a kind attribute. The kind attribute can be subtitles, captions, descriptions, chapters or metadata. (eg. kind="subtitles")
Another attribute is default which is used to select the default track if more than one is provided.
The label attribute is what will be displayed to the user in the default HTML5 video player. (eg. label="English Subtitles")
There is a srclang attribute to specify the langage. (eg. srlang="en")
Here is an example of real time audio processing of the microphone input.
HTML5 Graphics
The <canvas> Element
The canvas can be used for drawing pixel based graphics for graphs, game graphics and other images on the fly.
It supports drawing many shapes including lines, rectangles, ellipses, arcs, curves, text and images.
The canvas can handle doing animations at 60 frames per second and has very good support in almost all major browsers.
The canvas coordinate system uses (0, 0) as the top left corner like many others.
Here is my canvas. I added a border around it for visualization purposes. It is 600 pixels wide and 300 pixels tall.
Make sure the JS isn't called until you know the page is loaded using onload or similar. We store the canvas in a variable and then define a context for it.
Then we draw some rectangles. The fillStyle determines the color of filled rectangles and the strokeStyle determines the color of the wireframe ones.
Notice how the rectangles stack on top of each other in the order they are drawn, how you can see behind the wireframe ones and the second strokeRect uses the color previously set.
We also have a clearRect which pokes a hole in the green rectangle.
The drawMonster function just draws some rectangles the same way. Notice that when I draw it at (0, 0) it is not in the top left because of the translate before it.
Also notice that the next translate is based on the new coordinate system of the first translate.
The second time we draw the monster using the same call but it appears differently because of the transformations.
Doing the translate, rotate and scale in a different order would have a different result. This is the order recommended most of the time.
Notice the last rectangle is drawn in the same spot the second monster starts and it is purple because the last thing drawn on the monster is the mouth which is purple.
When doing transformations or calling functions that will change the context it is a good idea to save the current context so it can be restored.
This is done using ctx.save(); and ctx.restore(); and is good practice to save at the start of a function and restore at the end of a function.
Note: These rectangles as well as text and images are drawn in "immediate mode". "Path mode" or "buffered mode" is used for lines, arcs, curves and can also be used for rectangles. We'll see that later.
Drawing Text on the Canvas
You can draw text on the canvas with fillText and strokeText. You can specify how the text is drawn using the font property of the context. The font property is CSS-compliant ant thus you can specify the style, weight, size and face.
You can see in the code below how we draw strokeText on top of fillText to give the ext a border. You can also see how we specify font properties in different ways.
The last example uses the optional last parameter of maxWidth to constarin the text to the width specified.
The part in the middle measures the text and then draws a baseline under it with the legth of the text's width.
You can also change the way the text is drawn horizontally with the textBaseline property and the horizontal alignment with the textAlign property.
Check out this and this for demonstrations.
Drawing Images on the Canvas
Images must be fully loaded before they are drawn. For this reason they are loaded asynchronously in the background
In the code below we create an Image object and set up an onload callback. At the bottom we specify the source which stsrts loading the image. Once it is loaded the onload callback gets called.
In the callback we draw the image three diferent ways. The first is in the top corner with a width and height of 100. The second starts from the bottom corner of the first and has a width and height of 200.
The third is a little different. It selects a portion of the original starting at (50,0) with dimensions of (400,100) and then draws it on the canvas at (300,0) with dimensions of (175,50).
The image source can also be a video stream, another canvas or an <img> element.
Check out this link to see an example of drawing an image from a video source.
Path Mode Drawing
Path drawing mode is faster than immediate mode and can be used for drawing many things.
In the code below you see the path mode version of drawing rectangles. Note that when I draw the third rectangle, the red wireframe, that it also redraws the previous rectangle as a red wireframe as well.
This is because it is still in the buffer since we did not call beginPath in between them. Also note that only two lines of the triangle are specifically drawn. The other is drawn because of the closePath line.
Visit the w3schools Canvas Tutorial for more canvas drawing like arcs, curves, transformations and more.
Transparency, Gradients and More
Here is an example of drawing using the alpha channel and drawing using a gradient.
The first part of the code draws three rectangles using different values for the transparency.
I then create a rainbow gradient. The first line determines the placement and direction of the gradient. The color stops define the colors it uses. I then set the fillStyle to this gradient and draw some rectangles to show what gets displayed.
You can also apply gradients to stroke objects and create radial gradients. You can use shadows and style lines.
Basic animation consists of clearing the screen/canvas, drawing something on it, change some property of it and then repeat. Doing this fast enough will result in aniimation. An animation done at 60 frames per second (fps) can be smoother then one done at 30fps.
Before HTML5 and canvas this was done using divs, css backgrounds and positioning as well as Javascript.
The two methods used for animation were setinterval(function, ms) and setTimeout(function, ms). The diference in these is that seInterval will run every n milliseconds where setTimeout will run once after n milliseconds and you would generally call it again at the end of the function.
The new HTML5 method is requestAnimationFrame(function). There is no second parameter as it is set to 16.6ms to produce a 60fps animation.
Below I set up three canvas elements and put CSS borders around them so you can see where they are. The first uses setInterval, the second uses setTimeout and the third uses requestAnimationFrame to animate a rectangle.
As you can see in the code below, animation is not that difficult. We get the canvas and context as usual. We set the starting X of the rectangle and the number of pixels to move (speed) each update. Then we simply call one of the three animation funcions with a callback that does the update.
In the animate function we clear the canvas, draw the rectangle and then update the position for the next call. Since setTimeout and requestAnimationFrame only run once we call them again at the end of the function.
I have setInterval being called every 33ms, about 30fps, setTimeout at 22ms, about 45fps and requestAnimationFrame runs at about 60fps as long as the system it is running on can support that rate.
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.
setTimeout solves thi issue since it only runs once and is not called again until the end of the callback. However, both have problems with no being very prcise in their timing which may be noticeable in some situations.
requestAnimationFrame uses a high resolution timer which makes it more accurate, it also provides an extra parameter to the callback which is a high resolution time. It is useful in time-based animation which can account for any difference in the timing.
Check out this link for an animation that uses start and stop buttons, transformations and shows where the timestamp mentioned above comes from although it is not used.
Keyboard and Mouse Events in the Canvas
Below is a table drawn on a canvas to show some keyboard and mouse handling. It is designed so it only works when the mouse pointer is within the canvas. When the mouse moves inside the canvas the border turns blue to show it has focus.
While inside the canvas the page will capture several keyboard and mouse events. Note: mouseover only triggers when the mouse is moved outside the canvas and then back in.
Move the mouse around, click some buttons and press some keyboard keys to see what happens.
Last mouse event:
Canvas mouse position:
There is a lot going on in the code so I split it up into three sections. The first section has the main code and the next two sections have a few functions that are needed.
The first two lines get the canvas and context as usual. We want a 3x4 table so I calculate cellWidth and cellHeight from the canvas width and height. I set the font and and place the textBaseline at middle so it is easy to center the text vertically in the cell.
I call a function drawGrid to draw the grid which we'll look at later. I then get the spans for the mouse event and mouse position texts. I then add the needed event listeners.
The first two event listeners are mouseenter and mouseout. These are used to have the canvas get and lose focus without having to click on it. It is required to have focus to capture the events atttached to it.
The next four mouse event listeners handle the text displayed in the spans. The mousedown event also uses event.button to display the button pressed. It also uses preventDefault to stop the page from selecting text when the buton is pressed quickly.
The mousemove event calls the showMousePos function which calculates the mouse position on the canvas by subtracting where the top left of the canvas is on the page compared to where the mouse is on the page as a whole.
The last two event listeners set up the callbacks for the keydown and keyup events.
Inside these functions the cells are cleared before updating each text. We add 1 to the cellWidth and cellHeight start and subtract 2 for the end so it doesn't clear the lines made in drawGrid.
The text itself is drawn using an X padding of 10 and centered vertically using 1.5, 2.5 etc.
We use event.keyCode, event.key and event.code for the text to be drawn in the table. We also use preventDefault to stop the page from moving around etc while pressing keys.
In the drawGrid function we use for loops to draw the lines and then fillText for the labels. We use similar calculations here as above.
Check out this link for an example of combining key and mouse events with animation.
Resizing a Canvas
Changing the width or height property of a canvas in Javascript erases its content and resets its context. Using percentages in the CSS width and height properties does not change the nuber of pixels but scales the existing pixels which is likely undesireable a most times.
To create a responsive canvas, first enclose it in a div or some other parent element. Use percentages to change the parent element. Use a resize listener on the parent and inside the listener use Javascript to change the width and height of the canvas. Redraw the canvas at the appropriate scale.
Decide on some animation example. Maybe a small game.
HTML5 Forms
Exploring Several Options with Forms
Basic HTML forms have not changed much since 1997 until HTML5. This may not be apparent to most users since they were usually enhanced with custom Javascript or the use of frameworks.
HTML5 introduces some new elements, many new input types, built-in validation, CSS pseudo classes and more.
Some of these new input types are very helpful for mobile browsers including the ability to use contextual keyboards.
Not all of these options are fully supported on all browsers. Check the caniuse website for support, polyfills to add support etc.
Many of the input types can use attributes value, min, max, step and list.
There is a lot of html in this one so I will not reproduce it below. I recommend using the devtools to inspect it. I will show the CSS and Javascript below for convenience.
The first thing I will point out is the use of 'fieldset' and 'legend'. This not only helps to keep related information together but also helps with accessibility.
Each input also has a 'label for' element. This helps to describe the element and also helps for selecting elements as clicking on the text selects the input element.
All the 'Account Information' fields use CSS to color the fields based on their validity since they all have the 'required' atribute.
There are many types of inputs that accept varying types of input as seen. Some of these use special attributes to do different things.
For the first two I just use 'required' which makes it so the field must be filled in and 'placeholder' to show some sample text.
The username field adds the 'pattern' attribute which uses a regex to restrict the field to between 5 and 50 characters. It also uses a span that is not displayed once the field is valid using CSS.
The email field just uses the default validation to decide whether the field is valid or not.
The password fields also use a regex pattern to require one lowercase and one uppercase letter as well as one number. It also restricts it to at least 8 characters.
The first password field also uses a 'title' attribute to provide a tooltip that specifies what is required instead of the span used for username.
The second password field uses javascript to specify custom validation that requires it to match the first password field.
The lower part has similar attributes except the range input also uses a default 'value', 'min', 'max' and 'step' attributes.
The CSS
Most of it is pretty basic except the selection of the inputs using the 'valid' and 'invalid' pseudo selectors. Of note here is I also use the 'not' to exclude two fields.
Also of note is the last two selectors that hide or show the span on the username field.
The Javascript
Aside from the password validation metioned above there is also code to show the numeric value of the range input.
There is a lot more I have not covered and this site covers the really well.
This example shows how you can use for elements not just for forms but also to control other elements.
Using labels on options is also possible as shown in this example.
This example shows using min, max and step in a date input type.
Here is a site that helps styling sliders or can give you some inspiration.
In this example it shows aggregation of error messages and overiding default behaviour.
HTML5 Basic APIs
HTML5 Cache
The HTML5 cache can be used to decrease load times and bandwidth use as well as make pages or entire sites work while offline. This is good for desktop computers and great for mobile devices.
Previously, caching was done by the browser and a developer had little choice on what was and wasn't cached. Now a developer can define what should and shouldn't be cached.
Any part or functions of a web site that does not need immediate communication with the server can be cached and work offline.
This is done with a manifest file which lists the files needed to be cached. This includes files from othe sites if needed (like jquery etc). It can also list files not to cache.
A good place to start is by getting manifestR which will help you create a manifest file.
The manifest file should have an appcache extension like manifest.appcache. You also need the manifest attribute in the html tag of each page you want to cache. The attributes value is set to the filename.
It is good to watch the console in the devtools when you first add caching and then go offline or stop the server (you ar working on a test server and not a production server right?) to test it.
Example html tag.
<html lang="en" manifest="manifest.appcache">
If a file is available in the cache it will always be retrieved from the cache. You can, however, make it update the cache by modifying the manifest file.
If one file cannot be retrieved and cached then no files will be. There is no partial update so make sure to verify your manifest. Manifesto is one option.
The manifest file must start with CACHE MANIFEST and is followed by the files that need to be cached. You can optionally include comments to organize the file which helps when you need to update it.
You can also optionally include 3 sections: CACHE, FALLBACK and NETWORK. If you specify one, you should specify all three.
The CACHE section is for the files that must be cached. Wildcards are not allowed in this section.
The NETWORK section specifies files that should NOT be cached. Using a wildcard * is common practice and means "do not cache all files not in CACHE or FALLBACK sections".
The FALLBACK section specifies resources that will be displayed when a user requests a resource not available while offline like a login page.
Using "/ /offline.html" would cause offline.html to be displayed for anything that is not cached. Using "/images/ /images/missing.png" would display missing.png for any images not cached.
Here is the manifest file for this site at the time of writing this. The second line with #version... is useful for forcing an update.
The cache will not be updated just because you modify the html, css or other file. It will only be updated if the manifest file changes so you can simply change the version or date.
When refreshing the page it will still load from the disk but it will check the manifest file, realize it is changed and update the cache. So you will see changes on the following refresh.
Notice at the bottom here that I have smaller fallback videos that will play when offline and basically say "It appears you are offline".
The Web Storage API
The Web Storage API provides two interfaces called sessionStorage and localStorage. They both allow for the storage of key-value pairs of data.
It is similar to cookies but the main difference is the amount of data able to be stored is much larger.
The sessionStorage data is erased when the tab/browser is closed. The localStorage will remain until the data is deleted.
There is only one key-value store per domain which follows the same origin policy.
Storing and retrieving data is very simple as seen in the snippet below.
Check out this site for a basic example of storing form data as you type it and restoring it.
This can be very helpful if something happens to close the page. When you go back, you don't have to start over.
There are also several methods that can be used with the Web Storage API.
The setItem(key, value) method will set a key to the corresponding value. This can be useful with a key "First Name" which would not be able to be used using the dot notation above.
The getItem(key) method will get the value that is associated with the given key.
The removeItem(key) method will remove the key-value pair associated with that key.
The clear() method will erase everthing stored. Mostly used only when testing and from the devtools console.
You can also use localStorage.length and iterate through each key with localStorage.key(i) to get the value of each key.
Another method of accessing the values is by using localStorage[key].
A very good use of the localStorage is to save your settings of a web app so the next time you come back it remembers your settings.
Here is a great example that shows working with
generic reusable functions to save form data without having to know the number of fields, the names of the fields etc.
It is generally advised to keep data stored in localStorage below 5MB. This is mostly an arbitrary number but if you need a lot more storage than this you are likely better off using indexedDB.
This data may be wiped with cookies or by other means. If it is very important for your app to have this data or you want it to be shared across multiple devices you will have to synchronize it with data stored on the server.
If you want to store more than simple strings in the store you can use JSON objects. Use the JSON method stringify to convert it to a string and use the method parse to restore it.
Prior to HTML5, file management was limited to pretty much sending and receiving files.
The file API allows client-side JavaScript to work with local files without having to send them to the server.
The file API reads files and encodes them in what is called a data url. Here is the first piece of one "data:image/jpeg;base64,/9j/4AAQSkZJRgA"
The above data url is a small image of a kitten which was only 14k in size. As a data url it is almost 18k. If you had the full thing you could paste it in a tab and see the image.
Try uploading a file to dataurl.net to create your own and test it out.
Try this example to see image previews of files you load from your local disk.
This example shows how to read metadata of files and also shows the optional accept attribute to filter files.
Aside from readAsDataURL there are two other methods for reading files. They are readAsText and readAsArrayBuffer.
The readAsText method is used similar to the readAsDataURL method.
The coords object has properties of latitude, longitude, altitude, accuracy, altitudeAccuracy, heading and speed. Not all may be available and will be set to null if not available.
Tracking the current position is done with watchPosition(onSuccess, onError). It returns an id that can be used with clearWatch(id) to stop tracking.
You can pass a third parameter to the getCurrentPosition and watchPosition methods that can contain one or more options including enableHighAccuracy, maximumAge and timeout.
A sample usage is watchId=navigator.geolocation.watchPosition(onSuccess, onError, {enableHighAccuracy:true, maximumAge:30000, timeout:27000});
This example shows a static google map centered on the longitude and latitude.
This example uses an interactive google map and tries to get an approximate address.
This example shows how to autofill form fields using the location.