Mozilla

Web Developers Articles

Sort by:

View:

  1. The Web Developer Toolbox: ThreeJS

    This is the second of a series of articles dedicated to the useful libraries that all web developers should have in their toolbox. The intent is to show you what those libraries can do and help you to use them at their best. This second article is dedicated to the ThreeJS library.

    Introduction

    ThreeJS is a library originally written by Ricardo Cabello Miguel aka “Mr. Doob“.

    This library makes WebGL accessible to common human beings. WebGL is a powerful API to manipulate 3D environments. This web technology is standardized by the Kronos group and Firefox, Chrome and Opera now implement it as a 3D context for the HTML canvas tag. WebGL is basically a web version of another standard : OpenGL ES 2.0. As a consequence, this API is a “low level” API that require skills and knowledge beyond what web designers are used to. That’s where ThreeJS comes into play. ThreeJS gives web developers access to the power of WebGL without all the knowledge required by the underlying API.

    Basic usage

    The library has good documentation with many examples. You’ll notice that some parts of the documentation are not complete yet (feel free to help). However, the library and examples source code are very well structured, so do not hesitate to read the source.

    Even though ThreeJS simplifies many things, you still have to be comfortable with some basic 3D concepts. Basically, ThreeJS uses the following concepts:

    1. The scene: the place where all 3D objects will be placed and manipulated in a 3D space.
    2. The camera: a special 3D object that will define the rendering point of view as well as the type of spatial rendering (perspective or isometric)
    3. The renderer: the object in charge of using the scene and the camera to render your 3D image.

    Within the scene, you will have several 3D objects which can be of the following types:

    • A mesh: A mesh is an object made of a geometry (the shape of your object) and a material (its colors and texture)
    • A light point: A special object that defines a light source to highlight all your meshes.
    • A camera, as described above.

    The following example will draw a simple wireframe sphere inside an HTML element with the id “myPlanet”.

    /**
     * First, let's prepare some context
     */
     
    // The WIDTH of the scene to render
    var __WIDTH__  = 400,
     
    // The HEIGHT of the scene to render
        __HEIGHT__ = 400,
     
    // The angle of the camera that will show the scene
    // It is expressed in degrees
        __ANGLE__ = 45,
     
    // The shortest distance the camera can see
        __NEAR__  = 1,
     
    // The farthest distance the camera can see
        __FAR__   = 1000
     
    // The basic hue used to color our object
        __HUE__   = 0;
     
    /**
     * To render a 3D scene, ThreeJS needs 3 elements:
     * A scene where to put all the objects
     * A camera to manage the point of view
     * A renderer place to show the result
     */
    var scene  = new THREE.Scene(), 
        camera = new THREE.PerspectiveCamera(__ANGLE__, 
                                             __WIDTH__ / __HEIGHT__, 
                                             __NEAR__, 
                                             __FAR__),
        renderer = new THREE.WebGLRenderer();
     
    /**
     * Let's prepare the scene
     */
     
    // Add the camera to the scene
    scene.add(camera);
     
    // As all objects, the camera is put at the 
    // 0,0,0 coordinate, let's pull it back a little
    camera.position.z = 300;
     
    // We need to define the size of the renderer
    renderer.setSize(__WIDTH__, __HEIGHT__);
     
    // Let's attach our rendering zone to our page
    document.getElementById("myPlanet").appendChild(renderer.domElement);
     
    /**
     * Now we are ready, we can start building our sphere
     * To do this, we need a mesh defined with:
     *  1. A geometry (a sphere) 
     *  2. A material (a color that reacts to light)
     */
    var geometry, material, mesh;
     
    // First let's build our geometry
    //
    // There are other parameters, but you basically just 
    // need to define the radius of the sphere and the 
    // number of its vertical and horizontal divisions.
    //
    // The 2 last parameters determine the number of 
    // vertices that will be produced: The more vertices you use, 
    // the smoother the form; but it will be slower to render. 
    // Make a wise choice to balance the two.
    geometry = new THREE.SphereGeometry( 100, 20, 20 );
     
    // Then, prepare our material
    var myMaterial = {
        wireframe : true,
        wireframeLinewidth : 2
    }
     
    // We just have to build the material now
    material = new THREE.MeshPhongMaterial( myMaterial );
     
    // Add some color to the material
    material.color.setHSV(__HUE__, 1, 1);
     
    // And we can build our the mesh
    mesh = new THREE.Mesh( geometry, material );
     
    // Let's add the mesh to the scene
    scene.add( mesh );
     
    /**
     * To be sure that we will see something, 
     * we need to add some light to the scene
     */
     
    // Let's create a point light
    var pointLight = new THREE.PointLight(0xFFFFFF);
     
    // and set its position
    pointLight.position.x = -100;
    pointLight.position.y = 100;
    pointLight.position.z = 400;
     
    // Now, we can add it to the scene
    scene.add( pointLight );
     
     
    // And finally, it's time to see the result
    renderer.render( scene, camera );

    And if you want to animate it (for example, make the sphere spin), it’s this easy:

    function animate() {
        // beware, you'll maybe need a shim 
        // to use requestAnimationFrame properly
        requestAnimationFrame( animate );
     
        // First, rotate the sphere
        mesh.rotation.y -= 0.003;
     
        // Then render the scene
        renderer.render( scene, camera );
    }
     
    animate();

    JSFiddle demo.

    Advanced usage

    Once you master the basics, ThreeJS provides you with some advanced tools.

    Rendering system

    As an abstraction layer, ThreeJS offer options to render a scene other than with WebGL. You can use the Canvas 2D API as well as SVG to perform your rendering. There is some difference between all these rendering contexts. The most obvious one is performance. Because WebGL is hardware accelerated, the rendering of complex scene is amazingly faster with it. On the other hand, because WebGL does not deal always well with anti-aliasing, the SVG or Canvas2D rendering can be better if you want to perform some cell-shading (cartoon-like) stuff. As a special advantage, SVG rendering gives you a full DOM tree of objects, which can be useful if you want access to those objects. It can have a high cost in term of performance (especially if you animate your scene), but it allows you to not rebuild a full retained mode graphic API.

    Mesh and particles

    ThreeJS is perfect for rendering on top of WebGL, but it is not an authoring tool. To model 3D objects, you have a choice of 3D software. Conveniently, ThreeJS is available with many scripts that make it easy to import meshes from several sources (Examples include: Blender, 3DSMax or the widely supported OBJ format).

    It’s also possible to easily deploy particle systems as well as using Fog, Matrix and custom shaders. ThreeJS also comes with a few pre-built materials: Basic, Face, Lambert, Normal, and Phong). A WebGL developer will be able to build his own on top of the library, which provide some really good helpers. Obviously, building such custom things requires really specific skills.

    Animating mesh

    If using requestAnimationFrame is the easiest way to animate a scene, ThreeJS provides a couple of useful tools to animate meshes individually: a full API to define how to animate a mesh and the ability to use “bones” to morph and change a mesh.

    Limits and precaution

    One of the biggest limitations of ThreeJS is related to WebGL. If you want to use it to render your scene, you are constrained by the limitations of this technology. You become hardware dependent. All browsers that claim to support WebGL have strong requirements in terms of hardware support. Some browsers will not render anything if they do not run with an appropriate hardware. The best way to avoid trouble is to use a library such as modernizr to switch between rendering systems based on each browser’s capabilities. However, take care when using non-WebGL rendering systems because they are limited (e.g. the Phong material is only supported in a WebGL context) and infinitely slower.

    In terms of browser support, ThreeJS supports all browsers that support WebGL, Canvas2D or SVG, which means: Firefox 3.6+, Chrome 9+, Opera 11+, Safari 5+ and even Internet Explorer 9+ if you do not use the WebGL rendering mode. If you want to rely on WebGL, the support is more limited: Firefox 4+, Chrome 9+, Opera 12+, Safari 5.1+ only. You can forget Internet Explorer (even the upcoming IE10) and almost all mobile browsers currently available.

    Conclusion

    ThreeJS drastically simplifies the process of producing 3D images directly in the browser. It gives the ability to do amazing visual effects with an easy to use API. By empowering you, it allow you to unleash your creativity.

    In conclusion, here are some cool usages of ThreeJS:

  2. The Web Developer Toolbox: Raphaël

    This is the first of a series of articles dedicated to the useful libraries that all web developers should have in their toolbox. My intent is to show you what those libraries can do and help you to use them at their best. This first article is dedicated to the Raphaël library.

    Introduction

    Raphaël is a library originally written by Dmitry Baranovskiy and is now part of Sencha Labs.

    The goal of this library is to simplify work with vector graphics on the Web. Raphaël relies on the SVG W3C Recommendation (which is well supported in all modern browsers) and falls back to the Micrsoft VML language in order to address legacy versions of Internet Explorer. It also tries to harmonize some working issues across SVG implementations such as the SVG Animations. As a consequence, Raphaël is a very nice wrapper to produce consistent kick-ass graphics all over the Web.

    Basic usage

    The library has very good documentation with many examples. Do not hesitate to use it extensively.

    The following example will draw a simple red circle inside an HTML element with the id “myPaper”.

    // the following example creates a drawing zone
    // that is 100px wide by 100px high.
    // This drawing zone is created at the top left corner
    // of the #myPaper element (or its top right corner in
    // dir="rtl" elements)
    var paper = Raphael("myPaper", 100, 100); 
     
    // The circle will have a radius of 40
    // and its center will be at coordinate 50,50
    var c = paper.circle(50, 50, 40); 
     
    // The circle will be filled with red
    // Note that the name of each element property
    // follow the SVG recommendation
    c.attr({
        fill: "#900"
    });

    Advanced usage

    Despite the fact that Raphaël reduces the possibilities offered by SVG (mainly because of the VML fallback) it allows one to perform very advanced stuff:

    • Advance Matrix transformation
    • Advance event handler
    • Cross browser animations
    • Easy drag system
    • Path intersection detection

    Raphaël is also extensible through an extension system that allows you to build custom functions.

    For example, here’s an extension to draw pie charts:

    /**
     * Pie method
     *
     * cx: x position of the rotating center of the pie
     * cy: y position of the rotating center of the pie
     * r : radius of the pie 
     * a1: angle expressed in degrees where the pie start
     * a2: angle expressed in degrees where the pie end
     */
    Raphael.fn.pie = function (cx, cy, r, a1, a2) {
        var d,
            flag = (a2 - a1) > 180; 
     
        a1 = (a1 % 360) * Math.PI / 180;
        a2 = (a2 % 360) * Math.PI / 180; 
     
        d = [
            // Setting the rotating axe of the pie
            "M", cx, cy,
     
            // Go to the start of the curve
            "l", r * Math.cos(a1), r * Math.sin(a1),
     
            // Drawing the curve to its end
            "A", r, r, "0", +flag, "1",
            cx + r * Math.cos(a2), cy + r * Math.sin(a2),
     
            // Closing the path
            "z"
        ]; 
     
        return this.path(d.join(' '));
    };

    Note: In the example above, you have to be familiar with the SVG path syntax (Raphaël will convert it to the VML syntax under the hood), but once it’s done you can reuse it as any other Raphaël primitive. Look at this extension working to draw a color wheel on jsFiddle.

    JSFiddle demo.

    Limits and precaution

    If you are not familiar with SVG and/or want to support legacy MS Internet Explorer browsers, this tool is made for you. However, it’s a JavaScript library, which means that you have to know JavaScript to use it. You cannot use SVG and ask Raphaël to parse it and interpret it (to do that, it exists other libraries).

    In terms of browser support, Raphaël gives you a large base. Raphaël currently supports Firefox 3.0+, Safari 3.0+, Chrome 5.0+, Opera 9.5+ and Internet Explorer 6.0+.

    In fact, the only browser that can not take advantage of Raphaël is the native browser for Android 1.x and 2.x (and obviously many feature phone browsers). This is due to the fact that those browsers do not support any vector language. Android starts (partially) supporting SVG with Android 3.0 so take care if you want to work with all mobile devices.

    Conclusion

    Raphaël was the first library to allow web designers and web developers to use SVG in the wild. If you want to write some nice applications without the need of the full SVG DOM API or if you have to support legacy browsers, this library will give you some power.

    In conclusion, here are some cool usages of Raphaël:

  3. Ask your HTML5 Browser Tools Questions for SXSW Panel.

    At this years “South by Southwest” (SXSW) Interactive event I’m joining Paul Irish from Google, Mike Taylor from Opera, Brandon Satron from Telerik and Javascript Developer and author Garann Means in a panel on “The State of Browser Developer Tools

    The group has a Google Moderator page where you can ask your questions in advance. Please do so.

    Not able to attend the panel at SXSW? No problem. I’ll post a collection of the questions and answer right here on Hacks sometime after the event.

  4. Q & A With Michal Biniek: HTML5 Hacker and Frequent Dev Derby Winner

    Editor’s Note: Michal Biniek is a frontend developer on the Innogames Lagoonia team, and an enthusiast of JavaScript and new web technologies like HTML5/CSS3, WebSockets, and WebRTC. Back in November, michal.b took 2nd place in the MDN Developer Derby with Rob in Soundland, a fanciful Canvas demo.

    It was the fourth time one of Michal’s demos made to the Derby finals, and it was the third time he’d placed. If you’ve been following Dev Derby since it launched last year, you might remember seeing Fly, fly! or Too Many Fish in the Sea. Congratulations Michal, we can’t wait to see your next demo! Submissions are now open for upcoming Derbies: CSS 3D transforms, Audio, and the Web Sockets API.


    Tell us about developing Rob in Soundland and where your idea came from?

    My first idea for the Canvas demo was to prepare some kind of visualization – a sound visualization which could make a nice connection between two senses – vision and hearing. I thought it would be also nice if the user could interact with the application through keyboard or mouse.

    Finally I decided to prepare a simple game with third-person view in an infinite world, where the main character – Rob – wanders through the colorful (almost psychedelic) squares which are playing different notes.

    Interesting fact is that the game doesn’t contain any external media elements like images or sounds. Everything is generated using HTML5 technologies: Images are pre-generated at the start of the game and sounds are created and played ad hoc using the Audio Data API.

    Rob in Soundland - Canvas demo screenshot

    Do you remember your first computer and your first website?

    My first computer was Elwro Junior – the Polish version of a ZX Spectrum computer (English description here). A few years later I got my first PC with a 486 25MHz processor inside and a magical ‘turbo’ button.

    My history with websites started around 1999 when I prepared a site about my hobbies – skiing and astronomy. I even put some animations using JavaScript and DHTML (a buzzword from long ago):
    Never the marquee tag ;)


    How did you get started coding and hacking?

    I started coding on ZX Spectrum in BASIC, but shortly after that I moved to Turbo Pascal on the new PC. I think it is also important that my father was an IT teacher at school – so when I had some problems with programming I could always ask him for help.

    For me, the visual is one of the most important aspects of an application. That’s why I found Delphi/C++ Builder a really nice solution for building UIs. This is also the reason why I liked HTML from the beginning – as a perfect language for UIs, which with JavaScript is much easier to run animations rather that trying to run it on forms.

    You mentioned you’re from Wroclaw, Poland, and work as a Web developer for Innogames? Do you work remotely? What tools do you use for development?

    Actually, I live in Hamburg, where I got the software developer job at Innogames half a year ago. However, I still quite often visit Wroclaw.

    I’m working in team that works on Lagoonia, one of the latest games developed by Innogames. Modern Javascript engines in browsers enable us to take full advantage of JavaScript (and new features from HTML5 like sound and canvas). We can create games which easily compete with Flash-based games without additional runtime machine!

    Lagoonia by Innogames

    I usually use Eclipse to develop JavaScript applications. I find it a quite good code editor (however sometimes slow) with code auto-completion that works quite well. For testing and debugging, I use Firebug and the built-in console in Firefox, one of the best debugging tools for web applications ever.

    Do you play online games? What games influence your work? What do you play the most these days?

    I discovered online games while I was a student. I started with FPS shooters then switched to MMORPGs like MuOnline. I think that multiplayer games are the future of gaming – it is usually much more fun to play with real players rather than against a computer.

    My current company – Innogames is also focused on online games (mainly browser games) where the most important part is cooperation with other users.

    We can still observe old games (even from the days of the ZX Spectrum) refreshed with new fancy graphics and multiplayer mode which are bestsellers nowadays. However, many indie games show us completely new concepts of games – and I think these types of games influence me the most.

    Apart from that, I really like Valve games – especially for great stories in games like Half Life/Portal universum.

    The Nyan Cat version of your August History API demo reminded us how fast memes can travel on the Internet. Tell us about Fly, fly! and how the idea came to you?

    It was quite hard to find an original idea for the usage of History API, which in my opinion is prepared especially for websites using AJAX to set up the content. However, it could also be used as a timeline for virtual travels. The initial idea for this project was a flight by plane through the different cities.
    However I found it boring and I decided to add the popular Nyan Cat – one of the most positive memes – as an optional mean of transport. This choice causes the Nyan Cat to leave a rainbow-colored contrail in the sky, instead of leaving white lines, which makes the world more colorful and friendly for people.

    In addition, everything was matched to the original concept of the demo, even the different graphics looks much better – dark background, Nyan Cat instead of a plane, and a colorful path for the journey.

    Fly, fly - History API demo

    You’ve submitted 7 Dev Derby demos since the program launched, and 4 of them have placed as finalists. Congratulations and thank you! Are you working on another demo? Any other cool projects you want to tell us about?

    Thank you! Currently I’m working on another simple game using touch events, however a project grew up a bit and I’m not sure if I’ll find enough time to finish it before the deadline.
    Zombie-kiwi-touchevents-demo screenshot

    In the meantime I’m working with my colleague Barry Nagel on our own framework for HTML5 games, which is named Machine5. The goal of this project is to find the simplest way to create stunning HTML5 games and to provide a simple and easily maintainable project structure for developers.

    Machine5 game engine


    When you think about HTML5 & new Web technologies what are you most excited about?

    I’m really glad that the Canvas element is currently widely available and I can freely use it. It is a perfect solution for simple games – and I hope soon WebGL will be also available on all browsers, because it is a great feature that allows creating fullscreen games. Using these technologies together with new audio APIs and WebSockets or WebRTC as a communication stream, we can soon expect real FPS games like Counter Strike or a less violent type of game such as Sims MMO version ;)

    Anybody else who helps on your demos? Anyone you want to mention?

    I’d like to thank to Robert Zatycki for all the brainstorms about possible ideas for games and other applications. Some concepts which we were talking about were used in games.

    And I’d also like to thank to my brothers – Paweł and Łukasz who tested carefully my demos before I released them and for their frank feedback.

    What inspired you to participate in Dev Derby? Can you say something more about Open Source, Mozilla and why you contribute?

    Before the Dev Derby contest, I’d prepared some demos for Chrome Experiments and for Opera Widgets websites. Then I got a message from John Karahalis, where he mentioned a new Mozilla project for demos especially for new technologies.

    Currently I find the MDN is one of the best resources for JavaScript. All the work done by Mozilla to contribute, prepare and promote new technologies is great and really important for the modern internet. Firefox is one of the most popular web browsers, (and in Poland the most popular!) which I think is the best example that users also appreciate Mozilla’s excellent product.

    One idea of Open Source is really important: even nowadays when almost every concept can be patented, there are still a lot of people who are open to sharing their experience with other developers without any profit. I find that sharing code can be the best way to get feedback about code quality and to get suggestions for other possible (sometimes better) solutions for an application.

  5. Mozilla’s Boot to Gecko – The Web is the Platform

    Mozilla’s Boot to Gecko (B2G) is about building a complete, standalone operating system for the open web. It aims at making web technologies the number one choice for applications on desktop and mobile, and we believe it can displace proprietary, single-vendor stacks for application development. And we have made some exciting progress that we want to share with you!

    Continued…

  6. Old tricks for new browsers – a talk at jQuery UK 2012

    Last Friday around 300 developers went to Oxford, England to attend jQuery UK and learn about all that is hot and new about their favourite JavaScript library. Imagine their surprise when I went on stage to tell them that a lot of what jQuery is used for these days doesn’t need it. If you want to learn more about the talk itself, there is a detailed report, slides and the audio recording available.

    The point I was making is that libraries like jQuery were first and foremost there to give us a level playing field as developers. We should not have to know the quirks of every browser and this is where using a library allows us to concentrate on the task at hand and not on how it will fail in 10 year old browsers.

    jQuery’s revolutionary new way of looking at web design was based on two main things: accessing the document via CSS selectors rather than the unwieldy DOM methods and chaining of JavaScript commands. jQuery then continued to make event handling and Ajax interactions easier and implemented the Easing equations to allow for slick and beautiful animations.

    However, this simplicity came with a prize: developers seem to forget a few very simple techniques that allow you to write very terse and simple to understand JavaScripts that don’t rely on jQuery. Amongst others, the most powerful ones are event delegation and assigning classes to parent elements and leave the main work to CSS.

    Event delegation

    Event Delegation means that instead of applying an event handler to each of the child elements in an element, you assign one handler to the parent element and let the browser do the rest for you. Events bubble up the DOM of a document and happen on the element you want to get and each of its parent elements. That way all you have to do is to compare with the target of the event to get the one you want to access. Say you have a to-do list in your document. All the HTML you need is:

    <ul id="todo">
      <li>Go round Mum's</li>
      <li>Get Liz back</li>
      <li>Sort life out!</li>
    </ul>

    In order to add event handlers to these list items, in jQuery beginners are tempted to do a $('#todo li').click(function(ev){...}); or – even worse – add a class to each list item and then access these. If you use event delegation all you need in JavaScript is:

    document.querySelector('#todo').addEventListener( 'click', 
      function( ev ) {
        var t = ev.target;
        if ( t.tagName === 'LI' ) {
          alert( t + t.innerHTML ); 
          ev.preventDefault();
        }
    }, false);

    Newer browsers have a querySelector and querySelectorAll method (see support here) that gives you access to DOM elements via CSS selectors – something we learned from jQuery. We use this here to access the to-do list. Then we apply an event listener for click to the list.

    We read out which element has been clicked with ev.target and compare its tagName to LI (this property is always uppercase). This means we will never execute the rest of the code when the user for example clicks on the list itself. We call preventDefault() to tell the browser not to do anything – we now take over.

    You can try this out in this fiddle or embedded below:

    JSFiddle demo.

    The benefits of event delegation is that you can now add new items without having to ever re-assign handlers. As the main click handler is on the list new items automatically will be added to the functionality. Try it out in this fiddle or embedded below:

    JSFiddle demo.

    Leaving styling and DOM traversal to CSS

    Another big use case of jQuery is to access a lot of elements at once and change their styling by manipulating their styles collection with the jQuery css() method. This is seemingly handy but is also annoying as you put styling information in your JavaScript. What if there is a rebranding later on? Where do people find the colours to change? It is a much simpler to add a class to the element in question and leave the rest to CSS. If you think about it, a lot of times we repeat the same CSS selectors in jQuery and the style document. Seems redundant.

    Adding and removing classes in the past was a bit of a nightmare. The way to do it was using the className property of a DOM element which contained a string. It was then up to you to find if a certain class name is in that string and to remove and add classes by adding to or using replace() on the string. Again, browsers learned from jQuery and now have a classList object (support here) that allows easy manipulation of CSS classes applied to elements. You have add(), remove(), toggle() and contains() to play with.

    This makes it dead easy to style a lot of elements and to single them out for different styling. Let’s say for example we have a content area and want to show one at a time. It is tempting to loop over the elements and do a lot of comparison, but all we really need is to assign classes and leave the rest to CSS. Say our content is a navigation pointing to articles. This works in all browsers:

    <header>
      <h1>Profit plans</h1>
    </header>
    <section id="content">
      <nav id="nav">
        <ul>
          <li><a href="#step1">Step 1: Collect Underpants</a></li>
          <li><a href="#step2">Step 2: ???</a></li>
          <li><a href="#step3">Step 3: Profit!</a></li>
        </ul>
      </nav>
      <article id="step1">
        <header><h1>Step 1: Collect Underpants</h1></header>
        <section>
          <p>
            Make sure Tweek doesn't expect anything, then steal underwear 
            and bring it to the mine.
          </p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
      <article id="step2">
        <header><h1>Step 2: ???</h1></header>
        <section>
          <p>WIP</p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
      <article id="step3">
        <header><h1>Step 3: Profit</h1></header>
        <section>
          <p>Yes, profit will come. Let's sing the underpants gnome song.</p>
        </section>
        <footer><a href="#nav">back to top</a></footer>
      </article>
    </section>

    Now in order to hide all the articles, all we do is assign a ‘js’ class to the body of the document and store the first link and first article in the content section in variables. We assign a class called ‘current’ to each of those.

    /* grab all the elements we need */
    var nav = document.querySelector( '#nav' ),
        content = document.querySelector( '#content' ),
     
    /* grab the first article and the first link */
        article = document.querySelector( '#content article' ),
        link = document.querySelector( '#nav a' );
     
    /* hide everything by applying a class called 'js' to the body */
    document.body.classList.add( 'js' );
     
    /* show the current article and link */ 
    article.classList.add( 'current' );
    link.classList.add( 'current' );

    Together with a simple CSS, this hides them all off screen:

    /* change content to be a content panel */
    .js #content {
      position: relative;
      overflow: hidden;
      min-height: 300px;
    }
     
    /* push all the articles up */
    .js #content article {
      position: absolute;
      top: -700px;
      left: 250px;
    }
    /* hide 'back to top' links */
    .js article footer {
      position: absolute;
      left: -20000px;
    }

    In this case we move the articles up. We also hide the “back to top” links as they are redundant when we hide and show the articles. To show and hide the articles all we need to do is assign a class called “current” to the one we want to show that overrides the original styling. In this case we move the article down again.

    /* keep the current article visible */
    .js #content article.current {
      top: 0;
    }

    In order to achieve that all we need to do is a simple event delegation on the navigation:

    /* event delegation for the navigation */
    nav.addEventListener( 'click', function( ev ) {
      var t = ev.target;
      if ( t.tagName === 'A' ) {
        /* remove old styles */
        link.classList.remove( 'current' );
        article.classList.remove( 'current' );
        /* get the new active link and article */
        link = t;
        article = document.querySelector( link.getAttribute( 'href' ) );
        /* show them by assigning the current class */
        link.classList.add( 'current' );
        article.classList.add( 'current' );
      }
    }, false);

    The simplicity here lies in the fact that the links already point to the elements with this IDs on them. So all we need to do is to read the href attribute of the link that was clicked.

    See the final result in this fiddle or embedded below.

    JSFiddle demo.

    Keeping the visuals in the CSS

    Mixed with CSS transitions or animations (support here), this can be made much smoother in a very simple way:

    .js #content article {
      position: absolute;
      top: -300px;
      left: 250px;
      -moz-transition: 1s;
      -webkit-transition: 1s;
      -ms-transition: 1s;
      -o-transition: 1s;
      transition: 1s;
    }

    The transition now simply goes smoothly in one second from the state without the ‘current’ class to the one with it. In our case, moving the article down. You can add more properties by editing the CSS – no need for more JavaScript. See the result in this fiddle or embedded below:

    JSFiddle demo.

    As we also toggle the current class on the link we can do more. It is simple to add visual extras like a “you are here” state by using CSS generated content with the :after selector (support here). That way you can add visual nice-to-haves without needing the generate HTML in JavaScript or resort to images.

    .js #nav a:hover:after, .js #nav a:focus:after, .js #nav a.current:after {
      content: '➭';
      position: absolute;
      right: 5px;
    }

    See the final result in this fiddle or embedded below:

    JSFiddle demo.

    The benefit of this technique is that we keep all the look and feel in CSS and make it much easier to maintain. And by using CSS transitions and animations you also leverage hardware acceleration.

    Give them a go, please?

    All of these things work across browsers we use these days and using polyfills can be made to work in old browsers, too. However, not everything is needed to be applied to old browsers. As web developers we should look ahead and not cater for outdated technology. If the things I showed above fall back to server-side solutions or page reloads in IE6, nobody is going to be the wiser. Let’s build escalator solutions – smooth when the tech works but still available as stairs when it doesn’t.

    Translations

  7. Hidden Gems of HTML5: classList

    If you are a web developer, you surely must know how handy it is to dynamically change the class attribute on an element. The benefits this technique are quite a few:

    • You leave any changes in the look and feel to the CSS
    • You avoid having to loop lots of elements as you can allow CSS to do that job for you by assigning a class on a parent element
    • You can trigger CSS transitions and avoid having to write your own animation
    • And many more…

    The issue with classes is that it is not too simple to work with because of their representation in the DOM. When you read out className you get one string and you need to split it and use regex to find if a class was used and all kind of other annoyances. This is also why it is a very common interview questions for web developers to write a function to deal with classes.

    Well, you might not be aware of it, but HTML has a very cool new way to deal with classes called classList. This makes it dead easy to add, remove, toggle and check for classes on an element – natively in your browser. You can play with it at JSFiddle:

    JSFiddle demo.

    The methods you have are all you really need:

    • element.classList.add('foo') adds the class foo to the element (if it already exists it does nothing)
    • element.classList.remove('foo') removes the class foo from the element
    • element.classList.toggle('foo') alternatively adds and removes the class foo from the element
    • element.classList.contains('foo') returns if the class is applied to the element or not
    • element.classList.toString() returns all the classes as a string (same as reading out className)

    The browser support is very good with IE being the party pooper. However, there is a polyfill by Eli Grey available for you to use.