CSS Articles

Sort by:


  1. With the power of HTML5 – speaking at Converge SE in Columbia, SC

    Last week the Converge SE conference in Columbia, South Carolina attracted about 400 designers, developers and product managers to attend workshops and hear keynotes about all that is new and great in web development.

    As you can see on the conference schedule the conference covered a lot of topics, ranging from building communities and providing great end user service over creating engaging video demos up to using CSS pseudo selectors, web fonts and responsive design.

    It was especially refreshing to see that instead of showing theoretical examples or demos most of the speakers showed the new technologies as they used them in real products. Ethan Marcotte for example previewed the upcoming Boston Globe redesign to the audience.

    Mozilla’s involvement (apart from sponsoring the event) was a keynote on the why of HTML5. In 96 slides and just above 30 minutes I explained:

    • How HTML5 came to be
    • Why it is not about selling browsers or hardware or comparing yourself with the competition
    • That HTML5 is part of a larger world of new technologies
    • That HTML5 means first and foremost improving the infrastructure for web applications and using the hardware and software people use to their full potentials
    • That using HTML5 means a shift in our thinking as web developers and needs re-evaluation of some of our “best practices”
    • That everybody should start using it and help us make it really work instead of being amazed by cool demos but failing to use these new technologies in day to day products

    The slides are available on Slideshare:

    There is an audio recording of the talk on

    Converge SE was filmed, so I am quite sure the videos will be out soon and you will find more of the presentations using the convergese tag.

  2. Rofox, a CSS3 Animations demo

    Firefox 5 was released last week. This release comes with CSS3 Animations. Here is a demo made by Anthony Calzadilla.

    To illustrate what you can achieve with CSS3 Animations, we have been working on demo with Anthony Calzadilla (@acalzadilla), famous for his awesome Animation projects.

    Check out the demo on the Mozilla Demo Studio.

    And it works on Firefox Mobile too:

    The whole animation is orchestrated in CSS (keyframe) and the moves are animated transformations (transforms). The images are nested divs. If you translated a div and rotate its child, the transformations are combined. You can see the elements being transformed (bounding boxes) if you activate the debug mode.

    #arm-rt {
      transform-origin: 0 50%;
      /* The syntax is:
       animation: name duration timing-function delay count direction
      animation: arm-rt-action-01 60s ease-out 10s 1 both;
    @keyframes arm-rt-action-01 {
      /* This part of the animation starts after 10s and lasts for 60s */
      0% { transform : translate(-100px,0) rotate(0deg); }
      5% { transform : translate(0,0) rotate(0deg); }
      6% { transform : translate(0,0) rotate(-16deg); }
      21% { transform : translate(0,0) rotate(-16deg); }
      22% { transform : translate(-100px,0) rotate(0deg); }
      100% { transform : translate(-100px,0) rotate(0deg); }

    Tip: If you want to avoid some performance issues, we encourage you to use bitmap images. SVG images can make the animation a bit shoppy.

    Want to see more CSS3 Animations? Check out Anthony’s website: And feel free to submit your CSS3 Animations demos to the Mozilla Demo Studio.

  3. Firefox 5 is here

    Today, three months after the release of Firefox 4, we release Firefox 5, thanks to our new development cycle. Developers will be able to create richer animations using CSS3 Animations. This release comes with various improvements, performance optimization and bug fixes.

    CSS3 Animations

    CSS Animations (check out the documentation) are a new way to create animations using CSS. Like CSS Transitions, they are efficient and run smoothly (see David Baron’s article), and the developers have a better controls over the intermediate steps (keyframes), and can now create much more complex animations.

    Notable changes

    Other Bug Fixes and Performance Improvements:


    Canvas improvements

    • The <canvas> 2D drawing context now supports specifying an ImageData object as the input to the createImageData() method; this creates a new ImageData object initialized with the same dimensions as the specified object, but still with all pixels preset to transparent black.
    • Specifying non-finite values when adding color stops through a call to the CanvasGradient method addColorStop() now correctly throws INDEX_SIZE_ERR instead of SYNTAX_ERR.
    • The HTMLCanvasElement method toDataURL() now correctly lower-cases the specified MIME type before matching.
    • getImageData() now correctly accepts rectangles that extend beyond the bounds of the canvas; pixels outside the canvas are returned as transparent black.
    • drawImage() and createImageData() now handle negative arguments in accordance with the specification, by flipping the rectangle around the appropriate axis.
    • Specifying non-finite values when calling createImageData() now properly throws a NOT_SUPPORTED_ERR exception.
    • createImageData() and getImageData() now correctly return at least one pixel’s worth of image data if a rectangle smaller than one pixel is specified.
    • Specifying a negative radius when calling createRadialGradient() now correctly throws INDEX_SIZE_ERR.
    • Specifying a null or undefined image when calling createPattern() or drawImage() now correctly throws a TYPE_MISMATCH_ERR exception.
    • Specifying invalid values for globalAlpha no longer throws a SYNTAX_ERR exception; these are now correctly silently ignored.
    • Specifying invalid values when calling translate(), transform(), rect(), clearRect(), fillRect(), strokeRect(), lineTo(), moveTo(), quadraticCurveTo(), or arc() no longer throws an exception; these calls are now correctly silently ignored.
    • Setting the value of shadowOffsetX, shadowOffsetY, or shadowBlur to an invalid value is now silently ignored.
    • Setting the value of rotate or scale to an invalid value is now silently ignored.


    • Support for CSS animations has been added, using the -moz- prefix for now.


    • The selection object’s modify() method has been changed so that the “word” selection granularity no longer includes trailing spaces; this makes it more consistent across platforms and matches the behavior of WebKit’s implementation.
    • The window.setTimeout() method now clamps to send no more than one timeout per second in inactive tabs. In addition, it now clamps nested timeouts to the smallest value allowed by the HTML5 specification: 4 ms (instead of the 10 ms it used to clamp to).
    • Similarly, the window.setInterval() method now clamps to no more than one interval per second in inactive tabs.
    • XMLHttpRequest now supports the loadend event for progress listeners. This is sent after any transfer is finished (that is, after the abort, error, or load event). You can use this to handle any tasks that need to be performed regardless of success or failure of a transfer.
    • The Blob and, by extension, the File objects’ slice() method has been removed and replaced with a new, proposed syntax that makes it more consistent with Array.slice() and String.slice() methods in JavaScript. This method is named mozSlice() for now.
    • The value of window.navigator.language is now determined by looking at the value of the Accept-Language HTTP header.


    • Regular expressions are no longer callable as if they were functions; this change has been made in concert with the WebKit team to ensure compatibility (see WebKit bug 28285).
    • The Function.prototype.isGenerator() method is now supported; this lets you determine if a function is a generator.


    • The class SVG attribute can now be animated.
    • The following SVG-related DOM interfaces representing lists of objects are now indexable and can be accessed like arrays; in addition, they have a length property indicating the number of items in the lists: SVGLengthList , SVGNumberList , SVGPathSegList , and SVGPointList.


    • Firefox no longer sends the “Keep-Alive” HTTP header; we weren’t formatting it correctly, and it was redundant since we were also sending the Connection: or Proxy-Connection: header with the value “keep-alive” anyway.
    • The HTTP transaction model has been updated to be more intelligent about reusing connections in the persistent connection pool; instead of treating the pool as a FIFO queue, Necko now attempts to sort the pool with connections with the largest congestion window (CWND) first. This can reduce the round-trip time (RTT) of HTTP transactions by avoiding the need to grow connections’ windows in many cases.
    • Firefox now handles the Content-Disposition HTTP response header more effectively if both the filename and filename* parameters are provided; it looks through all provided names, using the filename* parameter if one is available, even if a filename parameter is included first. Previously, the first matching parameter would be used, thereby preventing a more appropriate name from being used. See bug 588781 .


    Developer tools

    • The Web Console’s Console object now has a debug() method, which is an alias for its log() method; this improves compatibility with certain existing sites.

  4. Aurora 6 is here

    What’s new in Aurora 6?

    The most notable addition to this new Aurora are the <progress> element, window.matchMedia API, better APIs for binary data, Server-Sent Events as well as the return of WebSockets.

    Aurora 6 has been published last week and can be downloaded from

    The <progress> element

    screenshot of progress bars as seen on windows
    This element can be used to give a visual cue of something in progress in the page. System progress bars are being used, which means that users of MacOS and Linux will see something different than what is pictured here.


    window.matchMedia() is the javascript equivalent of CSS Media Queries.

    Binary data APIs improvements

    • XHR2 responseType and response attributes allow getting the response from an XHR in the form of efficient Blob or ArrayBuffer.
    • FileReader.readAsArrayBuffer() allow reading files and get the response as an ArrayBuffer.
    • BlobBuilder allow concatenating multiple blobs as well as text and ArrayBuffer into a single Blob.

    Expect to see even more improvements in this area in Aurora 7.

    Server Sent Events

    Server Sent Events are a mean for a server-side script to generate client-side events accompanied with data.

    Messages generated on the server-side with a text/event-stream mime-type and consist of a list of events data.

    data: data generated by the server
    data: this line will generate a second event

    WebSockets are back!

    WebSockets can be used to create an interactive communication channel between a browser and a server. They are already used to build “HTML5” chats, multiplayer games, and much much more.
    Note that this API will be temporarily namespaced in prevision of upcoming changes to the specification.

    Other Interesting Additions

    Learn about what’s new in Aurora 6’s user interface on and let us know what you think.

  5. Advanced animations in Aurora with CSS3 Animations

    Firefox 4 came with CSS3 Transitions (ability to animate CSS properties from an initial value to a final one). In Firefox Aurora, we are experimenting with CSS3 Animations: a more powerful way to animate your content with CSS.

    Defining the animation

    The first thing is to define the intermediary CSS values of the properties to be animated, what is called keyframes in the specification. Users of Adobe Flash authoring tools should be familiar with this concept.

    Applying an animation

    While Transitions trigger implicitly when property values change, animations are explicitly executed when the animation properties are applied.

    More properties

    The specification defines other animation properties that opens a broad range of possibilities:

    • with animation-timing-function it is possible to take advantage of easings to make animations feel more natural (see demo below)
    • animation-direction: alternate; is the auto-reverse of CSS3 Animations. See how it is used to create the loader below.
    • without animation-fill-mode: forwards;, the properties will be set back to their initial values at the end of the animation
    • and guess what setting animation-play-state to paused would do…


    You should be using Firefox Aurora, Chrome or Safari 5 to see those demo.
    animated translations

    zero-image, gracefully degrading loader

    a complex animated scene
    View Madmanimation with a compatible browser, or watch a screencast of the animation.

    You’ve already used CSS3 animations? Let us know in the comment below or submit your demo in the Studio.

  6. MDN Learning: A place to ratchet your Web development skills

    If you’re looking to improve your Web development skills, we have compiled some great resources from around the Web to help every level of developer dig into their favorite open Web technologies. Our new MDN Learning space serves as a starting point for anyone interested in learning more about Web development. While there is already awesome documentation on MDN, not everyone knows how to find it — or other great tutorials and examples scattered around the Web. There is just so much content out there, we felt it was time to create a central place developers can go to quickly find the best resources.

    MDN Learning

    Our initial set of pages focus on documentation, tutorials, and other content for learning HTML, CSS and JavaScript. We will continue to add new content, including MDN Learning pages for topics like video, audio, webGL, etc. We also plan to use this new space to share more information about our collaboration with other organizations and projects that are developing open models around education, like P2PU’s School of Webcraft.

    This launch of MDN Learning is just the beginning of what we hope will become a permanent place on MDN for everything related to educating people about Web development and the resources available to them on not just MDN, but around the Web. We look forward to feedback and suggestions on how we can improve on this first step towards expanding MDN to cater to those getting started with developing for the Web.

  7. Promoting the use of new web technologies in Lithuania

    Last week around 2500 developers, designers, entrepreneurs and managers came to Vilnius, Lithuania to attend the fifth Login conference. Speakers included people from Nokia, Wired, (run by the founder of the Pirate Bay), Tate Modern and Amnesty international and the conference covered everything from viral video over web security and privacy up to bleeding edge web development practices.

    My job for Mozilla was to deliver the final keynote to remind people what they heard in the two days and to get them excited to play with the new toys we talked about. Here are the slides and the extensive notes of the talk. A video will be available soon and we will publish it here when it is out.

    Slides of the closing keynote “Building a better web with open, new technologies”

    You can also see and download an annotated version on Slideshare.

    Talk Notes

    Today I will talk about exciting new open technologies and how you can use them to change the web for better and make a name for yourself at the same time.

    I am Chris Heilmann, I work as the principal evangelist for Mozilla and I concentrate on HTML5 and the open web. I am a developer evangelist and if you don’t know what that is check out to learn all about it.

    I am a film buff – I don’t watch TV, I watch movies instead. And I love quirky movies. One of them I devoured lately was “The Hudsucker Proxy” by the Coen brothers. In this movie we get introduced to Norville Barnes, an business school graduate going to New York to find fame and fortune as an entrepreneur – only to end up as a lowly clerk in the mail room of a company. Norville, however, has ideas and a complete and utter lack of skill telling people about them. His pitch for his great idea is showing people a piece of paper with a ring on it saying “You know, for kids”. Norville gets a chance when the Boss of the company retires – by jumping out of the window. The other stakeholders find his will and realise that they are to make the company stock public which entices them to make sure the stock plummets beforehand. To make that happen they want to hire a complete idiot as CEO – and that is Norville.

    Norville gets the chance to build his invention which turns out to be the hula hoop. The company spends a lot of time with an advertising campaign and it fails immensely – nobody wants to buy a hula hoop. When a shop owner throws them out in the street and a kid starts using it in front of a school everything changes. The hula hoop becomes a massive success.

    So what does that have to do with this conference?

    The hula hoop is a great example of a product that should not need any marketing but works by seeing other people use it and needs one person to show how much fun it is to use it.

    Using new and cool things should not need any marketing…

    And this is what modern web technologies are. It is a total no-brainer to upgrade the technologies that drive the web. But instead of just giving them to the people who care about them we wait for big players to do it for us.

    There is no point in thinking about amazing technologies and waiting for magic to happen. A lot of the things we thought about are not really clever if you look at them closely.

    Just jump in and join the ride!

    Well, I am here today to tell you that you can and should use all the new tech you can get your hands on – for the sake of the web and for the sake of your companies.

    Aim for the long goal…

    Supporting new technology based on standards means that you are in it for the long term. You want to build something cool and new but you also want to make it maintainable in the future. The technologies are not hard to learn – CSS, JavaScript and HTML have been around for ever. The great news nowadays is that today we can build amazing things with them.

    Use the whole stack

    As entrepreneurs and new developers I think it is our duty to embrace new technologies and bring them to the main market. Old and settled companies do not have that chance. So take a stand and step into the circle and start moving.

    HTML5 provides us with much richer forms than ever before. We have Autocomplete controls, colour pickers, URL, phone and email fields that tap into the contacts DB of our smartphones and date pickers. Each of these also come with browser validation built-in which makes it much easier to build a great experience.

    Finding a visitor’s location is as simple as 3 lines of JavaScript – and using free databases like Yahoo’s GeoPlanet you can turn this for example into an address and pre-fill a form for the user with a “find me” button. Wouldn’t that be useful?

    With local and offline storage I can make my application work even when the visitor is on the go. Being without connectivity shouldn’t be the end of your application – simple tell the user you are offline and store the data locally until you can sync again. Local storage can also be used to cache information for the user that doesn’t have to be loaded from your server over and over again.

    Using SVG and Canvas we can paint on the web. We can build immensely rich interactive graphs and we can create games that until now where only available in Flash or Silverlight. D3 is a great library to turn any data in the document into an interactive graph. Libraries like d3.js can help you there a lot.

    CSS3 allows styling to go beyond adding colours, dimensions and fonts. You can build interfaces that resize according to the available screen, do transformations and create shadows and gradients.

    Using native video and audio you can interact with the document in a very simple manner. You can overlay videos and react to the time of the current video. In this example I’ve built the Indiana Jones maps by overlaying a video over an animated map. You can use this technology to simply build interactive video tutorials.

    You can easily build your own video players that have functionality that none of them had before – here for example I wrote a video player that allows you to zoom and rotate videos.

    Using Canvas and SVG together with video you can dynamically analyse the video data and react with it. In this demo we find the white parts of a video and use it as anchor points for injecting content.

    By using touch gestures and device orientation you can make your products much easier to use for humans – the games industry blossomed the last few years exactly because of that.

    WebGL allows you to use real 3D models natively in the browser. Check out the amazing Body Browser example by Google.

    Messaging and Workers

    Using Websockets for messaging between your site and the computers you can build real-time applications that scale up to thousands of users. Worker threads means that you can calculate intensely with JavaScript without slowing down the interface.

    Be greedy and aim for the best experience.

    Whilst in the past a HTML version of a certain system was a fallback for a Flash site when it comes to beautiful and rich experiences right now we don’t need to hide any longer. It is time to take the new technologies and build beautiful experiences with them.

    Through the looking glass…

    The great thing about using open web technologies is that you are fully in the open. Everybody can see what you are doing. This sounds scary but in the tech world is actually a big bonus. Debugging a product is much easier when there is no compilation necessary. As an extra bonus open systems also ensure that you attract talent. If your product features newest and coolest technology you will find it a much less arduous job to hire developers. Geeks love to be part of something cool and new. If you open up your source code – even better.

    Give your tech people a voice

    The next big step to being open is to trust your techies. Instead of hiding your technology skills have a blog with your achievements where you talk about your people and how they work. This shows that you care about your tech as much as your money.

    Of course there are problems!

    Nothing works immediately without any issues. There is no point pretending that this is the case. Not everything you use will fit. There are browser differences and support issues with the technologies we have right now. Embedding audio and video should be easy in HTML5 – it should be as simple as pointing to a video to add it to a document. Copyright and licensing differences across different browsers makes it necessary to have the video in 3 different formats though.

    You can’t expect everybody to have the newest browsers. IE6 is still around and a thorn in the side of any developer. However, it is dwindling and Microsoft is actively fighting the issue.

    Use things to help you out

    The work on the specifications is totally open and anyone can take part. You can see HTML5 as a debate club right now, and you are invited to state your case. There is lots of free up-to date documentation available on the web for you – for example on HTML5 Doctor or even a full book Dive into HTML5 by Mark Pilgrim.

    Modernizr is a JavaScript to embed in your products that tests for the support of all the new technology. It adds classes on the HTML element for you to read out and react to. HTML boilerplate is a copy and paste start to use HTML5 in your projects – it includes Modernizr and resets the CSS and gives you the correct server settings. is a service by that converts video into all the necessary formats and creates a single URL to point your video elements to. And doesn’t only create them for browsers – it also supports every handheld device and games console. It even creates videos that are smaller or larger in file size according to the end user’s connection speed.

    Appmator packs an HTML5 web site into a Google Application with one click. converts HTML5 applications to native code for all kind of devices in the cloud for you.

    Be part of the evolution

    HTML5 and new technologies should not only be for geeks and people who write all of their products by hand. We should strive for building products that allows us to build with new tech and move things to the browser that until now are still very much desktop jobs. There are some great examples about this already out there.

    • Popcorn and Butter allows you to sync video content with web content and send it as a presentation format to contacts.
    • Aviary is an online HTML5 image editor.
    • Scribd scrapes PDFs and Flash documents and makes them readable in HTML for iPads.
    • Diagramo is an HTML5 editor for flowcharts and diagrams.
    • Slideshare uses websockets for chats and webcasting.

    Don’t pretend new tech doesn’t involve you – let’s work together on this – you know – for a better web!

  8. Firefox 4 Demos: Awesome CSS3 Planetarium

    O hai pixel lovers! Check out this gorgeous CSS3 demo: Planetarium, by the LittleWorkshop team (@glecollinet & @whatthefranck).



    Youtube link.

    Gorgeous Animations

    The principal feature show-cased in this demo is CSS3 Transitions. The animation between the welcome-screen and the planet-screen, and the animation between the different planets are powered by transitions. But there are many little effects in this demo. Take a look at the Twitter button, the ruler, the credit page or the back button. These effects are CSS3 Transitions too.

    Another interesting detail. Next to the planet, you have some different animations. The way the animations is played depends on if you’re coming from the left, the right or from the home screen.

    Try it yourself: Click on the planet Earth, from the home screen. See the text “falling” from the top? Now, go to Mars, and come back to Earth. Now the text is “flying” from the right. Designers will love that :)

    Beautiful fonts

    @font-face allows you to use your own font for creative design. Combined with text-shadow and font-feature-settings, you can accurately forge and style your typographic content.

    Your turn!

    These are features you can use today.
    This demo works perfectly in Firefox 4, Safari and Chrome. Also, Transitions and font-face are easily degradable. Go. Check out the source code, read the documention, and if you’re proud of your code, feel free to submit a demo!

  9. Zooming and rotating for video in HTML5 and CSS3

    The source of the code examples in this post is available on GitHub and you can see the demo in action.

    There are dozens of video players that allow you to do all the normal things with videos: play, pause, jump to a certain time and so on. More advanced ones also allow you to fast forward and reverse the video and support subtitles.

    One thing I haven’t found yet though is zooming and rotation of a video. Granted, an edge use case, but sometimes it is cool to be able to zoom into a detail like a blooper (boom mic in the background) or an easter egg (check for the term “A 113″ in every Pixar movie – an homage to the classroom most of the original Pixar cast learned their trade in).

    Rotation might come in handy when you recorded your video in portrait instead of landscape on your camera and you don’t want to re-encode it before you put it on the web.

    The HTML5 video tag allows you to style the video with CSS and CSS3 transforms allow both for scaling and for rotation. So let’s put those together.

    Embedding a video is as simple as this (see this in action on the demo page):

    <video controls>
      <source src="" type="video/mp4">
      <source src="" type="video/ogg">
      <p>Your browser doesn't support the HTML5 video tag it seems.
         You can see this video as part of a collection <a href="">at</a>.</p>

    Now, to scale this video you can use CSS3 transform:scale:

    Scaling a video with CSS3 transformations


    You can rotate with CSS3 transform:rotate:

    Rotate a video with CSS3 transformations


    And you can do both:

    Rotate and scale a video with CSS3 transformations

      -moz-transform:scale(1.5) rotate(20deg);
      -webkit-transform:scale(1.5) rotate(20deg);
      -o-transform:scale(1.5) rotate(20deg);
      -ms-transform:scale(1.5) rotate(20deg);
      transform:scale(1.5) rotate(20deg);

    Now, this doesn’t make much sense though as it changes the dimension of the video (in the demo page I needed to change the margin for each video accordingly). To really provide a “zoom” functionality, we’d need to keep the original size and cut off the parts we don’t need. We could do this using a CANVAS element, but why go that far when a simple DIV does the job for us?

    All we need to do to keep the space is nest our videos in a DIV with the class stage:

    <div class="stage"><video controls>
      <source src="" type="video/mp4">
      <source src="" type="video/ogg">
      <p>Your browser doesn't support the HTML5 video tag it seems.
         You can see this video as part of a collection <a href="">at</a>.</p>

    The CSS to make the cropping work is the following:


    Absolutely positioned elements are taken out of the normal flow of the document. If you put an absolutely positioned element inside one that is relatively positioned, its top and left values are relative to the other element. In other words: the video now covers the stage completely.

    If we rotate the video we still have triangular spaces showing like in this example:

    Positioning a video absolutely in a relative container


    To work around this, we must add a overflow:hidden to the stage DIV:

    Setting overflow:hidden on the stage hides the overlapping parts of the video


    In order to provide a zoom and rotate functionality, we need to use JavaScript and buttons for the end user. The first hurdle here is – as you probably already realised from the CSS – browser differences in the syntax. Therefore we need to detect which of the transformations the current browser supports. The safest way is to ask the browser:

    var properties = ['transform', 'WebkitTransform', 'MozTransform',
                      'msTransform', 'OTransform'];
    var prop = properties[0];
    for(var i=0,j=properties.length;i<j;i++){
      if(typeof[properties[i]] !== 'undefined'){
        prop = properties[i];

    Once this runs we can set a transformation with the following JavaScript syntax:

    var zoom = 1.5;
    var rotate = 20;[prop]='rotate('+rotate+'deg) scale('+zoom+')';

    Of course it doesn’t make much sense to rotate the controls with the video. Therefore you need to provide your own. You can use any of the aforementioned players for that or roll your own. To demonstrate, I just built one with a single button allowing you to play and pause the video:

    The full source is available on GitHub, read the comments to see what is going on here.

    Just a quick example of what you can do with open technologies.

  10. A call for quality HTML5 demo markup

    HTML5 is a necessary evolution to make the web better. Before the HTML5 specs were created we used (and still use) a hacked together bunch of systems meant for describing and linking documents to create applications. We use generic elements to simulate rich interaction modules used in desktop development and we make assumptions as to what the user agent (browser) can do for the end user.

    The good thing about this mess is that it taught us over the last few years to be paranoid in our development approach – we realised that in order to deliver working, accessible, maintainable and scalable systems we have to be professional and intelligent in our decisions and especially in our planning and architecting.

    The trouble is that with the excitement around the cool new HTML5 things to play with a lot of these principles get lost and discarded as outdated. They aren’t – part of the mess that the web is in is that in 1999 a lot of people discarded everything else and instead worked only on the new hotness that was Internet Explorer 6 and DHTML. Let’s not repeat that mistake.

    The two faces of HTML5 enthusiasm

    Right now there are two things to get really excited about in HTML5: the richer, more meaningful semantics of new elements and the APIs that give us deep access into the workings of the browser and the operating system. The former allows us to build much richer interfaces and the latter allows us to build much more complex applications.

    All of this comes with the awesome of view source (or check in development tools) for debugging. You can advocate HTML5 by writing clean and useful markup. You can kill it by treating the markup as a second class citizen which is only there to serve the script.

    The markup enthusiasts are very happy about HTML5 and make it easy for people to upgrade – lots of cool new blog templates and boilerplate HTML templates are being built and polyfills created to allow using the new features and not leave behind outdated browsers.

    On the app development side of things it looks much different and that is just sad. My only possible explanation is that people who come from desktop environments now tackle the HTML5 APIs without ever having to care about markup. The pragmatism of HTML5 allows a much more forgiving syntax than XHTML but it shouldn’t mean that we can just re-apply all the bad mistakes that held us back when it comes to maintenance for years.

    During my career as a web developer I realised a few things make a lot of sense when building web apps:

    • If there is an element for a certain task – use that one. It is very likely that the element comes with accessibility and interaction features for free that you would otherwise have to simulate.
    • Separate CSS, JavaScript and HTML – which means it is easy to refactor your code without having to change all of them. It also means you can work in parallel with others instead of breaking each other’s code
    • Never rely on markup or content – as sooner or later some editing tool will come into place that messes with everything you created

    This means a lot of things:

    • For starters it means that inline styles are simply evil as they override any settings you have in your style sheets. Only use them when this is exactly what you need to do or when you calculate them dynamically.
    • The same applies to inline scripting. If you have an onclick="foo()" somewhere in your HTML and foo() changes to bar() you have to rename it in every HTML document (of course nowadays it is one template, but it still means hunting down a reference you might miss)
    • If instead of using a native HTML element for a certain job you use SPANs and DIVs you’ll have to add classes to make them look and work – and simulate the keyboard accessibility, too.
    • You can’t rely on the text value of any element. A <button>edit</button> using the “edit” as the trigger for certain functionality would have to have the JS localised, too when you create the German <button>bearbeiten</button>.

    Bla bla bla… C’mon Chris, it isn’t that bad!

    The above best practices have been mentioned for years and a lot of people get sick of seeing them repeated. After all, this is intelligent development and standard practice in backend technologies. I came across a lot of “creative” uses lately though when doing a view-source on HTML5 demos – specifically the ones in the HTML5 advent calendar. And here is my yield of what people do.

    Simulating a navigation list

    One of the first things I encountered was a painting tool that had a gallery of created graphics as a background. Now, to me this would be a simple list:

        <a href="{link}">
          <img src="{src}" alt="{title}">

    The markup I found though was this:

    <div id="sky">
      <div class="skyTile" style="{calculated styles};display:block">
        <img class="skyThumb" src="{src}" style="{generated styles}">
        <img src="images/thumb_dropShadow.png"
             style="{generated styles}">

    This, of course is generated by the backend. My first gripe is the dropshadow image, after all this is an HTML5 showcase – just use CSS3. We also have the three instances of generated styles and double classes. Granted, an extra class gives you a handle to all images instead of tiles, so why not. But as there is no real link around the image, the click handler has to read the url from somewhere. There is a lot of unnecessary back and forth between DOM and scripting here which does slow down the whole demo. Seeing that this is also the main navigation from the entry page to the editor this could be a list inside a nav element. A list groups these items together, a bunch of DIVs doesn’t (screen readers for example tell you how many items there are in a list).

    Another list I found was supposed to be links to refresh the app and have a hierarchy but instead was a flat list with classes to define hierarchy and group:

    <ul id="mitems">
      <li class="hedtop">Simple</li>
      <li class="mol">{name}</li>
      [... repeated ...]
      <li class="hed">{parent name}</li>
      <li class="mol">{name}</li>
      [... repeated ...]

    This could be OK, granted you also shift keyboard focus, but why not:

    <ul id="mitems">
      <li>{parent name}
          <li><a href="{url}">{name}</a></li>
          [... repeated ...]
      [... repeated ...]

    This would give you styling hooks and functionality for free. Links and buttons are great to trigger functionality – but it seems that is too easy.

    Click (probably) here for functionality

    If I build a button for an application to trigger a certain functionality this is the markup:

    <button type="button" class="edit">Edit</button>

    Buttons are what trigger functionality – both a backend script or a JavaScript. They are keyboard accessible, have a disabled state and sensible out-of-the-box styling that nowadays can be completely overwritten. The class can be the definition of what the button should do – instead of the text which will change. You could use an ID but a class allows to repeat buttons (for example on the top and the bottom of a results list).

    The buttons I found though were slightly different:

    <div id="homeButtonPanel">
      <div class="homeButton" id="drawHomeButton"
           style="display: block;">
        <p>Start Drawing</p>
      <div class="homeButton" id="viewHomeButton"
           style="display: block;">
        <p>View the Mural</p>
    <div id="controlPanel" style="display: block;">
    <div class="titleButton"><p>{title}</p></div>
      <div class="mainMenu">
        <div class="mainButton mainSelected" id="drawButton">
          <div id="inkDisplay">
            <div id="inkMeter" style="width: 94px;">
        <div class="menuContainer">
          <div class="menuButton drawMenuButton" id="behaviorsButton"
               style="display: block; opacity: 1;">
            <p>Gesture<br />Behaviors</p>
        <div class="menuContainer">
          <div class="menuButton drawMenuButton" id="artworkButton"
               style="display: block; opacity: 1;">
        <div class="menuContainer">
          <div class="menuButton drawMenuButton" id="resetButton"
               style="display: block; opacity: 1;">
        <div class="menuContainer">
          <div class="menuButton drawMenuButton" id="undoButton"
               style="display: block; opacity: 1;">
        <div class="menuContainer">
          <div class="menuButton drawMenuButton" id="saveButton"
               style="display: block; opacity: 1;">
      <div class="mainMenu">
        <div class="mainButton" id="viewButton"><p>View</p></div>
      <div class="mainMenu">
        <div class="secondaryButton" id="helpButton"><p>Help</p></div>
      <div class="mainMenu">
        <div class="mainShare shareButtonSmall" id="mainTwitterButton">
          <img alt="twitter" src="images/twitter_icon.png"
               style="opacity: 0.6;">
        <div class="mainShare shareButtonLarge" id="mainFacebookButton">
          <img alt="facebook" src="images/facebook_icon.png">
        <div class="mainShare shareButtonSmall" id="mainEmailButton">
          <img alt="email" src="images/email_icon.png" style="opacity: 0.6;">

    So instead of using a nested list with classes for each button and the hierarchy in the nesting we have a lot of classes and a hand-rolled DIV construct. Instead of making buttons really disabled we rely on opacity and there is quite a mix of inline images and background images (if all were background images, they could be one sprite!). Keyboard navigation will have to be written for this and if you were to add a button you’d have to come up with another ID.

    HTML5 actually has a construct for this. There is a menu element with command child elements. These are in use in Chrome’s side bar for example and should be what we use. If you want to make it work for everyone, a nested list with button elements is what to go for.

    The overly complex DIV construct is quite used though – this was another example:

    <div class="uiScreen" id="startScreen">
      <div class="panelBackground" id="mainResumeButton" style="display: none;">
        <div class="largeUIButton" id="resumeButton">Resume Game</div>
      <div class="panelBackground" id="mainStartButton">
        <div class="largeUIButton" id="startButton">Start Game</div>
      <div class="panelBackground" id="mainHelpButton">
        <div class="largeUIButton" id="helpButton">Help</div>
      <div class="panelBackground" id="mainHighscoreButton">
        <div class="largeUIButton" id="highscoreButton">High Scores</div>

    When in doubt – add an ID and class to everything.

    Other buttons I encountered were actually links pointing to javascript:// using an inline style to indicate hierarchy:

    <ul class="navlist">
      <li><a id="play" href="javascript://"
             style="display: inline;">Play</a></li>
      <li><a id="pause" href="javascript://">Pause</a></li>
      <li style="padding-left: 2px;">Effects:</li>
      <li><a id="bw" href="javascript://">Bw</a></li>
      <li><a id="outline" href="javascript://">Outline</a></li>
      <li><a id="color" href="javascript://">Color</a></li>
      <li><a id="invert" href="javascript://">Invert</a></li>
      <li><a id="matrix" href="javascript://">Matrix</a></li>
      <li><a id="old" href="javascript://">Old</a></li>

    Talking of inline – here’s a great example of a tool generating a lot of code that could be replaced by a single event handler and event delegation:

    <div id="tools">
      <span onmouseout="buttonOut(1)" onmouseover="buttonOver(1)"
            onclick="buttonClicked(1)" id="button1" class="button">
        <img alt="" src="image/button/1.png">
      <span onmouseout="buttonOut(2)" onmouseover="buttonOver(2)"
            onclick="buttonClicked(2)" id="button2" class="button">
            <img alt="" src="image/button/2.png">
      [...repeated 20 times...]
    <div id="toolsSeparator">&nbsp;</div>
      <a title="" id="toolbarButtonSave" class="toolbarButton"
        <img alt="" src="image/save.png">
      <a title="New" id="toolbarButtonNew" class="toolbarButton"
        <img alt="New" src="image/new.png"></a>
      <!--[if !IE]><![IGNORE[--><!--[IGNORE[]]-->
      <a id="toolbarButtonMenu" class="toolbarButton"
         onmouseout="closeMenuDelay()" onmouseover="showMenuHover()"
        <img alt="&gt;" src="image/menu.png">
      <div onmouseout="closeMenuDelay()" onmouseover="overMenu()" id="menu">
        <a class="saveMenu" onmouseout="closeMenuDelay()"
           onmouseover="overMenu()" href="javascript:saveCanvas()">
          save normal
        <a class="saveMenu" onmouseout="closeMenuDelay()"
           onmouseover="overMenu()" href="javascript:saveCanvasHi()">
          save high quality
          <span class="footnote">&nbsp; (rename to *.png)</span>
        <a onmouseout="closeMenuDelay()" onmouseover="overMenu()"
        <a class="lastMenu" target="_top" onmouseout="closeMenuDelay()"
          <span class="footnote">
          <em>a sound memory game</em>

    Notice that if the images for the button couldn’t be loaded for one reason or another (or you can’t see them at all) this application is very confusing indeed – no alternative text for the images and no text content to fall back to. I am also very much sure that the in and out handlers trigger visual effects CSS could handle better.

    Reasons and effects

    I know there are probably good reasons for all of this, and I am sure I will also do things wrongly when I am rushed or want to get things out quickly. What we have to understand though is that right now we have a responsibility to show the best of breed demos we can.

    We cannot preach the open web and technologies and view-source over closed systems and at the same time forget the things we learnt in the last decade. Some of these things I found look like code Frontpage or Dreamweaver could have produced in the 90ies and resulted in a lot of badly performing, hard to maintain products that either still annoy people who have to use them or get replaced every 2 years.

    We have a mandate to educate the new developers coming to the web. Unlearning something is much harder than learning it – so let’s not start with bloat and quick fixes that work but forget to advocate clean code and thinking about the impact your product has on the end users (thinking accessibility) and the poor sods that will have to maintain your product when you are gone. We are not here to advocate effects and products, we are here to promote the tools that allow anyone to easily build something cool that is also easy to understand.

    HTML5 is about evolving the web as a platform – we also need to evolve with it and take more responsibility. We have app and we have markup enthusiasts. Let’s make them work together to build things that are great functionality and clean semantics.