Layout System

Edit on Github
Open in Playground

Introduction

There are a number of tools in AMP and CSS to make responsive documents.

In each of these examples, we'll use a 200x200 grey square (inline-block) as a parent to each element to demonstrate the layout values.

We're going to build a demo panel of buttons that can adjust the size and aspect ratio of the individual samples so as to better display layout size changes. It should be visible in the bottom right corner.

Example

Adjust Aspect Ratio:
Adjust Size:
<div class="fixed-panel">
  <div>
    <span>Adjust Aspect Ratio:</span>
    <button on="tap:AMP.setState({deviceClass: 'vtphone'})">Set to Vertical Phone</button>
    <button on="tap:AMP.setState({deviceClass: 'desktop'})">Set to Desktop</button>
    <button on="tap:AMP.setState({deviceClass: 'hzphone'})">Set to Horizontal Phone</button>
    <button on="tap:AMP.setState({deviceClass: ''})">Set to Square</button>
  </div>
  <div>
    <span>Adjust Size:</span>
    <button on="tap:AMP.setState({sizeClass: 'half'})">Half size</button>
    <button on="tap:AMP.setState({sizeClass: ''})">Regular size</button>
    <button on="tap:AMP.setState({sizeClass: 'double'})">Double size</button>
  </div>
</div>

responsive

AMP HTML has a number of different layout types. The most common of these is the responsive layout attribute value.

When an element is given a height, width, and the layout="responsive" attribute value, it will use the height and width to calculate an aspect ratio, and responsively scale the element's box to match the width of the parent element.

Example

Lorem ipsum dolor sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-fit-text width="300"
      height="200"
      layout="responsive">Lorem ipsum dolor sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
  </div>

In the responsive layout, the height and width are only used for determining the aspect ratio. Thus 3x2 and 300x200 are functionally equivalent.

Example

Lorem ipsum dolor sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-fit-text width="3"
      height="2"
      layout="responsive">Lorem ipsum dolor sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
  </div>

The layout attribute applies to all amp-* tags, though not all amp tags support all layout types.

Example

  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-img width="300"
      height="200"
      layout="responsive"
      src="/img/amp.jpg"></amp-img>
  </div>

nodisplay

Some elements, such as amp-font and amp-install-serviceworker, only support the nodisplay type. These elements do not require space to be allocated on the page for their rendering.

Example

  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-install-serviceworker src="/sw.js"
      data-iframe-src="https://ampbyexample.com/sw.html"
      layout="nodisplay"></amp-install-serviceworker>
  </div>

fixed

The layout="fixed" attribute value indicates that the element should fit to the size its given (300x200).

Example

Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-fit-text width="300"
      height="200"
      layout="fixed">Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
  </div>

Elements with the layout="fixed" attribute value will render at the size provided, even if that exceeds the size of the parent element.

Example

Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-fit-text width="500"
      height="10"
      layout="fixed">Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
  </div>

fixed-height

The layout="fixed-height" attribute value indicates that the element should fill to the width that it's given, but remain at a fixed height.
As the width is disregarded in fixed-height, it can only be set to "auto" (or not set at all).

Example

Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-fit-text height="200"
      layout="fixed-height">Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
  </div>

Elements with a fixed-height layout attribute value will respond to the size of the parent element (and thus screen size), but will not respect aspect ratio.

Example

  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-img height="100"
      layout="fixed-height"
      src="/img/amp.jpg"></amp-img>
  </div>

flex-item

The layout="flex-item" attribute value is similar to the layout="fill" attribute value, except that it is used in a flexbox model.
For these examples, I've created a parent flex box container inside of the fixed-size square. The children in that container will expand in a row (horizontally) and will wrap if the size exceeds the width given.

Example

Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <div class="flexsquare">
      <amp-fit-text layout="flex-item">Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
      <amp-img layout="flex-item"
        src="/img/amp.jpg"></amp-img>
    </div>
  </div>

container

The layout="container" attribute value indicates that the element has no intrisic space needs of its own, and that it's size should be determined by the needs of its children. This is functionally equivalent to the default behavior of the "div" tag in HTML5. Use cases include amp-accordion, amp-live-list, and other tags whose content is determined by its children.

Example

Lipsum

Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.
  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-accordion layout="container">
      <section expanded>
        <h1>Lipsum</h1>
        <amp-fit-text width="300"
          height="200"
          layout="fixed">Lorem ipsum dolori sit amet, has nisl nihil convenire et, vim at aeque inermis reprehendunt.</amp-fit-text>
      </section>
    </amp-accordion>
  </div>

Sizes (Width)

The sizes attribute is a list of media conditions and source size values (width). This is similar to the "sizes" attribute in 'img' tags in HTML5, except it applies to all amp-* tags that allow use the responsive layout. It only works with the responsive layout.

Example

  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-img width="300"
      height="200"
      layout="responsive"
      src="/img/amp.jpg"
      sizes="(min-width:500px) 200px, 100px"></amp-img>
  </div>

Sizes (Height)

The heights attribute is a list of media conditions and source size values (height). This is similar to the "sizes" attribute in 'img' tags in HTML5, except it applies to all amp-* tags that allow use of the responsive layout. It only works with the responsive layout.

Example

  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-img width="300"
      height="200"
      layout="responsive"
      src="/img/amp.jpg"
      heights="(min-width:500px) 200px, 100px"></amp-img>
  </div>

Additionally, the value refers to a height, not a width, and unlike the "sizes" attribute, it can also use a percentage.

Example

  <div class="square"
    [class]="['square', deviceClass, sizeClass].join(' ')">
    <amp-img width="300"
      height="200"
      layout="responsive"
      src="/img/amp.jpg"
      heights="(min-width:500px) 200px, 30%"></amp-img>
  </div>