It is high time developers take back HTML5 from the marketing people, says Chrisian Heilmann. “HTML5 is the evolution of our web technologies, not another flashy add-on to already badly used outdated practices,” he writes in a blog posting that includes illuminating slides.
Francois Laberge has a fun demonstration of creating 3d looking effects via lighting and normal mapping on 2d photos.

The demos progressively add features, from left to right lighting, to glow effects, to a multiple colored lighting extravaganza! Very nice work Francois!
Samy has put together an impressive solution to store persistent cookies on user’s computers even when they have cookies disabled. The Evercookie script reaches deep into the toolbox to fish out some very interesting and devious tricks for local storage:
- Standard HTTP Cookies
- Local Shared Objects (Flash Cookies)
- Storing cookies in RGB values of auto-generated, force-cached PNGs using HTML5 Canvas tag to read pixels (cookies) back
- Storing cookies in Web History (seriously. see FAQ)
- HTML5 Session Storage
- HTML5 Local Storage
- HTML5 Global Storage
- HTML5 Database Storage via SQLite
TODO: adding support for:
- Silverlight Isolated Storage
- HTTP ETags
- window.name caching
- Using Java to produce a unique key based off of NIC info
Pretty impressive. The only thing working around it is NOSCRIPT.
Progressive enhancement is still a confusing matter for a lot of people who are very excited about the capabilities of JavaScript in modern browser environments. It can feel anachronistic to write your solutions for a non-JS environment and then once more enhances in JavaScript. I grew up like that so for me it is a simple matter of doing the right thing but with today’s world of JavaScript libraries and out-of-the-box widgets it can seem a drag.
Enter Dav Glass of the YUI team. He’s been turning the concept of progressive enhancement around in his head and as a JS lover and backend code “endurer” he set out to solve this issue once and for all in a pure JavaScript way.
Here’s the issue: you cannot assume JS to be available on the client side as your visitors might be on a slow mobile connection or are paranoid enough to turn off JS or actually have it turned off for them by company policy or many other cases.
So in order to use pure JavaScript to render a solution that works for everybody the natural thing was to move the JS solution to the server side and re-use it on the client when it is possible.
If you say server-side JavaScript you end up quickly talking about Node.js and so did Dav.
Check out the following demo:
All of what you see is driven by JavaScript – there is no server-side PHP fallback. Yet if you turn off JavaScript in your browser, you get the same experience.
The reason is that Dav uses Express.js and Node to render the HTML of the application server-side with JavaScript and YUI3. The code is available on GitHub and a video of him giving a talk about this is available soon on the YUI blog.
This is an exciting concept as it means that we can build progressively enhancing solutions using any widget library if we just think of the server-side case, too. This can mean a lot less code and easier maintenance as the only skill needed to build bullet-proof solutions is JavaScript.
The missing piece to the puzzle though is a fully fledged DOM renderer on the server side. DOMJS works but a C++ version would be much better in terms of performance and have all the features of DOM-2.
Via HRJ (“Overworked mad genius readying to take on the world. I am his neighbor”) comes a cool puzzle piece demo written using SVG and JQuery SVG:
HRJ has some nice code. First he calls the Flickr API using JQuery and JSON and makes a JigSaw puzzle piece for each one; in the code below he is also grabbing a picture name from the #hash value in the URL if it is present:
$.getJSON(‘http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key=3cac122425cd16eaa1ea4c1b8bb3ff26&photo_id=’+specifiedHash[1]+‘&format=json&jsoncallback=?’, function(response) {
if (response.stat && response.stat == ‘ok’) {
var p = response.photo;
$.getJSON(‘http://api.flickr.com/services/rest/?method=flickr.photos.getSizes&api_key=3cac122425cd16eaa1ea4c1b8bb3ff26&photo_id=’+specifiedHash[1]+‘&format=json&jsoncallback=?’, function(response2) {
if (response2.stat && response2.stat == ‘ok’) {
updateStatus(‘Observe the tiles. Click on them to begin.’);
var medSize = response2.sizes.size[4] ? response2.sizes.size[4] : response2.sizes.size[3];
currJigsaw = new JigSaw(medSize.source, medSize.width, medSize.height, p.urls.url[0]._content, p.title._content);
var locationMatch = photoHashIgnorePattern.exec(window.location),
myLocation = locationMatch ? locationMatch[1] : window.location;
$(‘#puzzleLink’).html(‘<a href="’+myLocation+‘#photo_’+p.id+‘">Puzzle\’s link</a>’);
}
});
} else {
updateStatus(‘Error! Couldn\’t load image’);
}
});
The code that animates all the tiles when you first click on a board is interesting, using a bit of JQuery SVG:
var imgCenter = {x : width/2, y: height/2};
for (var i = tiles.length; i–;) {
$(tiles[i].sN).animate({‘svgTransform’:‘rotate(‘+[tiles[i].r,imgCenter.x, imgCenter.y].join(‘,’)+‘) translate(‘+[imgCenter.x, imgCenter.y].join(‘,’)+‘)’}, {
duration:1000,
complete : startPlay
});
}
}
Basically each of the tiles is rotated and translated over 1 second with a nice animation effect.
I’ve been doing alot of experimenting with HTML5/CSS3 on the iPhone doing animation, and I’ve been surprised with the low frame rate of animating through Canvas or SVG. If you are trying to do animation, especially 3D, on the iPhone it seems like the name of the game is to it through the GPU, and the only way to do that these days on iOS is CSS3 Animations/Transitions/3D.
These experiments caused me to stumble on Paul Hayes interesting work simulating a 3D animated cube using CSS3, hence they happen on the GPU on the iPhone/iPad and are quite fast:
A 3D cube can be created solely in CSS, with all six faces. Using JavaScript to detect key presses and update inline styles this cube can be intuitively navigated.
Paul achieves this by having each face of the cube be a unique DIV, each with a ‘face’ class and inside of a larger ‘cube’ class all wrapped by an ‘experiment’ class:
<div id=“cube”>
<div class=“face one”>
One face
</div>
<div class=“face two”>
Up, down, left, right
</div>
<div class=“face three”>
Lorem ipsum.
</div>
<div class=“face four”>
New forms of navigation are fun.
</div>
<div class=“face five”>
Rotating 3D cube
</div>
<div class=“face six”>
More content
</div>
</div>
</div>
The outer wrapper is the camera and allows you to apply perspective and where you want the perspective origin to be:
-webkit-perspective: 800;
-webkit-perspective-origin: 50% 200px;
}
The #cube itself is given a size, CSS transition properties so things will animate nicely, and an instruction to preserve 3D children and not ‘flatten’ them:
position: relative;
margin: 0 auto;
height: 400px;
width: 400px;
-webkit-transition: -webkit-transform 2s linear;
-webkit-transform-style: preserve-3d;
}
Each of the faces is given some common styling:
position: absolute;
height: 360px;
width: 360px;
padding: 20px;
background-color: rgba(50, 50, 50, 0.7);
}
The individual face DIVs are then rotated and translated in 3D space into their correct positions:
-webkit-transform: rotateX(90deg) translateZ(200px);
}
#cube .two {
-webkit-transform: translateZ(200px);
}
#cube .three {
-webkit-transform: rotateY(90deg) translateZ(200px);
}
#cube .four {
-webkit-transform: rotateY(180deg) translateZ(200px);
}
#cube .five {
-webkit-transform: rotateY(-90deg) translateZ(200px);
}
#cube .six {
-webkit-transform: rotateX(-90deg) translateZ(200px) rotate(180deg);
}
Via Phil Franks comes an interesting HTML5/CSS3 site for There Studio, which is a kind of coworking space in London:

