v151 · Web APIs · Policy Reference
Policy Reference
Allowlist syntax, default values, sandbox interaction, and recommended header patterns for the focus-without-user-activation Permissions Policy directive.
directive behaviour
| Property | Value |
|---|---|
| Directive name | focus-without-user-activation |
| Default allowlist | * (all origins — allowed by default, matching pre-Chrome 151 behaviour) |
| When allowed | Iframes may call element.focus() at any time, including without a prior user gesture |
| When denied | focus() calls from within the iframe are silently ignored unless there is transient user activation in the iframe's frame |
| Top-level page | Policy only constrains iframes — the top-level document is unaffected regardless of its own header |
| Affects | HTMLElement.focus(), window.focus(), autofocus attribute processing |
header patterns
# Allow all origins (default — no change from pre-Chrome 151 behaviour)
Permissions-Policy: focus-without-user-activation=*
# Deny all iframes — iframes must have user activation to call focus()
Permissions-Policy: focus-without-user-activation=()
# Allow only same-origin iframes to focus without activation
Permissions-Policy: focus-without-user-activation=self
# Per-iframe override via allow attribute:
<!-- Explicitly allow a specific trusted embed to focus freely -->
<iframe src="https://trusted.example/"
allow="focus-without-user-activation"></iframe>
<!-- Deny focus stealing for an ad or analytics iframe -->
<iframe src="https://ads.example/"
allow="focus-without-user-activation 'none'"></iframe>
sandbox interaction
When an iframe uses the
sandbox attribute, it has no user activation by default unless allow-user-activation is also granted. The focus-without-user-activation directive adds a further layer: even with allow-user-activation, the iframe must wait for an actual user gesture before its focus() calls are honoured if the directive is denied.
<!-- Sandbox without allow-user-activation:
iframe has no activation at all → focus() blocked by sandbox -->
<iframe sandbox="allow-scripts allow-same-origin"
src="https://embed.example/"></iframe>
<!-- Sandbox with allow-user-activation + focus policy denied:
iframe can get activation via user gestures inside it,
but cannot call focus() spontaneously -->
<iframe sandbox="allow-scripts allow-same-origin allow-user-activation"
allow="focus-without-user-activation 'none'"
src="https://embed.example/"></iframe>
recommended patterns
// Pattern 1: blanket deny for untrusted embeds
// Add to your HTTP response:
// Permissions-Policy: focus-without-user-activation=()
//
// Then selectively re-allow trusted partners via the allow attribute:
// <iframe allow="focus-without-user-activation" src="...">
// Pattern 2: detect and warn about focus theft in development
document.addEventListener('focusin', (e) => {
if (!navigator.userActivation?.isActive) {
console.warn('Focus moved without user activation:', e.target);
}
}, { capture: true });
// Pattern 3: server-side opt-in for the whole page
// Permissions-Policy: focus-without-user-activation=self
// This allows same-origin iframes (e.g. component microfrontends)
// but blocks all cross-origin embeds from stealing focus.
see also
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