Loading...

This presentation is an HTML5 website

Press key to advance.

Slides controls
  • and to move around.
  • Ctrl/Command and + or - to zoom in and out if slides don’t fit.
  • S to view page source.
  • T to change the theme.
  • H to toggle syntax highlight.
  • N to toggle speaker notes.
  • 3 to toggle 3D effect.
  • 0 to toggle help.

HTML5*

Web Development to the next level

*Including other next generation technologies of the Web Development stack

Rough Timeline of Web Technologies
  • 1991 HTML
  • 1994 HTML 2
  • 1996 CSS 1 + JavaScript
  • 1997 HTML 4
  • 1998 CSS 2
  • 2000 XHTML 1
  • 2002 Tableless Web Design
  • 2005 AJAX
  • 2009 HTML 5
HTML5 ~= HTML + CSS + JS

Today, we will cover...

Offline / Storage

Expect the unexpected

HTML5 Offline & Storage
JS

Web Storage

// use localStorage for persistent storage
// use sessionStorage for per tab storage
saveButton.addEventListener('click', function () {
window.localStorage.setItem('value', area.value);
window.localStorage.setItem('timestamp', (new Date()).getTime());
}, false);
textarea.value = window.localStorage.getItem('value');
JS

Web SQL Database

var db = window.openDatabase("DBName", "1.0", "description", 5*1024*1024); //5MB
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM test", [], successCallback, errorCallback);
});
JS

IndexedDB

var idbRequest = window.indexedDB.open('Database Name');
idbRequest.onsuccess = function(event) {
var db = event.srcElement.result;
var transaction = db.transaction([], IDBTransaction.READ_ONLY);
var curRequest = transaction.objectStore('ObjectStore Name').openCursor();
curRequest.onsuccess = ...;
};
JS

Application Cache

<html manifest="cache.appcache">
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
}
}, false);
cache.appcache:
CACHE MANIFEST
# version 1.0.0

CACHE:
/html5/src/logic.js
/html5/src/style.css
/html5/src/background.png

NETWORK:
*
JS

Quota API

// Request Status
webkitStorageInfo.queryUsageAndQuota(webkitStorageInfo.TEMPORARY, function(used, remaining) {
console.log("Used quota: " + used + ", remaining quota: " + remaining);
}
);

// Request Quota (only for File System API)
webkitStorageInfo.requestQuota(webkitStorageInfo.PERSISTENT, 10 * 1024 * 1024, function(used) {
console.log("Used quota: " + used + ", remaining quota: " + remaining);
}
);

Realtime / Communication

Stay connected

HTML5 Realtime & Communication
JS

Web Workers

main.js:
var worker = new Worker('task.js');
worker.onmessage = function(event) { alert(event.data); };
worker.postMessage('data');
task.js:
self.onmessage = function(event) {
// Do some work.
self.postMessage("recv'd: " + event.data);
};
JS

WebSocket

var socket = new WebSocket('ws://html5rocks.websocket.org/echo');
socket.onopen = function(event) {
socket.send('Hello, WebSocket');
};
socket.onmessage = function(event) { alert(event.data); }
socket.onclose = function(event) { alert('closed'); }
JS

Notifications

if (window.webkitNotifications.checkPermission() == 0) {
// you can pass any url as a parameter
window.webkitNotifications.createNotification(tweet.picture, tweet.title,
tweet.text).show();
} else {
window.webkitNotifications.requestPermission();
}

File / Hardware Access

Deeper integration with the Operating System

HTML5 Device Access
JS

Native Drag & Drop

document.addEventListener('dragstart', function(event) {
  event.dataTransfer.setData('text', 'Customized text');
  event.dataTransfer.effectAllowed = 'copy';
}, false);
JS

Desktop Drag-In (File API)

Drag files in from the desktop:

document.querySelector('#dropzone').addEventListener('drop', function(e) {
  var reader = new FileReader();
  reader.onload = function(evt) {
    document.querySelector('img').src = evt.target.result;
  };

  reader.readAsDataURL(e.dataTransfer.files[0]);
}, false);
JS

Desktop Drag-Out

Drag files out onto the desktop:

<a href="src/star.mp3" draggable="true" class="dragout"
   data-downloadurl="MIMETYPE:FILENAME:ABSOLUTE_URI_TO_FILE">download</a>
var files = document.querySelectorAll('.dragout');
for (var i = 0, file; file = files[i]; ++i) {
  file.addEventListener('dragstart', function(e) {
    e.dataTransfer.setData('DownloadURL', this.dataset.downloadurl);
  }, false);
}
JS

FileSystem APIs

Asynchronously write a file to a sandboxed file system using JavaScript:

