HTML5, CSS3 and other fancy buzzwords Bringing sexy back to the mobile web hats Mohammad (Mo) Jangda batmoo@gmail.com mohammad.jangda@vortexmobile.ca http://digitalize.ca @mjangda HTML5 Move over Jesse James Garret! We've found the new AJAX! hat exactly is an HTML5 • HTML4 all grown up? • xHTML's way cooler cousin? • 5 Highly Trained Militant Lemurs? Steve Jobs Inventor of HTML5 a a bit of HTML + a dash of CSS + whole srinkling JavaScript of Family Semantics Geolocation Forms Offline Presentatio n Storage StylingTransformsAni mations Rich Media Audio Video Canvas Web Workers Web Sockets Minus some legitimate & illegitimate cousins... So what does HTML5 give us Strong Semantics Good markup is healthy markup. Richness without cost Add all the whiz, bang, and fireworks without having to rely on 3rd party libraries and plugins. Stuff that took images and extra markup and hours to perfect, now available through a CSS property or two. New levels of interactivi ty APIs that help us build more powerful, feature-rich mobile webapps. Helping bridge the gap between native and web. hats it mean for the Mobile • It's finally growing up • WebApps are better, smarter, sexier • WebApps can do more with less • WebApps can do the same, if not more than Native Apps <audio> & <video> <video src=“movie.mp4” /> <audio src=“sound.wav” /> CODE Simple CODE <video width=”320” height=”240” poster=”poster.png”> <source src="video.m4v" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /> <source src="video.webm" type='video/webm; codecs="vp8, vorbis"' /> <source src="video.ogv" type='video/ogg; codecs="theora, vorbis"' /> <object> <!-- Add Flash fallback here --> <!-- Be nice to really dumb devices --> <p>Download the <a href="video.mp4">video</a></p> </object> </video> Advanced Desktos have all the fun! Player is customizable and programmatically accessible through javascript (i.e. play, pause, etc.) Not the case on mobile devices (iPad excluded) Most devices offload audio and video playback to their native media players...which is a good thing • Oh, and support kinda sucks... •• YAUFW! (Yet Another Unnecessary Format War) CSS3 Styling <div class="qzForm roundedcornr_box_812460"> <div class="roundedcornr_top_812460"> <div></div> </div> <div class="roundedcornr_content_812460"> Your content goes here! </div> <div class="roundedcornr_bottom_812460"> <div></div> </div> </div> CODE <style> /* Rounded corner for registration tab */ .roundedcornr_box_812460 { background: url(../images/rounded/roundedcornr_812460_tl.png) no-repeat top left; } .roundedcornr_top_812460 { background: url(../images/rounded/roundedcornr_812460_tr.png) no-repeat top right; } .roundedcornr_bottom_812460 { background: url(../images/rounded/roundedcornr_812460_bl.png) no-repeat bottom left; } .roundedcornr_bottom_812460 div { background: url(../images/rounded/roundedcornr_812460_br.png) no-repeat bottom right; } .roundedcornr_content_812460 { background: url(../images/rounded/roundedcornr_812460_r.png) top right repeat-y; } .roundedcornr_top_812460 div,.roundedcornr_top_812460, .roundedcornr_bottom_812460 div, .roundedcornr_bottom_812460 { width: 100%; height: 15px; font-size: 1px; } .roundedcornr_content_812460, .roundedcornr_bottom_812460 { /*margin-top: -19px;*/ } .roundedcornr_content_812460 { padding: 0 15px; } </style> Pre-CSS3: Rounded Corners <div class=“rounded”> This is content </div> CODE <style type=“text/css”> .rounded { border-radius: 5px; border: 1px solid #111; } </style> CSS3: Rounded Corners Amazing! Yes, we just went from 3 billion lines of code... ...to just under 10. Some of the fancy newcorners: roerties: Rounded border-radius Drop shadows: box-shadow & text-shadow Multiple columns: column-count & column-gap Transparent backgrounds: rgba Multiple backgrounds Background gradients Because CSS3 is not yet a finalized sec, base roerties dont work in most browsers. Instead, you have to use the rorietary refix for each browser. • border-radius -moz-border-radius (for Fennec / FF)o-border-radius (for Opera Mobile)webkit-border-radius (in Mobile Safari, Android, webOS, BB6)-msborder-radius (in IE Mobile) CSS3 Selectors Full of sizzle-y goodness. Well, close enough. Attribute pattern-matching starts with [rel^=”awesome”] ends with [title$=”amazing”] contains [name*=”super”] Element matching nth-child(odd) nth-child nth-child(2) nth-child(2n) nth-last-child same as above, except working backwards not :not(input) and a whole bunch of others... CSS3 Transforms #Box1 Meet Mr. Box. Feelin’ Tipsy, Mr. Box? #Box1 { transform: rotate(45deg); } #Box1 #Box1 Feelin’ Out of Place, Mr. Box? #Box1 { transform: translate(10px, 10px); } #Box1 #Box1 Feelin’ (Vertically) Out of Place, Mr. Box? #Box1 { transform: translateY(10px); } #Box1 #Box1 Feelin’ (Horizontally) Out of Place, Mr. Box? #Box1 { transform: translateX(10px); } #Box1 Feelin’ a little bloated, Mr. Box? #Box1 { transform: scale(2); } #Box1 Feelin’ weak, Mr. Box? #Box1 { transform: scale(0.5); } #Box1 #Box1 How’s the weather up there, Mr. Box? #Box1 { transform: scaleY(2); } Ate too much, Mr. Box? #Box1 { transform: scaleX(2); } View (a)skew , Mr. Box? #Box1 { transform: skew(-30deg, 30deg); } hat about those cool 3D transforms in Toy Story iPhone-only at this point. (though, possibly BlackBerry 6 as well) Transform in Z-space using Z properties. scaleZ rotateZ rotate3D translateZ Are images dead nlikely. CSS3 Transition & Animation JavaScrit animations on mobile devices are ainful. Like first-crushditching-you-foryour-best-friendbecause-he-has-anewer-bike ainful. CSS animations are smoother, faster, and require far less code. And just for kicks, we’ll throw in some hardware acceleration too. As simle as adding a single roerty! transition: 1s; Whenever a property for the transition-ready element changes, the browser auto-tweens the element for you! #container { transition: 1s; } #container:hover { opacity: 0.4 } Transition Properties Which properties should be animated? transition-property: color; default: all How long should the transition take? transition-duration: 1s; default: 0, which means no animation. Required! Should we wait a bit before starting? transition-delay: 0.5s; default: 0 Can be negative. Will start as if pre-animated. Transition Properties (cont’d) Which timing curve should we use? transition-timing-function: ease-out; default: ease Other values: linear ease-in ease-out ease-in-out cubic-bezier (custom-defined) CODE Feeling lazy? Shorthand it. p{ transition: color 1s ease-in 2s;} Might change to: p{ transition: color 1s/2s ease-in;} Want to make everything transitionready? (though, probably a bad idea) *{ transition: 1s;} Whenever possible, use classes instead of direct CSS manipulation. Generally yields better performance. What about complex animations? Combine multiple transitions! Define tween checkpoints and the properties to be changed at each. #box1.animated { animation-name: goCrazy } @keyframes goCrazy { 0% { } 33% { left: 200px; } 66% { -webkit-transform: rotate(-90deg); } 100% { -webkit-transform: scale(2); opacity: 0; }} Animation Properties Same as before animation-duration: 1s; animation-delay: 0.5s; animation-timing-function: ease-out; Which direction should animations run? animation-direction: alternate; default: normal; Which direction should animations run? animation-iteration-count: 4; default: 1; Use infinite for a never-ending loop. Lets walk through simle 3D animation... a #Box1 #Box2 Remember Mr. Box? Say Hello to Mrs. Box. #Box1 #Box2 Let’s get animating! #Box1 #Box2 Flip horizontally transform: rotateY(180deg); position: relative; #Container #Box1 #Box2 Re-position and wrap position: absolute; #Container #Box1 Box 2 Enable 3D animation #container { transform-style: preserve-3d; transition: transform 1s; } #Container #Box1 Box 2 #Container #Box1 #Box2 Get flippy #container:hover { transform: rotateY(180deg); } #Container #Box1 Box 2 Because :hover and mobile don’t always get along... #container.flipped { transform: rotateY(180deg); } <div id=”container” onclick=”this.className = ‘flipped’”> ... </div> http://www.paulrhayes.com/experiments/cube3d/index.html Canvas Exactly what it sounds like A blank slate with which you can do (almost) anything: - create elements, shapes, lines, images, 3D things, text. - modify them - animate them - etc. Geolocation CODE if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(success, error); } else { alert('Your device doesn\'t support HTML5 geolocation'); } CODE function success( position ) { alert( 'Latitude: ' + position.coords.latitude ); alert( 'Longitude: ' + position.coords.longitude ); // position exposes other properties as well: // timestamp, accuracy, heading, altitude, etc. } CODE function error( error ) { alert( 'Sorry, we could\’nt figure out your location!' ); console.error( 'Error', error.code, error.message ); // error codes: // 1: location permission denied // 2: location fetch failed // 3: timeout // 0: unknown } • Not quite stalker-ish enough for you? if(navigator.geolocation) { watch = navigator.geolocation.watchPosition( success ); // Callback triggered whenever position changes // Success callback could add a point to a map // Or refresh a list of nearby locations // Etc. } CODE // Stop stalking clearWatch(watch); sers always have to allow access to their location first. Stalking Best Practices Always provide a fallback! IP location can suck. GPSes are awesome, but satellites can have bad days. Have an [edit location] button AND manual entry So, what can we do with Location Let’s Map It <div id="map"> </div> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> <script> function initMap(id) { var mapOptions = { center: new google.maps.LatLng(0, 0), zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP }; return new google.maps.Map(document.getElementById(id), mapOptions); } var map = initMap('map'); CODE </script> Initialize the map CODE <script> function mapPosition(map, lat, lng) { var position = new google.maps.LatLng(lat, lng); markerOptions = { position: position, map: map }; var marker = new google.maps.Marker(markerOptions); map.setCenter(position); return marker; } if(navigator.geolocation) { navigator.geolocation.getCurrentPosition( function( position ) { mapPosition(map, position.coords.latitude, position.coords.longitude ); }, function( error ) { alert(error.message); } ); } </script> Add User’s Location to the map Let’s Geocode It. CODE http://maps.google.com/maps/api/geocode/jso n?latlng=40.714224,-73.961452&sensor=false Server-side (need proxy) CODE new google.maps.Geocoder(); geocoder.geocode( { 'latLng': new google.maps.LatLng(lat, lng) }, function(results, status) { for( var i = 0; i < data.results.length; i++ ) { var result = results[i]; if(result.types[0] == 'locality' && result.types[1] == 'political') { alert('Your city: ' + result.formatted_address); } } } ); Client-side Connect with any of the 3 trillion Location-based APIs out there. Offline Manifes t Cache for storing HTML, CSS, JS required for offline usage. Storage Cache for storing data. 3 flavours: sessionStorage localStorage Web SQL (and a few other types being cooked up for the future...) Beyond just for "I'm going underground" scenarios. Pre-loading of content improves speed and prevents repeated roundtrips to server. Cache heavy or unique data loads that are unlikely to change, e.g. location information, favourites, etc. Specify the manifest file <!DOCTYPE HTML> <html manifest="offline-manifest"> offline-manifest file CODE CACHE MANIFEST index.html help.html style/main.css images/logo.png images/cupcakes.png sessionStorage.haveMessage = true; Window 1 Window 2 localStorage.messages = [ ‘Hello World’ , ‘Goodbye World’ ] Window 1 Window 2 sessionStorage.haveMessage => true localStorage.messages => [ ‘Hello World’, ‘Goodbye World’ ] sessionStorage.haveMessage => null localStorage.messages => [ ‘Hello World’, ‘Goodbye World’ ] eb SQL Full-fledged SQLLite database in the browser! // Basic API methods db = openDatabase( name, version ); db.transaction( callback ); CODE transaction.executeSql( sql, values, success, error ); CODE // Create database connection // @params: name, version, display name, size in bytes var db = openDatabase('bakery', '1.0', 'My Bakery', 1048576); CODE // Create table db.transaction(function(trans) { trans.executeSql('CREATE TABLE IF NOT EXISTS Cupcakes (name TEXT, description TEXT)', []); }); CODE // Add entries db.transaction(function(trans) { trans.executeSql('INSERT INTO Cupcakes VALUES (?, ?)', ['Vanilla', 'Good ol vanilla!']); trans.executeSql('INSERT INTO Cupcakes VALUES (?, ?)', ['Chocolate', 'Good ol chocolate!']); }); CODE // Select entries db.transaction(function(trans) { trans.executeSql(‘SELECT * FROM Cupcakes’, [], function(trans, results) { for(var i = 0; i < results.rows.length; i++) { var cupcake = results.rows.item(i); document.getElement('cupcakes').innerHTML += '<li>' + cupcake.name + ':</strong> ' + cucpake.description + '</li>'; } alert('We\'ve got ' + results.rows.length + ' cupcake(s)'); }); }); sessionStorage vs. localStorage vs. eb SQL Deends on the secificity and comlexity of your use cases. sessionStorage: Cupcake localStorage: Slice of cake Web SQL: Multi-tiered wedding cake (Though, the last two can vary depending on your views on SQL / noSQL) Storage in the ild Gmail Web SQL database Recent messages are pre-fetched. Certain data (labels) is prefetched. Requires force refresh for update. YouTube localStorage Caches AJAX requests, search history, user actions, etc. Sundry Cool Stuff #1 window.onhashchange / pushState Build true event-driven, dyanmic sites with solid back button support and fragement urls. Sundry Cool Stuff #2 data-attributes Store data as attributes within DOM Elements. <a data-flavour=”chocolate”>Cupcake!</a> CODE (Accessed via element.dataset.flavour => chocolate) se Case: eather ebA Get User Location (geolocation) Store Favourite Cities (localStorage) Pre-fetch long-term forecast (Web SQL) Weather Trends Graphs (Canvas) Eye Candy (CSS3 transitions / animations) Video Weather Report Tools of the Trade Because only nerds build everything from scratch. iUI jQTouch SenchaTouch SproutCore jQuery Mobile Numerous other libraries processing.js raphael.js geolocation (with fallbacks) jQuery.animate + CSS3 Animations persistence.js (with fallback to Gears) And, one more thing: Enhance Progressivel y! hats Next Hardware access? Notifications? Mind control? Thank You! Mohammad Jangda Vortex Mobile batmoo@gmail.com mohammad.jangda@vortexmobile.ca http://digitalize.ca @mjangda