HTML5, CSS3 and other fancy buzzwords Bringing sexy back to the mobile web.

Post on 29-Mar-2015

222 views 2 download

Tags:

Transcript of HTML5, CSS3 and other fancy buzzwords Bringing sexy back to the mobile web.

Bringing sexy back to the mobile web

Mohammad (Mo) Jangda

batmoo@gmail.commohammad.jangda@vortexmobile.ca

http://digitalize.ca@mjangda

Move over Jesse James Garret!

We've found the new AJAX!

• HTML4 all grown up?

• xHTML's way cooler cousin?

• 5 Highly Trained Militant Lemurs?

Steve JobsInventor of HTML5

HTML

CSS

JavaScript

Semantics

Forms

Geolocation

Offline

Presentation

StylingTransformsAnimations

Rich MediaAudioVideo

Canvas

Minus some legitimate & illegitimate cousins...

Web Workers

Web Sockets

Storage

Good markup is healthy markup.

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.

APIs that help us build more powerful, feature-rich mobile webapps.

Helping bridge the gap between native and web.

•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

CO

DE

<video src=“movie.mp4” />

<audio src=“sound.wav” />

Simple

CO

DE

<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

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)

CO

DE

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

<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

CO

DE

CSS3: Rounded Corners

<div class=“rounded”>This is content

</div>

<style type=“text/css”>.rounded {

border-radius: 5px;border: 1px solid #111;

}</style>

Yes, we just went from 3 billion lines of code...

...to just under 10.

Rounded corners:border-radius

Drop shadows: box-shadow & text-shadow

Multiple columns:column-count & column-gap

Transparent backgrounds:rgba

Multiple backgrounds

Background gradients

border-radius

-moz-border-radius (for Fennec / FF)-o-border-radius (for Opera Mobile)-webkit-border-radius (in Mobile Safari, Android, webOS, BB6)-ms-border-radius (in IE Mobile)

Well, close enough.

Attribute pattern-matching

starts with[rel^=”awesome”]

ends with[title$=”amazing”]

contains[name*=”super”]

Element matching

nth-childnth-child(odd) nth-child(2) nth-child(2n)

nth-last-childsame as above, except working backwards

not:not(input)

and a whole bunch of others...

#Box1#Box1

Meet Mr. Box.

#Box1

#Box1

Feelin’ Tipsy, Mr. Box?

#Box1 { transform: rotate(45deg);}

#Box1#Box1

Feelin’ Out of Place, Mr. Box?

#Box1 { transform: translate(10px, 10px);}

#Box1#Box1

#Box1#Box1

Feelin’ (Vertically) Out of Place, Mr. Box?

#Box1 { transform: translateY(10px);}

#Box1#Box1

#Box1#Box1

Feelin’ (Horizontally) Out of Place, Mr. Box?

#Box1 { transform: translateX(10px);}

#Box1#Box1

Feelin’ a little bloated, Mr. Box?

#Box1 { transform: scale(2);}

#Box1#Box1

Feelin’ weak, Mr. Box?

#Box1 { transform: scale(0.5);}

#Box#Box11

#Box1#Box1

How’s the weather up there, Mr. Box?

#Box1 { transform: scaleY(2);}

Ate too much, Mr. Box?

#Box1 { transform: scaleX(2);}

#Box1#Box1

View (a)skew , Mr. Box?

#Box1 { transform: skew(-30deg, 30deg);}

iPhone-only at this point.(though, possibly BlackBerry 6 as well)

Transform in Z-space using Z properties.

scaleZrotateZ

rotate3DtranslateZ

CSS animations are smoother, faster, and require far less code.

And just for kicks, we’ll throw in some hardware acceleration

too.

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: 0Can 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:

linearease-in

ease-outease-in-out

cubic-bezier (custom-defined)

CO

DE

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 transition-ready?

