This presentation is an HTML5 website
Press → key to advance.
Having issues seeing the presentation? Read the disclaimer
by Elijah Manor ( @elijahmanor )
What!?!
Adoption Strategies
Does This Look Familiar?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8">
<link rel="stylesheet" href="site.css" type="text/css" />
<style type="text/css">
h1 { color: red; }
</style>
</head>
<body>
<script type="text/javascript" src="common.js"></script>
</body>
</html>
HTML5 Simplifies Your Markup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="site.css" />
<style>
h1 { color: red; }
</style>
</head>
<body>
<script src="common.js"></script>
</body>
</html>
New Semantic Elements
HTML5 Forms
Application Cache
<html manifest="example.appcache"></html>
CACHE MANIFEST # Version 2 CACHE: # Explicitly cached after downloaded /index.html # ... Include css, img, js, favicon, html files here NETWORK: # White-listed that require connection to server. Requests bypass cache /login.aspx # Maps to a file /server # Maps to a folder FALLBACK: # Provide fallback pages if resource inaccessible /dashboard.aspx /static.html # Maps to a file /img/profile/ /img/offline.jpg # Maps a folder to a file
// UNCACHED, IDLE, CHECKING, DOWNLOADING, UPDATEREADY, OBSOLETE
window.applicationCache.status;
window.applicationCache.update(); // Attempts to update cache if manifest changed
window.applicationCache.swapCache(); // Swaps out the old cache for the new one
var appCacheEvents = [ "cached", "checking", "downloading", "error", "noupdate",
"obsolete", "progress", "updateready" ];
$( window ).bind( appCacheEvents.join( " " ), function( e ) {} );
Web Storage ( Local & Session )
try {
window.localStorage.setItem( "firstName", "Mike" );
window.localStorage.firstName = "Jonathan";
window.localStorage[ "firstName" ] = "Doug";
localStorage[ "firstName" ] = "Scott";
} catch ( e ) {
if ( e === QUOTA_EXCEEDED_ERR ) { }
}
localStorage.getItem( "firstName" );
localStorage.length;
localStorage.removeItem( "firstName" )
localStorage.clear();
Web SQL Database
var db = openDatabase( "HTML5", '1.0', "My Local Database", 5 * 1024 * 1024 );
db.transaction( function ( tx ) {
tx.executeSql( "CREATE TABLE IF NOT EXISTS Tweets " +
"( id real unique, tweet text )" );
tx.executeSql( "INSERT INTO Tweets ( id, text ) VALUES ( ?, ? )",
[ tweet.id, tweet.text ] );
tx.executeSql( "SELECT * FROM Tweets", [], function ( tx, results ) {
for ( var i = 0, length = results.rows.length; i < length; i++ ) {
console.log( results.rows.item( i ) );
}
});
});
| Date | From | Tweet |
|---|
Indexed DB
var tweet = {
open: function( callback ) {
var request = window.IndexedDB.open( "HTML5 IndexDB" ),
version = "1.0";
request.onsuccess = function( e ) {
var db = tweet.db = e.target.result;
db.createObjectStore( "tweet", { keyPath: "id" } );
callback.apply( this, arguments );
};
},
add: function( id, tweet ) {
var trans = this.db.transaction(["tweet"], IDBTransaction.READ_WRITE, 0),
store = trans.objectStore( "tweet" ),
request = store.add({ "id": id, "tweet": tweet });
},
getList: function() {
var trans = this.db.transaction(["tweet"], IDBTransaction.READ_WRITE, 0),
store = trans.objectStore( "tweet" ),
keyRange = IDBKeyRange.lowerBound( 0 ),
cursorRequest = store.openCursor( keyRange );
cursorRequest.onsuccess = function( e ) {
var result = e.target.result;
if ( result ) { console.log( result.value ); result.continue(); }
};
}
};
Geolocation API
var errors = {
1: "Permission denied",
2: "Position unavailable",
3: "Request timeout"
};
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition(
function( position ) {
console.log( "lat: " + position.coords.latitude + ", " +
"long: " + position.coords.longitude );
},
function( error ) {
console.log( "error: " + errors[ error.code ] );
}, {
enableHighAccuracy: true, // want best accuracy, but may take longer
timeout: 10 * 1000, // maximum length of time to wait
maximumAge: 0 // maximum age of cached position
}
);
}
else {
console.log( "Geolocation not available" );
}
Tilt Orientation
$( window ).bind( "deviceorientation MozOrientation", function( event ) {
event = event.originalEvent;
var a = event.alpha, // 0
b = event.beta, // 0
g = event.gamma; // 0
});
Web Sockets
var socket = new WebSocket( "ws://html5rocks.websocket.org/echo" );
socket.onopen = function() { // connection has been opened
console.log( "Connection opened" );
socket.send( "Hello World!" ); // send a message to the server
};
socket.onerror = function( error ) { // an error has occured
console.log( error );
};
socket.onmessage = function( e ) { // message was sent from the server
console.log( e.data ); // message from server
};
socket.onclose = function( e ) { // connection has been closed
console.log( "Connection closed" );
};
console.log( socket.readyState ); // { 0:"Connecting", 1:"Open", 2:"Closed }
Many of us have been implemented interval driven polling with AJAX and some have moved towards using long polling techniques, but both of these have the overhead of the HTTP stack. The goal of Web Sockets is to keep a connection between the client and server and make communication between them be very lightweight and fast.
Server-Sent Events
var source;
if ( window.EventSource ) {
source = new EventSource( "eventSource.aspx" );
} else {
// Fallback to some other technique
}
source.bind( "message", function( e ) {
e = e.originalEvent;
console.log( e.data );
});
source.bind( "open", function( e ) {
// The connection was opened
});
source.bind( "error", function( e ) {
// An error has occurred
});
Content-Type: text/event-stream
retry: 10000\n // Signal how long to wait for reconnection (default 3 sec)
id: 1233\n // Signal what point to sync if connection lost
data: { "echo": "Hello World!" }\n\n
Audio
<audio
preload="auto" <!-- preload none, metadata, or auto (let browser decide) -->
controls <!-- display controls to manipulate playback -->
autoplay <!-- automatically start audio when page loaded -->
loop <!-- loop the media playback -->
autobuffer <!-- if not autoplay, then buffer so starts quickly -->
muted <!-- initialized audio output to mute -->
crossorigin> <!-- setting if use CORS -->
<source src="intro.ogg" type="audio/ogg" /> <!-- remember to add type -->
<source src="intro.mp3" type="audio/mpeg" /> <!-- otherwise has to -->
<source src="intro.wav" type="audio/wav" /> <!-- download pieced & check -->
<!-- Add fallback flash object markup here... -->
This content appears if the audio tag or the codec is not supported.
</audio>
Video
<video
width="320" <!-- pixel width. defaults to width of video -->
height="240" <!-- pixel height. defaults to height of video -->
poster="intro.jpg" <!-- image displayed before or while loading -->
autoplay <!-- automatically start video when page loaded -->
controls <!-- display controls to manipulate playback -->
loop <!-- loop the media playback -->
autobuffer> <!-- if not autoplay, then buffer so starts quickly -->
<source src="intro.mp4" type="video/mp4" /> <!-- remember to add type -->
<source src="intro.webm" type="video/webm" /> <!-- otherwise has to -->
<source src="intro.ogv" type="video/ogg" /> <!-- download piece & check -->
<!-- Add fallback flash object markup here... -->
This content appears if the video tag or the codec is not supported.
</video>
Canvas
Bitmap Output
<canvas id="fancyCanvas" width="200" height="200"></canvas>
var context, image;
if ( Modernizr.canvas ) {
context = $( "fancyImage" )[ 0 ].getContext( "2d" );
image = new Image();
image.src = "./images/HTML5_3D_effects_128.png";
image.onload = function() {
context.drawImage( image, 0, 0 );
};
} else {
// Do something else... flash, image only, etc
}
Web Workers
setTimeout(), etc... but these just make things asynchronous, not making them multi-threaded.
Browser Prefixes
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-ms-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
CSS3 Font Face
/* http://www.fontsquirrel.com/fontface/generator */
@font-face {
font-family: "ActionManRegular";
src: url( "Action_Man-webfont.eot" );
src: url( "Action_Man-webfont.eot?#iefix" ) format( "embedded-opentype" ),
url( "Action_Man-webfont.woff" ) format( "woff" ),
url( "Action_Man-webfont.ttf" ) format( "truetype" ),
url( "Action_Man-webfont.svg#ActionManRegular" ) format( "svg" );
font-weight: normal;
font-style: normal;
}
body {
font-family: "ActionManRegular", Helvetica, Georgia, sans-serif;
}
CSS3 Media Queries
#main { width: 600px; float: left; }
#aside { width: 280px; float: right; }
@media screen and (max-width: 1024px) {
#main { width: 65%; }
#aside { width: 25%; }
}
@media screen and (max-width: 720px) { /* change to one column */
#main { width: 100%; float: none; }
#aside { width: 100%; float: none; }
}
CSS3 Media Queries: Demo
Image Taken From: http://mgd.go.ly
Chrome Frame
<!-- Prompt IE 6 users to install Chrome Frame.
http://chromium.org/developers/how-tos/chrome-frame-getting-started -->
<!--[if lt IE 7 ]>
<script src="//ajax.googleapis.com/.../CFInstall.min.js"></script>
<script>window.attachEvent( "onload", function() {
CFInstall.check( { mode: "overlay" })})</script>
<![endif]-->
<!-- Use Google ChromeFrame if
it is intalled -->
<meta http-equiv="X-UA-Compatible"
content="chrome=1">