Customizing PWA Title Bars with Window Controls Overlay

The Window Controls Overlay feature in Chromium-based browsers allows Progressive Web Apps (PWAs) to feel more like native desktop applications by reclaiming the full width of the window's title bar. This article provides a complete overview of how this feature works, covering how it extends the web viewport to the top of the app window, how developers use the Web App Manifest to enable it, and how CSS environment variables and JavaScript APIs are used to seamlessly place custom content next to the operating system's native window controls.

Extending the Viewport

By default, an installed desktop PWA displays a dedicated system title bar at the top of the window, which houses the app title and the minimize, maximize, and close buttons. The Window Controls Overlay feature removes this full-width bar. Instead, it extends the web content area—the viewport—all the way to the very top edge of the application window. The browser then renders only the essential native window control buttons as a floating overlay on top of the web content, freeing up the rest of the horizontal space for custom HTML elements like search bars, navigation tabs, or custom menus.

Enabling the Feature in the Manifest

To activate this behavior, developers must explicitly request it in the PWA's manifest.json file. This is done using the display_override property. By setting "display_override": ["window-controls-overlay"], the app instructs the Chromium browser to prioritize the overlay layout over the standard standalone or minimal-ui display modes when running on a supported desktop operating system.

Positioning Content with CSS Environment Variables

Because the native window controls (close, minimize, maximize) still exist as an overlay, developers need a way to prevent their custom content from being hidden underneath those buttons. Furthermore, these controls appear on the right side of the window on Windows and Linux, and on the left side on macOS.

Chromium solves this by providing four CSS environment variables that define the exact safe area available in the title bar region:

  • env(titlebar-area-x): The distance from the left edge of the viewport to where the safe title bar area begins.
  • env(titlebar-area-y): The distance from the top edge of the viewport (usually 0px).
  • env(titlebar-area-width): The total width of the safe area, excluding the native window controls.
  • env(titlebar-area-height): The height of the native title bar area.

By applying these variables to a fixed-position header container in CSS, the custom title bar automatically adapts its width and horizontal positioning to avoid colliding with the operating system's window controls, regardless of the platform.

Restoring Window Dragging Functionality

When the standard system title bar is removed, the user loses the default area used to click and drag the application window around the screen. To fix this, developers must use the -webkit-app-region CSS property.

By applying -webkit-app-region: drag; to the custom title bar container, the entire custom header becomes a draggable handle for the window. However, if the custom title bar contains interactive elements—such as a search input, a profile button, or navigation links—the user will not be able to click them if they are set to drag. Developers must explicitly apply -webkit-app-region: no-drag; to those specific interactive child elements so they remain clickable while the background around them remains draggable.

Detecting State with JavaScript

The Window Controls Overlay is not always active; a user can toggle it off using a button in the title bar, or the app might be running on a mobile device where the feature is unsupported. Chromium provides the navigator.windowControlsOverlay JavaScript API to handle this dynamically.

Developers can check the navigator.windowControlsOverlay.visible boolean property to see if the overlay is currently active and adjust the app's layout accordingly. Additionally, the API provides a getTitlebarAreaRect() method to query the exact pixel dimensions of the available space in JavaScript, and a geometrychange event listener that fires whenever the user toggles the overlay or resizes the window.