window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function(fs) {

  // fs.root is a DirectoryEntry object.
  fs.root.getFile('log.txt', {create: true}, function(fileEntry) {

    fileEntry.createWriter(function(writer) {  // writer is a FileWriter object.

        writer.onwrite = function(e) { ... };
        writer.onerror = function(e) { ... };

        var bb = new BlobBuilder();
        bb.append('Hello World!');

        writer.write(bb.getBlob('text/plain'));

    }, opt_errorHandler);
  }

}, opt_errorHandler);
JS

Geolocation

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(function(position) {
    var latLng = new google.maps.LatLng(
        position.coords.latitude, position.coords.longitude);
    var marker = new google.maps.Marker({position: latLng, map: map});
    map.setCenter(latLng);
  }, errorHandler);
}
JS

Device Orientation

window.addEventListener('deviceorientation', function(event) {
  var a = event.alpha;
  var b = event.beta;
  var g = event.gamma;
}, false);
HTML

Speech Input

<input type="text" x-webkit-speech />

Semantics & Markup

More meaningful elements

HTML5 Semantics & Markup
HTML

Better semantic tags

<body>
  <header>
    <hgroup>
      <h1>Page title</h1>
      <h2>Page subtitle</h2>
    </hgroup>
  </header>

  <nav>
   <ul>
     Navigation...
   </ul>
  </nav>
  <section>
   <article>
     <header>
       <h1>Title</h1>
     </header>
     <section>
       Content...
     </section>
   </article>
   <article>
     <header>
       <h1>Title</h1>
     </header>
     <section>
       Content...
     </section>
   </article>
  </section>

  <aside>
   Top links...
  </aside>

  <figure>
    <img src="..."/>
    <figcaption>Chart 1.1</figcaption>
  </figure>

  <footer>
   Copyright ©
<time datetime="2010-11-08">2010</time>. </footer> </body>
HTML

Markup for applications

<input list="cars"/>
<datalist id="cars">
  <option value="BMW"/>
  <option value="Ford"/>
  <option value="Volvo"/>
</datalist>


  
<menu>
  <command type="command" disabled label="Publish" />
</menu>

<details>
  <summary>HTML 5</summary>
  This slide deck teaches you everything you need to know about HTML 5.
</details>
HTML 5This slide deck teaches you everything you need to know about HTML 5.
<meter min="0" max="100" low="40" high="90" optimum="100" value="91">A+</meter>
Your score is: A+
<progress>working...</progress> Download is: working...
<progress value="75" max="100">3/4 complete</progress> Goal is: 3/4 complete
HTML

Microdata

<div itemscope itemtype="http://example.org/band">
 <p>My name is <span itemprop="name">Neil</span>.</p>
 <p>My band is called <span itemprop="band">Four Parts Water</span>.</p>
 <p>I am <span itemprop="nationality">British</span>.</p>
</div>
Google Rich Snippets Tool screenshot
Rich Snippets Testing Tool at http://www.google.com/webmasters/tools/richsnippet
HTML

ARIA attributes

<ul id="tree1"
      role="tree"
      tabindex="0"
      aria-labelledby="label_1">
  <li role="treeitem" tabindex="-1" aria-expanded="true">Fruits</li>
  <li role="group">
    <ul>
      <li role="treeitem" tabindex="-1">Oranges</li>
      <li role="treeitem" tabindex="-1">Pineapples</li>
      ...
    </ul>
  </li>
</ul>
HTML

New form types

<style>
  [required] {
    border-color: #88a;
    -webkit-box-shadow: 0 0 3px rgba(0, 0, 255, .5);
  }
  :invalid {
    border-color: #e88;
    -webkit-box-shadow: 0 0 5px rgba(255, 0, 0, .8);
  }
</style>
<input type="text" required />

<input type="email" value="some@email.com" />

<input type="date" min="2010-08-14" max="2011-08-14" value="2010-08-14"/>

<input type="range" min="0" max="50" value="10" />

<input type="search" results="10" placeholder="Search..." />

<input type="tel"  placeholder="(555) 555-5555"
         pattern="^\(?\d{3}\)?[-\s]\d{3}[-\s]\d{4}.*?$" />

<input type="color" placeholder="e.g. #bbbbbb" />

<input type="number" step="1" min="-5" max="10" value="0" />
HTML

Form field types on mobile

type="text"
android keyboard on input type text
Android Device
type="number"
android keyboard on input type number
Android Device
type="email"
iphone keyboard on input type email
iPhone Device
type="tel"
iphone keyboard on input type tel
iPhone Device

Graphics / Multimedia

2D & 3D

HTML5 3D & Effects HTML5 Multimedia
HTML JS

Audio + Video

<audio id="audio" src="sound.mp3" controls></audio>
document.getElementById("audio").muted = false;
<video id="video" src="movie.webm" autoplay controls></video>
document.getElementById("video").play();
HTML JS

Track Element

