AMP

AMPHTML 布局系统

概述

布局系统的主要目标是确保 AMP 元素可以表达其布局,以便运行时能够在任何远程资源(例如 JavaScript 和数据调用)完成之前推断元素的大小。这一点很重要,因为它可以显著减少渲染和滚动时的卡顿。

考虑到这一点,AMP 布局系统旨在支持少数但灵活的布局,这些布局提供良好的性能保证。此系统依赖于一组属性(例如 layoutwidthheightsizesheights)来表达元素的布局和大小需求。

行为

非容器 AMP 元素(即,layout != container)以未解析/未构建模式启动,其中其所有子元素都被隐藏,除了占位符(请参见 placeholder 属性)。完全构造元素所需的 JavaScript 和数据有效负载可能仍在下载和初始化,但 AMP 运行时已经知道如何调整元素的大小和布局,仅依赖于 CSS 类和 layoutwidthheightmedia 属性。在大多数情况下,如果指定了 placeholder,则它的大小和位置会占据元素的全部空间。

一旦元素构建完成并且其首次布局完成,placeholder 就会被隐藏。此时,该元素应已正确构建并定位其所有子元素,并且可以显示并接受读者的输入。这是默认行为。每个元素都可以覆盖,例如,更快地隐藏 placeholder 或将其保留更长时间。

该元素的大小和显示基于运行时通过 layoutwidthheightmedia 属性进行设置。所有布局规则都在内部通过 CSS 实现。如果元素的大小可通过 CSS 样式推断并且不会根据其子元素而更改,则称该元素“定义大小”:可用或动态插入。这并不意味着此元素的大小无法更改。该布局可以是完全响应式的,就像 responsivefixed-heightfillflex-item 布局一样。这仅仅意味着,如果没有显式的用户操作(例如在渲染或滚动期间或下载后),大小不会更改。

如果元素配置不正确,则在 PROD 中将根本不渲染该元素,而在 DEV 模式下,运行时将以错误状态渲染该元素。可能的错误包括 layoutwidthheight 属性的无效或不支持的值。

布局属性

widthheight

根据 layout 属性的值,AMP 组件元素必须具有包含整数像素值的 widthheight 属性。实际布局行为由以下所述的 layout 属性决定。

在少数情况下,如果未指定 widthheight,AMP 运行时可以按如下方式默认这些值

  • amp-pixelwidthheight 均默认为 0。
  • amp-audio:默认的 widthheight 是从浏览器推断的。

layout

AMP 提供了一组布局,用于指定 AMP 组件在文档布局中的行为。您可以通过添加带有下表中指定值之一的 layout 属性来为组件指定布局。

示例:一个简单的响应式图像,其中宽度和高度用于确定纵横比。

<amp-img
  src="/img/amp.jpg"
  width="1080"
  height="610"
  layout="responsive"
  alt="an image"
></amp-img>

layout 属性的受支持值

行为和要求
不存在 如果未指定值,则组件的布局将按如下方式推断
  • 如果存在 height 并且缺少 width 或将其设置为 auto,则假定为 fixed-height 布局。
  • 如果 widthheightsizesheights 属性一起存在,则假定为 responsive 布局。
  • 如果存在 widthheight,则假定为 fixed 布局。
  • 如果缺少 widthheight,则假定为 container 布局。
container 该元素让其子元素定义其大小,很像普通的 HTML div。该组件被假定为自身没有特定的布局,而仅充当容器;其子元素会立即渲染。
fill 该元素占用其可用的空间(宽度和高度)。换句话说,fill 元素的布局和大小与其父元素匹配。要使元素填充其父容器,请指定“fill”布局,并确保父容器指定 position:relativeposition:absolute
fixed 该元素具有固定的宽度和高度,不支持响应式。必须存在 widthheight 属性。唯一的例外是 amp-pixelamp-audio 组件。
fixed-height 该元素占用其可用的空间,但保持高度不变。此布局非常适合诸如 amp-carousel 之类的元素,这些元素涉及水平定位的内容。必须存在 height 属性。width 属性不得存在或必须等于 auto
flex-item 当父元素是弹性容器时(即,display: flex),该元素及其父元素中具有布局类型 flex-item 的其他元素会占用父容器的剩余空间。widthheight 属性不是必需的。
intrinsic 该元素占用其可用的空间,并自动调整其高度,使其达到 widthheight 属性给出的纵横比直到达到传递给 amp-imgwidthheight 属性定义的元素大小,或达到 CSS 约束(例如 max-width)。必须存在宽度和高度属性。此布局非常适合大多数 AMP 元素,包括 amp-imgamp-carousel 等。可用空间取决于父元素,也可以使用 max-width CSS 自定义。此布局与 responsive 的不同之处在于它具有固有的高度和宽度。这在浮动元素内部最明显,在浮动元素内部,responsive 布局将渲染为 0x0,而 intrinsic 布局将膨胀到其自然大小或任何 CSS 约束的较小者。
nodisplay 该元素不显示,并且在屏幕上占用零空间,就像其显示样式为 none 一样。此布局可以应用于每个 AMP 元素。假设该元素可以在用户操作时显示自身(例如,amp-lightbox)。widthheight 属性不是必需的。
responsive 该元素占用其可用的空间,并自动调整其高度,使其达到 widthheight 属性给出的纵横比。此布局非常适合大多数 AMP 元素,包括 amp-imgamp-video 等。可用空间取决于父元素,也可以使用 max-width CSS 自定义。必须存在 widthheight 属性。

