Sort by:


  1. Inspecting Security and Privacy Settings of a Website

    Inspecting the Content Security Policy of a Website

    Starting in Firefox 41, Mozilla provides a developer tool that allows users to inspect the security settings of a website. Using GCLI (Graphic Command Line Interface) a user can inspect the Content Security Policy (CSP) of a website. CSP is a security concept that allows websites to protect themselves against cross-site scripting (XSS) and related attacks. CSP allows website authors to whitelist approved sources from which content can be loaded safely. Browsers enforce that Content Security Policy header and only allow whitelisted resources to be loaded into that website. The CSP inspection tool » security csp lists all whitelisted sources.

    The main intention behind CSP is to protect websites against XSS attacks, but the protection needs to be deployed in a way that allows support for legacy code on these sites. For example, the keyword ‘unsafe-inline’ was originally introduced to support legacy inline scripts while transitioning sites to use CSP. This keyword whitelists all inline scripts for a site, but it also allows attacker-injected scripts to execute, making CSP ineffective against most XSS attacks. Hence, the CSP devtool not only lists all whitelisted sources, but also provides a rating for each whitelisted source, to indicate the level of protection.

    Inspecting the referrer policy of a website

    Starting in Firefox 43, Mozilla exposes more website privacy settings and also allows users to inspect the Referrer Policy » security referrer. The referrer policy allows websites to exercise more control over the browser’s referrer header. Specifically it allows website authors to instruct the browser to strip the referrer completely, reveal it only when navigating within the same origin, etc. The referrer devtool provides an example of what referrer will be used when visiting different websites, allowing the user and developer to inspect what information is sent when following a link.

    Inspecting the Content Security Policy as well as the Referrer Policy is only the starting point to providing end users with more feedback about the security and privacy settings a web page uses. We hope to add more tools in the future to give users more transparency and control over the security and privacy of the websites they visit.

  2. Trainspotting: Firefox 41

    Trainspotting is a series of articles highlighting features in the lastest version of Firefox. A new version of Firefox is shipped every six weeks – we at Mozilla call this pattern “release trains.”

    Firefox 41 (the Fire-y-est Fox to date) brings a bevy of new and improved features for browser users and web developer audiences. Let’s take a look at some highlights.

    For a full list of changes and additions, check out the Firefox 41 release notes.

    Screenshot a single element

    Need to capture just one bit of a web page? Using the Inspector panel, you can now screenshot the area of a page contained by a single element:

    Right click on a node in the markup view.

    The result is a snapshot cropped to perfection:

    Resulting Screenshot of an element on the page.

    Connection status

    The navigator.onLine API, historically, wasn’t all that useful. Pages could only inquire whether Firefox itself was in a specific “Work Offline” state, regardless of whether the computer had any network connection. Now, navigator.onLine uses system network information to mirror the state of the device’s Internet connection!

    See the Pen QjGoRP by Potch (@potch) on CodePen.

    Clipboard management

    Copying text on behalf of the user used to be the hardest problem in computer science. Web developers would have to embed a Flash widget on the page just to put some text in the user’s clipboard. No more! Developers can now copy text to a users’ clipboard programmatically directly in JavaScript, provided the user takes an explicit action such as clicking a button.

    Read the Hacks Post on clipboard manipulation for more details.

    Network Panel HAR exports

    We should rename the Network Panel to Hagar, because it’s now HAR-able! HAR is a network request archive format used by many performance and request analysis tools, and it’s now possible to export HAR information from the Network panel from the context menu.

    The location of the Save As HAR option in the context menu.

    <picture> perfect

    In a previous edition of Trainspotting, I provided the following caveat about responsive image support in Firefox:

    Responsive images will load using the correct media queries, but presently do not respond to viewport resizing. This bug is being actively worked on and tracked here, and will be fixed in a near-future version of Firefox.

    Well, that near-future version is this now-present version! Responsive images will now respond to post-load changes to the page’s viewport. Isn’t it nice when a plan comes together!

    There couldn’t possibly be more…

    …But there most definitely is. There’s plenty of additional information in the Developer Release Notes or, for large <table> enthusiasts, the full list of fixed bugs.

    Keep on rocking the Free Web!

  3. Do not let your CDN betray you: Use Subresource Integrity

    Mozilla Firefox Developer Edition 43 and other modern browsers help websites to control third-party JavaScript loads and prevent unexpected or malicious modifications. Using a new specification called Subresource Integrity, a website can include JavaScript that will stop working if it has been modified. With this technology, developers can benefit from the performance gains of using Content Delivery Networks (CDNs) without having to fear that a third-party compromise can harm their website.

    Using Subresource Integrity is rather simple:

    <script src=""

    The idea is to include the script along with its cryptographic hash (e.g. SHA-384) when creating the web page. The browser can then download the script and compute the hash over the downloaded file. The script will only be executed if both hashes match. The security properties of a collision resistant hash function, ensure that a modification results in a very different hash. This helps the site owner detect and prevent any changes, whether they come from a compromised CDN or an evil administrator.

    An important side note is that for Subresource Integrity to work, the CDN must support Cross-Origin Resource Sharing (CORS). The crossorigin attribute in the above code snippet enforces a CORS-enabled load. The anonymous value means that the browser should omit any cookies or authentication that the user may have associated with the domain. This prevents cross-origin data leaks, and also makes the request smaller.

    Integrity syntax

    As you may have noticed, the integrity attribute does not just include the hash value. It also contains the digest name. The syntax for the integrity attribute allows multiple tokens of this name-value format. This allows site owners to specify hashes of different strengths as well as the values of multiple scripts that may be behind a URL. This is useful for browser sniffing or content negotiation.

    <script src=""


    For the best performance, users would load all resources from the CDN, but if integrity cannot be verified, you don’t want your users to be trapped on a non-working web page. To make failover work, we recommend hosting a copy of the script on your own origin. To recover from failure one could then extend the previous snippet with the following code:

    <script>window.jQuery || /* reload from own domain here */;</script>

    This code will check if jQuery has been defined and could otherwise insert a script tag that loads the same origin version of the script.

    Please note that many scripts update regularly, especially if they do not come with a version number. If you want to secure your CDN-loaded scripts, it is best to stick to a specific version and not use filenames with the word ‘latest’ in them.

    HTTP or HTTPS?

    Subresource Integrity works on both HTTP and HTTPS. If you are serving your page over plain HTTP, the browser can still figure out if the script was modified on the CDN, but it is not protected against active network attackers, as they would be able to just remove the integrity attribute from your HTML. It is, however, in the interest of your users to provide confidentiality, integrity, and authenticity of your web applications by using HTTPS for the entirety of your website.

    Stylesheet support

    While we are working on adding support for subresources other than scripts, you can also use Subresource Integrity for CSS. Just use the integrity attribute that you now know so well on your <link> tag!

    Try Subresource Integrity Now!

    If you want to test browser support or toy with examples, take a look at, which can do all the grunt work of computing hashes as well as checking if your CDN already supports HTTPS. A few early adopters like BootstrapCDN, CloudFlare and GitHub are already experimenting with it.
    There is some additional documentation of Subresource Integrity on MDN. But if you want to read all the fine details of Subresource Integrity, take a look at the specification.

    To conclude, Subresource Integrity can make your website safer when using a CDN that you do not fully control. It’s as simple as adding just a few extra attributes to your script tags.

  4. Building RTL-Aware Web Apps & Websites: Part 1

    Making the web more accessible to more people, in more languages, is an ongoing effort and a mission we take very seriously at Mozilla.

    This post is the first of a series of articles to explain one of the most neglected and least well-known corners of web development: RTL (right-to-left) development. In a web development context it means making your web content compatible with RTL languages like Arabic, Hebrew, Persian, and Urdu, which are all written from right to left.

    This area is often neglected by developers because of the lack of teaching resources. In this series, we hope to provide enough information to allow developers to make content that’s accessible to a broader global audience using the RTL capabilities that most web browsers currently provide.

    What actually is RTL?

    To make things clear, there is a difference between a language and its script. A script is the text or written form — while the language refers to the spoken form. So technically, right-to-left describing the script in which a language is written, comparable to left-to-right scripts, like English or French, more familiar to many Western readers.

    For example, “Marhaban” – which means hello – is a word written in the English script, but has Arabic as its language, while “مرحبا” is both Arabic script and Arabic language.

    On the web, as we said earlier, the term Right-To-Left indicates more than just a script for writing. It stands for all facets of developing web apps and websites that do not break or become unreadable when used with Arabic, Urdu or any other RTL script.

    Before continuing, let’s just clear up some misconceptions about RTL.

    First, RTL is not about translating text to Arabic: It means more than translating your website into Arabic and calling it a day. It’s about making every aspect the UI and layout RTL-friendly. And as I always say – and can’t stress it enough – do RTL right or don’t bother! Doing it halfway will lose your audience and credibility.

    Second, RTL is more than just “flip all the things”: I’m not sure if this issue has been fixed yet or not, but setting your locale to Arabic in Gnome will cause the time to be shown as PM 33:12 instead of 12:33 PM.

    Well, that is not how it works. I’m a native Arabic speaker but that doesn’t mean I tell time backwards. There are some exceptions and things to pay attention to about numbers, and we will cover them in this series.

    Why should I care about RTL?

    You might have the impression that RTL is hard, scary, and will add a great deal of work to your project! Really, it’s not that difficult. Once you comprehend the basics, the extra effort required is not that great.

    You should really care about adding right-to-left support to your web app or website for many, many reasons. There are over 410 million native RTL speakers around the world as of 2010 (That’s a lot of people! Note: The assessment is based on Wikipedia’s list of all the languages.) It’s also millions of potential users and a huge potential market for your app or website. Most companies now add RTL support to their software (e.g. Windows, iOS, Android) and websites, so native RTL speakers expect your website to meet their expectations regarding RTL support. Without this support visitors to your web application may not become repeat users.

    In the case of Firefox OS, we only started shipping devices to the Middle East when we had RTL support fully implemented in the system, and thus our partner Orange was able to sell devices with the OS on it. This obviously opens up a whole new market of users to Firefox OS.

    Best practices for RTL

    Here are some general rules of thumb to keep in mind when developing RTL-aware websites and web apps:

    • Think from the right: In a region with an RTL script and language, books open from the right-hand side. Thus, most UI elements related to readability are going to be mirrored.
    • Hardware legacy UI is a thing: In MENA (Middle East and North Africa) and other regions where RTL languages are spoken, people use gadgets too. Audio hardware has the same control layout as anywhere else in the world. So buttons like Play, Fast Forward, Next, Previous have always been the same. And because of that, it’s not a good idea to mirror any of those buttons. Please don’t RTL the media player buttons. Another example of hardware legacy is the physical feature phone keyboard; before there were Blackberries and similar keyboards for handhelds, there was the simple physical numpad — until very recently it was widely popular in MENA countries. For this reason, It is strongly advised to *not* mirror the number keys. A good example of this is Firefox OS. As its initial target was developing countries, we made sure not to make the dialer mirrored in RTL.
    • Firefox OS Contacts AppThinking Right-To-Left is not thinking left-handed: Remember not to confuse developing RTL UIs with southpaw-first ones. In RTL regions of the world, right-handed people are a majority, just like in the rest of the world. So anything that is not related to how the user reads the actual content on the page should not be mirrored. An example of this is the Firefox OS A-Z scrollbar (image to the right) in the Contacts App. It is placed on the right because it’s easier to scroll through with the right hand, so such a thing should not go on the other side when your page is in RTL mode.

    Down to business: How to RTL content

    The first step towards making a web page RTL is adding the code dir="rtl" to the <html> tag:

    <html dir="rtl">

    dir stands for direction and setting its value to rtl defaults the horizontal starting point of elements to the right instead of the left.

    To target an element with CSS only when the page is RTL:

    1. Create a copy of any regular CSS rules that target it.
    2. Add a html[dir="rtl"] attribute selector onto the front of the selector chain.
    3. Next, whenever you find a property or a value that represents horizontal positioning of some kind in the RTL rule, use its opposite. For example, if you find `float: left` you should change it to float: right.

    As an example, if the original rule is as follows —

    .someClass {
        text-align: left;
        padding: 0 10px 0 0;
        text-decoration: underline;

    we would paste a copy of it after the original and update it as follows:

    html[dir="rtl"] .someClass {
        text-align: right;
        padding: 0 0 0 10px;

    Notice that the text-decoration: underline; declaration has been removed. We don’t need to override it for the RTL version because it doesn’t affect any direction-based layout elements. Thus, the value from the original rule will still be applied.

    Here’s an even more detailed example you can hack on directly:

    See the Pen dYGKQZ by Ahmed Nefzaoui (@anefzaoui) on CodePen.

    Of course, real-life cases won’t be quite as simple as this. There are applications with a huge number of CSS rules and selectors, and there are multiple strategies you could adopt. Here is one recommended approach:

    1. Copy and clean up: First, copy the content of your stylesheet to another file, add html[dir="rtl"] to all the rules, then clear out any properties that do not relate to horizontal direction setting. You should end up with a more lightweight file that deals purely with RTL.
    2. Mirror the styles: Change all of the properties left in the new file to their opposites: e.g. padding-left becomes padding-right, float: right becomes float: left, etc. Note: if you originally had padding-left and you changed it to padding-right, remember that the original padding-left still exists in the original rule. You must add padding-left: unset alongside padding-right, otherwise the browser will compute both properties: the padding-left from the original CSS rule and the new padding-right in the RTL rule. The same is true for any property that has multiple direction variants like the margin-left|right, border-left|right
    3. Paste back: After you’ve completed the previous steps, paste the newly created rules back into the original file, after the originals. I personally like to add a little comment afterwards such as: /* **** RTL Content **** */ for the sake of easier differentiation between the two parts of your style file.

    A better way: isolating left/right styles completely

    Sometimes you will find yourself facing edge cases that produce code conflict. This involves properties inheriting values from other properties, meaning that sometimes you won’t be sure what to override and what not to. Maybe you’ve added the margin-right to the RTL rule but are not sure what to set as the value for the original margin-left? In all real-world cases it is advisable to adopt another approach, which is better in general but more long-winded. For this approach we isolate direction-based properties completely from the rules for both the LTR and the RTL cases. Here’s an example: say we have .wrapper .boxContainer .fancyBox listed like this:

    .wrapper .boxContainer .fancyBox {
        text-align: left;
        padding-left: 10px;
        text-decoration: underline;
        color: #4A8CF7;

    Instead of adding another property for RTL with both padding-left and padding-right, you can do this:

    .wrapper .boxContainer .fancyBox {
        text-decoration: underline;
        color: #4A8CF7;
    html[dir="ltr"] .wrapper .boxContainer .fancyBox {
        text-align: left;
        padding-left: 10px;
    html[dir="rtl"] .wrapper .boxContainer .fancyBox {
        text-align: right;
        padding-right: 10px;

    This solution consists of 3 parts:

    1. The original rule/selector with only non-direction based properties, because they are shared by the LTR and the RTL layout.
    2. The left to right case — html[dir="ltr"] — with only the direction-based CSS properties included, their values set to match your LTR layout.
    3. The right to left case — html[dir="rtl"] — with the same properties as the LTR case, only with their values set according to what you want in your RTL layout.

    Notice that in the second rule we had padding-left only and in the third one we had padding-right only. That’s because each one of them is exclusive to the direction that was given to them in the dir attribute. This is a nice, clean approach that doesn’t require unsetting of properties. This is the exact approach we use when adding RTL support to Firefox OS. (Note: the unset keyword isn’t supported in all browsers. For the best compatibility you may need to explicitly re-declare the desired value for any properties you want to unset.)

    How do we get and set the direction of the page using JavaScript?

    It’s fairly easy, and requires only one line of code: document.documentElement.dir
    You can assign this line to a variable, and have it outputted to the console to see for yourself:  

    var direction = document.documentElement.dir; console.log(direction);

    Or try this example:

    See the Pen WQxWQQ by Ahmed Nefzaoui (@anefzaoui) on CodePen.

    To set the direction of the page, just use the following:
    document.documentElement.dir = "rtl"

    And here’s an example of both getting and setting the direction value for a web page:

    See the Pen gaMyPN by Ahmed Nefzaoui (@anefzaoui) on CodePen.

    Automatic RTL solutions

    Enough talk about manual ways to do RTL. Now let’s take a look at some automated approaches.


    Twitter has developed a solution to automate the whole process and make it easier for bigger projects to implement RTL. They have open sourced it and you can find it on Github.

    This NPM plugin covers pretty much all the cases you could find yourself facing when working on RTL, including edge cases. Some of its features include:

    • no-flip: To indicate to the mirroring engine that you don’t want a certain property flipped, just add /* @noflip*/ at the beginning of the property. So, for example, if you write /* @noflip*/ float: left, it will stay as float: left after css-flip is run.
    • @replace: When you have background images that differ between LTR and RTL, you can specify a replacement image by including /*@replace: url(my/image/path) before the original property. Let’s say you have background-image: url(arrow-left.png). If you update the line to
      /*@replace: url(arrow-rightish.png) */ background-image: url(arrow-left.png);
      You will end up with background-image: url(arrow-rightish.png); in the RTL layout.

    You can use css-flip through the command line by executing
    css-flip path/to/file.css > path/to/file.rtl.css or by requiring css-flip in your page. More about that on their github repo. css-flip is being actively used on Twitter properties.


    Another option for automatic conversion is a tool from Mohammad Younes called rtlcss — this is also available on github and provides some pretty nifty features. With this one engine you can:

    • Rename rule names (e.g. renaming #boxLeft to #boxRightSide).
    • Completely ignore rules from the mirroring process.
    • Ignore single properties.
    • Append/prepend new values.
    • Insert new property values in between other property values.

    Basic usage is via the command line — you can create your RTL CSS equivalent by the running the following in the same directory your original CSS is available in:

    rtlcss input.css output.rtl.css

    And of course you can just require it in your page. More details are available on github.

    This project is very popular and is being used by several projects including WordPress.

    Final words

    While there is still a lot to cover, this article aims to provide you with enough knowledge to start exploring RTL confidently. In the next article we’ll cover more advanced topics around RTL.

    Be sure to ask any questions you may have around RTL in the comments section and we will try to answer them here or in the next post!

  5. Let’s Write a Web Extension

    You might have heard about Mozilla’s WebExtensions, our implementation of a new browser extension API for writing multiprocess-compatible add-ons. Maybe you’ve been wondering what it was about, and how you could use it. Well, I’m here to help! I think the MDN’s WebExtensions docs are a pretty great place to start:

    WebExtensions are a new way to write Firefox extensions.

    The technology is developed for cross-browser compatibility: to a large extent the API is compatible with the extension API supported by Google Chrome and Opera. Extensions written for these browsers will in most cases run in Firefox with just a few changes. The API is also fully compatible with multiprocess Firefox.

    The only thing I would add is that while Mozilla is implementing most of the API that Chrome and Opera support, we’re not restricting ourselves to only that API. Where it makes sense, we will be adding new functionality and talking with other browser makers about implementing it as well. Finally, since the WebExtension API is still under development, it’s probably best if you use Firefox Nightly for this tutorial, so that you get the most up-to-date, standards-compliant behaviour. But keep in mind, this is still experimental technology — things might break!

    Starting off

    Okay, let’s start with a reasonably simple add-on. We’ll add a button, and when you click it, it will open up one of my favourite sites in a new tab.

    The first file we’ll need is a manifest.json, to tell Firefox about our add-on.

      "manifest_version": 2,
      "name": "Cat Gifs!",
      "version": "1.0",
      "applications": {
        "gecko": {
          "id": ""
      "browser_action": {
        "default_title": "Cat Gifs!"

    Great! We’re done! Hopefully your code looks a little like this. Of course, we have no idea if it works yet, so let’s install it in Firefox (we’re using Firefox Nightly for the latest implementation). You could try to drag the manifest.json, or the whole directory, onto Firefox, but that really won’t give you what you want.

    The directory listing


    To make Firefox recognize your extension as an add-on, you need to give it a zip file which ends in .xpi, so let’s make one of those by first installing 7-Zip, and then typing 7z a catgifs.xpi manifest.json. (If you’re on Mac or Linux, the zip command should be built-in, so just type zip catgifs.xpi manifest.json.) Then you can drag the catgifs.xpi onto Firefox, and it will show you an error because our extension is unsigned.

    The first error

    We can work around this by going to about:config, typing xpinstall.signatures.required in the search box, double-clicking the entry to set it to false, and then closing that tab. After that, when we drop catgifs.xpi onto Firefox, we get the option to install our new add-on!

    It’s important to note that beginning with Firefox 44 (later this year), add-ons will require a signature to be installed on Firefox Beta or Release versions of the browser, so even if you set the preference shown below, you will soon still need to run Firefox Nightly or Developer Edition to follow this tutorial.


    Of course, our add-on doesn’t do a whole lot yet.

    I click and click, but nothing happens.

    So let’s fix that!

    Adding features

    First, we’ll add the following lines to manifest.json, above the line containing browser_action:

      "background": {
        "scripts": ["background.js"],
        "persistent": false

    now, of course, that’s pointing at a background.js file that doesn’t exist yet, so we should create that, too. Let’s paste the following javascript in it:

    'use strict';
    /*global chrome:false */
    chrome.browserAction.setBadgeText({text: '(ツ)'});
    chrome.browserAction.setBadgeBackgroundColor({color: '#eae'});
    chrome.browserAction.onClicked.addListener(function(aTab) {
      chrome.tabs.create({'url': '', 'active': true});

    And you should get something that looks like this. Re-create the add-on by typing 7z a catgifs.xpi manifest.json background.js (or zip catgifs.xpi manifest.json background.js), and drop catgifs.xpi onto Firefox again, and now, when we click the button, we should get a new tab! 😄

    Cat Gifs!

    Automating the build

    I don’t know about you, but I ended up typing 7z a catgifs.xpi manifest.json a disappointing number of times, and wondering why my background.js file wasn’t running. Since I know where this blog post is ending up, I know we’re going to be adding a bunch more files, so I think it’s time to add a build script. I hear that the go-to build tool these days is gulp, so I’ll wait here while you go install that, and c’mon back when you’re done. (I needed to install Node, and then gulp twice. I’m not sure why.)

    So now that we have gulp installed, we should make a file named gulpfile.js to tell it how to build our add-on.

    'use strict';
    var gulp = require('gulp');
    var files = ['manifest.json', 'background.js'];
    var xpiName = 'catgifs.xpi';
    gulp.task('default', function () {
      console.log(files, xpiName)

    Once you have that file looking something like this, you can type gulp, and see output that looks something like this:

    Just some command line stuff, nbd.

    Now, you may notice that we didn’t actually build the add-on. To do that, we will need to install another package to zip things up. So, type npm install gulp-zip, and then change the gulpfile.js to contain the following:

    'use strict';
    var gulp = require('gulp');
    var zip = require('gulp-zip');
    var files = ['manifest.json', 'background.js'];
    var xpiName = 'catgifs.xpi';
    gulp.task('default', function () {

    Once your gulpfile.js looks like this, when we run it, it will create the catgifs.xpi (as we can tell by looking at the timestamp, or by deleting it and seeing it get re-created).

    Fixing a bug

    Now, if you’re like me, you clicked the button a whole bunch of times, to test it out and make sure it’s working, and you might have ended up with a lot of tabs. While this will ensure you remain extra-chill, it would probably be nicer to only have one tab, either creating it, or switching to it if it exists, when we click the button. So let’s go ahead and add that.

    Lots and lots of cats.

    The first thing we want to do is see if the tab exists, so let’s edit the browserAction.onClicked listener in background.js to contain the following:

    chrome.browserAction.onClicked.addListener(function(aTab) {
      chrome.tabs.query({'url': ''}, (tabs) => {
        if (tabs.length === 0) {
          // There is no catgif tab!
          chrome.tabs.create({'url': '', 'active': true});
        } else {
          // Do something here…

    Huh, that’s weird, it’s always creating a new tab, no matter how many catgifs tabs there are already… It turns out that our add-on doesn’t have permission to see the urls for existing tabs yet which is why it can’t find them, so let’s go ahead and add that by inserting the following code above the browser_action:

      "permissions": [

    Once your code looks similar to this, re-run gulp to rebuild the add-on, and drag-and-drop to install it, and then when we test it out, ta-da! Only one catgif tab! Of course, if we’re on another tab it doesn’t do anything, so let’s fix that. We can change the else block to contain the following:

          // Do something here…
          chrome.tabs.query({'url': '', 'active': true}, (active) => {
            if (active.length === 0) {
              chrome.tabs.update(tabs[0].id, {'active': true});

    Make sure it looks like this, rebuild, re-install, and shazam, it works!

    Making it look nice

    Well, it works, but it’s not really pretty. Let’s do a couple of things to fix that a bit.

    First of all, we can add a custom icon so that our add-on doesn’t look like all the other add-ons that haven’t bothered to set their icons… To do that, we add the following to manifest.json after the manifest_version line:

      "icons": {
        "48": "icon.png",
        "128": "icon128.png"

    And, of course, we’ll need to download a pretty picture for our icon, so let’s save a copy of this picture as icon.png, and this one as icon128.png.

    We should also have a prettier icon for the button, so going back to the manifest.json, let’s add the following lines in the browser_action block before the default_title:

        "default_icon": {
          "19": "button.png",
          "38": "button38.png"

    and save this image as button.png, and this image as button38.png.

    Finally, we need to tell our build script about the new files, so change the files line of our gulpfile.js to:

    var files = ['manifest.json', 'background.js', '*.png'];

    Re-run the build, and re-install the add-on, and we’re done! 😀

    New, prettier, icons.

    One more thing…

    Well, there is another thing we could try to do. I mean, we have an add-on that works beautifully in Firefox, but one of the advantages of the new WebExtension API is that you can run the same add-on (or an add-on with minimal changes) on both Firefox and Chrome. So let’s see what it will take to get this running in both browsers!

    We’ll start by launching Chrome, and trying to load the add-on, and see what errors it gives us. To load our extension, we’ll need to go to chrome://extensions/, and check the Developer mode checkbox, as shown below:

    Now we’re hackers!

    Then we can click the “Load unpacked extension…” button, and choose our directory to load our add-on! Uh-oh, it looks like we’ve got an error.

    Close, but not quite.

    Since the applications key is required for Firefox, I think we can safely ignore this error. And anyways, the button shows up! And when we click it…


    So, I guess we’re done! (I used to have a section in here about how to load babel.js, because the version of Chrome I was using didn’t support ES6’s arrow functions, but apparently they’ve upgraded their JavaScript engine, and now everything is good. 😉)

    Finally, if you have any questions, or run into any problems following this tutorial, please feel free to leave a comment here, or get in touch with me through email, or on twitter! If you have issues or constructive feedback developing WebExtensions, the team will be listening on the Discourse forum.

  6. Stereoscopic Rendering in WebVR

    At Mozilla, a small recon team has been toying with the idea of blending the best features of the web such as interconnectedness, permissionless content creation, and safe execution of remote code with the immersive interaction model of Virtual Reality.

    By starting out with support for Oculus’s DK2 headset, we’ve enabled those interested to begin experimenting with VR.  As a quick introduction, I wanted to show some of the differences in rendering techniques developers have to account for when building their first VR experience.  For this post, we’ll focus on describing rendering with the WebGL set of APIs.

    Screen Shot 2015-09-09 at 9.06.13 AM

    My first rendering in WebVR, the Stanford dragon. Firefox handles the vignetting effect, spatial, and chromatic distortion for us just by entering fullscreen.

    Multiple Views of the Same Scene

    An important first distinction to make: With traditional viewing on a monitor or screen, we’re flattening our three-dimensional scene onto a plane (the view-port).  While objects may have different distances from the view-port, everything is rendered from a single point of view.  We may have multiple draw calls that build up our scene, but we usually render everything using one view matrix and one projection matrix that’s calculated at scene creation time.

    For example, the view matrix might contain information such as the position of our virtual camera relative to everything else in the scene, as well as our orientation (Which way is forward? Which way is up?).  The projection matrix might encode whether we want a perspective or orthographic projection, view-port aspect ratio, our field of view (FOV), and draw distance.

    As we move from rendering the scene from one point of view to rendering on a head-mounted display (HMD), suddenly we have to render everything twice from two different points of view!

    monoscopic rendering

    stereoscopic rendering

    In the past, you might have used one view matrix and one projection matrix, but now you’ll need a pair of each.  Rather than having the choice of field of view (FOV), you now must query the headset the user’s FOV setting for each eye. As anyone who’s visited an eye doctor or had an eye exam lately can attest, your eyes each have their own FOV!  This is not necessary to correct for when rendering to a far away monitor, as the monitor usually is a subset within the current field of view, whereas a head-mounted display (HMD) encompasses the entire field of view (FOV).

    The Oculus SDK has a configuration utility where the user can set individual FOV per eye and interpupillary distance (IPD), essentially the space between eyes, measured from pupil to pupil).

    The unique fields of view give us two unique projection matrices.  Because your eyes are also offset from one another, they also have different positions or translations from the position of the viewer. This gives us two different view matrices (one per eye) as well.  It’s important to get these right so that the viewer’s brain is able to correctly fuse two distinct images into one.

    Without accounting for the IPD offset, a proper parallax effect cannot be achieved.  Parallax is very important for differentiating distances to various objects and depth perception.  Parallax is the appearance of objects further away from you moving slower than closer objects when panning side to side.  Github’s 404 page is a great example of parallax in action.

    That’s why some 360 degree video shot from a single view/lens per direction tends to smear objects in the foreground with objects farther away.  For more info on 360 degree video issues, this eleVR post is a great read.

    We’ll also have to query the HMD to see what the size of the canvas should be set to for the native resolution.

    When rendering a monoscopic view, we might have code like —

    function init () {
      // using gl-matrix for linear algebra
      var viewMatrix = mat4.lookAt(mat4.create(), eye, center, up);
      var projectionMatrix = mat4.perspective(mat4.create(), fov, near, far);
      var mvpMatrix = mat4.multiply(mat4.create(), projectionMatrix, viewMatrix);
      gl.uniformMatrix4fv(uniforms.uMVPMatrixLocation, false, mvpMatrix);
    function update (t) {
      gl.drawElements(mode, count, type, offset);

    in JS and in our GLSL vertex shader:

    uniform mat4 uMVPMatrix;
    attribute vec4 aPosition;
    void main () {
      gl_Position = uMVPMatrix * aPosition;

    …but when rendering from two different viewpoints with webVR, reusing the previous shader, our JavaScript code might look more like:

    function init () {
      // hypothetical function to get the list of
      // attached HMD's and Position Sensors.
    function update () {
      // hypothetical function that
      // uses the webVR API's to update view matrices
      // based on orientation provided by HMD's
      // accelerometer, and position provided by the
      // position sensor camera.
      // left eye
      gl.viewport(0, 0, canvas.width / 2, canvas.height);
      mat4.multiply(mvpMatrix, leftEyeProjectionMatrix, leftEyeViewMatrix);
      gl.uniformMatrix4fv(uniforms.uMVPMatrixLocation, false, mvpMatrix);
      gl.drawElements(mode, count, type, offset);
      // right eye
      gl.viewport(canvas.width / 2, 0, canvas.width / 2, canvas.height);
      mat4.multiply(mvpMatrix, rightEyeProjectionMatrix, rightEyeViewMatrix);
      gl.uniformMatrix4fv(uniforms.uMVPMatrixLocation, false, mvpMatrix);
      gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);

    In a follow-up post, once the webVR API has had more time to bake, we’ll take a look at some more concrete examples and explain things like quaternions!  With WebGL2’s multiple render targets (WebGL1’s WEBGL_draw_buffers extension, currently with less than 50% browser support, more info), or WebGL2’s instancing (WebGL1’s ANGLE_instanced_arrays extension, currently 89% browser support) it should be possible to not explicitly call draw twice.

    For more info on rendering differences, Oculus docs are also a great reference.

    90 Hz Refresh Rate and Low Latency

    When rendering, we’re limited in how fast we can show updates and refresh the display by the hardware’s refresh rate. For most monitors, this rate is 60 Hz.  This gives us 16.66 ms to draw everything in our scene (minus a little for the browser’s compositor). requestAnimationFrame will limit how quickly we can run our update loops, which prevents us from doing more work than is necessary.

    The Oculus DK2 has a max refresh rate of 75 Hz (13.33 ms per frame) and the production version currently slated for a Q1 2016 release will have a refresh rate of 90 Hz (11.11 ms per frame).

    So, not only do we need to render everything twice from two different viewpoints, but we only have two-thirds the time to do it (16.66 ms * 2 / 3 == 11.11)! While this seems difficult, hitting a lower frame time is doable by various tricks (lower scene complexity, smaller render target plus upscaling, etc). On the other hand, reducing the latency imposed by hardware is much more challenging!

    Not only do we have to concern ourselves with frame rate, but also with latency on user input. The major difference between real-time rendering and pre-rendering is that a real-time scene is generated dynamically usually with input from the viewer. When a user moves their head or repositions themselves, we want to have a tight feedback loop between when they move and when they see the results of their movement displayed to them. This means we want to get our rendering results displayed sooner, but then we run into the classic double buffering vs screen tearing issue. As Oculus Chief Scientist Michael Abrash points out, we want sub 20 ms latency between user interaction and feedback presentation.

    Whether or not current desktop, let alone mobile, graphics hardware is up to the task remains to be seen!

    To get more info or get involved in WebVR:

    * MozVR download page (everything you need to get up and running with WebVR in Firefox)

    * WebVR spec (in flux, subject to change, things WILL break.)

    * MDN docs (in progress, will change when spec is updated)

    * web-vr-dicuss public mailing list

    * /r/webvr subreddit

  7. Backing Up User Data on Firefox OS

    The FFOS Backup/Restore Team

    Portland State University’s Computer Science degree culminates in a capstone program that matches teams of students with industry sponsors for a six-month software engineering project. We had the privilege of working with Mozilla on an application to back up and restore personal data on Firefox OS. We are:

    Ryan Bernstein: Team Lead/History/Demo application.
    David Cobbley: Contacts/SMS Messages.
    Thomas Guerena: Architecture/Build environment/Media.
    Wu Hao: SMS Messages/Space checking.
    Kai Jiang: SMS Messages. Space checking.
    Nathan Larson: History/System settings.
    Ruben Niculcea: Build environment/Media/SMS Messages.
    Dean Nida: Media/Contacts/Testing.

    From left: Nathan Larson, Jiang Kai, Wu Hao, David Cobbley, Dean Nida, Ruben Niculcea, Thomas Guerena, Ryan Bernstein

    From left: Nathan Larson, Jiang Kai, Wu Hao, David Cobbley, Dean Nida, Ruben Niculcea, Thomas Guerena, Ryan Bernstein

    The Firefox OS Backup/Restore Library

    The purpose of this capstone project was to allow users of Firefox OS to back up and restore their personal data. The OS does not provide any native support for such backups, despite the fact that it is sorely needed; Firefox OS was initially targeted at developing nations, where it runs on inexpensive hardware and may be the user’s primary computing device.

    Making a backup application is a difficult task. As developers, we’re unable to anticipate future changes in both the operating system itself and the types of data that users create. Ultimately, we decided that the ephemeral nature of a senior capstone team meant that we would be unable to provide the long-term support necessary to deploy and maintain an application on the app store.

    We therefore decided to create a library, rather than a standalone application. Our reasoning was that we would be able to make a stronger impact by providing a foundation for other developers to build their own backup applications on. After six months of development, we had created the Firefox OS Backup/Restore (FFOSBR) library, as well as a small test application to demonstrate its basic capabilities.

    Capabilities of FFOSBR

    The Firefox OS Backup/Restore (FFOSBR) library is designed to back up media to an SD card. While we had envisioned being able to back up data via USB as well, this would have required the development of a companion application to interpret the data on the receiving PC, which was outside the scope of our project.

    The FFOSBR library is capable of backing up and restoring:

    • Photos
    • Music
    • Videos
    • Contacts
    • System Settings

    The library can also back up the user’s SMS and MMS messages. However, Firefox OS currently provides no API for adding messages to the phone without actually sending them via SMS or MMS. As such, messages are backed up as JSON objects to a text file on the SD card, but cannot be restored back to the phone.


    FFOSBR is implemented as a collection of modules. Each type of personal data has a module, but there are additional “helper” modules that are used to hold the library together. Notably, these include a ffosbr.settings module to track application settings (such as which data types have backups enabled) and a ffosbr.history module that tracks backup dates and sizes for each data type.

    Data type-specific modules each implement, at minimum, three public functions: backup(), restore(), and clean(). These functions all take a single callback parameter, oncomplete. The callback should be a function that takes two arguments. The first argument will always be the name of the type backed up; any errors that occur will be passed to the oncomplete function in the second argument. Passing the type as the first argument allows us to use a technique that we refer to as patient oncompletes, which will be described shortly.

    In addition, there are top-level helper modules — ffosbr.backup(), ffosbr.restore(), and ffosbr.clean() — which iterate over all of the enabled data type-specific modules and invoke their backup(), restore(), or clean() methods, respectively. This is where patient oncompletes come into play. Let’s look at ffosbr.backup() as an example.


    ffosbr.backup() takes three arguments, all of which are callback methods. These are onsuccess, onerror, and oncomplete.

    ffosbr.backup() runs each data type’s backup() method asynchronously with a function called callbackManager() as an oncomplete. As mentioned above, each data type’s backup() method calls its oncomplete method with the name of the data type as the first argument so that the callbackManager() can identify it.  As each data type completes, the callbackManager() examines its second argument to determine whether or not an error occurred. If so, it calls onerror(); otherwise, it calls onsuccess(). Only after every data type’s backup() method has completed does the ffosbr.backup() method finish and invoke its own oncomplete callback.


    A function that backs up all types of user data might therefore look something like this:

    var successes = [];
    var failures = [];
    var reportSuccess = function(type) {
      if (type && !successes.includes(type)) {
        alertUser(type + ' saved successfully');
    var reportError = function(type, error) {
      if (type && !failures.includes(type)) {
        alertUser(type + ' failed');
    var finished = function() {
      var sitrep = 'SUCCESSES:\n';
      for (var i = 0; i < successes.length; ++i) {
        sitrep += '\t' + successes[i] + '\n';
      sitrep += '\nFAILURES:\n';
      for (i = 0; i < failures.length; ++i) {
        sitrep += '\t' + failures[i] + '\n';
    ffosbr.backup(reportSuccess, reportError, finished);

    Cleaning and restoring look similar, but with ffosbr.clean() or ffosbr.restore() used in place of ffosbr.backup() on the last line.

    Demo Application

    In addition to the FFOSBR library itself, we’ve also created a simple demo application to show off some of its capabilities. The home screen displays information about current backup status, and has buttons to back up and restore all enabled types:


    Clicking on any of the listed types opens a submenu:

    From here, the user can enable or disable backups for that data type. They can also restore data of that type individually, or clear backups of that type from the SD card’s backup directory.

    Do keep in mind that our primary product was the library itself; as a demo, the application is relatively bare-bones. However, it does provide the capability for users to back up and restore their media, contacts, and system settings to an SD card.

    Future Improvements

    Unfortunately, not all backups are entirely nondestructive. Music, pictures, and videos work on a per-file basis. Thus, backing up or restoring data doesn’t remove the data already on the phone or SD card. However, contacts, messages, and system settings are backed up to specific files in the backup directory on the SD card. These files are overwritten with each backup. In the future, we can address this by appending a timestamp to the filenames so that each backup creates a new file.

    The contacts module also currently runs synchronously. ffosbr.contacts.backup() calls a function that gets contacts from the SIM card, which in turn calls a function that gets contacts from the device. Ideally, these should be two entirely separate operations which back up to entirely separate files, since it will also allow us to restore SIM contacts back to the SIM card and device contacts back to the device. We didn’t devise our patient oncomplete strategy until after the contacts module had been written, but employing this would allow us to back up SIM and device contacts in parallel to separate files.

    Installing Firefox OS Backup/Restore

    The FFOSBR project can be found on GitHub at If you are a Firefox OS developer or technical user, take a look and let us know what you think.

  8. Controlling WebRTC PeerConnections with an extension

    Author’s note: Firefox recently added some features (in Firefox 42) to allow users to exercise added control over WebRTC RTCPeerConnections, IP address gathering used in connecting them, and what IP addresses are exposed to JS applications. For a detailed explanation of the issues this is addressing and why Firefox is addressing them, please see my (Maire’s) personal blog post about the issue. Discussion of the problems, risks, tradeoffs, and reasoning are best done there. This article is about the new features in the code and how to access them.

    Maire Reavy
    Engineering Manager, WebRTC

    To control IP address exposure and RTCPeerConnection usage, we’ve provided methods to hook createOffer/createAnswer and added about:config prefs for controlling which candidates are available during ICE negotiation. Also, some controls already existed in about:config. You can learn more about the controls available on Mozilla’s wiki page about WebRTC privacy.

    The createOffer/createAnswer hooks allow extensions to modify the behaviour of the PeerConnection and, for example, add a door-hanger very similar to the one you get when a site uses the getUserMedia API to access camera and microphone. We have done a proof of concept extension and this is how it looks for a web site which only uses the DataChannel:


    From a user interaction perspective, it’s important to ask for access permission in a non-scary way that an end user can understand. For getUserMedia, i.e., access to the user’s camera and microphone, the question asked is:

    Would you like to share your camera and microphone with

    The implications of that are quite clear, as the website can record your voice and video and may send it to someone else.

    The sample extension door-hanger pops up in two cases:

    • The site uses a receive-only connection, i.e., only receives video — you can test it here.
    • The site uses the datachannel without calling getUserMedia as shown with this sample.

    For the case where the site has permission to access camera and microphone, e.g., no additional question is asked. This minimizes the number of questions the user has to answer and retains much of the current behaviour.

    For the receive-only case, it is a more awkward question to ask. The use-case here is one-way streaming, e.g., for a webinar. Users don’t expect to be asked for permission here since you don’t need to grant similar permissions to watch a recorded video on YouTube.

    For data channels, there are a number of different use cases, ranging from file transfer to gaming to peer-to-peer CDNs. For file transfer, the workflow is rather easy to explain to the user — they select a file, the door-hanger pops up, they allow it, and the file gets transferred. There is a direct connection between the user action and the popup. That applies to gaming as well.

    The peer-to-peer CDN use case is harder. You start playing a video and the browser asks for something called DataChannel?! If you are a developer relying on this use-case, we recommend you try the sample extension, and use it to develop a good user experience around that use-case. We’d love to hear your real world feedback.

    In the recently reported case of the New York Times’ somewhat surprising usage of WebRTC, the developer cited “fraud detection” as the use case. WebRTC was not built to solve this problem, and there are better tools and technologies for the job. We urge you to put those to use.

    If you are an extension developer you can take a look at the source code of the extension to see what is needed to implement this interaction; you basically need to override the handling of rtcpeer:Request in the webrtcUI.receiveMessage handler. Let us know if you have any questions, either in the comments or open an issue over at github.

  9. The future of layout with CSS: Grid Layouts

    In this article we’ll take a look at the wonderful world of the CSS Grid Layout, a relatively new W3C specification that has partially started to see the day in some browsers.

    But before we dive into what this new CSS technique is all about and how to use it, let’s quickly review grid theory.

    My really short introduction to grid theory

    I am not a designer nor did I know much about grid theory before stumbling upon the CSS Grid Layout specification, so don’t take my word for it and go look it up yourself, but if you don’t care to, here’s my pitch:

    In essence, a grid is a set of invisible vertical and horizontal lines that are used to position the various design and content pieces of a web page, magazine, or newspaper. The goal of a grid is to serve as a base for placing the various pieces of content and to make sure these pieces are aligned and spaced out evenly. A grid, even if not visible, provides the viewer with a way to navigate content visually.

    So what has CSS got to do with it?

    CSS is getting a set of entirely new properties that, when used together, allow you to define grids for your web content to go onto. These properties are defined in the CSS Grid Layout specification.

    CSS hasn’t particularly been known for its ability to handle complex layouts. Although this may not have been a problem when CSS first came out, it has evolved to be a pretty common one over the years, as all sorts of complex layouts couldn’t be easily implemented. People have been very creative at getting around the lack of support by using floats or absolute positioning and a variety of CSS layout frameworks emerged.

    So it’s about time CSS got some proper layout solutions to support today’s use cases.

    Can I use it?

    Yes you can start using it today, to experiment and learn. It’s a bit too early to use it on a commercial website.

    Chrome has implemented the specification far enough to play with Grid. Turn the experimental Web Platform features flag on to get it to work. The Chrome implementation is currently the most up-to-date with the recent changes to the CSS Grid Layout specification.

    Internet Explorer had the first implementation of CSS Grid (dating back to IE10), but the spec has evolved since it was added and so it’s not entirely compatible with the latest spec anymore. They’ll be updating their implementation soon.

    Firefox has started implementing it too, so it shouldn’t be too long before you can use it in this browser.

    Finally, a polyfill exists, so you have no excuses not to start experimenting. (And I strongly encourage you to do so!) You probably should not use the polyfill in production, however.

    So what’s a CSS grid layout?

    At its core, a grid layout in CSS is a set of vertical and horizontal lines that define cells into which content can be arbitrarily positioned.
    So it looks like a table in a way, except for a few key differences we’ll see later.

    1 zcOcwuBtMoBaUfHHAJPNyg

    The figure above shows the building blocks of a grid:

    • Lines: In this case there are 4 vertical lines and 3 horizontal lines. Lines are given numbers starting from 1. Vertical lines are shown from left to right, but this depends on the writing direction. Lines can optionally be given names, which helps with referencing them in CSS, as we’ll see later.
    • Tracks: A track is simply the space between 2 parallel lines. So in the above example, there are 3 vertical tracks and 2 horizontal tracks. Lines are useful to indicate where content starts and stops, but tracks are ultimately where content goes.
    • Cells: A cell is where a horizontal and a vertical track meet. In the figure above, only one cell has been highlighted, but there are 6 cells in the grid.
    • Areas: An area is a rectangular shape that can span an arbitrary number of cells. Areas, like lines, can be named. In the above grid, we could for example define areas A, B and C as shown below:

    1 zcOcwuBtMoBaUfHHAJPNyg

    Now that we know these simple definitions, let’s take a look at what makes grids so powerful.

    One key advantage of CSS grids is that they enforce real separation of layout and markup.

    Indeed, the grid itself is completely defined in pure CSS. This means that apart from the parent HTML element the grid is applied to, there’s no need to define any extra elements for the columns, rows, cells, or areas.

    When you think of it, that’s a really interesting property. One aspect of it is that the visual order of elements on the page is decoupled from the order of elements in the markup. That’s important because on a page the source order is used for things like speech and tab navigation, so CSS Grids allow you to optimize the markup for accessibility without compromising your ability to manipulate the visual result. One other point is that the markup will be somewhat lighter and easier to understand, and therefore easier to maintain.

    But more importantly, it gives us a very powerful tool for separating the content from the layout, effectively decoupling them in a way that makes it possible to change one without impacting or otherwise breaking the other.
    As a designer, you can easily experiment with new layouts without having to change anything other than CSS, as long as your new layouts provide the expected lines and areas the content uses.
    And as a developer, you simply use the numbered or named lines and areas to position your content on the grid.

    Imagine the simple following grid layout:

    1 zcOcwuBtMoBaUfHHAJPNyg

    In this layout, named areas have been defined, allowing content to be positioned in them simply by referencing the names. This means that not only can we change this layout relatively easily in the future, as long as we maintain the named regions (here the named regions act as the layout’s public API in a way), but media-queries can be used to change this layout dynamically too. Remember, the whole layout is defined in CSS, so media-queries play with grid layouts very well.

    For instance, using a media query, the previous layout could switch to something like this on smaller screens:

    1 zcOcwuBtMoBaUfHHAJPNyg

    Enough with the theory, let’s see how grid layouts are actually defined using CSS.

    Creating grids with CSS

    Defining a grid requires only one HTML element to be present: the grid container. That’s the element the layout is going to be applied to. Any HTML element that’s a child of the grid container is a grid item. Grid items are what go onto the grid.

    Setting an element as being a grid container is as simple as:

    .container { display: grid; }

    Just doing this though isn’t nearly enough, we also need to define what this grid looks like, how many columns and rows it has, and how big they are.
    This can be done using grid templates as shown in the following example:

    .container {
      display: grid;
      grid-template-rows: 200px 100px;
      grid-template-columns: repeat(4, 100px);

    In the example above, we’re explicitly defining a grid that has 2 rows and 4 columns. Note how the repeat() function is used here to avoid repeating a fragment of the tracks 4 times, this is equivalent to 100px 100px 100px 100px.

    Each of the defined tracks is given a size, and so we end up with a grid structure that looks like this:

    1 zcOcwuBtMoBaUfHHAJPNyg

    But grids can also be implicitly defined like in:

    .container {
      display: grid;
      grid-template-rows: auto;
      grid-template-columns: repeat(4, 100px);

    In this case, the browser will keep on adding rows as needed to fit the content.

    Now let’s add some content. As we said previously, we only need 2 levels of elements, the container and the items, so let’s use this:

    <div class="container">
      <div class="item1">item 1</div>
      <div class="item2">item 2</div>
      <div class="item3">item 3</div>
      <div class="item4">item 4</div>
      <div class="item5">item 5</div>

    Which, without any specific CSS code to position the items, leads to the following arrangement:

    1 zcOcwuBtMoBaUfHHAJPNyg

    As you can see above, since we didn’t define where these items should sit on the grid, the browser has positioned them automatically by putting one item per cell until the first row got filled in, at which point it decided to put the rest of the items on the next row.

    The spec defines an algorithm for automatically placing items on the grid if they haven’t been given a position. This is sometimes useful when, for example, you have either many items or a dynamic number of items and don’t want to or can’t define the position for them all.

    Let’s see how our items can be positioned on the grid.

    .item1 {
      grid-row-start: 1;
      grid-row-end: 2;
      grid-column-start: 1;
      grid-column-end: 3;
    .item2 {
      grid-row-start: 1;
      grid-row-end: 2;
      grid-column-start: 3;
      grid-column-end: 5;

    Here we’ve defined the position of the 2 first items, which means that the other ones will still be automatically positioned by the browser, as shown below:

    1 zcOcwuBtMoBaUfHHAJPNyg

    The above example uses line-based placement in that it uses numeric indexes of lines to place items. Items 1 and 2 are defined to be positioned between horizontal lines 1 and 2, and between vertical lines 1 and 3 and 3 and 5.

    What happens now if we keep on adding items, but there aren’t any grid cells defined to receive them?

    1 zcOcwuBtMoBaUfHHAJPNyg

    The grid keeps on adding rows and columns as needed. Note that these new tracks will have their sizes depend on the content size.

    So that’s all well and good, but one thing that’s really useful when it comes to CSS Grids is grid areas, as we saw earlier. Let’s take a look at how grid areas can be used in CSS.

    First of all you’ll need to define the grid container and its tracks and areas:

    .container {
      display: grid;
      grid-template-rows: 100px auto 100px;
      grid-template-columns: 100px auto;
        "header  header"
        "sidebar content"
        "footer  footer";

    In this example, we’ve defined 3 rows, the top and bottom ones being 100px high, while the middle one will just adapt to its content. We’ve also defined 2 columns, the left one 100px wide, and the right one adapting to its content.

    We’ve also introduced the grid-template-areas property that may look strange at first, but it’s really simple when you realize it’s only a representation of the grid with names on it. Let’s explain this.

    We said we had 3 rows and 2 columns right? Let’s represent them in ascii-art like this:

    | . | . |
    | . | . |
    | . | . |

    Each dot is a cell where areas can be defined. So let’s define areas for a typical website layout:

    | header | header |
    | sidebar| content|
    | footer | footer |

    We want the header and footer to span the whole width, so we’ve repeated them in the 2 columns.
    Now, if we just remove all the useless ascii-art style borders and include each line in double-quotes, we get something like this:

    "header  header"
    "sidebar content"
    "footer  footer"

    which is exactly how grid areas are defined in CSS using the grid-template-areas property. It helps thinking about it as a 2D representation of the grid in ascii-art and aligning area names.

    You can also use dots ‘.’ when a cell isn’t covered by an area. Here’s an example:

    .container {
      display: grid;
      grid-template-rows: repeat(5, 100px);
      grid-template-columns: repeat(5, 100px);
        ". . . . ."
        ". . . . ."
        ". . a . ."
        ". . . . ."
        ". . . . .";

    In this example, there are 25 cells and 1 area that is defined to occupy only the center cell.

    Now, going back to the previous header, sidebar, content, footer example, let’s add some markup to it:

    <div class="container">
      <div class="header">header</div>
      <div class="sidebar">sidebar</div>
      <div class="footer">footer</div>
      <div class="content">
        <p>Lorem ipsum dolor sit amet...</p>

    The last thing that needs to be done now is position each grid item in the correct named areas (we’ve conveniently used class names that correspond to area names here):

    .header { grid-area: header; }
    .sidebar { grid-area: sidebar; }
    .footer { grid-area: footer; }
    .content { grid-area: content; }

    Which would produce something like this:

    1 zcOcwuBtMoBaUfHHAJPNyg

    Now, if we wanted to change this layout at any point, or make it adapt to variable screen sizes thanks to media queries, we would only have to change the grid declaration. Maybe to something like this:

    .container {
      display: grid;
      grid-template-rows: auto;
      grid-template-columns: 100%;

    Without any other changes to the CSS or markup, we’ve produced this:

    1 zcOcwuBtMoBaUfHHAJPNyg

    We could even completely reshuffle the order of items in the grid without having to change their order in the markup.

    CSS Grids in the real world

    So far we’ve only seen simplistic examples of grids, but websites making use of grid systems often have much more complex grid structures. It’s not uncommon for such websites to be based on 12 columns, each of them separated by gutters (narrower columns used to space things out).

    Take for example, this design showcase website makes use of a grid to display the designs uploaded by their users. Here the grid is very easily visible because each design occupies exactly one cell (excluding gutter rows and columns):

    Dribbble’s grid layout is also responsive, so if the viewport size changes, the size and number of columns change gradually, as shown in the following animation:

    Using the new properties that come with the CSS Grid Layout implementation, we can try and create a dribbble-like layout. For an added twist, let’s try and insert a piece of text content on the second row, and make that content span the whole row.

    First of all, our markup will be something like this:

    <ul class="dribbbles">
      <li class="dribbble">...</li>
      <li class="dribbble">...</li>
      <li class="dribbble">...</li>
      <li class="advert">Some text ....</li>

    Here the dribbbles element is the main container for all items, and each .dribbble element represents one of the designs showcased on the page. The last item, .advert, is the piece of textual content we want to show on the second row.

    Now, let’s make a grid for it:

    .dribbbles {
      display: grid;
      /* Let's assume the default design has a fixed width */
      width: 880px;
      grid-template-columns: repeat(4, 220px);
        ".      .      .      ."
        "advert advert advert advert";
      justify-items: center;
    .advert {
      grid-area: advert;

    Here we’ve defined 4 columns in our grid. We haven’t said anything about rows, so the browser will automatically create rows as needed.
    We did, however, define a couple of rows using the grid-template-areas property and that’s because we need to place our advert text content on the second row. So we’ve just said that we want a first row with empty cells that are going to be filled in automatically with grid items, as they come, and then a second row that defines an advert area that spans all 4 columns.

    Finally, the second rule in there uses the grid-area property to place the grid item that has the class advert inside the advert area.

    Given the markup we created earlier, this should end up looking something like this:

    Pretty simple, right? Of course this requires some styling code to make the items look nice and all, but the layout CSS code is really short and there’s no extra markup required.

    Now, we can make this responsive too. Let’s say we want to jump to a 3-columns layout for smaller screens:

    @media (max-width: 880px) and (min-width: 660px) {
      .dribbbles {
        width: 660px;
        grid-template-columns: repeat(3, 220px);
          ".      .      ."
          "advert advert advert";

    And so on, for all the screen sizes we want to support. And so, just adding a couple more short media queries, we could end up with something like this:

    Sites like Dribbble don’t use the CSS Grid Layout yet, but there are well known CSS libraries that provide grid systems.

    A good example of a grid system in CSS is the Bootstrap CSS library but there are others like PureCSS, 960 Grid System, Responsive Grid System, Materialize, and more.

    These grid systems unfortunately have to use arrangements of carefully sized and floated DIVs, and need extra DIVs for columns and rows, as well as pseudo-elements for clearing floats. It’s not all that complex—after all, the tricks that these libraries rely on have been known for years—but they’re still just tricks, and it’s time we get a proper built-in solution and get rid of them.

    Don’t get me wrong, these libraries are awesome in all sorts of way, and most importantly, they helped make it clear we needed a new CSS feature for defining grids in web layouts. Ultimately, therefore, they are what made the CSS Grid Layout specification possible.

    Closing words and references

    As we saw, CSS grids are a pretty good tool for defining layouts that have nice characteristics like authoring simplicity, maintainability, separation of content and layout — characteristics that play well with responsive design.
    But we’ve only barely scratched the surface of what is possible with CSS grids. The various properties and syntax possibilities allow for a lot of really cool things to be done, and I hope this article makes you want to dig further by yourself.

    Here are some interesting references if you wish to know more:

  10. Implementing Air Mozilla’s Related Events Feature

    Editor’s note: It’s not often that we hear from web developers and software engineers at the start their careers here on the Hacks blog. This post is a great reminder of what it’s like.

    Mozilla participates in Outreachy, and offers internship opportunities to bring women and other under-represented groups into the world of free and open source software. The application process for the upcoming round will open on September 22, 2015. The application deadline is October 26. Internship dates will be December 7, 2015 to March 7, 2016. If you’ve been thinking of applying, read this, be like Gloria – and go for it!

    How I became a Mozilla intern

    It was a spring night in Greece when I got the news I’d been selected by Mozilla to be an Outreachy intern. Outreachy is a project of the Software Freedom Conservancy that helps people from groups underrepresented in FOSS (free and open source software) to get involved by offering focused internship opportunities with a number of open source software organizations. That night, I was the happiest person in my town, I believe. I remember rushing to say a big thank you to my mentor Peter Bengtsson, before I got too overwhelmed with happiness to the point that I forgot to be grateful. It was a two-way street. I chose Mozilla and Mozilla chose me.

    I started contributing to Air Mozilla in March 2015, by solving beginner-friendly bugs. Initially I didn’t want to apply at all, because there were too many wonderful contributors, and in some way I felt overwhelmed by how rigorous the process was. I told several people I won’t apply because I am afraid I won’t be getting it, and sometimes it is okay to be afraid, but it is not okay to be afraid of something you are capable of achieving to the point of sabotaging yourself.

    After several pep talks, I went to view the list of the companies and decided to apply only for Mozilla. It will be a hit or miss, I told myself. I noticed it listed “Python” and I was aware that I didn’t know Python that well as it was something I self-studied briefly in the past, but I told myself to go ahead and try. Sometimes you need to do hard things to get the experience you want. Every expert was once a newbie. I went to check Bugzilla to see what I could fix. One bug looked very easy, so I thought I should work on that. That’s how it all started. Feedback after feedback, perseverance, pull, merge, merge conflicts, and getting a deeper understanding of how the code base functions made me able to contribute a lot more. One thing I loved about interning with open source is the fact that everything is open. I was asked to blog about what I worked on, and I didn’t need to hide anything that concerned it. Well… that doesn’t mean I shared my passwords too though! Passwords need to be protected and secret for a reason.

    Getting to work on Air Mozilla

    The internship day officially started on May 25th. I was told that after discussions I am being assigned to add a new feature. That new feature will act as a recommendation system suggesting similar events to Air Mozilla viewers while they view a specific event. Air Mozilla is a platform for Mozilla’s online multimedia presence that provides live and pre-recorded shows, interviews, news snippets, tutorial videos, and features about the Mozilla community.

    That sounded fascinating. I wasn’t nervous at all, it seemed pretty interesting and I always wondered how those things worked, that’s until I started getting really stuck down the road. Then I realized the complexity of it. I had to either build my own algorithms and computations to do the job, or find an open source tool we could use instead of reinventing the wheel. After several days of research we decided Elastic Search seemed like a good fit. Elastic Search, is a search server. It has a function called “More Like This” and that helps you search for similar events based on your set parameters. I went and read the documentation of Elastic Search but to be honest, I had a very hard time navigating it. Mostly because I couldn’t find enough examples on how to use it with Python. At some point we decided pyelasticsearch might make things easier; it’s a Python library version of Elastic Search that has the functionalities we were looking for.

    For a short recap, Elastic Search creates a mapping and indexes all the events on Air Mozilla. When you visit an event page, with the “More Like This” feature, we ask it to search the indexed events that are similar to the event you are currently viewing and return back the title, id, tags and its similarity scores on the back-end. For events to be considered related, their tags, channel and titles must be very much alike, but that’s not where we stop.

    We also need to be able to set someone’s level of access: a person who is logged in as a Mozilla employee will have more access than an anonymous guest would. A logged in volunteer contributor will have more access than an anonymous guest, but less than a Mozilla employee. You get the idea. Each event has its own access level setting. Some events are private and limited to employees, while the majority of Air Mozilla events are accessible to the public or to members of the entire Mozilla community. Regardless, the Related Events feature lets people see a list of similar events, filtered for their level of access, with the most similar “related events” appearing on top.

    Implementing Elastic Search

    In the code below we are using the more_like_this (mlt) query. We break the tags and the titles into different queries because we want to boost the relevance score of each one to a different degree. In this case we want a similar title to have a higher relevance score than the similar tags. The field parameter is used to determine which field we are trying to run mlt against, the docs parameter is the documents we are trying to find similar events for. You can read more about this at the More Like This Query page.

    mlt_query1 = { 
        'more_like_this': { 
            'fields': ['title'], 
            'docs': [ 
                    '_index': index, 
                    '_type': doc_type, 
            'min_term_freq': 1, 
            'max_query_terms': 20, 
            'min_doc_freq': 1, 
            'boost': 1.0, 
    mlt_query2 = { 
        'more_like_this': { 
            'fields': ['tags'], 
            'docs': [ 
                    '_index': index, 
                    '_type': doc_type, 
            'min_term_freq': 1, 
            'max_query_terms': 20, 
            'min_doc_freq': 1, 
            'boost': -0.5, 


    Below we are asking that one or more of the given mlt queries should match the documents, i.e., list of events:

    query_ = { 
        'bool': { 
            'should': [mlt_query1, mlt_query2], 


    Below, with request.user.is_active we are checking if the user is logged in and what their access level is. If the user is logged in as a volunteer the events that appear must not contain events that are restricted to Mozilla employees only.

    If the user is logged in and is not a volunteer, that means they are Mozilla paid staff members. Their “related events” results should contain all events that are similar to the event we are currently viewing.

    In the case of an anonymous user, the “related events” results must contain only events that are accessible to everyone.

    if request.user.is_active: 
      query = { 
        'fields': fields, 
        'query': query_ 
      query = { 
        'fields': fields, 
        'query': query_, 
        "filter": { 
          "bool": { 
            "must": { 
              "term": {"privacy": Event.PRIVACY_PUBLIC} 

    In the code above you see we used the more_like_this query along with a filter. More_like_this does return similar events based on title, tags and channels but it doesn’t ensure that the events returned are filtered by access level. So this is where “filter” comes in. It makes sure to filter the relevant events and allow only the ones the user can view based on their level of access.

    With the use of cron jobs I completely delete and re-index the index for the week, and every 10 minutes we re-index (without first deleting) all events that have changed in the last 10 minutes.

    AJAX queries were used to get the thumbnails and links of the related events. AJAX loads asynchronously, so running those queries doesn’t slow the pageload. When I view an event, I want it to load the page fully without waiting for Elastic Search to finish running the queries. Elastic Search queries run pretty fast but it still takes some time. Sometimes, it can be slow. The relevant events section appears under the events’ details. Ideally, someone watching an event won’t mind if there is a slight delay in the loading of the related events while they view the event, however a page that loads slowly as a whole can be frustrating. Through AJAX our Elastic Search queries can run in the background after the page has loaded.

    In the screenshots below, you can see how it works. I have added red arrows to the title of event we are on and the title of the first recommended event. If you compare both pictures you can see how the events we are viewing, and/or recommending, relate to each other.

    Example of Related Events for volunteers and staff

    A second example of Related Events

    Examples of related events for signed-in users


    4 key things that make you realize how much you enjoyed your internship:

    • Your mentor made sure you took the right steps to learn a lot.
    • You feel that every portion of it, even the frustrating moments, made you grow not only in skills but as a person.
    • You were extremely happy you got it.
    • You are extremely sad it is ending.

    That’s exactly how it’s been for me. I want to take a moment to thank Outreachy, my mentor Peter, and the other Mozillians I met on IRC and in email during my internship. Thank you for being helpful, welcoming, and for contributing to my learning experience.

    What made the pensive ending of my internship bright and merry is a motto Mozilla takes pride in: Once a Mozillian, Always a Mozillian.