Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 37 additions & 41 deletions extensions/amp-iframe/amp-iframe.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
-->

### <a name="amp-iframe"></a> `amp-iframe`
## <a name="amp-iframe"></a> `amp-iframe`

Displays an iframe.

`amp-iframe` has several important differences from vanilla iframes that are designed to make it more secure and avoid AMP files that are dominated by a single iframe:
The `amp-iframe` extension has several important differences from standard iframes, designed to make it more secure and avoid AMP files that are dominated by a single iframe:

- `amp-iframe` may not appear close to the top of the document (except for iframes that use `placeholder` as described below). They must be either 600px away from the top or not within the first 75% of the viewport when scrolled to the topwhichever is smaller. NOTE: We are currently looking for feedback as to how well this restriction works in practice.
- They are sandboxed by default. [Details](#sandbox)
- They must only request resources via HTTPS or from a data-URI or via the srcdoc attribute.
- They must not be in the same origin as the container unless they do not allow `allow-same-origin` in the sandbox attribute. See the doc ["Iframe origin policy"](../../spec/amp-iframe-origin-policy.md) for further details on allowed origins for iframes.
- `amp-iframe` may not appear close to the top of the document (except for iframes that use `placeholder`, described below). They must be either 600px away from the top or not within the first 75% of the viewport when scrolled to the top, whichever is smaller. **Note:** We are currently looking for feedback as to how well this restriction works in practice.
- They are sandboxed by default (see below).
- They must only request resources via HTTPS, from a data-URI, or via the `srcdoc` attribute.
- They must not be in the same origin as the container unless they do not use `allow-same-origin` in the sandbox attribute. See the [iframe origin policy](../../spec/amp-iframe-origin-policy.md) document for further details on allowed origins for iframes.

Example:
```html
Expand All @@ -35,32 +35,31 @@ Example:
</amp-iframe>
```

#### Attributes
### Attributes

##### src, srcdoc, frameborder, allowfullscreen, allowtransparency
**src, srcdoc, frameborder, allowfullscreen, allowtransparency**

The attributes above should all behave like they do on standard iframes.
These attributes should behave like they do on standard iframes.

##### sandbox
**sandbox**

Iframes created by `amp-iframe` always have the `sandbox` attribute defined on them. By default the value is empty. That means that they are "maximum sandboxed" by default. By setting sandbox values, one can opt the iframe into being less sandboxed. All values supported by browsers are allowed. E.g. setting `sandbox="allow-scripts"` allows the iframe to run JavaScript, or `sandbox="allow-scripts allow-same-origin"` allows the iframe to run JavaScript, make non-CORS XHRs, and read/write cookies.
Iframes created by `amp-iframe` always have the `sandbox` attribute defined on them. By default the value is empty, meaning that they are "maximum sandboxed". By using other sandbox values, you can set the iframe to be less sandboxed. All values supported by browsers are allowed. For example, setting `sandbox="allow-scripts"` allows the iframe to run JavaScript, while `sandbox="allow-scripts allow-same-origin"` allows the iframe to run JavaScript, make non-CORS XHRs, and read/write cookies.

If you are iframing a document that was not specifically created with sandboxing in mind, you will most likely need to add `allow-scripts allow-same-origin` to the `sandbox` attribute and you mights need to allow additional capabilities.
If you are iframing a document that was not specifically created with sandboxing in mind, you will most likely need to add `allow-scripts allow-same-origin` to the `sandbox` attribute.

Note also, that the sandbox applies to all windows opened from a sandboxed iframe. This includes new windows created by a link with `target=_blank` (Add `allow-popups` to allow this to happen). Adding `allow-popups-to-escape-sandbox` to the `sandbox` attribute, makes those new windows behave like non-sandboxed new windows. This is likely most of the time what you want and expect. Unfortunately, as of this writing, `allow-popups-to-escape-sandbox` is only supported by Chrome.
Note also that the sandbox applies to all windows opened from a sandboxed iframe. This includes new windows created by a link with `target=_blank` (add `allow-popups` to allow this to happen). Adding `allow-popups-to-escape-sandbox` to the `sandbox` attribute makes the new windows behave like non-sandboxed new windows. This is what you want and expect most of the time. However, as of this writing, `allow-popups-to-escape-sandbox` is only supported by Chrome.

See the [the docs on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox) for further details on the sandbox attribute.
See the [sandbox docs on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox) for further details on the sandbox attribute.

#### Iframe Resizing
### Iframe Resizing

An `amp-iframe` must have static layout defined as is the case with any other AMP element. However,
it's possible to resize an `amp-iframe` in runtime. To do so:
An `amp-iframe` must have static layout defined as any other AMP element. However, it is possible to resize an `amp-iframe` in runtime. To do so:

1. The `amp-iframe` must be defined with `resizable` attribute;
2. The `amp-iframe` must have `overflow` child element;
3. The IFrame document has to send a `embed-size` request as a window message.
1. The `amp-iframe` must be defined with the `resizable` attribute.
2. The `amp-iframe` must have an `overflow` child element.
3. The iframe document must send an `embed-size` request as a window message.

Notice that `resizable` overrides `scrolling` value to `no`.
Note that the `resizable` attribute forces the `scrolling` attribute value to `no`.

Example of `amp-iframe` with `overflow` element:
```html
Expand All @@ -73,7 +72,7 @@ Example of `amp-iframe` with `overflow` element:
</amp-iframe>
```

Example of Iframe resize request:
Example of iframe resize request:
```javascript
window.parent.postMessage({
sentinel: 'amp',
Expand All @@ -82,20 +81,16 @@ window.parent.postMessage({
}, '*');
```

Once this message is received the AMP runtime will try to accommodate this request as soon as
possible, but it will take into account where the reader is currently reading, whether the scrolling
is ongoing and any other UX or performance factors. If the runtime cannot satisfy the resize events
the `amp-iframe` will show an `overflow` element. Clicking on the `overflow` element will immediately
resize the `amp-iframe` since it's triggered by a user action.
When this message is received, the AMP runtime will try to accommodate it as soon as possible, but it will take into account where the reader is on the page, whether the scrolling is ongoing, and any other UX or performance factors. If the runtime cannot satisfy the resize request, the `amp-iframe` will show an `overflow` element. Clicking the `overflow` element immediately resizes the `amp-iframe` because it is triggered by a user action.

Here are some factors that affect how fast the resize will be executed:

- Whether the resize is triggered by the user action;
- Whether the resize is requested for a currently active Iframe;
- Whether the resize is requested for an Iframe below the viewport or above the viewport.
- Whether the resize is triggered by a user action
- Whether the resize is requested for a currently active iframe
- Whether the resize is requested for an iframe below or above the viewport

#### Iframe with Placeholder
It is possible to have an `amp-iframe` appear on the top of a document when the `amp-iframe` has a `placeholder` element as shown in the example below.
### Iframe with Placeholder
It is possible to have an `amp-iframe` appear on the top of a document when the `amp-iframe` has a `placeholder` element:

```html
<amp-iframe width=300 height=300
Expand All @@ -105,32 +100,33 @@ It is possible to have an `amp-iframe` appear on the top of a document when the
<amp-img layout="fill" src="https://foo.com/foo.png" placeholder></amp-img>
</amp-iframe>
```
- The `amp-iframe` must contain an element with the `placeholder` attribute, (for instance an `amp-img` element) which would be rendered as a placeholder till the iframe is ready to be displayed.
- Iframe readiness can be known by listening to `onload` of the iframe or an `embed-ready` postMessage which would be sent by the Iframe document, whichever comes first.

Example of Iframe embed-ready request:
- The `amp-iframe` must contain an element with the `placeholder` attribute (such as an `amp-img` element) which would be rendered as a placeholder until the iframe is ready to be displayed.
- Iframe readiness can be determined by listening to the iframe's `onload` event or an `embed-ready` postMessage which would be sent by the iframe document, whichever comes first.

Example of iframe embed-ready request:
```javascript
window.parent.postMessage({
sentinel: 'amp',
type: 'embed-ready'
}, '*');
```

#### Iframe viewability
### Iframe Viewability

Iframes can send a `send-intersection` message to its parent to start receiving IntersectionObserver style [change records](http://rawgit.com/slightlyoff/IntersectionObserver/master/index.html#intersectionobserverentry) of the iframe's intersection with the parent viewport.
An iframe can send a `send-intersection` message to its parent to start receiving IntersectionObserver style [change records](http://rawgit.com/slightlyoff/IntersectionObserver/master/index.html#intersectionobserverentry) of the iframe's intersection with the parent viewport.

Example of Iframe `send-intersection` request:
Example of iframe `send-intersection` request:
```javascript
window.parent.postMessage({
sentinel: 'amp',
type: 'send-intersection'
}, '*');
```

The Iframe can listen to an `intersection` message from the parent window to receive the intersection data.
The iframe can listen to an `intersection` message from the parent window to receive the intersection data.

Example of Iframe `send-intersection` request:
Example of iframe listening for an `intersection` message:
```javascript
window.addEventListener('message', function(event) {
const listener = function(event) {
Expand All @@ -147,4 +143,4 @@ window.addEventListener('message', function(event) {
});
```

The intersection message would be sent by the parent to the iframe when the iframe moves in or out of the viewport (or is partially visibile), when the iframe is scrolled or resized.
The intersection message would be sent by the parent to the iframe when the iframe moves in or out of the viewport (or is partially visibile) when the iframe is scrolled or resized.