Mozilla

CSS Articles

Sort by:

View:

  1. Live Editing Sass and Less in the Firefox Developer Tools

    Sass and Less are expressive languages that compile into CSS. If you’re using Sass or Less to generate your CSS, you might want to debug the source that you authored and not the generated CSS. Luckily you can now do this in the Firefox 29 developer tools using source maps.

    The Firefox developer tools use source maps to show the line number of rules in the original source, and let you edit original sources in the Style Editor. Here’s how to use the feature:

    1. Generate the source map

    When compiling a source to CSS, use the option to generate a sourcemap for each style sheet. To do this you’ll need Sass 3.3+ or Less 1.5+.

    Sass

    sass index.scss:index.css --sourcemap

    Less

    lessc index.less index.css --source-map

    This will create a .css.map source map file for each CSS file, and add a comment to the end of your CSS file with the location of the sourcemap: /*# sourceMappingURL=index.css.map */. The devtools will use this source map to map locations in the CSS style sheet to locations in the original source.

    2. Enable source maps in developer tools

    Right-click anywhere on the inspector’s rule view or in the Style Editor to get a context menu. Check off the Show original sources option:

    Enabling source maps in devtools

    Now CSS rule links will show the location in the original file, and clicking these links will take you to the source in the Style Editor:

    Original source showing in Style Editor

    3. Set up file watching

    You can edit original source files in Style Editor tool, but order to see the changes apply to the page, you’ll have to watch for changes to your preprocessed source and regenerate the CSS file each time it changes. To set watching up:

    Sass

    sass index.scss:index.css --sourcemap --watch

    Less

    For Less, you’ll have to set up another service to do the watching, like grunt.

    4. Save the original source

    Save the original source to your local file system by hitting the Save link or Cmd/Ctrl-S:

    Saving source to disk

    Saving source to disk

    The devtools will infer the location of the generated CSS file locally and watch that file for changes to update the live style sheet on the page.

    Now when you edit an original source and save it, the page’s style will update and you’ll get immediate feedback on your Sass or Less changes.

    The source has to be saved to disk and file watching set up in order for style changes to take effect.

  2. HTML5, CSS3, and the Bookmarklet that Shook the Web

    On Valentine’s Day last year we released a bookmarklet that went viral riding the popularity of the Harlem Shake meme. On the anniversary of its release we’d like to take a moment look back at the technical nuts and bolts of the bookmarklet as a case study in applying HTML5. In fact, the HTML, JavaScript, and CSS we used wouldn’t have worked on a single browser a few years ago. What follows is a technical discussion on how we took advantage of recent browser developments to shake up the web.

    Background

    Last year the Harlem Shake meme forced itself on to nearly every screen under the sun and, like everyone else, we had joked about doing our office version of the video. After tossing around a few bad video ideas, Ishan half-jokingly suggested a bookmarklet that made a web page do the Harlem Shake. Omar and Hari immediately jumped on the ingenuity of his idea and built a prototype within an hour that had the entire office LOLing. After pulling a classic all nighter we released it on February 14th, declaring “Happy Valentine’s Day, Internet! Behold, the Harlem Shake Bookmarklet”.

    Pretty soon it was picked up by news outlets like TechCrunch and HuffingtonPost, and our traffic skyrocketed. Meanwhile the bookmarklet offered a new avenue of expression in the watch-then-remix cycle that is the lifeblood of a viral meme like the Harlem Shake. Instead of creating a video of people dancing, developers could now remix this symbiotic meme in code. Startups like PivotDesk incorporated the bookmarklet into their websites, and HSMaker used the code to build a Harlem-Shake-As-A-Service website. Eventually, YouTube even built their own version as an easter egg on their site.

    So, how does it work?

    Once you click the Harlem Shake bookmark, a snippet of JS is evaluated on the webpage, just as you’d see by entering javascript:alert(“Hi MozHacks!”); in your address bar. This JavaScript will play the Harlem Shake audio, “shake” DOM nodes (according to timing events attached to the audio), and remove all DOM changes afterward.

    How did we attach the audio to the page and get the timing for the shakes just right?

    HTML5’s extensive audio support made this implementation fairly easy. All that was required was inserting an <audio> tag with the src pointed to the Harlem_Shake.ogg file. Once inserted into the DOM, the file would begin downloading, and playback begins once enough of the file has been buffered.

    HTML5 timed audio events allow us to know exactly when playback begins, updates, and ends. We attach a listener to the audio node which evaluates some JS once the audio reaches certain time. The first node starts shaking once the song is beyond 0.5s. Then, at 15.5s, we flash the screen and begin shaking all of the nodes. At 28.5s, we slow down the animations, and once the audio has ended, we stop all animations and clean up the DOM.

    audioTag.addEventListener("timeupdate", function() {
      var time = audioTag.currentTime,
          nodes = allShakeableNodes,
          len = nodes.length, i;
     
      // song started, start shaking first item
      if(time >= 0.5 && !harlem) {
        harlem = true;
        shakeFirst(firstNode);
      }
     
      // everyone else joins the party
      if(time >= 15.5 && !shake) {
        shake = true;
        stopShakeAll();
        flashScreen();
        for (i = 0; i < len; i++) {
          shakeOther(nodes[i]);
        }
      }
     
      // slow motion at the end
      if(audioTag.currentTime >= 28.4 && !slowmo) {
        slowmo = true;
        shakeSlowAll();
      }
    }, true);
     
    audioTag.addEventListener("ended", function() {
      stopShakeAll();
      removeAddedFiles();
    }, true);

    How did we choose which parts of the page to shake?

    We wrote a few helpers to calculate the rendered size of a given node, determine whether the node is visible on the page, and whether its size is within some (rather arbitrary) bounds:

    var MIN_HEIGHT = 30; // pixels
    var MIN_WIDTH = 30;
    var MAX_HEIGHT = 350;
    var MAX_WIDTH = 350;
     
    function size(node) {
      return {
        height: node.offsetHeight,
        width: node.offsetWidth
      };
    }
    function withinBounds(node) {
      var nodeFrame = size(node);
      return (nodeFrame.height > MIN_HEIGHT &&
              nodeFrame.height < MAX_HEIGHT &&
              nodeFrame.width > MIN_WIDTH &&
              nodeFrame.width < MAX_WIDTH);
    }
    // only calculate the viewport height and scroll position once
    var viewport = viewPortHeight();
    var scrollPosition = scrollY();
    function isVisible(node) {
      var y = posY(node);
      return (y >= scrollPosition && y <= (viewport + scrollPosition));
    }

    We got a lot of questions about how the bookmarklet was uncannily good at iniating the shake on logos and salient parts of the page. It turns out this was the luck of using very simple heuristics. All nodes are collected (via document.getElementsByTagName(“*”)) and we loop over them twice:

    1. On the first iteration, we stop once we find a single node that is within the bounds and visible on the page. We then start playing the audio with just this node shaking. Since elements are searched in the order they appear in the DOM (~ the order on the page), the logo is selected with surprising consistency.
    2. After inserting the audio, we have ~15 seconds to loop through all nodes to identify all shakeable nodes. These nodes get stored in an array, so that once the time comes, we can shake them.
    // get first shakeable node
    var allNodes = document.getElementsByTagName("*"), len = allNodes.length, i, thisNode;
    var firstNode = null;
    for (i = 0; i < len; i++) {
      thisNode = allNodes[i];
      if (withinBounds(thisNode)) {
        if(isVisible(thisNode)) {
          firstNode = thisNode;
          break;
        }
      }
    }
     
    if (thisNode === null) {
      console.warn("Could not find a node of the right size. Please try a different page.");
      return;
    }
     
    addCSS();
     
    playSong();
     
    var allShakeableNodes = [];
     
    // get all shakeable nodes
    for (i = 0; i < len; i++) {
      thisNode = allNodes[i];
      if (withinBounds(thisNode)) {
        allShakeableNodes.push(thisNode);
      }
    }

    How did we make the shake animations not lame?

    We utilized and tweaked Animate.css’s library to speed up the process, its light and easy to use with great results.

    First, all selected nodes gets a base class ‘harlem_shake_me’ that defines animation parameters for duration and how it should apply the styles.

    .mw-harlem_shake_me {
      -webkit-animation-duration: .4s;
         -moz-animation-duration: .4s;
           -o-animation-duration: .4s;
              animation-duration: .4s;
      -webkit-animation-fill-mode: both;
         -moz-animation-fill-mode: both;
           -o-animation-fill-mode: both;
              animation-fill-mode: both;
    }

    The second set of classes that defines the animation’s behavior are randomly picked and assigned to various nodes.

    @-webkit-keyframes swing {
      20%, 40%, 60%, 80%, 100% { -webkit-transform-origin: top center; }
      20% { -webkit-transform: rotate(15deg); } 
      40% { -webkit-transform: rotate(-10deg); }
      60% { -webkit-transform: rotate(5deg); }  
      80% { -webkit-transform: rotate(-5deg); } 
      100% { -webkit-transform: rotate(0deg); }
    }
     
    @-moz-keyframes swing {
      20% { -moz-transform: rotate(15deg); }  
      40% { -moz-transform: rotate(-10deg); }
      60% { -moz-transform: rotate(5deg); } 
      80% { -moz-transform: rotate(-5deg); }  
      100% { -moz-transform: rotate(0deg); }
    }
     
    @-o-keyframes swing {
      20% { -o-transform: rotate(15deg); }  
      40% { -o-transform: rotate(-10deg); }
      60% { -o-transform: rotate(5deg); } 
      80% { -o-transform: rotate(-5deg); }  
      100% { -o-transform: rotate(0deg); }
    }
     
    @keyframes swing {
      20% { transform: rotate(15deg); } 
      40% { transform: rotate(-10deg); }
      60% { transform: rotate(5deg); }  
      80% { transform: rotate(-5deg); } 
      100% { transform: rotate(0deg); }
    }
     
    .swing, .im_drunk {
      -webkit-transform-origin: top center;
      -moz-transform-origin: top center;
      -o-transform-origin: top center;
      transform-origin: top center;
      -webkit-animation-name: swing;
      -moz-animation-name: swing;
      -o-animation-name: swing;
      animation-name: swing;
    }

    Shake it like a polaroid picture

    What started a joke ended up turning into its own mini-phenomenon. The world has moved on from the Harlem Shake meme but the bookmarklet is still inspiring developers to get creative with HTML5.

    If you want to see the full source code or have suggestions, feel free to contribute to the Github repo!

  3. Application Layout with CSS3 Flexible Box Module

    It has become very easy to create fluid application layouts thanks to the CSS3 Flexible Box Layout Module. In this article we are going to implement a simple application layout, which fills the whole screen, resizes with the browser window and comes with the additional bonus of a draggable splitter.

    Instead of the classic <div> elements let’s also use some HTML5 structural tags. This will not only make the code more semantic, but also more convenient to work with, since we can directly address the elements with a CSS type selector without having to rely on id attributes or parent-child relationships.

    Take a look at the complete demo to see how it works.

    First step: Add Vertical Boxes

    We start with only three tags (<header>, <main> and <footer>) in the body.

    <!DOCTYPE html>
    <html>
    <head>
        <title>CSS3 Application Layout</title>
    </head>
     
    <body>
    <header></header>
    <main></main>
    <footer></footer>
    </body>
    </html>

    Let’s add the CSS to make these three elements fill the space vertically. This is achieved by setting the CSS display property of the <body> to flex and the flex-direction property to column. This tells the browser to lay out the body’s children (<header>, <main> and <footer>) as vertical flexible boxes.

    How this available space is distributed can be controlled with the flex shorthand property. You can read about it on MDN. In this application layout though, we don’t want the size to shrink or expand proportionally. Instead the <header> and the <footer> element should have a fixed height, whereas the <main> should just fill the remaining space by setting its flex property to auto.

    html, body {
        height: 100%;
        width: 100%;
        padding: 0;
        margin: 0;
    }
     
    body {
        display: flex;
        flex-direction: column;
    }
     
    header {
        height: 75px;
    }
     
    main {
        flex: auto;
    }
     
    footer {
        height: 25px;
    }

    Show demo

    Second Step: Horizontal Boxes

    Let’s add three more elements (<nav>, <article> and <aside>) inside the <main> element. But this time we want them to fill the space inside the <main> element horizontally instead of vertically.

    <body>
    <header></header>
    <main>
        <nav></nav>
        <article></article>
        <aside></aside>
    </main>
    <footer></footer>
    </body>

    This is achieved by setting the display property of the <main> element also to flex, but the flex-direction property to row (this is the default). The <nav> and <aside> element should have a fixed width, while the <article> should just fill the remaining space: this is achieved in the same kind of manner as before:

    main {
        display: flex;
        flex-direction: row;
        flex: auto;
    }
     
    nav {
        width: 150px;
    }
     
    article {
        flex: auto;
    }
     
    aside {
        width: 50px;
    }

    Show demo

    Thats all. Resize your browser window and enjoy the flexible application layout.

    Next step: CSS Refinements

    But wait. When there is a lot of content, an element can become smaller than specified and also scrollbars can appear.

    Therefore, we need to add a min-width property to all elements where we added a width property. We also should set the overflow property of the <body> and the <main> element to hidden as well as the overflow-y of <article> and <aside> to auto to only show scrollbars where we want them.

    body {
    	overflow: hidden;
    	display: flex;
    	flex-direction: column;
    }
     
    header {
    	height: 75px;
    	min-height: 75px;
    }
     
    footer {
    	height: 25px;
    	min-height: 25px;
    }
     
    main {
    	display: flex;
    	flex-direction: row;
    	flex: auto;
    	border: solid grey;
    	border-width: 1px 0;
    	overflow: hidden;
    }
     
    nav {
    	width: 150px;
    	min-width: 150px;
    }
     
    article {
    	border: solid grey;
    	border-width: 0 0 0 1px;
    	flex: auto;
    	overflow-x: hidden;
    	overflow-y: auto;
    }
     
    aside {
    	width: 50px;
    	min-width: 50px;
    	overflow-x: hidden;
    	overflow-y: auto;
    }

    Note: This does probably not work in Safari yet. You might be able to get it to work by using the -webkit- prefix.

    Final Step: Throw a little JavaScript into the Mix

    As the final step, we want the user to be able to resize the <aside> element when dragging it with the mouse. For that we add a <div> element as a splitter, which will serve as the drag handle.

    <body>
    <header></header>
    <main>
        <nav></nav>
        <article></article>
        <div class="splitter"></div>
        <aside></aside>
    </main>
    <footer></footer>
    </body>

    We set the width of the handle to 4px and give the cursor attribute a value of col-resize, to show the user that this element can be resized East-West.

    .splitter {
        border-left: 1px solid grey;
        width: 4px;
        min-width: 4px;
        cursor: col-resize;
    }

    All what’s left now is to add a little JavaScript, that enables moving the splitter.

    var w = window, d = document, splitter;
     
    splitter = {
        lastX: 0,
        leftEl: null,
        rightEl: null,
     
        init: function(handler, leftEl, rightEl) {
            var self = this;
     
            this.leftEl = leftEl;
            this.rightEl = rightEl;
     
            handler.addEventListener('mousedown', function(evt) {
                evt.preventDefault();    /* prevent text selection */
     
                self.lastX = evt.clientX;
     
                w.addEventListener('mousemove', self.drag);
                w.addEventListener('mouseup', self.endDrag);
            });
        },
     
        drag: function(evt) {
            var wL, wR, wDiff = evt.clientX - splitter.lastX;
     
            wL = d.defaultView.getComputedStyle(splitter.leftEl, '').getPropertyValue('width');
            wR = d.defaultView.getComputedStyle(splitter.rightEl, '').getPropertyValue('width');
            wL = parseInt(wL, 10) + wDiff;
            wR = parseInt(wR, 10) - wDiff;
            splitter.leftEl.style.width = wL + 'px';
            splitter.rightEl.style.width = wR + 'px';
     
            splitter.lastX = evt.clientX;
        },
     
        endDrag: function() {
            w.removeEventListener('mousemove', splitter.drag);
            w.removeEventListener('mouseup', splitter.endDrag);
        }
    };
     
    splitter.init(d.getElementsByClassName('splitter')[0], d.getElementsByTagName('article')[0], d.getElementsByTagName('aside')[0]);

    Note: For some reason the resizing doesn’t work in IE11 (, Safari?) or Chrome 31. It seems that it has something to do with the display: flex; property value.

  4. CSS Variables in Firefox Nightly

    As reported by Cameron McCormack, Firefox Nightly (version 29) now supports CSS variables. You can get a quick overview in this short screencast:

    You can define variables in a context with a var- prefix and then implement them using the var() instruction. For example:

    :root {
      var-companyblue: #369; 
      var-lighterblue: powderblue;
    }
     
    h1 {
      color: var(companyblue);
    }
    h2 {
      color: var(lighterblue);
    }
    <h1>Header on page</h1>
    <h2>Subheader on page</h2>

    This defines the two variables companyblue and lighterblue for the root element of the document which results in (you can try it here using Firefox Nightly):

    Variables are scoped, which means you can overwrite them:

    :root {
      var-companyblue: #369;
      var-lighterblue: powderblue;
    }
    .partnerbadge {
      var-companyblue: #036;
      var-lighterblue: #cfc;
    }
     
    h1 {
      color: var(companyblue);
    }
    h2 {
      color: var(lighterblue);
    }
    <h1>Header on page</h1>
    <h2>Subheader on page</h2>
     
    <div class="partnerbadge">
      <h1>Header on page</h1>
      <h2>Subheader on page</h2>
    </div>

    Using these settings, headings inside an element with a class of partnerbadge will now get the other blue settings:

    Variables can be any value you want to define and you can use them like any other value, for example inside a calc() calculation. You can also reset them to other values, for example inside a media query. This example shows many of these possibilities.

    :root {
      var-companyblue: #369;
      var-lighterblue: powderblue;
      var-largemargin: 20px;  
      var-smallmargin: calc(var(largemargin) / 2);
      var-borderstyle: 5px solid #000;
      var-headersize: 24px;
    }
    .partnerbadge {
      var-companyblue: #036;
      var-lighterblue: #369;
      var-headersize: calc(var(headersize)/2);
      transition: 0.5s;
    }
     
    @media (max-width: 400px) {
      .partnerbadge {
         var-borderstyle: none;  
         background: #eee;
      }
    }
     
    /* Applying the variables */
    body {font-family: 'open sans', sans-serif;}
     
    h1 {
      color: var(companyblue);
      margin: var(largemargin) 0;
      font-size: var(headersize);
    }
    h2 {
      color: var(lighterblue);
      margin: var(smallmargin) 0;
      font-size: calc(var(headersize) - 5px);
    }
     
    .partnerbadge {
      padding: var(smallmargin) 10px;
      border: var(borderstyle);
    }

    Try resizing the window to less than 400 pixels to see the mediaQuery change in action.

    An initial implementation of CSS Variables has just landed in Firefox Nightly, which is currently at version 29 and after the February 3 merge, in Firefox Aurora. There are still a few parts of the specification which still need to be supported before the can go into the release cycle of Firefox Beta and Firefox. Cameron has the details on that:

    The only part of the specification that has not yet been implemented is the CSSVariableMap part, which provides an object that behaves like an ECMAScript Map, with get, set and other methods, to get the values of variables on a CSSStyleDeclaration. Note however that you can still get at them in the DOM by using the getPropertyValue and setProperty methods, as long as you use the full property names such as "var-theme-colour-1".

    The work for this feature was done in bug 773296, and my thanks to David Baron for doing the reviews there and to Emmanuele Bassi who did some initial work on the implementation. If you encounter any problems using the feature, please file a bug!

    For now, have fun playing with CSS variables in Nightly and tell us about issues you find.

  5. CSS Length Explained

    When styling a web site with CSS you might have realised that an inch on a screen is not an actual inch, and a pixel is not necessarily an actual pixel. Have you ever figured out how to represent the speed of light in CSS pixels? In this post, we will explore the definition of CSS length units starting by understanding some of the physical units with the same name, in the style of C.G.P. Grey[1].

    The industrial inch (in)

    People who live in places where the inch is a common measure are already familiar with the physical unit. For the rest of us living in places using the metric system, since 1933, the “industrial inch” has been defined as mathematical equivalent of 2.54 centimeters, or 0.0254 metres.

    The device pixel

    Computer screens display things in pixels. The single physical “light blob” on the display, capable of displaying the full color independent of it’s neighbour is called a pixel (picture element). In this post, we refer to the physical pixel on the screen as “device pixel” (not to be confused with CSS pixel which will be explained later on).

    Display pixel density, dots per inch (DPI), or pixels per inch (ppi)

    The physical dimension of a device pixel on a specific device can be derived from the display pixel density given by the device manufacturer, usually in dots per inch (DPI), or pixels per inch (PPI). Both units are essentially talking about the same thing when they refer to a screen display, where DPI is the commonly-used-but-incorrect unit and PPI is the more-accurate-but-no-one-cares one. The physical dimension of a device pixel is simply the inverse number of it’s DPI.

    The MacBook Air (2011) I am currently using comes with a 125 DPI display, so

    (width or height of one device pixel) = 1/125 inch = 0.008 inch = 0.02032 cm

    Obviously this is a number too small to be printed on the specification, so the DPI stays.

    The CSS pixel (px)

    The dimension of a CSS pixel can be roughly regarded as a size to be seen comfortably by the naked human eye, not too small so you’d have to squint, and not big enough for you to see pixelation. Instead of consulting your ophthalmologist on the definition of “seen comfortably”, the W3C CSS specification gives us a recommend reference:

    The reference pixel is the visual angle of one pixel on a device with a pixel density of 96 DPI and a distance from the reader of an arm’s length.

    The proper dimension of a CSS pixel is actually dependent on the distance between you and the display. With the exception of Google Glass (which mounts on your head), people usually find their own unique comfortable distance, dependent on their eyesight, for a particular device. Given the fact we have no way to tell whether the user is visually impaired, what concerns us is simply typical viewing distance for the given device form factor — e.g., a mobile phone is usually held closer, and a laptop is usually used on a desk or a lap. Thus, the “viewing distance” of mobile phones is shorter than the one of laptops, or desktop computers.

    The viewing distance

    As previously mentioned, the viewing distance varies from person to person and from device to device, which is why we must categorise devices into form factors. The recommended reference viewing distance (“an arm’s length”) and the reference pixel density (“96 DPI”) is actually historical; it is a testimony of the way people during the late-20th century usually accessed the web:

    The first computer that runs the web. From Wikipedia: WWW

    The first computer that runs the web. From Wikipedia: WWW.

    For day-to-day devices of the 21st century, we have different reference recommendations:

    Baseline pixel density

    Width/height of one CSS pixel

    Viewing distance

    A 20th century PC with CRT display

    96 DPI

    ~0.2646 mm (1/96in)

    28 in (71.12cm)

    Modern laptop with LCD[2]

    125 DPI

    0.2032 mm (1/125in)

    21.5 in (54.61cm)

    Smartphones/Tablets[3]

    160 DPI

    ~0.159mm (1/160 in)

    16.8in (42.672cm)

    From this table, it’s pretty easy to see that as the pixel density increases and size of a CSS pixel gets smaller, muggles like you and me usually need to hold the device closer to comfortably see what’s on the device screen.

    With that, we established a basic fact in the world of CSS: a CSS pixel will be displayed in different physical dimensions but it will always be displayed in the correct size in which the viewer will find comfortable. By leveraging the principle, we can safely set the basic dimensions (e.g. base font size) to a fixed pixel size, independent of device form factors.

    CSS inch (in)

    On a computer screen, a CSS inch has nothing to do with the physical inch. Instead, it is being redefined to be exactly equal to 96 CSS pixels. This has resulted in an awkward situation, where you can never reliably draw an accurate ruler on the screen with basic CSS units[4]. Yet this gives us what’s intended: elements sized in CSS units will always be displayed across devices in a way where the user will feel comfortable.

    As a side note, if the user prints out the page on a piece of paper, browsers will map the CSS inch to the physical inch. You can reliably draw an accurate ruler with CSS and print it out. (make sure you’d turn off “scale to fit” in the printer settings!)

    Device pixel ratio (DPPX)

    As we step into the future (where is my flying car?), many of the smartphones nowadays are shipped with high-density displays. In order to make sure that CSS pixels are sized consistently across every device that accesses the web (i.e. everything with a screen and network connection), device manufacturers had to map multiple device pixels to one CSS pixel to make up for it’s relative bigger physical size. The ratio of the dimension of CSS pixel relative to device pixels is the device pixel ratio (DPPX).

    Let’s take iPhone 4 as the most famous example. It comes with a 326 DPI display. According to our table above, as a smartphone, it’s typical viewing distance is 16.8 inches and it’s baseline pixel density is 160 DPI. To create one CSS pixel, Apple chose to set the device pixel ratio to 2, which effectively makes iOS Safari display web pages in the same way as it would on a 163 DPI phone.

    Before we move on, take a look back on the numbers above. We can actually do better by not setting device pixel ratio to 2 but to 326/160 = 2.0375, and make a CSS pixel exactly the same compared to the reference dimensions. Unfortunately, such ratio will result in an unintended consequence: as each CSS pixel is not being displayed by whole device pixels, the browser would have to make some efforts to anti-alias all the bitmap images, borders, etc. since almost always they are defined as whole CSS pixels. It’s hard for browsers to utilize 2.0375 device pixels to draw your 1 CSS pixel-wide border: it’s way more easier to do it if the ratio is simply 2.

    Incidentally, 163 DPI happens to be the pixel density of the previous generation of the iPhone, so the web will work the same way without having developers to do any special “upgrades” to their websites.

    Device manufacturers usually choose 1.5, or 2, or other whole numbers as the DPPX value. Occasionally, some devices decided not to play nice and shipped with something like 1.325 DPPX; as web developers, we should probably ignore those devices.

    Firefox OS, initially being a mobile phone operating system, implemented DPPX calculation in this way. The actual DPPX will be determined by the manufacturer of each shipping device.

    CSS point (pt)

    Point is a commonly used unit that came from the typography industry, as the unit for metal typesetting. As the world gradually moved from letterpress printing to desktop publishing, a “PostScript point” was then redefined as 1/72 inches. CSS follows the same convention and mapped 1 CSS point to 1/72 CSS inches, and 96/72 CSS pixels.

    You can easily see that just like a CSS inch, on a device display, CSS point has little to do with the traditional unit. Its size only matches it’s desktop publishing counterpart when we actually print out the web page.

    CSS pica (pc), CSS centimeter (cm), CSS millimeter (mm)

    Just like CSS inch, while their relative relationships are kept, their basic size on the screen have been redefined by CSS pixel, instead of the standard SI unit (metre), which is defined by the speed of light, a universal constant.

    We could literally redefine the speed of light in CSS; it is 1,133,073,857,007.87 CSS pixels per second[5] – relativity in CSS makes light travel a bit slower on devices with smaller form factors than traditional PCs, from our perspective, looking into the screen from the real world.

    The viewport meta tag

    Though the smartphone is handy in the palm of your hand and its guaranteed that CSS pixels will be displayed in a size comfortable to users, a device capable of showing only a part of a fixed-width desktop website is not going to be very useful. It would be equally not useful if the phone violated the CSS unit rules and pretended it to be something else.

    The introduction of the viewport meta tag brought the best of both worlds to mobile devices by giving the control of page scaling to both users and web developers. You could design a mobile layout, and opt out of viewport scaling, or, you could leave your website made for desktop browsers as-is and have the mobile browser scale down the page for you and the user. As always, detailed descriptions and usage can be found on Mozilla Developer Network.

    Conclusion

    Browser vendors, while being in competition, recognize the effort of maintaining the stability of the Web platform and coordinate their feature sets through a standard organization. Features and APIs exposed will be carefully tested for their usefulness across all scenarios, before declaring their suitability as a standard. The definition of CSS pixel has one of those since the beginning. New features introduced must maintain backward-compatibility instead of changing the old behavior[6], so many of them (device pixels, viewport meta tag, etc.) are being introduced as extra layers of complexity. Old web pages that use standardized features, thus have a built-in “forward-compatibility”.

    With that in mind, Mozilla, together with our partners, nurture and defend the Open Web — the unique platform that we all cherish.


    [1] Well, not actually, cause we are not going to make a video about it. I won’t mind if C.G.P. Grey actually made a video about this!

    [2] Appears to be common values for laptops[citation needed].

    [3] The typical value is documented here as a “mdpi” Android device.

    [4] With one exception: the non-standard CSS unit mozmm gives you the ability to do so provided that Firefox knows the pixel density it runs on. This is out of scope of our topic there.

    [5] 299,792,458 metres per second ÷ 0.0254 meters per inch x 96 pixels per inch

    [6] There was a brief period of time where people tried to come up with an entirely new standard that breaks backward compatibility (*cough* xHTML *cough*), but that’s a story for another time.

  6. Capturing – Improving Performance of the Adaptive Web

    Responsive design is now widely regarded as the dominant approach to building new websites. With good reason, too: a responsive design workflow is the most efficient way to build tailored visual experiences for different device screen sizes and resolutions.

    Responsive design, however, is only the tip of the iceberg when it comes to creating a rich, engaging mobile experience.


    Image Source: For a Future-Friendly Web by Brad Frost

    The issue of performance with responsive websites

    Performance is one of the most important features of a website, but is also frequently overlooked. Performance is something that many developers struggle with – in order to create high-performing websites you need to spend a lot of time tuning your site’s backend. Even more time is required to understand how browsers work, so that you make rendering pages as fast as possible.

    When it comes to creating responsive websites, the performance challenges are even more difficult because you have a single set of markup that is meant to be consumed by all kinds of devices. One problem you hit is the responsive image problem – how do you ensure that big images intended for your Retina Macbook Pro are not downloaded on an old Android phone? How do you prevent desktop ads from rendering on small screen devices?

    It’s easy to overlook performance as a problem because we often conduct testing under perfect conditions – using a fast computer, fast internet, and close proximity to our servers. Just to give you an idea of how evident this problem is, we conducted an analysis into some top responsive e-commerce sites which revealed that the average responsive site home page consists of 87.2 resources and is made up of 1.9 MB of data.

    It is possible to solve the responsive performance problem by making the necessary adjustments to your website manually, but performance tuning by hand involves both complexity and repetition, and that makes it a great candidate for creating tools. With Capturing, we intend to make creating high-performing adaptive web experiences as easy as possible.

    Introducing Capturing

    Capturing is a client-side API we’ve developed to give developers complete control over the DOM before any resources have started loading. With responsive sites, it is a challenge to control what resources you want to load based on the conditions of the device: all current solutions require you to make significant changes to your existing site by either using server-side user-agent detection, or by forcing you to break semantic web standards (for example, changing the src attribute to data-src).

    Our approach to give you resource control is done by capturing the source markup before it has a chance to be parsed by the browser, and then reconstructing the document with resources disabled.

    The ability to control resources client-side gives you an unprecedented amount of control over the performance of your website.

    Capturing was a key feature of Mobify.js 1.1, our framework for creating mobile and tablet websites using client-side templating. We have since reworked Mobify.js in our 2.0 release to be a much more modular library that can be used in any existing website, with Capturing as the primary focus.

    A solution to the responsive image problem

    One way people have been tackling the responsive image problem is by modifying existing backend markup, changing the src of all their img elements to something like data-src, and accompanying that change with a <noscript> fallback. The reason this is done is discussed in this CSS-Tricks post

    “a src that points to an image of a horse will start downloading as soon as that image gets parsed by the browser. There is no practical way to prevent this.

    With Capturing, this is no longer true.

    Say, for example, you had an img element that you want to modify for devices with Retina screens, but you didn’t want the original image in the src attribute to load. Using Capturing, you could do something like this:

    if (window.devicePixelRatio && window.devicePixelRatio >= 2) {
        var bannerImg = capturedDoc.getElementById("banner");
        bannerImg.src = "retinaBanner.png"
    }

    Because we have access to the DOM before any resources are loaded, we can swap the src of images on the fly before they are downloaded. The latter example is very basic – a better example to highlight the power of capturing it to demonstrate a perfect implementation of the picture polyfill.

    Picture Polyfill

    The Picture element is the official W3C HTML extension for dealing with adaptive images. There are polyfills that exist in order to use the Picture element in your site today, but none of them are able to do a perfect polyfill – the best polyfill implemented thus far requires a <noscript> tag surrounding an img element in order to support browsers without Javascript. Using Capturing, you can avoid this madness completely.

    Open the example and be sure to fire up the network tab in web inspector to see which resources get downloaded:

    Here is the important chunk of code that is in the source of the example:

    <picture>
        <source src="/examples/assets/images/small.jpg">
        <source src="/examples/assets/images/medium.jpg" media="(min-width: 450px)">
        <source src="/examples/assets/images/large.jpg" media="(min-width: 800px)">
        <source src="/examples/assets/images/extralarge.jpg" media="(min-width: 1000px)">
        <img src="/examples/assets/images/small.jpg">
    </picture>

    Take note that there is an img element that uses a src attribute, but the browser only downloads the correct image. You can see the code for this example here (note that the polyfill is only available in the example, not the library itself – yet):

    Not all sites use modified src attributes and <noscript> tags to solve the responsive image problem. An alternative, if you don’t want to rely on modifying src or adding <noscript> tags for every image of your site, is to use server-side detection in order to swap out images, scripts, and other content. Unfortunately, this solution comes with a lot of challenges.

    It was easy to use server-side user-agent detection when the only device you needed to worry about was the iPhone, but with the amount of new devices rolling out, keeping a dictionary of all devices containing information about their screen width, device pixel ratio, and more is a very painful task; not to mention there are certain things you cannot detect with server-side user-agent – such as actual network bandwidth.

    What else can you do with Capturing?

    Solving the responsive image problem is a great use-case for Capturing, but there are also many more. Here’s a few more interesting examples:

    Media queries in markup to control resource loading

    In this example, we use media queries in attributes on images and scripts to determine which ones will load, just to give you an idea of what you can do with Capturing. This example can be found here:

    Complete re-writing of a page using templating

    The primary function of Mobify.js 1.1 was client-side templating to completely rewrite the pages of your existing site when responsive doesn’t offer enough flexibility, or when changing the backend is simply too painful and tedious. It is particularly helpful when you need a mobile presence, fast. This is no longer the primary function of Mobify.js, but it still possible using Capturing.

    Check out this basic example:

    In this example, we’ve taken parts of the existing page and used them in a completely new markup rendered to browser.

    Fill your page with grumpy cats

    And of course, there is nothing more useful then replacing all the images in a page with grumpy cats! In a high-performing way, of course ;-).

    Once again, open up web inspector to see that the original images on the site did not download.

    Performance

    So what’s the catch? Is there a performance penalty to using Capturing? Yes, there is, but we feel the performance gains you can make by controlling your resources outweigh the minor penalty that Capturing brings. On first load, the library (and main executable if not concatenated together), must download and execute, and the load time here will vary depending on the round trip latency of the device (ranges from around ~60ms to ~300ms). However, the penalty of every subsequent request will be reduced by at least half due to the library being cached, and the just-in-time (JIT) compiler making the compilation much more efficient. You can run the test yourself!

    We also do our best to keep the size of the library to a minimum – at the time of publishing this blog post, the library is 4KB minified and gzipped.

    Why should you use Capturing?

    We created Capturing to give more control of performance to developers on the front-end. The reason other solutions fail to solve this problem is because the responsibilities of the front-end and backend have become increasingly intertwined. The backend’s responsibility should be to generate semantic web markup, and it should be the front-end’s responsibility to take the markup from the backend and processes it in such a way that it is best visually represented on the device, and in a high-performing way. Responsive design solves the first issue (visually representing data), and Capturing helps solve the next (increasing performance on websites by using front-end techniques such as determining screen size and bandwidth to control resource loading).

    If you want to continue to obey the laws of the semantic web, and if you want an easy way to control performance at the front-end, we highly recommend that you check out Mobify.js 2.0!

    How can I get started using Capturing?

    Head over to our quick start guide for instructions on how to get setup using Capturing.

    What’s next?

    We’ve begun with an official developer preview of Mobify.js 2.0, which includes just the Capturing portion, but we will be adding more and more useful features.

    The next feature on the list to add is automatic resizing of images, allowing you to dynamically download images based on the size of the browser window without the need to modify your existing markup (aside from inserting a small javascript snippet)!

    We also plan to create other polyfills that can only be solved with Capturing, such as the new HTML5 Template Tag, for example.

    We look forward to your feedback, and we are excited to see what other developers will do with our new Mobify.js 2.0 library!

  7. Firefox Development Highlights – H.264 & MP3 support on Windows, scoped stylesheets + more

    Time for the first look this year into the latest developments with Firefox. This is part of our Bleeding Edge and Firefox Development Highlights series, and most examples only work in Firefox Nightly (and could be subject to change).

    H.264 & MP3 support on Windows

    Firefox for Android and Firefox OS already support H.264 and MP3. We are also working on bringing these formats to Firefox Desktop. On Windows 7 and above, you can already test it by turning on the preference media.windows-media-foundation.enabled in about:config. Decoding is done on the OS side (no decoder included in Firefox source code, not like WebM or Ogg Theora). For Linux and Mac, work is in progress.

    The new Downloads panel has been enabled

    We have now enabled the new Downloads panel:

    Scoped style attribute

    It’s now possible to define scoped style elements. Usually, when we write a stylesheet, we use <style>...</style>, and CSS code is applied to the whole document. If the <style> tag is nested inside a node (let’s say a <div>), and the <style> tag includes the scoped attribute (<style scoped>), then the CSS code will apply only to a subtree of the document, starting with the parent node of the <style> element. The root of the subtree can also be referred via the :scope pseudo-class.

    Demo

    Scoped style demo support on JS Bin.

    Our friends over at HTML5Rocks have also written about it in A New Experimental Feature: scoped stylesheets.

    @supports and CSS.supports

    In Firefox 17, we shipped the @supports CSS at-rule. This lets you define specific CSS code only if some features are supported. For example:

    @supports not (display: flex) {
      /* If flex box model is not supported, we use a different layout */
      #main {
          width: 90%;
      }
    }

    In Firefox 20, it’s now possible to do the same thing, but within JavaScript:

    if (CSS.supports("display", "flex")) {
      // do something relying on flexbox
    }
  8. A tale of a CSS3 Animation Demo

    Once upon a time, there was this good hearted web developer, who was everyday worried about learning new cool things and trying new crazy stuff his browser could barely be able to do. Also, there were some giants, working hard to increase the power of the magic web, allowing all the peoples to live, code, learn and share freely.

    Among those things, there was CSS3 with its new features! I heard about something called Mozilla Dev Derby, and by that month, the focused feature was exactly CSS3 animations! What an opportunity to learn cool and be part of something like that! It’s awesome that companies like Mozilla are working so hard to keep these subjects and contents available to us!

    Two examples will be used here to both explain the technologies and tell the history. Felipe prepared a demo using HTML5 and CSS3 animations to do a Earth planet spinning, and, not aware of that, Deivid Marques had a similar idea.

    Why a planet Earth?

    Inspiration was the key. Since I was a child I have been fascinated with the Universe (both the micro, and macro ones) and the Earth, being what it is for us…such a good host! I decided to use it as inspiration!

    Images

    Obviously, images would be required. I tried to avoid images as much as possible, but I simply wouldn’t represent the Earth in a blurred image! Also, the moon, the stars in the background and the small sun are images.

    What should be animating?

    Before animating things around there, I mapped everything that could make sense to be moving, and how. First of all, the planet itself! The earth has to spin in one direction, while also bents to create the four seasons. Also, there is the day and night of the Earth due to its rotation.

    The Moon runs around the globe, but once it is behind the Earth, it should get darker. Also, the Moon should come to the front of the planet, and then hide behind it. Also, a slow movement, added to the stars in the background, could be of use!

    HTML Structure

    I didn’t want to make it too complex, so I didn’t use pseudo elements. That forced me to have the HTML just a little bit bigger.

    This is what is inside the Body tag:

    <div id="sun">
    </div>
    <div id="atmosphere">
    </div>
    <div id='globe'>
    </div>
    <div id='moon'>
    </div>
    <div id="sunLight1">
    </div>
    <div id="sunLight2">
    </div>
    <div id="sunLight3">
    </div>
    <div id="sunLight4">
    </div>
    <div id="sunLight5">
    </div>
    <div id="sunLight6">
    </div>

    Visual effects

    Well, you know that everything seems pretty from out there! So the visual effects should be cool too!

    The globe

    The globe is basically a rounded div, with a global map as its background. It is centered with an absolute position and sizes, and uses a box-shadow effect to represent the side of the planet where it’s night.

    #globe
    {
        background-image: url(images/globe-hearth.jpg) repeat-x;
        border: solid 1px #000;
        position:absolute;
        top: 50%;
        left: 50%;
        width: 600px;
        height: 600px;
        margin-left: -300px; /* aligning it to the center */
        margin-top: -300px;
        border-radius: 50%; /* making it round */
        z-index:0;
        box-shadow: inset 2px 2px 10px #000, inset -140px -70px 100px #000;
    }

    The atmosphere

    The atmosphere is another round div with a box-shadow effect.

    #atmosphere
    {
        position:absolute;
        top: 50%;
        left: 50%;
        width: 600px;
        height: 600px;
        margin-left: -300px;
        margin-top: -300px;
        border-radius: 50%;
        opacity: 0.7;
        box-shadow: -6px -6px 20px #eef;
    }

    The Sun

    The Sun, in this demo is just another div with an image as background, although, there is a tricky detail here! I wanted the Sun to be positioned right in the horizon of the globe, so, just centering it would not work! Also, I couldn’t know the resolution to fit it exactly there! But, I knew the size of the planet and I also knew it was centered!

    Therefore, I just had to center it, and then adjust its position by changing its margin values.

    #sun
    {
        background-image: url(images/sun.png);
        position: absolute;
        top: 50%;
        left: 50%;
        width: 50px;
        height: 47px;
        margin-left: -320px;
        margin-top: -110px;
    }

    The stars behind

    The stars were simply a div with a repeatable background image.

    The Moon

    The Moon was quite more complex. It had to turn around the globe, so, I’d have to play with its z-index as well. Besides that, it was simply another round div.

    Sun lights

    Also, there are a few reflections of the light of the Sun. Those, are other round divs, absolutely positioned with different colours and opacity. Box-shadow could also be an optional nice touch! So I also used it.

    Animation time

    To animate the Earth, I created two animations using the keyframes CSS3 feature.

    (Note: In these examples, I’m just showing the “-moz” definition of the animations, but you have to create them for each vendor if you want it to work in different browsers).

    @-moz-keyframes dayByDay
    {
        from{
                background-position: -1600px;
        }
        to{
                background-position: 0px;
        }
    }

    This way, the background of the globe would be passing, as pretending the globe was spinning. Also, I created the animation for the seasons:

    @-moz-keyframes seasons
    {
        from{
            -moz-transform: rotate(6deg);
        }
        to{
            -moz-transform: rotate(16deg);
        }
    }

    You know, the planet Earth is not fully straight to the 0 degrees. Now, I had to add those animations to the globe:

    #globe{
        -moz-animation: dayByDay 24s linear 0s infinite, seasons 2688s linear alternate 0s infinite;
    }

    Animating the sky behind everything followed the very same technique as the dayByDay animation.

    Animating the Moon was more of a challenge! To animate it, I had to change its size and position. Also making it darker or lighter and taking care of its z-index.

    Below, is how I did that back then (on june 2011). Nowadays, I would try it with -moz-transform using the scale transform, instead of changing its width and height. Also, back then, I used negative and positive values for the z-index of the moon…instead, I could have added a z-index to the Earth, like 2, and use only positive values in the Moon’s z-index(1, and 3) to move it to the back or front of the planet. I didn’t want to change it here, because this is how it is running on the uploaded demo, in Mozilla Derby.

    @-moz-keyframes moon
    {
       0%{
           width: 30px;
           height: 31px;
           margin-left: -310px;
           margin-top: -40px;
           z-index:-1;
       }
       10%{
           margin-left: -450px;
           margin-top: -50px;
           width: 60px;
           height: 61px;
           z-index:1;
       }
       20%{
           margin-left: -500px;
           margin-top: -50px;
           width: 80px;
           height: 81px;
           z-index:1;
       }
       30%{
           margin-left: -450px;
           margin-top: -50px;
           width: 90px;
           height: 92px;
           z-index:1;
       }
       50%{
           margin-left: 0px;
           margin-top: -50px;
           width: 120px;
           height: 122px;
           z-index:1;
       }
       60%{
           margin-left: 300px;
           margin-top: -50px;
           width: 120px;
           height: 122px;
           z-index:1;
       }
       60%{
           margin-left: 410px;
           margin-top: -50px;
           width: 90px;
           height: 92px;
           z-index:1;
           box-shadow: inset 0px 0px 80px #000;
       }
       70%{
           margin-left: 460px;
           margin-top: -50px;
           width: 80px;
           height: 82px;
           z-index:1;
           box-shadow: inset 0px 0px 80px #000;
       }
       80%{
           margin-left: 420px;
           margin-top: -50px;
           width: 60px;
           height: 61px;
           z-index:-1;
           box-shadow: inset 0px 0px 80px #000;
       }
       90%{
           margin-left: 0px;
           margin-top: -50px;
           width: 30px;
           height: 31px;
           z-index:-1;
       }
       100%{
           width: 30px;
           height: 31px;
           margin-left: -310px;
           margin-top: -40px;
           z-index:-1;
       }
    }

    Mozilla Dev Derby

    The above demo can be found as CSS3 up and running! in Mozilla’s Demo Studio.

    Some time later, Deivid Marques did his Planeta Terra demo, using only one DIV. While studying CSS3, the idea of creating a planet Earth also came to his mind. He noticed the example in a flash tutorial and thought of creating that with CSS3 instead.

    His planet Earth is made of a single div and uses the CSS to animate the background image. So, it is simpler to reproduce and understand.

    The div has the following CSS applied to it:

    .earth{
        background: url(images/terra.jpg) repeat-x 0 0;
        border: 1px solid rgba(26,18,101,0.3);
        border-radius: 225px;
        box-shadow: -8px 0 25px rgba(256,256,256,0.3), -1px -2px 14px rgba(256,256,256,0.5) inset;
        height: 450px;
        left: 50%;
        margin: -225px 0 0 -225px;
        position: absolute;
        top: 50%;
        width: 450px;
        animation: loop 80s linear infinite;
    }

    And here is his animation definition in CSS3:

    @keyframes loop {
        0% { background-position: 0 0; }
        100%{ background-position: -900px 0;}
    }

    His demo was also posted to Mozilla Dev Derby once he was also inspired to tell the world about he had learnt while developing this demo! Planeta Terra is also available on GitHub.

    This is how we both met and were invited to write this article.

    Conclusion

    It was great for me to learn new things, face new challenges, talk to a lot of people about their experiences with it, and …well, lots and lots of gains, no losses!

    I hope it has motivated you somehow, to create your own demo, submit it…the least you get, is a lot of fun! :)