28 Jan 2012

This article discusses some experimental browser features from several talks at Fronteers 2011. Since these are experimental features it doesn't work predictably across all browsers. Try Firefox 10+ or Chrome 17+ to see it the way I intended it to work.

Showing/hiding a box of content used to require JavaScript until the introduction of the :hover pseudo class in CSS (setting a block to visible/invisible on hover, in this case). Now Bruce Lawson introduces the new HTML5 element <details>, an HTML native way to toggle content. For the moment, it only works in Chrome.

The summary for the <details> element. (Click the triangle)The code used is:

<details>
    <summary>The summary for the <details> element...</summary>
    <span>Droste effect prevention</span>
</details>

Browsers other than Chrome will simply show all the contents of the <details> element (and therefore this text) all the time.

More or less along the lines of the <details> element, Alex Russel advocates the concept of web components. While it doesn't introduce anything that can't be done with JavaScript, it offers a cleaner approach to modify the behavior of HTML elements. It is a suggestion for defining custom HTML elements, and although some browsers already support this in some way (remember Microsoft HTC files?), the WHATWG is still working on a standard, which is still very much in progress.

Alex explains that the limited support for the extensibility of HTML elements causes cross-cutting concerns; sometimes you will even end up with a nearly empty HTML document, where everything, including DOM elements, are added dynamically with JavaScript. This is for instance the way Gmail and Google Documents work. One might argue whether or not this is a bad thing, if it works for Google, but from a theoretical standpoint, at least it is not pretty.

In an earlier post I've introduced my graph JavaScript library, which also dynamically inserts a small amount of HTML elements. In my case, that is needed to overlay two canvas elements, one containing the graph and one containing the labels, to prevent having to redraw the graph every time a label needs to be shown on hover. I suppose the extensibility as suggested in web components allows the creation of a single <x-graph-canvas> custom element, that inherits from the <canvas> element and adding the functionality I now add with JavaScript.

I must stress that I support his views that it is advisable to create custom HTML elements in certain cases, and I would love to show a demo here, but the spec is not supported in any browser yet. The details of the spec can be found on the site of the WHATWG.

Alex also introduces scoped CSS, a much debated subject because of the possible impact it's lack of backwards compatibility may entail, as is mentioned on it's demo page on html5doctor.com. It would allow you to set CSS classes specific to only a part of the HTML document. For me this would be ideal, because I use Drupal* as my CMS, and for every post with crazy/weird styling I just include CSS in the top of the page, but this requires a lot of regression testing, and I am far too lazy to do that for my personal site.

Bruce Lawson also discusses the lack of semantic need for multiple levels of headings. The H1 through H6 elements were created to make a semantical hierarchy within the HTML document. By now however, it becomes apparent that this is not always as trivial as it was dreamt up to be. E.g. when syndicated content is injected into the document, which contains its own H1, it doesn't have the same meaning as the H1 in your document's header. And even within your own document, sometimes it isn't so clear when to use what level of heading. In the future, browsers are supposed to phase out this distinction and determine the hierarchy based on other clues from the document, but for now it is still advised to use H1 etc., because screenreaders and indexers will fail to figure out the hierarchy of your site, at this time.

Less experimental are the new form elements and attributes introduced by Robert Nyman, i.e. most new browsers already support them, one way or another. The required attribute on an input element within a form will prevent the form from submitting when the input doesn't contain characters, and the browser will show an error message:

The pattern attribute can be used to limit the input on a text field. On the following input element the regex "\d{3}" requires you to enter 3 digits.

But an input required validation is considered satisfied when only spaces are input (which is not always what you want), when required is used on an e-mail address, diacritics aren't allowed and when pattern is used, empty fields are valid. So guess what? UX is hard!

Unfortunately, this article is getting far too long as it is, so I'm going to refer you to Robert's slides for more details.

In my humble opinion, the most spectacular example of an experimental feature currently possible in modern browsers would be rendering 3D objects in canvas. And sure enough, upon pressing the button below, in the background of this page you will find my pièce de résistance.

I know, I'm hardly a 3D artist, and it shows. But after weeks (yes, weeks) of playing around with lighting, collision, vertices, faces and whatnot, I thought it was about time to wrap it all up, and leave you this demo. This only proves 3D can be done in the browser, making something beautiful is possible if you're skilled in 3D.

This demo uses the THREE.js JavaScript library for creating 3D scenes in canvas. I find there are some lovely demos without documentation and some good basic documentation without a demo. So I tried to play around a bit to figure out the basics myself. Eventually, I used the cube in this tutorial as the base for this demo.

All the JavaScript to handle animating the contents of the background is included in a library I wrote specifically for this demo. It is called canvallax.js, a contraction of canvas and parallax (since scrolling parallax backgrounds are so hip right now). A similar project is the jQuery plugin plax (used on the github 404 page). Although that doesn't use 3D objects, it's far more robust and flexible, making it actually fit for use.

When going into the details of the canvallax demo in the background, bear in mind that the foreground avatar, that moves around when you scroll and move the mouse, is "handcrafted". With that I mean, it's not an export from a 3D studio, I just typed in the vectors and faces myself, to get a better grasp of the 3D space. The definition is dynamically loaded from this json file (license).

The "skyline" layer is generated dynamically by a simple algorithm each page load. This algorithm draws a random path with some parameters and than extrudes this path to give it depth, a very simple way to make a 3D object.

The "stars" layer uses particle systems to render a large amount of (small) objects at once. I actually use two different approaches, because the WebGL and the default canvas renderer approach are mutually exclusive. Particle systems can also be used to generate smoke or sparks, for example.

Unlike most demos you'll see, I have added an automated switch that tries the WebGL renderer first and if that fails (because the browser or the GPU doesn't support it) falls back to the default 3D canvas renderer. If that fails you're using IE :P But seriously, even an iPad with out-of-the-box Safari is capable of running this demo with the default 3D canvas renderer, albeit at a rather low FPS rate.

The difference between the two renderers, besides the aforementioned different particle system implementations, is that WebGL uses your GPU directly, mostly resulting in higher FPS rates, but also alleviating the CPU for other tasks (source).

If the browser is running in WebGL, below a green box is displayed. If the default 3D canvas renderer is used, a red box will be displayed. If WebGL is supported, you can disable it by unchecking the "Force enable WebGL" box to see what it looks (and performs) like with the default renderer.

Force enable WebGL

This 3D demo was inspired on the talk by Seb Lee-Delisle of creativejs.com fame.

NB: Before any of you comes to me complaining the HTML for this post is not valid, I know. I have seen 3 errors, one relating to the custom CSS for this post (I do not have the intention to update my main styles for each post), one relating to a stray </p> (which I consider a validation bug), and one relating to an experimental Mozilla attribute. Other than that, let me know of any errors!

*: This was on the old version of this blog.