The site itself has a number of circles with information bouncing on the screen that respond to mouse clicks and moves.
Let’s crack the site open using View Source and see how they are doing things. First, they have a repeated background with a little plus symbol with the following style rule on the <body> tag:
The textual content in each of the circles is clean semantic HTML that is search engine friendly:
To turn that into this:

The <h3> is first transformed into having an underline with the padding and margin being on the bottom:
border-bottom: 1px solid #ccc;
display: block;
font-size: 25px;
font-weight: normal;
padding: 0 0 10px;
margin: 0 0 8px;
}
JavaScript creates the circle. The script tags themselves are at the end of the HTML page at the bottom of the <body> tag, a good performance practice in general.
The heart of drawing each circle is in the createBall and createContentBall methods. If a ball will have HTML content, then the createContentBall method is used, otherwise the createBall method is used. Let’s look at the createContentBall method; we’ll break it down:
var element = document.createElement( ‘div’ );
element.className = className;
element.width = element.height = size;
element.style.position = ‘absolute’;
element.style.left = -size + ‘px’;
element.style.top = -size + ‘px’;
element.style.cursor = “default”;
canvas.appendChild(element);
elements.push( element );
var circle = document.createElement( ‘canvas’ );
circle.width = size;
circle.height = size;
if (className !==‘image’ && className !==‘image first’) {
var graphics = circle.getContext( ’2d’ );
graphics.fillStyle = color;
graphics.beginPath();
graphics.arc( size * .5, size * .5, size * .5, 0, PI2, true );
graphics.closePath();
graphics.fill();
}
element.appendChild( circle );
content = document.createElement( ‘div’ );
content.className = “content”;
content.onSelectStart = null;
content.innerHTML = html;
element.appendChild(content);
if (className !==‘image’ && className !==‘image first’ ) {
content.style.width = (size – contentPadding*2) + ‘px’;
content.style.left = (((size – content.clientWidth) / 2)) +‘px’;
content.style.top = ((size – content.clientHeight) / 2) +‘px’;
}
var b2body = new b2BodyDef();
var circle = new b2CircleDef();
circle.radius = size / 2;
circle.density = ballDensity;
circle.friction = ballFriction;
circle.restitution = ballRestitution;
b2body.AddShape(circle);
b2body.userData = {element: element};
b2body.position.Set( Math.random() * stage[2], Math.random() * (stage[3]-size) + size/2);
b2body.linearVelocity.Set( Math.random() * 200, Math.random() * 200 );
bodies.push( world.CreateBody(b2body) );
}
First, we create an absolutely positioned DIV that will house our Canvas tag:
element.className = className;
element.width = element.height = size;
element.style.position = ‘absolute’;
element.style.left = -size + ‘px’;
element.style.top = -size + ‘px’;
element.style.cursor = “default”;
canvas.appendChild(element);
elements.push( element );
Then we draw the actual circle itself using the Canvas tag and append it to our container DIV (Note that an SVG circle created programmatically could have also been used here):
circle.width = size;
circle.height = size;
if (className !==‘image’ && className !==‘image first’) {
var graphics = circle.getContext( ’2d’ );
graphics.fillStyle = color;
graphics.beginPath();
graphics.arc( size * .5, size * .5, size * .5, 0, PI2, true );
graphics.closePath();
graphics.fill();
}
element.appendChild( circle );
Then we create another DIV to house the HTML content itself:
content.className = “content”;
content.onSelectStart = null;
content.innerHTML = html;
element.appendChild(content);
if (className !==‘image’ && className !==‘image first’ ) {
content.style.width = (size – contentPadding*2) + ‘px’;
content.style.left = (((size – content.clientWidth) / 2)) +‘px’;
content.style.top = ((size – content.clientHeight) / 2) +‘px’;
}
Notice that we are setting content.onSelectStart to null above; this is so that when you run the mouse button over the text it doesn’t select (An alternative way to do this is to use the HTML pointer-events CSS property).
Next comes code to deal with the physics of the circles, which uses Box2D.js, a JavaScript physics engine ported from Flash:
var circle = new b2CircleDef();
circle.radius = size / 2;
circle.density = ballDensity;
circle.friction = ballFriction;
circle.restitution = ballRestitution;
b2body.AddShape(circle);
b2body.userData = {element: element};
b2body.position.Set( Math.random() * stage[2], Math.random() * (stage[3]-size) + size/2);
b2body.linearVelocity.Set( Math.random() * 200, Math.random() * 200 );
bodies.push( world.CreateBody(b2body) );
Basically, we define a circle, give it a radius, density, friction, and restitution, and then add it to our collection of shapes with a position and linear velocity. Box2D will then handle the physics and we can just take the values back out to draw things on the screen with a setInterval, which happens in the loop method:
delta[0] += (0 – delta[0]) * .5;
delta[1] += (0 – delta[1]) * .5;
world.m_gravity.x = 0 // -(0 + delta[0]);
world.m_gravity.y = -(100 + delta[1]);
mouseDrag();
world.Step(timeStep, iterations);
for (i = 0; i <bodies.length; i++) {
var body = bodies[i];
var element = elements[i];
element.style.left = (body.m_position0.x – (element.width>> 1)) + ‘px’;
element.style.top = (body.m_position0.y – (element.height>> 1)) + ‘px’;
if (ballRotation && element.tagName == ‘DIV’) {
var rotationStyle = ‘rotate(‘ + (body.m_rotation0 * 57.2957795) + ‘deg)’;
element.style.WebkitTransform = rotationStyle;
element.style.MozTransform = rotationStyle;
element.style.OTransform = rotationStyle;
}
}
}
This method gets called with a setInterval periodically. Basically, we apply a delta and a gravity at each time step; see if the mouse is being pressed down (with hooks for touch devices like the iPhone to see if a finger is being pressed down); tell the Box2D World about our gravity and delta and to make an iteration step; and finally use the computed physics values from Box2D to apply CSS3 rotation transforms on our parent DIV and move the element’s CSS top and left values around the screen.
Kevin Decker has upgraded his border-image generator tool. The major update is the ability to not have to host an image, but also use local ones. The tool itself is useful, but the post is very interesting as we get to listen in to the implementation process of Kevin as he got the feature working on bleeding edge browser APIs (e.g. Data URIs, the File API and the Web Storage API):
Display
The problem of displaying the image was the easiest to solve as all of the targeted browsers support data URIs as part of the border-image property. This allowed the application to generate URLs like the following
CSS:border-width: 46px;
border-image: url(“data:image/png;base64,iVBORw0KGgoAAA….”) 46 stretch;
Reading
Reading
With the actual display issue solvled, there was still the non-trivial issue of actually loading the content. My initial investigations involved Flash, which provides FileReference.load API which allowing for this functionality, but under the version I was testing on this API is only usable if invoked in response to user input. Being a HTML guy and lacking functional knowledge of the Flash development process I quickly ruled this technique out.
Continuing my research I came across an article on MDC that covered this exact use case, using the draft File API specification. This worked like a charm, even exposing the ability to read the image contents directly into a data URI.
The API is very clean for use cases such as this:
JAVASCRIPT:function loadFile(file) {
var reader = new FileReader();
reader.onload = function(event) {
updateImageURI(file.name, reader.result);
};
reader.readAsDataURL(file);
}
Where the
filevariable above is aFileobject retrieved from a <input type="file">or the
dataTransferobject passed to thedrophtml event.JAVASCRIPT:$("body").bind("dragenter dragover", function(event) {
// We have to cancel these events or we will not recieve the drop event
event.preventDefault();
event.stopPropagation();
});
$("body").bind("drop", function(event) {
event.preventDefault();
event.stopPropagation();
var dataTransfer = event.originalEvent.dataTransfer,
file = dataTransfer.files[0];
loadFile(file);
});
$("#localImage").bind("change", function(event) {
var file = this.files[0];
loadFile(file);
});
This unfortunately is not without it’s issues. The File API is very much bleeding edge at this point and support is somewhat limited. As of this writing Firefox is the only browser which features this in production (Version 3.6). Support landed in the WebKit trunk literally earlier this month and can be used in their nightlies, but so far has not made it into any production releases.
The site is currently designed to progressively enhance as it detects support for the File API, so no need to worry about being left out of the site as a whole if you are not on one of these browsers yet.
History
After loading the content using the File API, the original implementation utilized the same #hash storage method for the data URIs, but this proved to be problematic as these strings can become quite large and interacting with these URLs was unwieldily. Needing another data store and being forced to maintain a cache of all local images due to the security model employed by the File API, we were left the options of storing all data in Javascript space or using the new Web Storage APIs implemented as part of HTML5.
Examining both options it seemed the the best course was to utilize the
sessionStorageobject when available and fail over to the javascript data model when not.JAVASCRIPT:// Check for browser support of session storage and that it is accessible
// This may be inaccessible under certain contexts such as file://
function supportsSessionStorage() {
try {
return !!window.sessionStorage;
} catch (err) {
return false;
}
}
var localDataBinding = (function() {
if (supportsSessionStorage()) {
// If they support FileReader they really should support storage… but who knows (With the exception of file://)
return {
storeImage: function(name, data) {
var entryId = (parseInt(sessionStorage["imageList-count"])||0)+1;
sessionStorage["imageList-count"] = entryId;
sessionStorage["imageList-src-" + entryId] = data;
sessionStorage["imageList-display-" + entryId] = name;
return entryId;
},
getImage: function(entryId) {
return { src: sessionStorage["imageList-src-" + entryId], displayName: sessionStorage["imageList-display-" + entryId] };
}
};
} else {
// Fail over to plain js structures, meaing that refresh, etc will cause failures.
var cache = [];
return {
storeImage: function(name, data) {
cache.push({ src: data, displayName: name });
return cache.length-1;
},
getImage: function(entryId) {
return cache[entryId];
}
};
}
})();
Give the post a look through, and check out the tool itself to get those nice borders :)
I think we are seeing a new meme. Matt Nowack has taken the awesome HTML5 presentation app in HTML5, which is open source, and has created a presentation discussing jQuery 1.4.
It is good stuff, using the fact that you can embed the features that you want to show. Just as long as you can hit the right arrow to get through the “look at all the people who use jQuery” part (we get it! lots of people use jQuery!)

