What Is the Window Controls Overlay API?
The Window Controls Overlay API gives Progressive Web Apps installed on desktop operating systems the ability to hide the default window title bar and display their own content over the full surface area of the app window. The system window control buttons--maximize, minimize, and close--become an overlay displayed on top of the web content, ensuring users retain access to essential window management functions while developers gain complete control over the visual presentation.
Traditional PWA windows on desktop consist of two distinct areas: a title bar region containing the application name and window controls, and a content area below where the web content renders. The title bar area typically includes the maximize, minimize, and close buttons, along with the application name derived from the HTML title element. With window controls overlay enabled, Progressive Web Apps can extend their content across the entire window surface, creating truly immersive, native-like interfaces.
This capability transforms how developers think about PWA design, enabling PWAs to feel genuinely integrated with the operating system--mirroring how native applications like Visual Studio Code and Microsoft Teams handle their title bar areas.
If you're building Progressive Web Apps that need to rival native desktop applications, mastering the Window Controls Overlay API is essential for delivering professional, polished user experiences. Advanced implementations can combine this API with AI automation features to create intelligent, adaptive interfaces that respond to user behavior and preferences.
What the Window Controls Overlay API enables for your PWAs
Full Surface Content
Display your web content over the entire window surface, including the traditional title bar area for immersive experiences.
Custom Title Bars
Create branded, themed title bars that match your application's design language and user experience goals.
Native-Like Feel
Achieve visual parity with native desktop applications, improving user perception and professional appearance.
Drag Region Controls
Define custom drag regions with app-region: drag for window manipulation without traditional title bars.
Enabling Window Controls Overlay
Before using the Window Controls Overlay API, specific conditions must be satisfied. The web app manifest's display_override member must be set to "window-controls-overlay", and the Progressive Web App must be installed on a desktop operating system. These requirements ensure the feature is intentionally enabled and only activates in appropriate contexts.
Manifest Configuration
The manifest file controls how your PWA appears and behaves when installed. To enable window controls overlay, add the display_override property to your manifest:
{
"display_override": ["window-controls-overlay"]
}
The display_override property allows developers to specify a fallback chain of display modes. By placing "window-controls-overlay" first in the array, you request this display mode as your primary preference. If the browser doesn't support window controls overlay, it falls back to the next mode in the array.
Understanding Display Mode Precedence
When configuring your manifest, consider the full fallback chain. A common approach combines window controls overlay with other display modes:
{
"display_override": ["window-controls-overlay", "standalone", "browser"]
}
This configuration requests window controls overlay first, then falls back to standalone display mode (the traditional installed PWA experience), and finally to browser display mode (running in a browser tab). The cascading fallback ensures your PWA remains functional across different browser capabilities and contexts.
Proper manifest configuration is just one part of building a robust PWA. Our team can help you implement all the progressive web app features that matter for your business, including search engine optimization to ensure your application gets discovered by users searching for solutions in your industry.
CSS Environment Variables for Title Bar Area
The Window Controls Overlay API provides four CSS environment variables that define the available title bar area. These variables enable precise positioning and sizing of content in the title bar region, adapting automatically to different window sizes and operating system configurations.
Available Environment Variables
| Variable | Description |
|---|---|
titlebar-area-x | Distance in pixels from the left side of the window to the title bar area |
titlebar-area-y | Distance in pixels from the top of the window to the title bar area |
titlebar-area-width | Width of the title bar area in pixels |
titlebar-area-height | Height of the title bar area in pixels |
Positioning Content in the Title Bar Area
To position your own content where the title bar would normally appear, use the env() CSS function with these environment variables:
#custom-titlebar {
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, 50px);
}
The position: fixed declaration ensures your title bar content remains aligned with the window controls overlay regardless of scrolling. The env() function accepts a fallback value as its second parameter, which applies when the environment variable isn't available.
Handling Platform Differences
The overlay positioning varies between operating systems. On Windows, window controls typically appear on the right side of the title bar area, while macOS places them on the left. The environment variables automatically account for these differences, but your CSS should be flexible enough to accommodate the variable positioning.
Using Fallback Values Effectively
The fallback values in env() declarations serve two purposes: providing defaults when environment variables are unavailable and defining behavior when window controls overlay is disabled. Consider a comprehensive example:
#title-bar {
position: fixed;
left: env(titlebar-area-x, 0);
top: env(titlebar-area-y, 0);
width: 100%;
height: env(titlebar-area-height, 40px);
max-width: calc(100% - env(titlebar-area-width, 0));
}
This CSS creates a title bar that respects the available area while avoiding overlap with window controls. The max-width calculation accounts for the space window controls occupy, preventing content from rendering beneath them.
JavaScript API Reference
The Window Controls Overlay API extends the Navigator interface with the windowControlsOverlay property and provides the WindowControlsOverlay interface for interacting with title bar geometry.
Accessing the API
if ('windowControlsOverlay' in navigator) {
const overlay = navigator.windowControlsOverlay;
console.log('Window controls overlay is available');
}
This property returns a WindowControlsOverlay object that exposes information about the title bar geometry in desktop Progressive Web Apps.
WindowControlsOverlay Interface
The interface provides three key members:
- visible: A boolean that returns true when the window controls overlay is visible
- getTitlebarAreaRect(): A method that returns a DOMRect representing the available title bar area
- ongeometrychange: An event handler for geometry change events
Detecting Title Bar Visibility
if ('windowControlsOverlay' in navigator) {
const isOverlayVisible = navigator.windowControlsOverlay.visible;
if (isOverlayVisible) {
console.log('Window controls overlay is currently visible');
// Adapt layout for overlay mode
} else {
console.log('Title bar is displayed, overlay is hidden');
// Use standard title bar layout
}
}
The getTitlebarAreaRect() method returns a DOMRect with x, y, width, and height properties describing the available title bar area. This rect excludes the area occupied by window controls, making it ideal for positioning custom content:
if ('windowControlsOverlay' in navigator) {
const titleBarRect = navigator.windowControlsOverlay.getTitlebarAreaRect();
console.log(`Title bar area: ${titleBarRect.width}px wide, ${titleBarRect.height}px tall`);
console.log(`Position: (${titleBarRect.x}, ${titleBarRect.y})`);
}
Responding to Geometry Changes
Users can resize windows, toggle title bar display, or change display settings while your PWA is running. Your application needs to respond to these geometry changes to maintain proper layout.
The Geometry Change Event
The geometrychange event fires whenever the title bar geometry changes, including window resizing and title bar toggling:
navigator.windowControlsOverlay.addEventListener('geometrychange', (event) => {
const isOverlayVisible = navigator.windowControlsOverlay.visible;
const titleBarRect = event.titlebarAreaRect;
console.log(`Overlay visible: ${isOverlayVisible}`);
});
The event object includes a titlebarAreaRect property containing the new geometry information, allowing immediate access to updated dimensions without calling getTitlebarAreaRect() separately.
Performance Considerations
The geometrychange event fires frequently during window resizing operations. Running layout-changing code on every event can cause performance problems. Use a debounce function to limit how often your handler executes:
const debounce = (func, wait) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
navigator.windowControlsOverlay.addEventListener(
'geometrychange',
debounce(handleGeometryChange, 200)
);
This debounce implementation waits until 200 milliseconds have passed without a geometry change before executing your handler. Adjust the wait time based on your performance needs--shorter values feel more responsive while longer values reduce computational overhead.
Geometry change events can fire dozens of times during a single window resize operation. Implementing proper debouncing or throttling is essential for maintaining smooth 60fps performance during rapid window resizing.
Creating Draggable Title Bar Regions
When the title bar is hidden, only the system window controls remain visible. This leaves minimal space for users to drag the application window. The app-region CSS property addresses this limitation by allowing you to designate any element as a window drag handle.
Using app-region: drag
#custom-titlebar {
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, 50px);
app-region: drag;
}
#titlebar-content {
app-region: drag;
}
When users click and drag on elements with app-region: drag, the operating system moves the entire window as if the user had grabbed the title bar. This enables you to create custom title bars with your own branding and functionality while preserving essential window management capabilities.
Avoiding Interactive Elements in Drag Regions
Elements with app-region: drag should not contain interactive controls like buttons or links. Interactive elements within drag regions can create user experience problems because clicks intended for controls might be interpreted as drag operations.
If you need both drag functionality and interactive elements in your title bar, separate them:
#titlebar {
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, 50px);
display: flex;
align-items: center;
}
#drag-region {
flex: 1;
app-region: drag;
}
#window-controls {
app-region: no-drag;
}
By separating draggable and non-draggable regions, you provide both window-moving capability and full interactive functionality. This pattern is essential for creating professional web applications that users can easily manage.
Browser Compatibility
The Window Controls Overlay API is an experimental feature with limited browser support. Chrome and Edge (Chromium-based browsers) provide the most complete implementation. Firefox and Safari have not yet widely implemented the feature.
Feature Detection
Always use feature detection rather than browser detection:
function supportsWindowControlsOverlay() {
return 'windowControlsOverlay' in navigator;
}
if (supportsWindowControlsOverlay()) {
// Use the API
} else {
// Implement fallback behavior
// Perhaps use a traditional fixed header instead
}
Graceful Degradation
When window controls overlay isn't available, your PWA should still function correctly. Consider these fallback strategies:
- Use a fixed-position header that mimics a title bar appearance
- Accept the default browser-provided title bar without customization
- Provide a message informing users about enhanced features in supported browsers
Before using this API in production, verify current browser support and implement appropriate fallbacks. The display_override fallback chain ensures your PWA remains functional across different browser capabilities.
Testing with DevTools
Microsoft Edge DevTools includes a feature for simulating window controls overlay without requiring PWA installation. This capability accelerates development by eliminating the need to rebuild and reinstall the PWA for each CSS adjustment. The simulated overlay uses static values matching your selected platform, allowing you to preview how your CSS environment variables will behave.
Frequently Asked Questions
Sources
- W3C Window Controls Overlay Specification - The authoritative specification document providing the complete technical definition of the API
- MDN Web Docs: Window Controls Overlay API - Comprehensive developer documentation covering browser compatibility and practical API usage
- Microsoft Learn: Display Content in Title Bar using Window Controls Overlay - Step-by-step implementation guide with code examples and DevTools simulation features