CSS Articles

Sort by:


  1. Rendering 3D with CSS and JavaScript with dom3d (guest post)

    James Long Today we have a guest post by James Long (@jlongster).

    James is the tech lead for on the Web Development team. James is passionate about interactive graphics on the open web.

    Today he explains how you can create 3D objects using CSS without having 3D transforms support. Take it away, James.

    Recently I was tinkering with CSS3 and I discovered that it enabled me to do primitive 3D rendering, which I found fascinating! This led to the creation of dom3d, a JavaScript library that uses CSS to render basic 3D objects.

    Now the question is: why? Aren’t canvas, WebGL, and even SVG better technologies to work with for this? Possibly. However, CSS is becoming a powerful language for describing complex effects and shapes, and we should experiment.

    Keep that in mind, because CSS definitely isn’t intended to do this, but it’s worth trying to see where we should take CSS in the future.


    Although this is more of an experiment, it has a few real world benefits:

    All rendering libraries available for the web (canvas, WebGL, SVG) require a canvas, which is a constrained box on the page with a specific width and height. It is not possible to render anything outside this box. The canvas also captures all DOM events (like clicks), even completely transparent sections. Theoretically, this could make it difficult to do effects that overlay large parts of the page or are somehow deeply integrated to the content.

    Using CSS, we aren’t constrained to a box, and the effect can overlay large portions of the page without covering any the the links or other content requiring interaction.

    Other advantages include no need to initialize canvas 2D or WebGL, and a simplistic API making it easy to pick up even if you don’t know much about 3D. It might be easier for kids to start playing around with this before they jump into WebGL or something else. Also, because it’s just a dump of DOM elements you can embed it anywhere (without animation).

    So keep in mind that this is a hack, but with the above advantages. This might be good for certain effects: 3D cursor, nav transitions, and others.

    How it works

    Three-D objects are just a bunch of triangles put together, so let’s start with one simple triangle. If we get that working, it’s a simple step forward to render multiple triangles to form a 3D object.

    Rendering a 3d triangle on a 2D screen involves something called “projection”. This is the act of taking a 3D point and projecting it onto a 2D screen. Plug in a 3D triangle to a simple math equation, and you get a 2D triangle representing how the 3D one would look on the screen.

    The math is remarkably simple but may seem weird if you aren’t familiar with linear algebra. You can take a look at the renderer code.

    Now comes the fun part: can you render any 2D triangle simply with CSS3 transforms? Turns out you can! It just takes some fiddling to figure out which transforms to generate. CSS3 transforms are composed of translate, scale, rotate, and skew values, and we need a few equations to compute these values for a specific 2D triangle.

    First, let’s take a simple DOM element and turn it into a triangle. We can do this with the linear-gradient background image (another way is border triangles).

    JSFiddle demo.

    Now let’s draw the following blue triangle with the points [20, 20], [50, 120], and [120, 30]. A vital step is to set a few initial reference points which set everything in the same space. Our equations will assume these coordinate spaces. This is how the points A, B, C and the side AB are related.

    Triangle comparison

    If we take a closer look at this, we can derive the transform values. First, get an idea of which angles and values we need and then use geometry to form the equations (in pseudo-code). The red box represents the DOM element, the form AB represents the side formed by points A and B, and rotation occurs clockwise.

    dissecting triangles

    rotation = atan2(AB.x, AB.y)
    AC' = rotate(AC, -rotation)
    width = AC'.x
    height = length(AB)
    skew = atan2(AC'.y, AC'.x)
    translate = A

    Awesome! Let’s try it out. Here is a live DOM element being transformed by applying each of our equations:

    JSFiddle demo.

    The resulting triangle matches our target triangle! Here is the final CSS:

    width: 93px;
    height: 104px;
    background: -moz-linear-gradient(-0.727211rad, #0000FF 50%, transparent 0pt);
    -moz-transform: translate(20px, 20px) rotate(-0.291457rad) skewY(0.391125rad);
    -moz-transform-origin: top left;

    Note: The tranform-origin: top left line is important. Normally transforms happen relative to the center of the element, but our equations assume the top left.

    Note: dom3d also generates code with the -webkit and -o prefixes for WebKit and Opera support.

    You can view the implementation of these equations. It turns out that these equations work for any triangle, as long as the points given are in counter-clockwise order, which is standard in the graphics world.

    Taking it all the way

    Since we can project a 3D triangle into 2D space and render it with CSS, all we have to do now is apply that to several 3D triangles to form a 3D object!

    We need some 3D data at this point. I used Blender to export a teapot into the simple OBJ file format and wrote a script to dump the data as JavaScript. Rendering all those triangles with this technique produces the following:

    JSFiddle demo.

    Teapot! However, we can do much better. A big part of the 3D effect is shading. If we calculate normals, a vector representing where the triangle is facing, and specify a light direction, we can take the dot product of the normal and light for each triangle to get flat shading. View the code for flat shading.

    JSFiddle demo.

    There are many tweaks that take this even further. For example, the above objects have z-indexing enabled. Without this, a triangle that is supposed to be behind another may actually appear on top because it was rendered later. The dom3d uses a heap to render the triangles from back to front.

    Real-time animation can be achieved with a setTimeout or requestAnimationFrame function that continually renders the object. The dom3d supports the scale, translate, yaw, and pitch transformations, but there’s nothing stopping you from modifying the object data however you like between renderings. See some examples over at the dom3d website.

    Here is the code which renders the teapot animation with dom3d:

    JSFiddle demo.

    It’s more appropriate for webpages to update an animation in response to user interaction instead of constantly rendering and hogging the CPU. See the pole example on the dom3d site for an example.

    Improvements and last thoughts

    The most interesting possibility with this is to include actual page elements as part of 3D objects. A navigation item could pop out and swirl around in 3d space, and the nav item is seamlessly transformed along with it.

    That’s where this hack starts to show its faults, though. Unfortunately this is a little too hacky to provide an appropriate web experience. Because it tricks DIVs into fake triangles, it removes the possibility of integrating any page elements with it. With the coming of 3D CSS transforms though, we can start building true 3D objects made up of any kind of page elements. The only restriction with 3D transforms is that the 3D objects need to built with rectangles instead of triangles.

    Other people have already experimented with 3D transforms, like building a pure CSS 3D city. There’s another cool library, Sprite3D, which provides a JavaScript API for building basic 3d objects from page elements.

    The most glaring problem with dom3d is the seams in the object, which appear in all browsers. Apparently there are a few bugs in rendering engines when stressing their CSS3 transforms and using linear-gradients!

    The dom3d library provides an API to work with all of this, but is hasn’t been documented very well yet. Feel free to browse the README and code on github. These APIs could be improved as well. It also provides an SVG rendering backend, seen here, but I don’t this is the right direction to take. We should focus on building basic 3D objects with page elements.

    This was a fun experiment and I’m excited by how fast and capable browsers are becoming. The web is an exciting platform and getting richer and more powerful every year!

  2. Congratulations to our June Dev Derby winners!

    We kicked off our series of monthly developer challenges in June to see what Web developers could do with CSS3 Animations. Our first ever Dev Derby was a huge success with almost 30 entries and a variety of demos that brought action to the Web without JavaScript. The results have been awesome!

    Early fan favorites included Rofox CSS3 and CSS Nyan Cat, which remain among the most viewed on Demo Studio.

    While all the demos were amazing, we had a tough task in narrowing down the submissions to 5 finalists based on our judging criteria. After careful review and feedback, the following demos surfaced as candidates for our final round of voting:

    Animated menu icons
    Auto-run photo album
    CSS Tricks
    Plan B – Retro Demo

    With those 5 demos left in the running, we brought in our expert judges and a few members of the Mozilla team to vote on the finalists. Judges rated each demo on a scale of 1 – 5 across the following dimensions:

    • Technology – Does the demo showcase the power of open Web technologies?
    • Originality – How innovative and unique is the demo?
    • Aesthetics – How good is the visual design and interaction experience?
    • Practicality – How useful is this demo in enhancing the Web today?

    It was a close race and we’re excited to announce that the winners of the June Dev Derby are:

    1st Place: CSS Tricks by Mircea Piturca.
    2nd Place: Animated menu icons by Koen Hendrix.
    3rd Place: Plan B – Retro Demo by matt64.

    Auto-run photo album

    Thanks to everyone that submitted their awesome demos for the June Dev Derby. Up next we have HTML5 video for July, History API for August and Geolocation for September. We look forward to seeing even more great submissions for July and beyond! Hack on.

  3. HTML5 and CSS3: Exploring Mobile Possibilities – presentation at London Ajax Mobile Event

    In the beginning of July, I was attending and giving a presentation at the London Ajax Mobile Event about possibilities offered by HTML5 and CSS3 when it comes to developing mobile web sites and applications.

    Short introduction of me

    Being my first post here at Mozilla Hacks, I thought I’d start by briefly introducing myself first: My name is Robert Nyman and I’ve recently joined Mozilla as a Technical Evangelist, talking about HTML5, the Open Web and how we can help web developers. I’ve been working since 1999 with Front End development for the web, and I regularly blog at, tweet as @robertnyman and love to travel and meet people!

    The London Ajax Mobile Event

    The conference took place at the Vodafone headquarters in London, arranged by Sitepen CEO and Dojo co-founder Dylan Schiemann. It was packed to the brim with speakers, from early morning raging on into the night. Various talks were given on a number of topics – from mobile apps and implementations to a more experimenting approach and future visions.

    My presentation

    You can see the slides from my HTML5 and CSS3: Exploring Mobile Possibilities below or download the slides at SlideShare

    The aim of my talk was to give both an introduction and reiterate on some of the important options we have when developing web sites, especially when it comes to the mobile world. With the CSS3 field I covered CSS Media Queries and Flex Box and the options they give us in creating more flexible layouts and presentation alternatives. I also spoke about CSS Transitions and Animations and how they can assist in an easy manner to get nice effects, that are also hardware-accelerated on certain devices.

    When it comes to the HTML5 part, I’m excited by all the new HTML5 form elements and how they can improve both user experience and the input of data. As support grows for this in web browsers, I believe it will make things a lot easier for both developers and end users.

    I briefly touched on link protocols, such as tel: and sms:, to trigger mobile-specific actions when activating a link, and then various useful APIs such as Web Storage, Offline Applications, History API and Geolocation (not all necessary official HTML5 APIs, but usually used in conjunction with them).

    I ended the talk with touching on tool such as Steve Souders’ Mobile Perf bookmarklet and weinre, for remote debugging on mobile devices.

    You and mobile

    What I am interested in is if you are developing for a multitude of mobile and other devices, what you believe are the biggest obstacles as well as the most promising options. Any thoughts, please let me know!

  4. Aurora 7 is here

    Aurora Logo

    Download Aurora

    Keeping up the pace with our new development cycle, today we release Aurora 7. Enjoy its new features and performance improvements: CSS “text-overflow: ellipsis“, Navigation Timing API, reduced memory usage, a faster javascript parser, and the first steps of Azure, our new graphics API.

    text-overflow: ellipsis;

    It is now possible to get Firefox to display “” to give a visual clue that a text is longer than the element containing it.

    At last, with text-overflow implemented in Aurora 7 it’s now possible to create a cross-browser ellipsis!

    Navigation Timing

    Performance is a key parameter of the user experience on the Web. To help Web developers monitor efficiently the performance of their Web pages, Aurora 7 implements the Navigation Timing specification: using the window.performance.timing object, developers will be able to know the time when different navigation steps (such as navigationStart, connectStart/End, responseStart/End, domLoading/Complete) happened and deduce how long one step or a sequence of steps took to complete.

    Reduced Memory Usage

    Our continuous efforts to monitor and reduce memory consumption in Firefox will substantially pay off with Aurora 7:

    • The memory “zone” where javascript objects reside gets fragmented as objects are created and deleted. To reduce the negative impact of this fragmentation, long-lived objects created by the browser’s own UI have been separated from the objects created by Web pages. The browser can now free memory more efficiently when a tab is closed or after a garbage collection.
    • Speaking of garbage collection, as we successfully reduced the cost of this operation, we are able to execute it more often. Not only is memory freed more rapidly, but this also leads to shorter GC pauses(the period where javascript execution stops to let the garbage collector do his job, which is sometime noticeable during heavy animations).
    • All those improvements are reflected in the about:memory page, which is now able to tell how much memory a particular Web page or the browser’s own UI, is using.

    More frequent updates and detailed explanations of the memshrink effort are posted on Nicholas Nethercote’s blog.

    Faster Javascript Parsing

    A javascript parser is the part of the browser that reads the javascript before it gets executed by the javascript engine. With modern Web applications such as Gmail or Facebook sending close to 1Mb of javascript, being able to still read all of that code instantly matters in the quest of responsive user experience.
    Thanks to Nicholas’s work, our parser is now almost twice as fast as it used to. This adds up well with our constant work to improve the execution speed of our javascript engine.

    First Steps of Azure

    After the layout engine (Gecko) has computed the visual appearance (position, dimension, colors, …) of all elements in the window, the browser asks the Operating System to actually draw them on the screen. The browser needs an abstraction layer to be able to talk to the different graphics libraries of the different OSes, but this layer has to be as thin and as adaptable as possible to deliver the promises of hardware acceleration.
    Azure is the name of the new and better graphics API/abstraction layer that is going to gradually replace Cairo in hardware accelerated environments. In Aurora 7, it is already able to interact with Windows 7’s Direct2D API to render the content of a <canvas> element (in a 2D context). You can read a detailed explanation of the Azure project and its next steps on Joe Drew’s blog.

    Other Improvements



    • Specifying invalid values when calling setTransform(), bezierCurveTo(), or arcTo() no longer throws an exception; these calls are now correctly silently ignored.
    • Calling strokeRect with a zero width and height now correctly does nothing. (see bug 663190 )
    • Calling drawImage with a zero width or height <canvas> now throws INVALID_STATE_ERR. (see bug 663194 )
    • toDataURL() method now accepts a second argument to control JPEG quality (see bug 564388 )



    • XLink href has been restored and the MathML3 href attribute is now supported. Developers are encouraged to move to the latter syntax.
    • Support for the voffset attribute on <mpadded> elements has been added and behavior of lspace attribute has been fixed.
    • The top-level <math> element accepts any attributes of the <mstyle> element.
    • The medium line thickness of fraction bars in <mfrac> elements has been corrected to match the default thickness.
    • Names for negative spaces are now supported.


    • The File interface’s non-standard methods getAsBinary(), getAsDataURL(), and getAsText() have been removed as well as the non-standard properties fileName and fileSize.
    • The FileReader readAsArrayBuffer() method is now implemented. (see bug 632255 )
    • document.createEntityReference has been removed. It was never properly implemented and is not implemented in most other browsers. (see bug 611983 )
    • document.normalizeDocument has been removed. Use Node.normalize instead. (see bug 641190 )
    • DOMTokenList.item now returns undefined if the index is out of bounds, previously it returned null. (see bug 529328 )
    • Node.getFeature has been removed. (see bug 659053 )



    • WebSockets are now available on Firefox Mobile. (see bug 537787 )

    console API

    • Implement console.dir(), console.time(), console.timeEnd(), and console.groupEnd() methods.
    • Message logged with console.log before the WebConsole is opened are now stored and displayed once the WebConsole is opened.

    (see the Web Console page in the Wiki)

    Web Timing

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. 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.