(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 beforeanimation-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.

#Box2#Box2#Box1#Box1

Remember Mr. Box?Say Hello to Mrs. Box.

#Box2#Box2#Box1#Box1

Let’s get animating!

#Box2#Box2#Box1#Box1

Flip horizontally

transform: rotateY(180deg);

#Box2#Box2#Box1#Box1

Re-position and wrap

position: absolute;

#Container#Container

position: relative;

#Container#Container

Box 2Box 2#Box1#Box1

Enable 3D animation

#container { transform-style: preserve-3d; transition: transform 1s;}

#Container#Container

Box 2Box 2#Box1#Box1

#Container#Container

#Box1#Box1

Get flippy

#container:hover { transform: rotateY(180deg);}

#Box2#Box2

#Container#Container

Box 2Box 2#Box1#Box1

#container.flipped { transform: rotateY(180deg);}

<div id=”container” onclick=”this.className = ‘flipped’”>...</div>

Because :hover and mobile don’t always get along...

A blank slate with which you can do (almost) anything:

- create elements, shapes, lines, images, 3D things, text.- modify them- animate them- etc.

CO

DE

if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(success, error);

} else {alert('Your device doesn\'t support HTML5 geolocation');

}

CO

DE

function success( position ) {alert( 'Latitude: ' + position.coords.latitude );alert( 'Longitude: ' + position.coords.longitude );// position exposes other properties as well:// timestamp, accuracy, heading, altitude, etc.

}

CO

DE

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?

CO

DE

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.

}

// Stop stalkingclearWatch(watch);

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

Let’s Map It

CO

DE

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

</script>

Initialize the map

CO

DE

Add User’s Location to the map

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

Let’s Geocode It.

CO

DE

Client-side

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

}}

);

Connect with any of the 3 trillion Location-based APIs out there.

Cache for storing HTML,

CSS, JS required for offline usage.

Cache for storing data.

3 flavours:

sessionStoragelocalStorage

Web SQL

(and a few other types being cooked up for the

future...)

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.

CO

DE

<!DOCTYPE HTML><html manifest="offline-manifest">

CACHE MANIFESTindex.htmlhelp.htmlstyle/main.cssimages/logo.pngimages/cupcakes.png

Specify the manifest file

offline-manifest file

sessionStorage.haveMessage = true;

localStorage.messages = [ ‘Hello World’ , ‘Goodbye World’]

Window 1

Window 2

sessionStorage.haveMessage=> truelocalStorage.messages=> [ ‘Hello World’, ‘Goodbye World’ ]

Window 1

Window 2

sessionStorage.haveMessage=> nulllocalStorage.messages=> [ ‘Hello World’, ‘Goodbye World’ ]

Full-fledged SQLLite database in the browser!

CO

DE

// Basic API methods

db = openDatabase( name, version );

db.transaction( callback );

transaction.executeSql( sql, values, success, error );

CO

DE

// Create database connection// @params: name, version, display name, size in bytes var db = openDatabase('bakery', '1.0', 'My Bakery', 1048576);

CO

DE

// Create tabledb.transaction(function(trans) { trans.executeSql('CREATE TABLE IF NOT EXISTS Cupcakes (name TEXT, description TEXT)', []);});

CO

DE

// Add entriesdb.transaction(function(trans) {

trans.executeSql('INSERT INTO Cupcakes VALUES (?, ?)', ['Vanilla', 'Good ol vanilla!']); trans.executeSql('INSERT INTO Cupcakes VALUES (?, ?)', ['Chocolate', 'Good ol chocolate!']);});

CO

DE

// Select entriesdb.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: CupcakelocalStorage: Slice of cake

Web SQL: Multi-tiered wedding cake

(Though, the last two can vary depending on your views on SQL / noSQL)

Gmail Web SQL databaseRecent messages are pre-fetched. Certain data (labels)

is pre-fetched. Requires force refresh for update.

YouTube localStorageCaches AJAX requests, search history, user actions, etc.

window.onhashchange / pushState

Build true event-driven, dyanmic sites with solid back button support and fragement

urls.

data-attributes

Store data as attributes within DOM Elements.

CO

DE

<a data-flavour=”chocolate”>Cupcake!</a>

(Accessed via element.dataset.flavour => chocolate)

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(<video>)

Because only nerds build everything from

scratch.

iUI

jQTouch

SenchaTouch

SproutCore

jQuery Mobile

processing.js

raphael.jsgeolocation (with fallbacks)

jQuery.animate + CSS3 Animationspersistence.js (with fallback to Gears)

’Hardware access?

Notifications?Mind control?

Mohammad JangdaVortex Mobile

batmoo@gmail.commohammad.jangda@vortexmobile.ca

http://digitalize.ca@mjangda