Salvador Diaz has taken things in another direction. He has ported the HTML5 app to GWT under the hood.
Maybe this presentation app can be the “Java Pet Store” of Ajax libraries :)
Gmail started off with the awful input type="file" “add more” typical solution that we all know and love. Then they added the ability to select multiple files via Flash…. and now they allow the ability to drag and drop files right onto the message compose using HTML5 standards.

Want to do it too? Check out the APIs and how you can do it all, including showing the thumbnails:
-
-
function handleFiles(files) {
-
for (var i = 0; i <files.length; i++) {
-
var file = files[i];
-
var imageType = /image.*/;
-
-
if (!file.type.match(imageType)) {
-
continue;
-
}
-
-
var img = document.createElement(“img”);
-
img.classList.add(“obj”);
-
img.file = file;
-
preview.appendChild(img);
-
-
var reader = new FileReader();
-
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
-
reader.readAsDataURL(file);
-
}
-
}
-
Watch the video above by Volodya Kolesnikov, the developer behind the Mail.app prototype that uses the UKI framework.
ukijs matured and I put it to the test. The idea for the test was to replicate Mac Mail.app core experience in the browser. With as much attention to details as possible and acceptable performance. The whole thing took me about 15 hours and 65kb of gziped code.
Nice work Volodya!
Geolocation functionality is hot. Every app you see now wants to ID where you’re at and help you find cool things around you. The great thing is that building this functionality into your applications is getting easier and easier. For example, Eric Ferraiuolo wanted to create an app that showed off the features in YUI 3.1 and with a little help from the JSONIP Google App Engine app, YQL, the W3C Geolocation API, Flickr Photos Search API , & CSS3, he built a Photos Around You, an app which finds geo-tagged photos based on your estimated location.
The post does a great job of breaking down the YUI modules used for building out the app and showing plenty of code samples for leveraging the various APIs. Here’s the code that handles the IP-based lookup via YQL or the browser’s geolocation capabilities:
-
-
locFromIP = function (ip, callback) {
-
var query = ‘select * from geo.places where woeid in ‘ +
-
‘(select place.woeid from flickr.places where (lat, lon) in ‘ +
-
‘(select Latitude, Longitude from ip.location where ip="{ip}"));’;
-
-
new Y.yql(Y.substitute(query, { ip: ip }), function(r){
-
callback(r.query && r.query.results ? r.query.results.place : null);
-
});
-
};
-
-
locFromPos = function (pos, callback) {
-
var pos = { lat: pos.coords.latitude, lon: pos.coords.longitude },
-
query = ‘select * from geo.places where woeid in ‘ +
-
‘(select place.woeid from flickr.places where lat={lat} and lon={lon});’;
-
-
new Y.yql(Y.substitute(query, pos), function(r){
-
callback(r.query && r.query.results ? r.query.results.place : null);
-
});
-
};
-
-
if (navigator.geolocation) {
-
navigator.geolocation.getCurrentPosition(
-
Y.rbind(locFromPos, this, callback),
-
Y.bind(getIP, this, Y.rbind(locFromIP, this, callback))
-
);
-
} else {
-
getIP(Y.rbind(locFromIP, this, callback));
-
}
-
What I really like about Eric’s code is his decision to leverage Christian Heilmann’s YQL Geo Library as a failover for those browsers that currently don’t support the W3C Geolocation API for IP-based location identification. I wasn’t quite able to get the YQL version to function for me. It did find my location but wouldn’t correctly display any geo-tagged pictures. Firefox’s geolocation implementation, which uses Google Location Services as its service provider, worked great though and that in itself is a big win. When Firefox first debuted the feature, the results seemed frequently off but it looks like the data is becoming more consistent.
Coming in at about ~180 lines of code, it’s a great tutorial app that demonstrates some nice power features of YUI 3.1 and the referenced APIs. Check it out.



