Skip to main content

Closing a 30 pixel gap between native and web

Written By published September 27, 2022

We talk a lot about Progressive Web Apps (PWA) in the context of mobile devices, but they have an enormous potential on desktop operating systems that’s only beginning to materialize.

Recently, with many new web capabilities in the Chromium browser engine and UX changes in Microsoft Edge and on Windows, installed desktop web apps are really starting to look and feel like native apps.

One remaining gap in how web apps appear on desktop is their ability to create their own title bar experiences.

While native apps have been able to display content anywhere in the app window, including in the title bar, installed web apps have been forced to go with the default experience, making them visually different.

Two screenshots of VSCode. The first is VSCode as a native app, showing that the app can display its own custom content in the title bar. The second is VSCode as a web app, showing that the entire top area is reserved for the default title bar.

We’re excited to announce the availability of a new PWA feature that closes this gap and helps blur the line between apps and websites even more.

The Window Controls Overlay feature gives web apps the ability to use the full surface area of the app window to display their own content, including where the default title bar is normally displayed. Only the system critical window buttons remain and are displayed as an overlay on top of the web content.

Even if the title bar is about 30 pixels high only, the design implications of having access to the area it normally occupies are huge. What can we do with just 30 pixels? Display a custom title, a menu bar, some account information, navigation tabs? Look at other desktop apps you use, and you’ll quickly realize that they all make use of this area in some way. And now, installed web apps can too!

An illustration of a web app window, showing that the the app can display its content over the entire surface area of the window, except where the window control buttons appear.

We worked on this feature as part of our contributions in the Web Capabilities project (aka Project Fugu), in collaboration with other browser makers and tech companies. This project aims to make it possible to build all types of apps using web technologies, and to push the barriers for what’s possible on the web today.

We proposed the Window Controls Overlay feature as an explainer in January 2020, then built the early implementation in Chromium, made it available as an Origin Trial, and published a formal specification. We’re now releasing the Window Controls Overlay feature as a default experience for all to use in Microsoft Edge 105.

Learn to use the Window Controls Overlay

To learn to use the feature, check out the technical documentation as well as the MDN reference docs. You might also be interested in these A List Apart and web.dev tutorials.

These resources go into much more detail than we will see in this article. Here, we’ll quickly go over the 3 most important building blocks of Window Controls Overlay:

  • the required Manifest change,
  • the new titlebar-area-* CSS environment variables,
  • and the new navigator.windowControlsOverlay JavaScript API.

Opt-in to the feature with your Manifest

PWAs need a Web App Manifest to be installable, and many PWA features are declared in the Manifest file. The Window Controls Overlay is no exception. To opt-in to this feature use the display_override manifest member and set its value to [“window-controls-overlay”].

Here is a code snippet showing this:

{
  "name": "App name",
  "description": "App description",
  "lang": "en-US",
  "start_url": "/",
  "theme_color": "#ffffff",
  "background_color": "#ffffff",
  "display_override": [
    "window-controls-overlay"
  ]
}

On the surface, this is the only required change to start making use of the title bar area.

However, the feature also comes with new CSS environment variables and a JavaScript API which both help make sure you deliver an experience that works well across devices and operating systems.

Adapt to the environment with the titlebar-area-* CSS variables

Once the app uses the Window Controls Overlay feature, its web content is displayed over the entire window surface, and the control buttons act as an overlay. To avoid displaying content below these buttons the new titlebar-area-x/y/width/height variables can be used in the env() CSS function.

They give you the geometry of the area that the title bar would have occupied next to the control buttons if it was displayed. Because this area can be different on Mac, Windows, and Linux, having access to browser-provided variables helps create a layout that works everywhere.

As shown below, the title bar area is different on Windows (and Linux) and macOS.
An illustration showing 2 windows, one on Windows or Linux and the other on macOS. The location of the title bar area is highlighted in both.

The following code snippet shows how these variables can be used to position a fixed header element in the title bar area:

header {
  position: fixed;
  left: env(titlebar-area-x, 0);
  top: env(titlebar-area-y, 0);
  width: env(titlebar-area-width, 100%);
  height: env(titlebar-area-height, 30px);
}

Since the env() function supports fallback values (the second parameter in the function), this snippet will work even when the Window Controls Overlay feature isn’t being used, such as when the web app is displayed in a browser window.

Detect when changes occur with the navigator.windowControlsOverlay API

In addition to the CSS environment variables, you can use the new navigator.windowControlsOverlay API to know the coordinates of the title bar area from JavaScript and detect when they change.

This can be helpful to re-arrange the web content displayed in this area as the app window size changes, or when the user opts-out of the Window Controls Overlay feature.

In the following code example, we listen to geometry changes and apply a class on the body element if the width of the title bar area is smaller than 250px.

if (navigator.windowControlsOverlay) {
  navigator.windowControlsOverlay.addEventListener('geometrychange', () => {
    const { width } = navigator.windowControlsOverlay.getTitlebarAreaRect();
    document.body.classList.toggle('narrow', width < 250);
  });
}

Note how we first test if the API exists, which helps ensure the app works in browsers that don’t support the feature.

You can also use the navigator.windowControlsOverlay.visible boolean to know if the overlay is visible (i.e. if the default title bar is hidden) and the navigator.windowControlsOverlay.getTitlebarAreaRect() method to get its geometry.

We believe PWAs are a great fit for making desktop web applications. Turning your website into an app that really feels like it belongs on desktop has never been so easy and using the Window Controls Overlay feature will help you create desktop apps that look much more modern and engaging to your users.

We hope it is useful to you, and can’t wait to see what you build!