注意:具有 "layout=responsive" 的元素没有固有的大小。元素的大小由其容器元素确定。为确保您的 AMP 元素显示,您必须为包含元素指定宽度和高度。请勿在包含元素上指定 "display:table",因为这会覆盖 AMP 元素的显示,从而导致 AMP 元素不可见。

sizes

所有支持 responsive 布局的 AMP 元素也都支持 sizes 属性。此属性的值是 sizes 表达式,如 img sizes 中所述,但扩展到所有元素,而不仅仅是图像。简而言之,sizes 属性描述如何根据媒体条件计算元素的宽度。

当同时指定 sizes 属性以及 widthheight 时,layout 的默认值为 responsive

示例:使用 sizes 属性

在以下示例中,如果视口宽度大于 320px,则图像宽度为 320px;否则,其宽度将为 100vw(视口宽度的 100%)。

<amp-img
  src="https://acme.org/image1.png"
  width="400"
  height="300"
  layout="responsive"
  sizes="(min-width: 320px) 320px, 100vw"
>
</amp-img>

disable-inline-width

sizes 属性本身会在元素上设置内联 width 样式。当将 disable-inline-widthsizes 配对使用时,AMP 元素会将 sizes 的值传播到元素的底层标签,就像 amp-img 内部嵌套的 img 一样,而不会sizes 在 AMP 中通常那样自行设置内联 width

示例:使用 disable-inline-width 属性

在以下示例中,<amp-img> 元素的宽度不受影响,而 sizes 仅用于从 srcset 中选择一个源。

<amp-img
  src="https://acme.org/image1.png"
  width="400"
  height="300"
  layout="responsive"
  sizes="(min-width: 320px) 320px, 100vw"
  disable-inline-width
>
</amp-img>

heights

所有支持 responsive 布局的 AMP 元素也都支持 heights 属性。此属性的值是一个基于媒体表达式的大小表达式,类似于 img sizes 属性,但有两个主要区别:

  1. 它应用于元素的高度,而不是宽度。
  2. 允许使用百分比值,例如 86%。如果使用百分比值,则表示元素宽度的百分比。

当同时指定 heights 属性以及 widthheight 时,layout 的默认值为 responsive

示例:使用 heights 属性

在以下示例中,图像的高度默认为宽度的 80%,但如果视口宽度大于 500px,则高度上限为 200px。由于指定了 heights 属性以及 widthheight,因此布局默认设置为 responsive

<amp-img
  src="https://acme.org/image1.png"
  width="320"
  height="256"
  heights="(min-width:500px) 200px, 80%"
>
</amp-img>

media

大多数 AMP 元素都支持 media 属性。media 的值是一个媒体查询。如果查询不匹配,则根本不会渲染该元素,并且不会获取其资源以及可能的子资源。如果浏览器窗口更改大小或方向,则会重新评估媒体查询,并根据新结果隐藏和显示元素。

示例:使用 media 属性

在以下示例中,我们有两个具有互斥媒体查询的图像。根据屏幕宽度,将获取并渲染两个图像中的一个。media 属性在所有 AMP 元素上都可用,因此它可以与非图像元素(例如广告)一起使用。

<amp-img
  media="(min-width: 650px)"
  src="wide.jpg"
  width="466"
  height="355"
  layout="responsive"
></amp-img>
<amp-img
  media="(max-width: 649px)"
  src="narrow.jpg"
  width="527"
  height="193"
  layout="responsive"
></amp-img>

placeholder

placeholder 属性可以设置在任何 HTML 元素上,而不仅仅是 AMP 元素上。placeholder 属性表示标记有此属性的元素充当父 AMP 元素的占位符。如果指定,占位符元素必须是 AMP 元素的直接子元素。默认情况下,即使 AMP 元素的资源尚未下载或初始化,也会立即显示 AMP 元素的占位符。准备就绪后,AMP 元素通常会隐藏其占位符并显示内容。关于占位符的确切行为取决于元素的实现。

<amp-anim src="animated.gif" width="466" height="355" layout="responsive">
  <amp-img placeholder src="preview.png" layout="fill"></amp-img>
</amp-anim>

fallback

fallback 属性可以设置在任何 HTML 元素上,而不仅仅是 AMP 元素上。回退是一种约定,允许元素向读者传达浏览器不支持该元素。如果指定,回退元素必须是 AMP 元素的直接子元素。关于回退的确切行为取决于元素的实现。

<amp-anim src="animated.gif" width="466" height="355" layout="responsive">
  <div fallback>Cannot play animated images on this device.</div>
</amp-anim>

noloading

noloading 属性指示是否应为此元素关闭“加载指示器”。许多 AMP 元素都允许显示“加载指示器”,这是一种基本的动画,显示该元素尚未完全加载。元素可以通过添加此属性来选择退出此行为。

(tl;dr)布局要求和行为摘要

下表描述了用于 layout 属性的可接受的参数、CSS 类和样式。请注意:

  1. 任何以 -amp- 为前缀的 CSS 类和以 i-amp- 为前缀的元素都被认为是 AMP 内部的,不允许在用户样式表中使用。此处显示它们仅用于提供信息。
  2. 即使在表中指定了 widthheight 是必需的,默认规则也可能适用,就像 amp-pixelamp-audio 的情况一样。
布局 宽度/
高度 是否必需?
定义大小? 其他元素 CSS "display"
container
fill 是,父元素的大小。
fixed 是,由 widthheight 指定。 内联块
fixed-height heightwidth 可以是 auto 是,由父容器和 height 指定。
flex-item 是,基于父容器。
intrinsic 是,基于父容器和 width:height 的宽高比。 是,i-amphtml-sizer block (行为类似于 替换元素)
nodisplay
responsive 是,基于父容器和 width:height 的宽高比。 是,i-amphtml-sizer