1. Click highlights with CSS transitions

    When you watch screencasts from time to time you’ll see that some software adds growing dots to the clicks the person explaining does to make them more obvious. Using CSS transitions this can be done very simply in JavaScript, too.
    click highlighting with CSS

    Check out the following demo on JSFiddle and you see what we mean. When you click on the document a dot grows where you clicked and it vanishes again. If you keep the mouse pressed the dot stays and you can move it around.

    Moving the dot

    The code is incredibly simple. We generate a DIV element and move it with the mouse. For this, we need JavaScript. Check the comments to see what is going on:

    (function(){
     
      // create a DIV element, give it an ID and add it
      // to the body
      var plot = document.createElement('div'),
          pressed = false;
      plot.id = 'clickhighlightplot';
      document.body.appendChild(plot);
     
      // define offset as half the width of the DIV 
      // (this is needed to put the mouse cursor in
      // its centre)
      var offset = plot.offsetWidth / 2;
     
      // when the mouse is moved and the mouse button is pressed, 
      // move the DIV to the current position of the mouse cursor
      document.addEventListener('mousemove', function(ev) {
        if (pressed) { moveplot(ev.pageX, ev.pageY); }
      }, false);
     
      // when the mouse button is pressed, add a class called 
      // 'down' to the body of the element and define pressed
      // as true. Then move the DIV to the current mouse 
      // position.
      document.addEventListener('mousedown', function(ev) {
        document.body.classList.add('down');
        pressed = true;
        moveplot(ev.pageX, ev.pageY);
      }, false);
     
      // when the mouse is released, remove the 'down' class 
      // from the body and set pressed to false
      document.addEventListener('mouseup', function(ev) {
        document.body.classList.remove('down');
        pressed = false;
      },  false);
     
      // move the DIV to x and y with the correct offset
      function moveplot(x, y) {
        plot.style.left = x - offset + 'px';
        plot.style.top = y - offset + 'px';
      }
    })();

    This takes care of creating and moving the DIV and also gives us classes on the body element to play with.

    Growing the dot

    The growing of the dot uses CSS transitions. We change the scale of the dot from 0,0 to 1,1 in a certain amount of time. Notice that we need to scale down rather than up as Webkit zooms scaled elements instead of leaving crisp outlines like Firefox does (the first iteration of this script scaled a 10×10 pixel dot upwards and looked horrible).

    #clickhighlightplot {
      cursor: pointer;
      pointer-events: none;
      background: rgba(255, 255, 10, 0.7);
      width:100px;
      height: 100px;
      position: absolute;
      border-radius: 100px;
      -webkit-transition: -webkit-transform 1s;
         -moz-transition: -moz-transform 1s;
          -ms-transition: -ms-transform 1s;
           -o-transition: -o-transform 1s;
              transition: transform 1s;
       -webkit-transform: scale(0, 0);
          -moz-transform: scale(0, 0);
           -ms-transform: scale(0, 0);
            -o-transform: scale(0, 0);
               transform: scale(0, 0);
    }
    .down #clickhighlightplot {
      -webkit-transform: scale(1, 1);
         -moz-transform: scale(1, 1);
          -ms-transform: scale(1, 1);
           -o-transform: scale(1, 1);
              transform: scale(1, 1);
    }

    Fixing the “covered clickable elements” issue

    The main annoyance with the way the script works now is that you cover elements with the growing dot making them effectively unclickable. That might not be what you want which is why we need to make sure the dot covers them but still allows for clicks to go through. The good news is that there is a thing called pointer events for that. This is supported in Firefox and Webkit but sadly enough not in IE and Opera.

    Moving from JS and CSS to pure JS (but using CSS)

    Now, whilst it is cool to be able to maintain all the look and feel in CSS, the issue is that we need to repeat all the vendor prefixes and we run into issues that browsers might not support what we want to do. That’s why sometimes it makes more sense to move the whole functionality into JavaScript as we have the chance to test support there and write less code.

    Clickhighlight.js does all that. Instead of keeping the maintenance in the CSS (and requiring you to add all the vendor prefixes) you can now have the effect by simply adding the script and calling its init() method:

    <script src="clickhighlight.js"></script>
    <script>clickhighlight.init();</script>

    Elements with the class “nohighlight” will not get the effect. You can change the look by passing an initialisation object:

    clickhighlight.init({
      size:        '300px', // the maximum size of the dot
      duration:    '2s',    // duration of the effect (seconds) 
      colour:      'green', // the dot colour - RGBA = transparency 
      nohighlight: 'notme'  // class of elements not highlighted
    });

    You can see it in action in this video on YouTube:

    The next steps could be to add touch support and to turn this into a bookmarklet so you can use it on any page. Any other ideas?

  2. WebRTC efforts underway at Mozilla!

    Last week, a small team from Mozilla attended IETF 83 in Paris, and we showed an early demo of a simple video call between two BrowserID-authenticated parties in a special build of Firefox with WebRTC support. It is still very early days for WebRTC integration in Firefox, but we’re really excited to show you something that works!

    At Mozilla Labs, we’ve been experimenting with integrating social features in the browser, and it seemed like a cool idea to combine this with WebRTC to establish a video call between two users who are signed in using BrowserID (now called Persona). The SocialAPI add-on, once installed, provides a sidebar where web content from the social service provider is rendered. In our demo social service, we show a “buddy list” of people who are currently signed in using Persona.

    The video chat page that is served when the user initiates a video chat uses a custom API intended to simulate the getUserMedia and PeerConnection APIs currently being standardized at the W3C. A <canvas> is used to render both the remote and local videos, though it is also possible to render them in a <video>. We’re working very quickly to implement the standard APIs, and you can follow our progress on the tracker bug.

    A lot of folks burned the midnight oil to get this demo ready before the IETF event, and special thanks are due to Eric Rescorla, Michael Hanson, Suhas Nandakumar, Enda Mannion, Ethan Hugg, the folks behind Spacegoo, and Randell Jesup, in addition to the whole media team here at Mozilla.

    Current development is being done on a branch of mozilla-central called alder. It is going to be an exciting few months ahead as we work towards bringing WebRTC to Firefox. There is a lot of work to do, and if you are interested in contributing, please reach out! Maire Reavy, our product person and project lead for WebRTC would be happy to help you find ways to contribute. Many of us are also usually available in IRC at #media, and we have a mailing list.

    Transcript of screencast:

    Hi, I’m Anant from Mozilla Labs and I’m here at IETF where we are demonstrating a simple video call between two BrowserID-authenticated parties, using the new WebRTC APIs that we are working on.

    This is a special build of Firefox with WebRTC support, and also has the experimental SocialAPI add-on from Mozilla Labs installed. On the right hand side you can see web content served by demosocialservice.org, to which I will sign with BrowserID. Once I’m signed in, I can see all my online friends on the sidebar. I see my friend Enda is currently online, and so I’m going to click the video chat button to initiate a call.

    Here, I see a very early prototype of a video call window served up by our demo social service. Now, I can click the Start Call button to let Enda know that I want to speak with him. Once he accepts the call, a video stream is established between the two parties as you can see. So, that was a video call built entirely using JavaScript and HTML!

    You can check out the source code for this demo, as well as learn how to contribute to the ongoing WebRTC efforts at Mozilla in this blog post. Thanks for watching!

  3. BrowserQuest – a massively multiplayer HTML5 (WebSocket + Canvas) game experiment

    It’s time for some gaming action with a new HTML5 game demo: BrowserQuest, a massively multiplayer adventure game created by Little Workshop (@glecollinet & @whatthefranck) and Mozilla.

    Play the game: browserquest.mozilla.org
    BrowserQuest

    BrowserQuest is a tribute to classic video-games with a multiplayer twist. You play as a young warrior driven by the thrill of adventure. No princess to save here, just a dangerous world filled with treasures to discover. And it’s all done in glorious HTML5 and JavaScript.

    Even better, it’s open-source so be sure to check out the source code on GitHub!

    Watch a screencast:

    A multiplayer experience

    BrowserQuest screenshot

    BrowserQuest can be played by thousands of simultaneous players, distributed across different instances of the in-game world. Click on the population counter at any time to know exactly how many total players are currently online.

    Players can see and interact with each other by using an in-game chat system. They can also team up and fight enemies together.

    BrowserQuest is a game of exploration: the more dangerous the places you go, the better the rewards.

    Powered by WebSockets

    WebSockets are a new technology enabling bi-directional communication between a browser and a server on the web.

    BrowserQuest is a demo of how this technology can be used today to create a real-time multiplayer game in a single webpage. When you start to play, your browser opens up a WebSocket connection to one of several load-balanced game servers. Each server hosts multiple world instances and handles the player synchronization and game logic within all instances. Because the server code is running on Node.js, both the server and client codebases share a small portion of the same JavaScript source code.

    Server code is available on Github.

    BrowserQuest screenshot

    Built on the Web platform

    BrowserQuest makes extensive use of different web technologies, such as:

    • HTML5 Canvas, which powers the 2D tile-based graphics engine.
    • Web workers, allowing to initialize the large world map without slowing down the homepage UI.
    • localStorage, in which the progress of your character is continually saved.
    • CSS3 Media Queries, so that the game can resize itself and adapt to many devices.
    • HTML5 audio, so you can hear that rat or skeleton die!

    Available everywhere

    Since BrowserQuest is written in HTML5/JavaScript, it is available across a lot of different browsers and platforms. The game can be played in Firefox, Chrome and Safari. With WebSockets enabled, it’s also playable in Opera. Moreover, it’s compatible with iOS devices, as well as tablets and phones running Firefox for Android.

    BrowserQuest screenshot

    The mobile versions are more experimental than the desktop experience, which has richer features and performance, but it’s an early glimpse of what kind of games will be coming to the mobile Web in the future. Give it a try with your favorite mobile device!

    Join the adventure

    Want to be part of BrowserQuest? Create your own character and venture into the world. Fight enemies by yourself or with friends to get your hands on new equipment and items. You might even stumble upon a couple of surprises along the way…

  4. Making the Dino roar – syncing audio and CSS transitions

    It started with Brian King setting up our Google+ page using this round MDN logo by John Slater. I thought this looks cool and reminded me of the famous MGM intro so I wondered if I could turn it into an intro for our video tutorials (not sure if we will do that though). And, some photoshop and sound work later and with a sprinkle of HTML5 audio and CSS transitions, here we are (source on GitHub):

    I started with the sound. If you need Creative Commons licensed sounds, Freesound is a good resource. So I took Chinese Fanfare by Nick-Nack and Roar by CGEffex and put them together in Audacity.

    Saving them as OGG and MP3 gave me an audio element that I could tie into. All I needed was to listen to the timeupdate event and compare the currentTime to trigger the animations. The animations (rotation of the dino and opening and closing of the jaw) are CSS transitions triggered by classes on the parent element. The main trick was to store both the dino and the jaw inside a div and transition them separately. The jaw animation also needed a change in transformation origin as we don’t rotate the image around its center.

    If you got seven minutes to spare, here is a blow-by-blow screencast explaining what is going on:

  5. A simple image gallery using only CSS and the :target selector

    Back in the old days of web development and when CSS2 got support I always cringed at “CSS only” demos as a lot of them were hacky to say the least. With CSS growing up and having real interaction features it seems to me though that it is time to reconsider as – when you think about it – visual effects and interactivity should be maintained in the CSS rather than in JavaScript and CSS.

    With the support we have in new browsers it would be a waste not to use what has been put in. If you have to give all the visual candy to IE6, OK, then you’d have to use a library like jQuery for your effects. But you can have your cake and eat it if you don’t give the shiny to the old browsers out there, but give them a simpler interface and make sure they don’t get what they don’t understand.

    So today let’s take a look at an image gallery using the target selector. This has been done before (lightbox example, thumbnail preview example) but I thought it’d be good to explain the details of what is going on.

    So here is a screencast of our “CSS only image gallery” in action and you can see it for yourself.

    Starting with HTML

    We start with HTML that works across all browsers (except for IE < 9, where you need a polyfill to style HTML5 elements):

    <section class="gallery">
      <nav>
        <ul>
          <li><a href="#one">One</a></li>
          <li><a href="#two">Two</a></li>
          <li><a href="#three">Three</a></li>
          <li><a href="#four">Four</a></li>
        </ul>
      </nav>
      <article id="one" class="target">
        <figure>
          <img src="http://placekitten.com/g/300/200" alt="Kitten 1">
        </figure>
      </article>
      <article id="two" class="target">
        <figure>
          <img src="http://placekitten.com/g/300/201" alt="Kitten 2">
        </figure>
      </article>
      <article id="three" class="target">
        <figure>
          <img src="http://placekitten.com/g/301/200" alt="Kitten 3">
        </figure>
      </article>
      <article id="four" class="target">
        <figure>
          <img src="http://placekitten.com/g/301/201" alt="Kitten 4">
        </figure>
      </article>
    </section>

    Without any CSS this would just show all the kitten images in a vertical row and the links would point to them. This works, and should be more than enough for the IE6 users out there.

    For browsers that support newer CSS, however, we can turn this into our gallery in a few easy steps:

    Step 1: Position the articles

    To make sure we don’t give IE older than 9 any CSS it chokes on, we can wrap all the selectors in a simple media query (in this case checking that the window is at least 400 pixels wide):

    @media screen and (min-width: 400px) {
      ... all the good stuff ...
    }

    We then can give the gallery dimensions and an overflow of hidden to make sure that elements positioned outside of it will not be shown. We also position it relative so that every positioned child element will be positioned relatively to it:

    .gallery {
      position: relative;
      height: 280px;
      width: 340px;
      overflow: hidden;
    }

    Then we position all the target elements absolutely in the gallery with 320 pixels to the left. This hides them off screen as we hide the overflow:

    .target {
      position: absolute;
      top: 60px;
      left: -320px;
      height: 220px;
      width: 300px;
    }

    Now in order to show the image when the link to it was clicked we use the :target selector. This one assigns the CSS to the element when it was targeted – either by activating a link to it in the document or from the URL when the page loaded. With this pseudo selector, we override the left setting and move it to 20 pixels, thus showing the image.

    .target:target {
      left: 20px;
    }

    You can try this out for yourself:

    To make this smoother, all we need to do is to add a CSS transition to the target styles. Now all the changes to the styles will happen smoothly during a second rather than immediately.

    .target {
      position: absolute;
      top: 60px;
      left: -320px;
      height: 220px;
      width: 300px;
      -webkit-transition: 1s;
         -moz-transition: 1s;
          -ms-transition: 1s;
           -o-transition: 1s;
              transition: 1s;
    }

    Again, see it in action and play with it.

    That is all there is to it – the rest of the effects are just different variations of the same trick – animating opacity from 0 to 1 or CSS transitions.

    Target selectors can be a very powerful trick. The main issue they have though is that the page scrolls to the target, so if there is a big distance between the link and the target you’ll get unsightly jumps.

  6. Creating thumbnails with drag and drop and HTML5 canvas

    HTML5 Canvas is a very cool feature. Seemingly just an opportunity to paint inside the browser with a very low-level API you can use it to heavily convert and change image and video content in the document. Today, let’s take a quick look at how you can use Canvas and the FileReader API to create thumbnails from images dropped into a browser document.

    The final code is available on GitHub and you can see an online demo here. There is also a screencast available on YouTube:

    Step 1: Getting the files into the browser

    The first step to resize images in the browser is to somehow get them. For this, we can just add an element in the page and assign drag and drop event handlers to it:

    s.addEventListener( 'dragover', function ( evt ) {
      evt.preventDefault();
    }, false );
    s.addEventListener( 'drop', getfiles, false );

    Notice that we only prevent the default behaviour when we drag things over the element. This is to prevent the browser from just showing the images when we drag them in.

    The getfiles() function then does the hard work of reading all the files in and sending them on to the functions that do the resizing and image generation:

    function getfiles( ev ) {
      var files = ev.dataTransfer.files;
      if ( files.length > 0 ) {
        var i = files.length;
        while ( i-- ) {
          var file = files[ i ];
          if ( file.type.indexOf( 'image' ) === -1 ) { continue; }
          var reader = new FileReader();
          reader.readAsDataURL( file );
          reader.onload = function ( ev ) {
            var img = new Image();
            img.src = ev.target.result;
            img.onload = function() {
            imagetocanvas( this, thumbwidth, thumbheight, crop, background );
            };
          };
        }
      }
      ev.preventDefault();
    };

    The drop event gives us a property called dataTransfer which contains a list of all the files that have been dropped. We make sure that there was at least one file in the drop and then iterate over them.

    If the file type was not an image (or in other words the type property of the file does not contain the string “image”) we don’t do anything with the file and continue the loop.

    If the file is an image we instantiate a new FileReader and tell it to read the file as a Data URL. When the reader successfully loaded the file it fires its onload handler.

    In this handler we create a new image and set its src attribute to the result of the file transfer. We then send this image to the imagetocanvas() function with the parameters to resize (in the demo these come from the form):

    function imagetocanvas( img, thumbwidth, thumbheight, crop, background ) {
      c.width = thumbwidth;
      c.height = thumbheight;
      var dimensions = resize( img.width, img.height, thumbwidth, thumbheight );
      if ( crop ) {
        c.width = dimensions.w;
        c.height = dimensions.h;
        dimensions.x = 0;
        dimensions.y = 0;
      }
      if ( background !== 'transparent' ) {
        cx.fillStyle = background;
        cx.fillRect ( 0, 0, thumbwidth, thumbheight );
      }
      cx.drawImage( 
        img, dimensions.x, dimensions.y, dimensions.w, dimensions.h 
      );
      addtothumbslist( jpeg, quality );
    };

    This function gets the desired thumbnail size and resizes the canvas to these dimensions. This has the added benefit of wiping the canvas so that no old image data would be added to our thumbnail. We then resize the image to fit into the thumbnail using a resize() function. You can see for yourself what this one does in the source code, it just means the image gets resized to fit. The function returns an object with the width and the height of the new image and the x and y position where it should be positioned onto the canvas.

    If we don’t want the full-size thumbnail but instead crop it we resize the canvas accordingly and reset x and y to 0.

    If the user requested a background we fill the canvas with the colour. After that we put the image on the canvas with the x and y coordinates and the new width and height.

    This takes care of creating a new thumbnail on the canvas, but we haven’t got it as an image in the document yet. To this end, we call addtothumbslist():

    function addtothumbslist( jpeg, quality ) {
      var thumb = new Image(),
          url = jpeg ? c.toDataURL( 'image/jpeg' , quality ) : c.toDataURL();
      thumb.src = url;
      thumb.title = Math.round( url.length / 1000 * 100 ) / 100 + ' KB';
      o.appendChild( thumb );
    };

    This one creates a new image and checks if the users wanted a JPG or PNG image to be created. PNG images tend to be better quality but also bigger in file size. If a JPG was requested we call the canvas’ toDataURL() method with two parameters: the requested JPEG mime type and the quality of the image (ranging between 0 and 1 with 1 being best quality). If a PNG is wanted, we can just call toDataURL() without any parameters as this is the default.

    We set the src of the image to the generated url string and add a title showing the size of the image in KB (rounded to two decimals). All that is left then is to add the thumb to the output element on the page.

    That’s it, you can now drag and drop images into the browser to generate thumbnails. Right now, we can only save them one at a time (or if you have some download add-ons all at once). Would be fun to add Zip.js to the mix to offer them as a zip. I dare you! :)

    More reading:

  7. Screencast: 3D CSS rollovers and 3D CSS tester

    CSS 3D transforms as supported in the latest Aurora allow us to do some nice effects that in the past were only possible in Flash or with a lot of trickery using skewing and filters. I was asked to show a small demo the other day and thought it would be fun to spice up the classic image rollover:

    You can see this in action using Chrome, Safari or Firefox Aurora/Nightly. Older browsers should just show a normal roll-over (and yes, the first example looks weird due to the logo transparency but it makes the effect much cooler in supporting browsers).

    As people asked how this is done I thought it easiest to create a testing tool where you can play with 3D CSS yourself. Here’s a screencast where I explain how to use it and how the roll-over effects were done.

    I found a few interesting bugs while creating this and will file them now. This is the benefit of playing with new tech. Enjoy!

    More reading on this:

  8. Making the wait for the holidays easier – the MDN advent calendar

    Tomorrow we will release the MDN advent calendar at http://thewebrocks.com/calendar with a daily link on a web technology product, a MDN wiki page or a great demo collected by us over the last few days. You can get a preview of how the calendar will look and work here:

    As an extra bonus, we thought it would be fun to document the step-by-step development of the calendar and release it for you to re-use or get inspired by.

    You can get a white-labeled version of the calendar on GitHub and there is a two-part step-by-step instruction how it was built available: Part 1Part 2.

    It is an example of how to build something server-side (so you can’t cheat by setting your operating system calendar ahead), enhance it with JavaScript and make it smooth by using CSS transitions. This should work for everybody and by playing each technology to its strengths, the code is very small indeed.

    Enjoy, and see you tomorrow and the day after, and the day after that and…

  9. HTML5 context menus in Firefox (Screencast and Code)

    You may not know it, but the HTML5 specifications go beyond what we put in the pages and also define how parts of the browser should become available to developers with HTML, CSS and JavaScript. One of these parts of the specs are context menus, or “right click menus”. Using HTML5 and a menu element you can add new options to these without having to write a browser add-on. In Firefox 8 (the current one) we have support for those. See the following screencast for a context menu demo.

    The image example is pretty simple and was actually written by Paul Rouget as a demo in the original Firefox bug request. The main core is the HTML of it:

    <section id="noninteractive" contextmenu="imagemenu">
     
      <img src="html5.png" alt="HTML5" id="menudemo">
     
        <menu type="context" id="imagemenu">
          <menuitem label="rotate" onclick="rotate()"
                    icon="arrow_rotate_clockwise.png">
          </menuitem>
          <menuitem label="resize" onclick="resize()"
                    icon="image-resize.png">
          </menuitem>
          <menu label="share">
            <menuitem label="twitter" onclick="alert('not yet')"></menuitem>
            <menuitem label="facebook" onclick="alert('not yet')"></menuitem>
          </menu>
        </menu>
     
    </section>

    As you can see you link the menu element to an element via its ID. The contextmenu attribute then points to this one. Each menu can have several menuitems. Each of those gets a textual label and a possible icon. You can also nest menu elements to create multiple layer menus. Here, we add inline onclick handlers to point to different JavaScript functions to call when the menu item gets activated. The resulting context menu looks like this:

    image with a context menu

    The functionality is simple, all the rotate() and resize() functions do is add class names to the image using querySelector and classList:

    function rotate() {
      document.querySelector('#menudemo').classList.toggle('rotate'); 
    }
    function resize() {   
      document.querySelector('#menudemo').classList.toggle('resize'); 
    }

    The real effect is in CSS transforms and transitions. As the image has an ID of menudemo here is what is needed in CSS to rotate and resize:

    #menudemo { 
      -moz-transition: 0.2s; 
      width:200px;
    }
    #menudemo.rotate { 
      -moz-transform: rotate(90deg); 
    }
    #menudemo.resize { 
      -moz-transform: scale(0.7); 
    }
    #menudemo.resize.rotate { 
      -moz-transform: scale(0.7) rotate(90deg); 
    }

    Notice that in a real product we should of course add the other browser prefixes and go prefix-less but as the functionality now only works in Firefox, this is enough for this demo.

    Detecting support and visual hinting

    Now, as this is extending the normal user offerings in the browser we need to make it obvious that there is a right-click menu available. In CSS3, there is a context-menu cursor available to us. When context menus are available, this should be shown:

    .contextmenu #menudemo, .contextmenu .demo {
      cursor: context-menu;
    }

    We test the browser for support by checking for contextmenu on the body element and for HTMLMenuItemElement in the window (this has been added as a pull request to Modernizr, too).

    if ('contextMenu' in document.body && 'HTMLMenuItemElement' in window) {
      document.documentElement.classList.add('contextmenu');
    } else {
      return;
    }

    Wouldn’t HTMLMenuItemElement be enough? Yes, but a real context menu should only offer functionality when it is sensible, and that is where contextMenu comes in.

    Turning menuitems on and off depending on functionality

    As a slightly more complex example, let’s add a “count words” functionality to the document. For this, we generate a counter element that will become a tooltip when the words were counted:

    var counter = document.createElement('span');
    counter.id = 'counter';
    counter.className = 'hide';
    document.body.appendChild(counter);
     
    counter.addEventListener('click', function(ev){
      this.className = 'hide';
    },false);

    This one is hidden by default and becomes visible when the hide class is removed. To make it smooth, we use a transition:

    #counter{
      position: absolute;
      background: rgba(0,0,0,0.7);
      padding:.5em 1em;
      color: #fff;
      font-weight:bold;
      border-radius: 5px;
      -moz-transition: opacity 0.4s;
    }
    #counter.hide{
      opacity: 0;
    }

    We start with two sections with context menus:

    <section id="noninteractive" contextmenu="countmenu">
      <menu type="context" id="countmenu">
          <menuitem class="wordcount" label="count words"></menuitem>
      </menu>
    </section>
     
    <section id="interactive" contextmenu="countmenuinteractive">
      <menu type="context" id="countmenuinteractive">
          <menuitem class="wordcount" label="count words"></menuitem>
      </menu>
    </section>

    We then loop through all the menuitems with the class wordcount and apply the functionality.

    var wordcountmenus = document.querySelectorAll('.wordcount'),
        i = wordcountmenus.length;
     
    while (i--) {
      wordcountmenus[i].addEventListener('click', function(ev){
        // add functionality 
      }, false);
    }

    We need to find out what has been selected in the page. We do this by using getSelection() and splitting its string version at whitespace. We then show the counter by removing the hide class name.

    var wordcountmenus = document.querySelectorAll('.wordcount'),
        i = wordcountmenus.length;
     
    while (i--) {
      wordcountmenus[i].addEventListener('click', function(ev){
        var text = document.getSelection(),
            count = text.toString().split(/\s/).length;
        counter.innerHTML = count + ' words';
        counter.className = '';
      }, false);
    }

    You can see this in action in the second context menu demo. Now, the issue with this (as explained in the screencast) is that it always counts the words, regardless of the user having selected some text. What we want is the menu only to be active when there is text selected.

    context menu item available or not available depending on selection

    So in order to make our menu only become available when it makes sense we check if there is a selection in the document. Every context menu fires an event called contextmenu when it opens. So all we need to do is to subscribe to this event.

    When something is selected in the document document.getSelection().isCollapsed is true. Otherwise it is false, so all we need to do is to enable or disable the menu item accordingly:

    document.querySelector('#interactive').addEventListener(
      'contextmenu', function(ev) {
        this.querySelector('.wordcount').disabled =
        document.getSelection().isCollapsed;  
      },
    false);

    The last thing to solve is the position of the mouse to position the counter element. As the menu selection event doesn’t give us the mouse position we need to add a contextmenu handler to the whole document that positions the counter invisibly behind the menu when it is opened:

    document.body.addEventListener(
      'contextmenu', function(ev) {
        counter.style.left = ev.pageX + 'px';
        counter.style.top = ev.pageY + 'px';
        counter.className = 'hide';
      }, 
    false);

    Further reading and resources

  10. Screencast: CSS 3D rollover with fallback for older browsers

    Here’s a quick screencast how to create a 3D image rollover and still give a useful interface to browsers that do not support 3D transforms. If you want to see the effect in Firefox get the latest Aurora or Nightly. Check the following video to see what it looks like (first with a browser without CSS 3D transport, then with a newer one):

    The screencast is on YouTube:

    The main procedure to achieve the effect is simple. First we need a semantically valuable way to show these images, in our case a HTML list with figures and figcaptions. Notice that images still need an alternative text as the figcaption can apply to several images:

    <ul>
      <li class="image3d">
        <figure>
          <img src="mittens.jpg" alt="Mittens the cat">
          <figcaption>
            <p>
              <strong>Mittens</strong> loves to play with yarn and stuff.
            </p>
          </figcaption>
        </figure>
      </li>
    <!-- repeated -->
    </ul>

    We then position the caption absolutely inside the list item, give the list item dimensions and an overflow of hidden and move the caption outside of the visible space. When the user hovers over the list item (or focuses it with a keyboard) we move the caption to the right place and lower the opacity of the image.

    .positioned {
      list-style: none;
      width: 300px;
      height: 200px;
      position: relative;
    }
    .positioned figcaption {
      position: absolute;
      background: rgba( 0, 0, 0, 0.7 );
      color: #fff;
      border-radius: 5px;
      left: 65px;
      bottom: 10px;
      width: 230px;
    }
    .positioned img {
      opacity:0.4 ;    
    }
    .positioned figcaption strong {
      display: block;
      color: lime;
      font-weight: normal;
      font-size:22px;
      padding: 5px 0;
    }
    .positioned figcaption p {
      display: block;
      color: white;
      padding: 5px;
    }
    .interactive {
      overflow: hidden;
    }
    .interactive img {
      opacity: 1;
    }
    .interactive figcaption {
      left: 300px;
    }  
    .interactive:hover img, .interactive:focus img {
      opacity: 0.4;
    }
    .interactive:hover figcaption, .interactive:focus figcaption {
      left: 75px;
    }

    We make the effect smooth by adding transitions. Notice that it makes sense to list all the browser prefixes and set a prefix-less fallback. That way we don’t need to re-write code when a new browser supports them.

    .smooth img {
      -webkit-transition: all 1s;
      -moz-transition:    all 1s;
      -o-transition:      all 1s;
      -ms-transition:     all 1s;
      transition:         all 1s;
    }
    .smooth figcaption {
      -webkit-transition: all 1s;
      -moz-transition:    all 1s;
      -ms-transition:     all 1s;
      -o-transition:      all 1s;
      transition:         all 1s;
    }

    In order to rotate the kitty in 3D space, we need to give the list item a perspective and rotate the image and shift it in 3D space with translate3D to avoid clipping:

    .threed {
      -webkit-perspective: 800px;
      -moz-perspective:    800px;
      -ms-perspective:     800px;
      -o-perspective:      800px;
      perspective:         800px;
    }
    .threed:hover img, .threed:focus img {
      -webkit-transform: rotateY( 50deg ) rotateX( 10deg )
                         translate3d( 80px, -20px, -100px );
      -moz-transform:    rotateY( 50deg ) rotateX( 10deg )
                         translate3d( 80px, -20px, -100px );
      -o-transform:      rotateY( 50deg ) rotateX( 10deg )
                         translate3d( 80px, -20px, -100px );
      -ms-transform:     rotateY( 50deg ) rotateX( 10deg )
                         translate3d( 80px, -20px, -100px );
      transform:         rotateY( 50deg ) rotateX( 10deg )
                         translate3d( 80px, -20px, -100px );
    }

    That’s it. By adding all the browser prefixes, falling back to a simple rollover and by making sure you do the effect on hover and on focus you support all the browsers and bring the cool to the newest ones.

    More reading and resources: