Firefox 72 — our first song of 2020

2020 is upon us, folks. We’d like to wish everyone reading this a happy new year, wherever you are. As you take your first steps of the new year, figuring out what your next move is, you may find it comforting to know that there’s a new Firefox release to try out!

Version 72 to be exact.

One of the highlights that we are most proud of is that user gestures are now required for a number of permission-reliant methods, such as Notification.requestPermission(). User research commonly brings up permission prompt spam as a top user annoyance, so we decided to do something about it. This change reduces permission spam and strengthens users’ agency over their online experience.

This release brings several other new features, including DevTool improvements such as Watchpoints, WebSockets inspector improvements, and resource download times; support for CSS features like shadow parts, motion path, and transform properties; and JS/API features such as event-based form participation and the nullish coalescing operator.

Read on for more highlights. To find the full list of additions, check out the following MDN articles:

Now that we’ve moved to a 4-week browser release cycle, you’ll see fewer new features in each individual release, but features will be added to Firefox more often. This gives you faster access to new functionality and bug fixes. You can read our full rationale for the change in Moving Firefox to a faster 4-week release cycle.

DevTools improvements

First, we’ll look at Firefox 72 DevTools improvements in more detail.

Pause on variable access or change

Watchpoints are a new type of breakpoint that can pause execution when an object property gets read or set. You can set watchpoints from the context menu of any object listed in the Scopes panel.

setting watchpoints in the debugger, using options in the context menu of objects in the scopes panel

This feature is described in more detail in the Use watchpoints article on MDN, and Debugging Variables With Watchpoints in Firefox 72 on Hacks.

Firefox DevEdition only: Asynchronous Stacks in Console

Console stacks capture the full async execution flow for <a href="">console.trace()</a> and <a href="">console.error()</a>. This lets you understand scheduling of timers, events, promises, generators, etc. over time, which would otherwise be invisible.

an asynchronous callstack being shown in the javascript console

They are only enabled in Firefox Developer Edition for now. We are working to make this feature available to all users after improving performance. Async stacks will also be rolled out to more types of logs, and of course the Debugger.

SignalR formatting & download/upload size for WebSockets

Before shipping the new WebSocket inspector in 71 we had it available in Firefox DevEdition and asked for your input. We didn’t just get a lot of fantastic ideas, some of you even stepped up to contribute code. Thanks a lot for that, and keep it coming!

Messages sent in ASP.NET’s Core SignalR format are now parsed to show nicely-formatted metadata. The bug was filed thanks to feedback from the ASP.NET community and then picked up by contributor Bryan Kok.

Similarly, the community asked to have the total transfer size for download and upload available. This is now a reality thanks to contributor Hayden Huang, who took up the bug as their first Firefox patch.

Start and end times for Network resources

The Timings tab of the Network Monitor now displays timings for each downloaded resource, making dependency analysis a lot easier:

  • Queued — When the resource was queued for download.
  • Started — When the resource started downloading.
  • Downloaded — When the the resource finished downloading.

And as always, faster and more reliable

Here are just a few highlights from our continued performance and quality investments:

  • In the Inspector, editing CSS is no longer blocked by CSP rules.
  • The Inspector‘s badge for Custom Elements now correctly opens the original script for source maps.
  • The Inspector now correctly preserves the selected element for <a href=""><iframes></a> when reloading.
  • The Debugger now loads faster when many tabs are open, by prioritizing visible tabs first.

CSS additions

Now let’s move on to the most interesting new CSS features in Firefox 72.

Shadow Parts

One problem with styling elements contained inside a Shadow DOM is that you can’t just style them from CSS applied to the main document. To make this possible, we’ve implemented Shadow Parts, which allow shadow hosts to selectively expose chosen elements from their shadow tree to the outside page for styling purposes.

Shadow parts require two new features. The part attribute exposes an element inside a shadow tree to the outside page:

  <p part="example">A paragraph</p>

The ::part() pseudo-element is then used to select elements with a specific part attribute value:

custom-element::part(example) {
  border: solid 1px black;
  border-radius: 5px;
  padding: 5px;

CSS Motion Path

Motion Path is an interesting new spec for all you animators out there. The idea here is that you can define a path shape and then animate a DOM node along that path. The spec proposes an alternative to having to animate transform: translate(), position properties like top, right, and so on, or use some other property that often isn’t ideal and could result in very complex sets of keyframes.

With motion path, you define the shape of the path using offset-path:

offset-path: path('M20,20 C20,100 200,0 200,100');

Define an animation to animate the element between different values of the offset-distance property, which defines how far along the defined path you want the element to appear:

@keyframes move {
  0% {
    offset-distance: 0%;

  100% {
    offset-distance: 100%;

Then, animate the element using those keyframes:

animation: move 3000ms infinite alternate ease-in-out;

This is a simple example. There are additional properties available, such as offset-rotate and offset-anchor. With offset-rotate, you can specify how much you want to rotate the element being animated. Use offset-anchor to specify which background-position of the animated element is anchored to the path.

Individual transform properties

In this release the following individual transform properties are enabled by default: scale, rotate, and translate. These can be used to set transforms on an element, like so:

scale: 2;
rotate: 90deg;
translate: 100px 200px;

These can be used in place of:

transform: scale(2);
transform: rotate(90deg);
transform: translate(100px 200px);

Or even:

transform: scale(2) rotate(90deg) translate(100px 200px);

These properties are easier to write than the equivalent individual transforms, map better to typical user interface usage, and save you having to remember the exact order of multiple transform functions specified in the transform property.

JavaScript and WebAPI updates

If JavaScript is more your thing, this is the section for you. 72 has the following updates.

User gestures required for a number of permission-reliant methods

Notification permission prompts always show up in research as a top web annoyance, so we decided to do something about it. To improve security and avoid unwanted and annoying permission prompts, a number of methods have been changed so that they can only be called in response to a user gesture, such as a click event. These are Notification.requestPermission(), PushManager.subscribe(), and MediaDevices.getDisplayMedia().

By requiring a user gesture before the permission prompts are shown, Firefox significantly reduces permission spam, thereby strengthening users’ agency over their online experience.

So, for example, prompting for notification permission on initial page load is no longer possible. You now need something like this:

btn.addEventListener('click', function() {
  // Handle other notification permission stuff in here

For more detail on associated coding best practices for Notification permissions, read Using the Notifications API.

Nullish coalescing operator

The nullish coalescing operator, ??, returns its right-hand side operand when its left-hand side operand is null or undefined. Otherwise, it returns its left-hand side operand.

This is a useful timesaver in a number of ways, and it is also useful when you only consider null and undefined to be unwanted values, and not other falsy values like 0 and ' '.

For example, if you want to check whether a value has been set and return a default value if not, you might do something like this:

let value;

if(!value) {
  value = 'default';

That’s a bit long, so you might instead use this common pattern:

let value;
let value = value || 'default';

This also works OK, but will return unexpected results if you want to accept values of 0 or ' '.

With ??, you can do this instead, which is concise and solves the problem described above:

let value;
value = value ?? 'default';

Event-based form participation

Event-based form participation is now enabled by default. This involves using the new FormData event, which fires when the form is submitted, but can also be triggered by the invocation of a FormData() constructor. This allows a FormData object to be quickly obtained in response to a formdata event firing, rather than needing to create it yourself — useful when you want to submit a form via XHR, for example.

Here’s a look at this feature in action:

formElem.addEventListener('submit', (e) => {
  // on form submission, prevent default

  // construct a FormData object, which fires the formdata event
  new FormData(formElem);

formElem.addEventListener('formdata', (e) => {
  console.log('formdata fired');

  // Get the form data from the event object
  let data = e.formData;

  // submit the data via XHR
  let request = new XMLHttpRequest();"POST", "/formHandler");

Picture-in-picture for video now available on macOS & Linux

In the previous release post, we announced that Picture-in-picture had been enabled in Firefox 71, albeit this was for Windows only. However,today we have the goods that this very popular feature is now available on macOS and Linux too!

picture in picture on mac os; a video being played in a separate overlay form the page where it is actually embedded

About Chris Mills

Chris Mills is a senior tech writer at Mozilla, where he writes docs and demos about open web apps, HTML/CSS/JavaScript, A11y, WebAssembly, and more. He loves tinkering around with web technologies, and gives occasional tech talks at conferences and universities. He used to work for Opera and W3C, and enjoys playing heavy metal drums and drinking good beer. He lives near Manchester, UK, with his good lady and three beautiful children.

More articles by Chris Mills…


  1. paola

    Well I am sure this will not crash like Chrome 79 has been doing on my PC due to an outdated version of Symantec Endpoint Protection. Every time open it it goes AW SNAP, the only way is to open it in safe mode and the I can visit my site but even then there are problems because the plugins are not loading, now I am working only with Firefox and everything is great.

    January 7th, 2020 at 14:19

  2. Chris

    Why are you forcing millions of websites (including me) to suddenly have a black scrollbar? I don’t want this. I have a light website and a dark scrollbar looks terrible. When will you change it back?

    January 8th, 2020 at 15:47

    1. Chris Mills

      I’m not seeing a dark scrollbar that looks terrible on websites I visit. What OS are you on?

      January 8th, 2020 at 23:53

      1. Chris

        Win 10 (but the same on Windows 8)
        Firefox 72.0.1 (64-Bit)


        Is there a way to deactivate this. Or what affects the decision which scrollbar color will appear? In this example it seems the footer color is the reason. But then I see pages where footer (and/or header) are black but the scrollbar is light.

        January 12th, 2020 at 13:16

        1. Bill

          I visited the site you linked and I see no black scrollbar that you speak of.

          January 13th, 2020 at 15:30

          1. Chris Mills

            I don’t either. Maybe submit a bug on, so the engineers can investigate and try to reproduce?

            January 14th, 2020 at 00:21

        2. Shawn

          I see the black scrollbar on your site as well, but every other page I’ve been on has a light one. Not sure how to help, just want to let you know its not just you.

          January 15th, 2020 at 08:11

          1. Shubham Shah

            I see the black scrollbar as well. It is because of one of the updates to Firefox which changes the scrollbar based on body background color. That website has a dark background-color rule set for body which is leading to dark scrollbar on a white interface.

            January 30th, 2020 at 04:30

  3. Alexandre Leduc

    The Picture-in-picture functionality is amazing!

    January 8th, 2020 at 19:41

    1. Roman

      Indeed, but I can’t use it everyday due to lack of all basic controls except pause.

      January 9th, 2020 at 06:22

  4. Scott

    Love that the nullish coalescing operator is now being implemented in browsers.

    January 9th, 2020 at 13:52

  5. Ana Costa

    Does anyone know why combobox options no longer rendering webfonts?
    Anyone else notice this?

    January 14th, 2020 at 05:00

  6. Ian Dickinson

    I love these detailed but clear breakdowns of the new features in FF, thank you for writing them.

    A request though: can you please add `id` attributes to the `h3` elements so that we can deep-link to particular feature write-ups when sharing with colleagues? Or, indeed, on Twitter!

    January 20th, 2020 at 05:48

    1. Chris Mills

      Glad you like them!

      I agree adding IDs to the headings would be useful. I’ll pass this feedback on.

      January 20th, 2020 at 05:53

Comments are closed for this article.