<video width="390" id="clip" controls>
  <source src="Google_Developer_Stories.webm"
          type='video/webm; codecs="vp8, vorbis"' />
  <track label="English subtitles" kind="subtitles" srclang="en"
         src="video-subtitles-en.vtt" default />
</video>
CSS JS

FullScreen API

if (elem.webkitRequestFullScreen) {
  elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
} else if (elem.mozRequestFullScreen) {
  elem.mozRequestFullScreen();
} else if (elem.requestFullScreen){
  elem.requestFullScreen();
}
:-webkit-full-screen-ancestor:root {
  overflow: hidden;
}
:-webkit-full-screen-ancestor {
  z-index: auto;
  -webkit-transform: none;
  -webkit-transition: none;
}
pre:-webkit-full-screen {
  background-color: white;
}
HTML JS

Canvas 2D

<canvas id="canvas" width="838" height="220"></canvas>

<script>
  var canvasContext = document.getElementById("canvas").getContext("2d");
  canvasContext.fillRect(250, 25, 150, 100);

  canvasContext.beginPath();
  canvasContext.arc(450, 110, 100, Math.PI * 1/2, Math.PI * 3/2);
  canvasContext.lineWidth = 15;
  canvasContext.lineCap = 'round';
  canvasContext.strokeStyle = 'rgba(255, 127, 0, 0.5)';
  canvasContext.stroke();
</script>
HTML JS

Canvas example

HTML JS

Canvas 3D (WebGL)

<canvas id="canvas" width="838" height="220"></canvas>

<script>
  var gl = document.getElementById("canvas").getContext("experimental-webgl");
  gl.viewport(0, 0, canvas.width, canvas.height);
  ...
</script>
            
HTML

Inline SVG

<html>
  <svg width="300px" height="300px">
    <defs>
      <linearGradient id="myGradient" x1="0%" y1="100%" x2="100%" y2="0%">
        <stop offset="5%" stop-color="red"></stop>
        <stop offset="95%" stop-color="blue" stop-opacity="0.5"></stop>
      </linearGradient>
    </defs>
    <circle id="myCircle" class="important" cx="50%" cy="50%" r="100" 
        fill="url(#myGradient)" onmousedown="alert('hello');"/>
  </svg>
</html>
HTML

SVG example

CSS3

Presentation & Styling

HTML5 Styling
CSS

CSS Selectors

Selectors

.row:nth-child(even) {
  background: #dde;
}
.row:nth-child(odd) {
  background: white;
}

Image-like display

div {
  display: inline-block;
}

Specific attributes

input[type="text"] {
  background: #eee;
}

Negation

:not(.box) {
  color: #00c;
}
:not(span) {
  display: block;
}

More specific targetting

h2:first-child { ... }

div.text > div { ... }
h2 + header { ... }
CSS

Webfonts

@font-face {
  font-family: 'LeagueGothic';
  src: url(LeagueGothic.otf);
}

@font-face {
  font-family: 'Droid Sans';
  src: url(Droid_Sans.ttf);
}

header {
  font-family: 'LeagueGothic';
}
CSS

Text wrapping

div {
  text-overflow: ellipsis;
}
CSS

Columns

-webkit-column-count: 2;
-webkit-column-rule: 1px solid #bbb;
-webkit-column-gap: 2em;
CSS

Text stroke

div {
  -webkit-text-fill-color: black;
  -webkit-text-stroke-color: red;
  -webkit-text-stroke-width: 0.00px;
}
CSS

Opacity

  color: rgba(255, 0, 0, 0.75);
  background: rgba(0, 0, 255, 0.75);
CSS

Hue/saturation/luminance color

