Loading...

This presentation is an HTML5 website

This deck was last updated mid-2011. While the basics of HTML5 remain the same, many newer APIs are available, and a few APIs have changed during the standardization process. See HTML5 Rocks for up-to-date information. ~February 2014

Press key to advance.

Having issues seeing the presentation? Read the disclaimer

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');

Save text value on the client side (crash-safe)

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);
});

See the generated database: Developer > Developer Tools > Storage

    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:
    *
    

    Turn off your internet connection and refresh this page!

    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);
      }
    );
    Default (Temporary)Quota Requested (Persistent)
    Web Storage5MbN/A
    App Cache10% of available disk in total
    Used: -- BytesRemaining: -- Bytes
    IndexedDB
    WebSQL
    File System APIArbitrary
    in Bytes Used: -- Bytes

    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);
    };
    

    Loading Route...

    Try dragging the map while the complex route is being calculated (you will only be able to do that with Workers!)

    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'); }
    

    Full-duplex, bi-directional communication over the Web: Both the server and client can send data at any time, or even at the same time. Only the data itself is sent, without the overhead of HTTP headers, dramatically reducing bandwidth.

    Use the echo demo below to test a WebSocket connection from your browser. Both the message you send and the response you receive travel over the same WebSocket connection.

    Location:



    Message:

    Output:
    Demo powered by
    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();
    }
    

    Note: Use this button if you also want to reset the permissions


    Enter your twitter user name to show your last tweet as a notification

    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);
    
    1. Select text and drag (original text will be dropped)
    2. Select text and drag (dragged text data will be altered from original)
    Source Data
    Drop Area
    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);
    
    Drop in images from your desktop
    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);
    }
    
    Drag each of these files onto your desktop: .pdf file .mp3 file

    ( this feature is only available in Google Chrome )

    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);
    

    ( The FileSystem API is currently only implemented in Google Chrome 9+ )

    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);
    

    This sample requires FF3.6+ or Google Chrome on a device with a built in accelerometer or iOS 4.2.

    HTML

    Speech Input

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

    Speech input is not enabled in your browser.
    Try running Google Chrome with the --enable-speech-input flag.

    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;
    }
    
    close: 'ENTER' or 'ESC'
    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;
    }
    
    Row 1
    Row 2
    Row 3
    Row 4

    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';
    }
    LeagueGothic font with no image replacement
    CSS

    Text wrapping

    div {
      text-overflow: ellipsis;
    }
    A long cold winter delayed the blossoming of the millions of cherry, apricot, peach, and prune plum trees covering hundreds of square miles of the Valley floor. Then, unlike many years, the rains that followed were light and too early to knock the blossoms from their branches.
    A long cold winter delayed the blossoming of the millions of cherry, apricot, peach, and prune plum trees covering hundreds of square miles of the Valley floor. Then, unlike many years, the rains that followed were light and too early to knock the blossoms from their branches.
    A long cold winter delayed the blossoming of the millions of cherry, apricot, peach, and prune plum trees covering hundreds of square miles of the Valley floor. Then, unlike many years, the rains that followed were light and too early to knock the blossoms from their branches.

    Play with the slider on this and further pages!

    CSS

    Columns

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

    In March 1936, an unusual confluence of forces occurred in Santa Clara County.

    A long cold winter delayed the blossoming of the millions of cherry, apricot, peach, and prune plum trees covering hundreds of square miles of the Valley floor. Then, unlike many years, the rains that followed were light and too early to knock the blossoms from their branches.

    Instead, by the billions, they all burst open at once. Seemingly overnight, the ocean of green that was the Valley turned into a low, soft, dizzyingly perfumed cloud of pink and white. Uncounted bees and yellow jackets, newly born, raced out of their hives and holes, overwhelmed by this impossible banquet.

    Then came the wind.

    It roared off the Pacific Ocean, through the nearly uninhabited passes of the Santa Cruz Mountains and then, flattening out, poured down into the great alluvial plains of the Valley. A tidal bore of warm air, it tore along the columns of trees, ripped the blossoms apart and carried them off in a fluttering flood of petals like foam rolling up a beach.

    This perfumed blizzard hit Stevens Creek Boulevard, a two-lane road with a streetcar line down its center, that was the main road in the West Valley. It froze traffic, as drivers found themselves lost in a soft, muted whiteout. Only the streetcar, its path predetermined, passed on...

    CSS

    Text stroke

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

    Opacity

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

    Hue/saturation/luminance color

    color: hsla(
      128 
      74% 
      33% 
      1.00 
            
    HSL example
    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;
    Shadows example
    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)));
    
    Web 2.0 Logo Creatr
    CSS

    Background enhancements

    Background sizing

    #logo {
      background: url(logo.gif) center center no-repeat;
      background-size:
        ;
    }
    

    Resize me! »

    Multiple backgrounds

    div {
      background: url(src/zippy-plus.png) 10px center no-repeat,
                  url(src/gray_lines_bg.png) 0 center repeat-x;
    }
                
    Test
    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