|
| 1 | +# Draggable App Region |
| 2 | + |
| 3 | +## Authors |
| 4 | + |
| 5 | +- [Diego Gonzalez](https://github.com/diekus) |
| 6 | + |
| 7 | +## Participate |
| 8 | + |
| 9 | +- [Issue tracker](https://github.com/MicrosoftEdge/MSEdgeExplainers/labels/Draggable%20App%20Region) |
| 10 | + |
| 11 | +## Status of this Document |
| 12 | + |
| 13 | +This document is intended as a starting point for engaging the community and |
| 14 | +standards bodies in developing collaborative solutions fit for standardization. |
| 15 | +As the solutions to problems described in this document progress along the |
| 16 | +standards-track, we will retain this document as an archive and use this section |
| 17 | +to keep the community up-to-date with the most current standards venue and |
| 18 | +content location of future work and discussions. |
| 19 | + |
| 20 | +* This document status: **Active** |
| 21 | +* Expected venue: [CSS Working Group](https://www.w3.org/Style/CSS/) |
| 22 | +* Current version: this document |
| 23 | + |
| 24 | +## Table of Contents |
| 25 | + |
| 26 | +- [Draggable App Region](#draggable-app-region) |
| 27 | + - [Authors](#authors) |
| 28 | + - [Introduction](#introduction) |
| 29 | + - [Goals](#goals) |
| 30 | + - [Non Goals](#non-goals) |
| 31 | + - [Feature Usage](#feature-usage) |
| 32 | + - [Property Values](#property-values) |
| 33 | + - [Current Property Behaviour](#current-property-behaviour) |
| 34 | + - [Sample Use Case](#sample-use-case) |
| 35 | + - [Stakeholder Feedback / Opposition](#stakeholder-feedback--opposition) |
| 36 | + - [Accessibility, Privacy, and Security Considerations](#accessibility-privacy-and-security-considerations) |
| 37 | + - [References \& acknowledgements](#references--acknowledgements) |
| 38 | + |
| 39 | + |
| 40 | +## Introduction |
| 41 | + |
| 42 | +The `-webkit-app-region` and `app-region` properties exist as a styling feature used primarily in desktop web applications to define draggable regions of a window. This is useful when applications recreate a custom title bar or title bar region, as it **allows users to click and drag the window to move it when the default OS window chrome is not present**. |
| 43 | + |
| 44 | +This property is used by several technologies to move a window in the OS, including: |
| 45 | +* [Web Apps through the WCO API](https://wicg.github.io/window-controls-overlay/) |
| 46 | +* [Electron](https://www.electronjs.org/docs/latest/tutorial/custom-window-interactions#custom-draggable-regions) |
| 47 | + |
| 48 | +The property is not currently standard, this leaves a gap on implementations that needs to be fixed. |
| 49 | + |
| 50 | +## Goals |
| 51 | + |
| 52 | +* Standardize the `app-region` CSS property. |
| 53 | +* Allow a _standalone_ window to be moved by a user when no other platform UX is present. |
| 54 | + |
| 55 | +## Non-goals |
| 56 | + |
| 57 | +* Allow DOM objects to move a browser window (app running inside a tab). |
| 58 | +* Work outside of scenarios that show the default platform's window moving UX (generally the titlebar). |
| 59 | + |
| 60 | +## Feature Usage |
| 61 | + |
| 62 | +There is interest in standardizing this feature as it is already 'widely' used on the platform and it enables a basic expected interaction for applications. At the time of writing (August 2025), `-webkit-app-region` shows [0.79%](https://chromestatus.com/metrics/css/timeline/popularity/412) of page loads using it and `app-region` [0.24%](https://chromestatus.com/metrics/css/timeline/popularity/702). The lack of definition and assumptions on what the feature does can be confusing for users, and undesirable for technologies that need to rely on this property. |
| 63 | + |
| 64 | +* [User asking about definition of property in IDEs](https://stackoverflow.com/questions/54448328/why-is-webkit-app-region-not-a-defined-css-property-in-most-code-editors). |
| 65 | +* [Confusion on how the feature works](https://github.com/electron/electron/issues/1354). |
| 66 | + |
| 67 | +## Property Values |
| 68 | + |
| 69 | +The `app-region` property has 2 possible values: |
| 70 | +* `drag`: marks an element as a draggable area. Clicking and dragging on the element moves the entire window on the screen. |
| 71 | +* `no-drag`: cancels the draggable behaviour in a nested element. |
| 72 | + |
| 73 | +## Current property behaviour |
| 74 | + |
| 75 | +The `app-region` property works on `inline` and `block` elements. There is one requirement for the feature to work on web apps and that is to have the application running in a standalone window and with a `display-override` value of `['window-controls-overlay']`. The reason for this is that when in this override, the host window loses its titlebar, which is the only area that allows an end user to move the window in the screen. |
| 76 | + |
| 77 | +Below is an illustration of such case, showing the [WCO](https://developer.mozilla.org/en-US/docs/Web/API/Window_Controls_Overlay_API) feature toggled _on_: |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | +And here is the HTML code for the example: |
| 82 | + |
| 83 | +```html |
| 84 | +<!DOCTYPE html> |
| 85 | +<html lang="en"> |
| 86 | +<head> |
| 87 | + <meta charset="UTF-8"> |
| 88 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 89 | + <title>test</title> |
| 90 | + <link rel="manifest" href="manifest.json"> |
| 91 | + <style> |
| 92 | + button { |
| 93 | + font-size: 1.5rem; |
| 94 | + animation-name: moveDown; |
| 95 | + animation-duration: 120s; |
| 96 | + animation-iteration-count: infinite; |
| 97 | + app-region: drag; /* <-------- APP-REGION */ |
| 98 | + } |
| 99 | +
|
| 100 | + @keyframes moveDown { |
| 101 | + from { margin-top: 0px; } |
| 102 | + to { margin-top: 600px;} |
| 103 | + } |
| 104 | + </style> |
| 105 | +</head> |
| 106 | +<body> |
| 107 | + <button title="should be draggable"> |
| 108 | + Generic Beautiful Button |
| 109 | + </button> |
| 110 | + |
| 111 | +</body> |
| 112 | +</html> |
| 113 | +``` |
| 114 | + |
| 115 | +In this example, the 'WCO' feature is enabled, hence the window has lost the meaningful area to be moved across the screen. |
| 116 | + |
| 117 | +The (Generic Beautiful) button has the `app-region` set to `drag`. This button can be used to drag the window around. |
| 118 | + |
| 119 | +> Note: This is just an example to test the _current_ behaviour on elements that have animations. The `app-region` is generally used on emulated titlebars or other UX designed to let the end user move the window around. |
| 120 | +
|
| 121 | +### `app-region` and pointer events |
| 122 | + |
| 123 | +Current implementations of `app-region` **consume all pointer events**, even if they don't result in a drag. Interactive elements inside an area defined with `app-region: drag` will require a `app-region: no-drag` to be interacted with. |
| 124 | + |
| 125 | +### Suppression of `app-region` |
| 126 | + |
| 127 | +The `app-region` property applies to a DOM element, and allows it to become a point from where to drag and move a window. If this element's `visibility` is `hidden` or `collapsed`, or if the element is occluded by an element with a higher `z-index` then the window can't be dragged from that element. |
| 128 | + |
| 129 | +### `app-region` and animations |
| 130 | +A drag operation started in an `app-region` continues so long as the user continues to keep their pointer down, even if an animation has moved the element away from where that pointer is. |
| 131 | + |
| 132 | +## Sample use case |
| 133 | + |
| 134 | +A sample use case is a web application that is using [Window Controls Overlay](https://developer.mozilla.org/en-US/docs/Web/API/Window_Controls_Overlay_API) to create a custom titlebar. Elements like buttons and textboxes that need to be interacted with use the `no-drag` value to be accessed. Everything else in the `#titlebar` style will be a point from where the user can drag and move the window. |
| 135 | + |
| 136 | +```css |
| 137 | +/* Custom titlebar style */ |
| 138 | +#titlebar { |
| 139 | + width: env(titlebar-area-width, 100%); |
| 140 | + height: env(titlebar-area-height, 32px); |
| 141 | + top: env(titlebar-area-y, 0px); |
| 142 | + left: env(titlebar-area-x, 0px); |
| 143 | + ... |
| 144 | + -webkit-app-region: drag; |
| 145 | + app-region: drag; |
| 146 | +} |
| 147 | + |
| 148 | +/*A search textbox inside the custom titlebar*/ |
| 149 | +#searchBox { |
| 150 | + app-region: no-drag; /* allows the textbox to be interacted with*/ |
| 151 | +} |
| 152 | +``` |
| 153 | +## Stakeholder Feedback / Opposition |
| 154 | +The process to standardize this feature was logged in an [issue #7017](https://github.com/w3c/csswg-drafts/issues/7017) in 2022. This explainer aims at restarting the conversation. |
| 155 | + |
| 156 | +Note that there is [positive](https://github.com/w3c/csswg-drafts/issues/7017#issuecomment-1609114145) developer signals in the issue. |
| 157 | + |
| 158 | +## Accessibility, Privacy, and Security Considerations |
| 159 | +There are no considerations at this time. |
| 160 | + |
| 161 | +## References & acknowledgements |
| 162 | + |
| 163 | +This work aknowledges and thanks the following individuals for their contributions: |
| 164 | + |
| 165 | +- Amanda Baker |
0 commit comments