Re: [csswg-drafts] [css-sizing] Auto-resize iframes based on content (#1771)

Been discussing this with @chrishtr as an idea to revive.

The killer problem with iframe resizing is that the intrinsic size of a third-party page can be an important/dangerous information channel on its own, so allowing sites to get this effect on arbitrary third-party sites is out of the question. A less obvious issue is the reverse; if an iframe can *unexpectedly* control its own size, it can be used to attack the framing page.

The trick, then, is making sure that this is opt-in on both sides.

1. In the iframe, leverage the existing `window.resizeTo()` function, which currently is a no-op in an iframe, to instead fire a "resize" event on the iframe in the containing document (bubbling, cancelable) when resizing is allowed.
2. In the containing page, explicitly allow resizing with a new value for the `allow` attribute, `allow=resize`. If this is not set, the "resize" event will never show up.
3. The containing page can `preventDefault()` the event, in which case nothing happens.
4. Otherwise, the requested size sets a new "from-element intrinsic size" (name TBD) that can be referenced by a new `from-element` keyword on `contain-intrinsic-size`. Like the existing `c-i-s: auto`, you can accompany this with a default size which'll be used before it's set, like `contain-intrinsic-size: from-element 400px 500px;`.

In total, then, the containing page doesn't need to run any script at all if they trust the framed page; they can just write `<iframe allow=resize style="contain-intrinsic-size: from-element 500px 500px">` and be done. The iframe will start out with a 500x500 intrinsic size (rather than 300x150, the default), and if the iframe'd document calls `window.resizeTo()`, the iframe will automatically switch its intrinsic size to that value.

However, if the outer page does want to control things (inspecting the value before approving it, batching resizes until later, etc) it's trivial to just listen for the event and `preventDefault()` when it needs to delay something.  The iframe'd page can tell when its been resized by listening for the "resize" event on its own window, as normal.

(`contain-intrinsic-size` is used here because, effectively, iframes are *always* size-contained (the requirement for `c-i-s` to apply), and `c-i-s` lets you hijack the intrinsic size of the element, which is the right place for this size to be inserted into the layout model. It also lets you provide a default, which is useful on its own.)

----------

The above proposal does require the iframe'd page to run some script, and if it wants its size to be content-based, to do measurement on its own, possibly polling if the size might change over time or due to user interaction. This is because even in a fairly trusted situation, directly exposing content-based sizes can still be dangerous for both sides.

However, in a same-origin environment, we can generally loosen these restrictions and assume trustworthiness, so we can do proper content-based resizing and just need to make sure that it's opt-in so we don't get a behavior change on existing pages. So, the proposal for same-origin iframes is:

1. Continue to use `allow=resize` and `contain-intrinsic-size: from-element` to signal that the outer page wants the iframe to be resizable.
2. *If* the iframe is same-origin, it can set a new property (name TBD) on its root element: `intrinsic-size: auto | <<length>>{1,2};`, with `auto` meaning the laid-out size of the root element. The `c-i-s: from-element` value *automatically* updates to match what this property dictates.

----------

So, how does this proposal sound? Agenda+ to intro it at the next call (no need for decision yet).

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/1771#issuecomment-805117925 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 23 March 2021 18:08:03 UTC