color: hsla(
  128
  74%
  33%
  1.00
        
CSS

Rounded corners

              face: border-radius: 0px;
              left eye: border-radius: 0px;
              right eye: border-radius: 0px;
              base white: border-radius: 0px;
              mouth: border-radius: 0px;
              nose: border-radius: 0px;
              left black eye: border-radius: 0px;
              right black eye: border-radius: 0px;
            
CSS

Gradients

background-image: linear-gradient(top, #00abeb 0%, #fff 50%,
                            #66cc00 50%, #fff 100%);

background-image: radial-gradient(center, circle cover, red, #000 40%);
CSS

Shadows

text-shadow:
  rgba(64, 64, 64, 0.5)
  0px 
  0px 
  0px; 

box-shadow: rgba(0, 0, 128, 0.25) 0px 0px 0px;
CSS

Instant Web 2.0 (just add sliders)

text-shadow: rgba(0, 0, 0, 0.5) 0 0px 0px; 

background:
  -webkit-gradient(linear, left top, left bottom, 
                   from(rgba(200, 200, 240, 0)), to(rgba(255, 255, 255, 0)));

border-radius: 0px; 

-webkit-box-reflect: below 10px
  -webkit-gradient(linear, left top, left bottom, 
                   from(transparent), to(rgba(255, 255, 255, 0)));
CSS

Background enhancements

Background sizing

#logo {
  background: url(logo.gif) center center no-repeat;
  background-size: auto|contain|cover|100%;
}

Multiple backgrounds

div {
  background: url(src/zippy-plus.png) 10px center no-repeat,
              url(src/gray_lines_bg.png) 0 center repeat-x;
}
            
CSS

Border image

Border image No.1
Border image No.2
Border image No.3
Border image No.4
Border image No.5
-webkit-border-image: url(border_image_1.png) ; border-width: 10px;
CSS

Flexible Box Model

.box {
  display: -webkit-box;
  -webkit-box-orient: ;
}
.box .one, .box .two {
  -webkit-box-flex: 1;
}
.box .three {
  -webkit-box-flex: 3;
}
Box one
Box two
Box three
CSS

Flexible Box Model

.box {
    display: -webkit-box;
    -webkit-box-pack: ;
    -webkit-box-align: ;
  }
CSS

Transitions

#box.left {
  margin-left: 0;
}
#box.right {
  margin-left: 1000px;
}

document.getElementById('box').className = 'left'; 
document.getElementById('box').className = 'right'; 
#box {
  -webkit-transition: margin-left 1s ease-in-out;
}

document.getElementById('box').className = 'left'; 
document.getElementById('box').className = 'right'; 
CSS

Transforms

Hover over me:

-webkit-transform: rotateY(45deg);
-webkit-transform: scaleX(25deg);
-webkit-transform: translate3d(0, 0, 90deg);
-webkit-transform: perspective(500px)
#threed-example {
  -webkit-transform: rotateZ(5deg);

  -webkit-transition: -webkit-transform 2s ease-in-out;
}
#threed-example:hover {
  -webkit-transform: rotateZ(-5deg);
}

Now press 3!

CSS

Animations

@-webkit-keyframes pulse {
 from {
   opacity: 0.0;
   font-size: 100%;
 }
 to {
   opacity: 1.0;
   font-size: 200%;
 }
}

div {
  -webkit-animation-name: pulse;
  -webkit-animation-duration: 2s;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-direction: alternate;
}

*Please make a better use of it. We don't want a new blink tag ;)

Pulse!

Nuts & Bolts

Improvements to the core platform

HTML5 Performance & Integration
JS

New Selectors

Finding elements by class (DOM API)

var el = document.getElementById('section1');
el.focus();

var els = document.getElementsByTagName('div');
els[0].focus();

var els = document.getElementsByClassName('section');
els[0].focus();

Finding elements by CSS syntax (Selectors API)

var els = document.querySelectorAll("ul li:nth-child(odd)");
var tds = document.querySelectorAll("table.test > tr > td");
var el = document.querySelector("table.test > tr > td"); // el == tds[0]
HTML JS

Custom data-* attributes

Define, store, and retrieve custom data on the DOM.

<div id="out" data-id="good" data-name="joe" data-screen-name="user1"></div>
// Add new data attributes via JS.
var el = document.querySelector('#out');
el.setAttribute('data-foo', 'bar');

var html = [];
for (var key in el.dataset) {
  html.push(key, ': ', el.dataset[key], '<br>');
}

el.innerHTML = html.join('');

Output:

id: good
name: joe
screenName: user1
foo: bar
JS

Element.classList

<div id="main" class="shadow rounded"></div>
var el = document.querySelector('#main').classList;
el.add('highlight');
el.remove('shadow');
el.toggle('highlight');

console.log(el.contains('highlight')); // false
console.log(el.contains('shadow')); // false
console.log(el.classList.toString() == el.className); // true

Output:

<div id="main" class="rounded"></div>
JS

History API

link.addEventListener('click', function(event) {
  // manually add a value to the history stack
  // without making the browser load any new page
  history.pushState('Contact Page Form', 'Contact Page', '/contact');
});

// capture navigation in case we want to change,
// for instance, some content when it changes
window.addEventListener('popstate', function(event) {
  document.querySelector('h1').innerHTML = event.state; // 'Contact Page Form'
});

See it today?

  • Modern Browsers
  • Mobile Browsers
  • Chrome extensions/Firefox Jetpack/Safari extensions

Chrome Frame

  • Minimal effort for bringing IE6, 7 and 8 up to the latest HTML5 technologies
  • Two ways to get your websites ready for Chrome Frame:

Client side:

<meta http-equiv="X-UA-Compatible" content="chrome=1">

Server side:

X-UA-Compatible: chrome=1

Try to load this presentation in IE!

HTML5 ~= HTML + CSS + JS

HTML5 = Next Generation Features for Modern Web Development