v149 · origin trial · privacy & security

Permissions Policy: focus-without-user-activation

Embedders can now restrict iframes from stealing keyboard focus without explicit user interaction. Setting allow="focus-without-user-activation 'none'" silently blocks element.focus(), the autofocus attribute, and dialog.showModal() in the embedded frame until the user first interacts with it.

concepts

  1. Focus Hijack Guard

    Two embedded frames attempt to steal keyboard focus on a timer, matching the behavior of an ad or analytics widget. One is unrestricted; the other carries the policy. Watch the focus indicator update to see the difference in real time.

  2. Autofocus Lockdown

    The HTML autofocus attribute normally fires before the user has touched the page. Embed the same form in two iframes — one with the policy, one without — and observe whether the input takes focus on load.

  3. Policy Test Lab

    Side-by-side: unrestricted container (can steal focus on timer or programmatically) vs. restricted container (all attempts blocked, user-initiated focus still works). Event log shows every blocked and allowed focus attempt with timestamp and cause.

  4. Header Builder

    Pick an allowlist mode — *, 'self', (), or a custom origin list — and instantly get the HTTP Permissions-Policy response header, the iframe allow attribute, and an nginx/Apache config snippet. Add or remove allowed origins with chips and copy any panel in one click.

  5. Focus Timeline

    Every focus and blur event is timestamped in a live log. Use action buttons to trigger user focus, script .focus(), timer-based focus, load-time focus, and an interval hijack. Toggle the live iframe policy to see which attempts are blocked — with per-category counters tracking user, script, blocked, and blur events.

  6. Autofocus Policy Tester

    An allow/block toggle controls the allow="focus-without-user-activation" attribute on a live <iframe srcdoc> with <input autofocus>. The iframe posts focus result messages back; a focus log shows document.activeElement changes in real time. A threat replay panel explains the keyboard hijack vector, and a policy header generator produces Permissions-Policy: headers for server deployment.

why it shipped

Programmatic focus is a covert power: an iframe can call element.focus() at any moment, hijacking the user's keyboard away from the top-level page. This is especially problematic with ads, embeds, or third-party widgets that don't need keyboard control. The focus-without-user-activation policy gives the embedding site a declarative off-switch. When the policy is denied for a frame, all attempts to focus without prior user activation are silently dropped — user-initiated interactions (tab, click, keyboard) are never affected. Focus delegation from a parent to a child iframe is still allowed, preserving legitimate use cases.

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