|
| 1 | +<!--- |
| 2 | +Copyright 2015 The AMP HTML Authors. All Rights Reserved. |
| 3 | +
|
| 4 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +you may not use this file except in compliance with the License. |
| 6 | +You may obtain a copy of the License at |
| 7 | +
|
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | +Unless required by applicable law or agreed to in writing, software |
| 11 | +distributed under the License is distributed on an "AS-IS" BASIS, |
| 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +See the License for the specific language governing permissions and |
| 14 | +limitations under the License. |
| 15 | +--> |
| 16 | + |
| 17 | +# AMP HTML ⚡ Layout System |
| 18 | + |
| 19 | +## Overview |
| 20 | + |
| 21 | +The main goal of the layout system is to ensure that AMP elements can express their layout |
| 22 | +so that the runtime is able to infer sizing of elements before any remote resources, such as |
| 23 | +JavaScript and data calls, have been completed. This is important since this significantly |
| 24 | +reduces rendering and scrolling jank. |
| 25 | + |
| 26 | +With this in mind the AMP Layout System is designed to support few but flexible layout |
| 27 | +that provide good performance guarantees. This system relies on a set of attributes such |
| 28 | +as `layout`, `width` and `height` to express the element's layout and sizing needs. |
| 29 | + |
| 30 | +## Layout Attributes |
| 31 | + |
| 32 | +### `width` and `height` |
| 33 | + |
| 34 | +Depending on the value of the `layout` attribute AMP component elements must have a `width` and |
| 35 | +`height` attribute that contains an integer pixel value. Actual layout behavior is determined by the |
| 36 | +`layout` attribute as described below. |
| 37 | + |
| 38 | +In a few cases if `width` or `height` are not specified the AMP runtime can default these values |
| 39 | +as following: |
| 40 | +- `amp-pixel`: Both `width` and `height` are defaulted to 0. |
| 41 | +- `amp-audio`: The default `width` and `height` are inferred from browser. |
| 42 | + |
| 43 | +### `layout` |
| 44 | + |
| 45 | +The optional layout attribute allows specifying how the component behaves in the document layout. |
| 46 | +Valid values for the layout attribute are: |
| 47 | + |
| 48 | +- Not present: The `layout` will be inferred as following: |
| 49 | + - if `width` equals to `auto` `fixed-height` layout is assumed; |
| 50 | + - if `width` or `height` attributes are present `fixed` layout is assumed; |
| 51 | + - if `width` and `height` are not present `container` layout is assumed |
| 52 | +- `fixed`: The `width` and `height` attributes must be present. The only exceptions are `amp-pixel` |
| 53 | +and `amp-audio` elements. |
| 54 | +- `fixed-height`: The `height` attribute must be present. The `width` attribute must not be present |
| 55 | +or must be equal to `auto`. |
| 56 | +- `responsive`: The `width` and `height` attributes must be present and are used to determine the |
| 57 | +aspect ratio of the component. The component is sized to the width of its container element while |
| 58 | +maintaining the height based on the aspect ratio. |
| 59 | +- `fill`: Element size will be determined by the parent element. |
| 60 | +- `container`: The component is assumed to not have specific layout itself but only act as a |
| 61 | +container. Its children are rendered immediately. |
| 62 | +- `nodisplay`: The component takes up zero space on the screen as if its display style was `none`. |
| 63 | +The `width` and `height` attributes are not required. |
| 64 | + |
| 65 | +Each element documents which `layout` values it supported. If an element does not support the |
| 66 | +specified value it would trigger a runtime error. |
| 67 | + |
| 68 | +### `media` |
| 69 | + |
| 70 | +All AMP custom elements support the `media` attribute. The value of media is a media query. If the query does not match, the element is not rendered at all and it's resources and potentially it's child resources will not be fetched. If the browser window changes size or orientation the media queries are re-evaluated and elements are hidden and shown based on the new results. |
| 71 | + |
| 72 | +Example: Here we have 2 images with mutually exclusive media queries. Depending on the screen width one or the other will be fetched and rendered. Note that the media attribute is available on all custom elements, so it can be used with non-image elements such as ads. |
| 73 | + |
| 74 | +```html |
| 75 | + <amp-img |
| 76 | + media="(min-width: 650px)" |
| 77 | + src="wide.jpg" |
| 78 | + width=466 |
| 79 | + height=355 layout="responsive" ></amp-img> |
| 80 | + <amp-img |
| 81 | + media="(max-width: 649px)" |
| 82 | + src="narrow.jpg" |
| 83 | + width=527 |
| 84 | + height=193 layout="responsive" ></amp-img> |
| 85 | +``` |
| 86 | + |
| 87 | +### `placeholder` |
| 88 | + |
| 89 | +The `placeholder` attribute can be set on any HTML element, not just AMP elements. It indicates that |
| 90 | +the element marked with this attribute acts as a placeholder for the parent AMP element. If specified |
| 91 | +a placeholder element must be a direct child of the AMP element. By default, the placeholder is |
| 92 | +immediately shown for the AMP element, even if the AMP element's resources have not been downloaded |
| 93 | +or initialized. Once ready the AMP element typically hides its placeholder and shows the content. |
| 94 | +The exact behavior w.r.t. to placeholder is up to the element's implementation. |
| 95 | + |
| 96 | +```html |
| 97 | + <amp-anim src="animated.gif" width=466 height=355 layout="responsive" > |
| 98 | + <amp-img placeholder src="preview.png" layout="fill"></amp-img> |
| 99 | + </amp-anim> |
| 100 | +``` |
| 101 | + |
| 102 | +### `fallback` |
| 103 | + |
| 104 | +The `fallback` attribute can be set on any HTML element, not just AMP elements. It's a convention that |
| 105 | +allows the element to communicate to the reader that the browser does not support it. If specified |
| 106 | +a fallback element must be a direct child of the AMP element. The exact behavior w.r.t. to fallback |
| 107 | +is up to the element's implementation. |
| 108 | + |
| 109 | +```html |
| 110 | + <amp-anim src="animated.gif" width=466 height=355 layout="responsive" > |
| 111 | + <div fallback>Cannot play animated images on this device.</div> |
| 112 | + </amp-anim> |
| 113 | +``` |
| 114 | + |
| 115 | +## Behavior |
| 116 | + |
| 117 | +A non-container (`layout != container`) AMP element starts up in the unresolved/unbuilt mode in which |
| 118 | +all of its children are hidden except for a placeholder (see `placeholder` attribute). The JavaScript |
| 119 | +and data payload necessary to fully construct the element may still be downloading and initializing, |
| 120 | +but the AMP runtime already knows how to size and layout the element only relying on CSS classes and |
| 121 | +`layout`, `width`, `height` and `media` attributes. In most cases a `placeholder`, if specified, is |
| 122 | +sized and positioned to take all of the element's space. |
| 123 | + |
| 124 | +The `placeholder` is hidden as soon as the element is built and its first layout complete. At this |
| 125 | +point the element is expected to have all of its children properly built and positioned and ready |
| 126 | +to be displayed and accept a reader's input. This is the default behavior. Each element can override |
| 127 | +to, e.g., hide `placeholder` faster or keep it around longer. |
| 128 | + |
| 129 | +The element is sized and displayed based on the `layout`, `width`, `height` and `media` attributes |
| 130 | +by the runtime. All of the layout rules are implemented via CSS internally. The element is said to |
| 131 | +"define size" if its size is inferrable via CSS styles and does not change based on its children: |
| 132 | +available immediately or inserted dynamically. This does not mean that this element's size cannot |
| 133 | +change. The layout could be fully responsive as is the case with `responsive`, `fixed-height` and |
| 134 | +`fill` layouts. It simply means that the size does not change without an explicit user action, e.g. |
| 135 | +during rendering or scrolling or post download. |
| 136 | + |
| 137 | +If the element has been configured incorrectly it will not be rendered at all in PROD and in DEV mode |
| 138 | +the runtime will display the element in the error state. Possible errors include invalid or unsupported |
| 139 | +values of `layout`, `width` and `height` attributes. |
| 140 | + |
| 141 | +## (tl;dr) Appendix 1: Layout Table |
| 142 | + |
| 143 | +What follows is the table of layouts, acceptable configuration parameters and CSS classes and styles |
| 144 | +used by this layouts. Notice that: |
| 145 | +1. Any CSS class marked prefixed with "-amp-" and elements prefixed with "i-amp-" are considered to be |
| 146 | +internal to AMP and their use in user stylesheets is not allowed. They are shown here simply for |
| 147 | +informational purposes. |
| 148 | +2. The only layouts that currently do not "define size" are `container` and `nodisplay`. |
| 149 | +3. Even though `width` and `height` are specified in the table as required the default rules may |
| 150 | +apply as is the case with `amp-pixel` and `amp-audio`. |
| 151 | + |
| 152 | +| Layout | Width/Height Required? | Defines Size? | Additional Elements | CSS "display" | |
| 153 | +|--------------|------------------------|---------------|---------------------|---------------| |
| 154 | +| nodisplay | no | no | no | `none` | |
| 155 | +| fixed | yes | yes, specified by `width` and `height` | no | `inline-block` | |
| 156 | +| responsive | yes | yes, based on parent container and aspect ratio of `width:height` | yes, `i-amp-sizer` | `block` | |
| 157 | +| fixed-height | `height` only. `width` can be `auto` | yes, specified by the parent container and `height` | no | `block` | |
| 158 | +| fill | no | yes, parent's size | no | `block` | |
| 159 | +| container | no | no | no | `block` | |
0 commit comments