AMPHTML 布局系统
概述
布局系统的主要目标是确保 AMP 元素能够表达其布局,以便运行时能够在完成任何远程资源(例如 JavaScript 和数据调用)之前推断元素的大小。这一点很重要,因为它可以显著减少渲染和滚动抖动。
考虑到这一点,AMP 布局系统旨在支持一些灵活的布局,这些布局提供了良好的性能保证。此系统依赖于一组属性,例如 layout
、width
、height
、sizes
和 heights
来表达元素的布局和尺寸需求。
行为
非容器 AMP 元素(即 layout != container
)以未解析/未构建模式启动,其中除了占位符(请参阅 placeholder
属性)之外,所有子元素都处于隐藏状态。构建元素所需的 JavaScript 和数据负载可能仍在下载和初始化,但 AMP 运行时已知道如何仅依靠 CSS 类和 layout
、width
、height
和 media
属性对元素进行大小调整和布局。在大多数情况下,如果指定了 placeholder
,则会调整其大小和位置以占据元素的所有空间。
一旦构建元素及其第一个布局完成,placeholder
就会被隐藏。此时,该元素应已正确构建和定位其所有子元素,并已准备好显示和接受读者的输入。这是默认行为。每个元素都可以覆盖,例如,更快地隐藏 placeholder
或将其保留更长时间。
元素的大小和显示基于运行时的 layout
、width
、height
和 media
属性。所有布局规则都通过内部 CSS 实现。如果元素的大小可以通过 CSS 样式推断出来并且不会根据其子元素(立即可用或动态插入)而改变,则称该元素“定义大小”。这并不意味着该元素的大小不能改变。布局可以完全响应,就像 responsive
、fixed-height
、fill
和 flex-item
布局一样。这仅仅意味着在没有明确用户操作(例如,在渲染、滚动或下载后)的情况下,大小不会改变。
如果元素配置不正确,则在 PROD 中它根本不会被渲染,而在 DEV 模式中,运行时会以错误状态渲染元素。可能的错误包括 layout
、width
和 height
属性的无效或不受支持的值。
布局属性
width
和 height
根据 layout
属性的值,AMP 组件元素必须具有包含整数像素值的 width
和 height
属性。实际布局行为由 layout
属性确定,如下所述。
在少数情况下,如果未指定 width
或 height
,则 AMP 运行时可以将这些值默认为以下值
amp-pixel
:width
和height
都默认为 0。amp-audio
:默认width
和height
从浏览器中推断。
layout
AMP 提供了一组布局,用于指定 AMP 组件在文档布局中的行为。您可以通过添加 layout
属性以及下表中指定的值之一来为组件指定布局。
示例:一个简单的响应式图片,其中宽度和高度用于确定纵横比。
<amp-img src="/img/amp.jpg" width="1080" height="610" layout="responsive" alt="an image" ></amp-img>
layout
属性支持的值
值 | 行为和要求 |
---|---|
不存在 | 如果未指定值,则组件的布局将推断如下
|
container | 元素允许其子元素定义其大小,就像普通的 HTML div 一样。假定组件本身没有特定的布局,而只是充当容器;其子元素立即呈现。 |
fill | 元素占据其可用的空间——宽度和高度。换句话说,fill 元素的布局和大小与其父元素匹配。要使元素填充其父容器,请指定“fill”布局,并确保父容器指定 position:relative 或 position:absolute 。 |
fixed | 元素具有固定的宽度和高度,不支持响应性。必须存在 width 和 height 属性。唯一的例外是 amp-pixel 和 amp-audio 组件。 |
fixed-height | 元素占据其可用的空间,但保持高度不变。此布局适用于涉及水平定位内容的元素,例如 amp-carousel 。必须存在 height 属性。width 属性必须不存在或必须等于 auto 。 |
flex-item | 当父级是灵活容器(即 display: flex )时,元素及其父级中具有布局类型 flex-item 的其他元素占据父容器的剩余空间。不需要 width 和 height 属性。 |
内在 | 该元素占据其可用空间,并根据 `width` 和 `height` 属性提供的纵横比自动调整其高度,直至达到由传递给 `amp-img` 的 `width` 和 `height` 属性定义的元素大小,或达到 CSS 约束(例如 `max-width`)。必须存在 width 和 height 属性。这种布局非常适用于大多数 AMP 元素,包括 `amp-img`、`amp-carousel` 等。可用空间取决于父元素,也可以使用 `max-width` CSS 进行自定义。这种布局与 `responsive` 的不同之处在于具有内在高度和宽度。这在浮动元素内部最明显,其中 `responsive` 布局将呈现 0x0,而 `intrinsic` 布局将膨胀到其自然大小或任何 CSS 约束的较小值。 |
nodisplay | 该元素不显示,并且在屏幕上不占用任何空间,就好像其显示样式为 `none`。此布局可应用于每个 AMP 元素。假设元素可以在用户操作时显示自身(例如,`amp-lightbox`)。不需要 `width` 和 `height` 属性。 |
responsive | 该元素占据其可用空间,并根据 `width` 和 `height` 属性提供的纵横比自动调整其高度。这种布局非常适用于大多数 AMP 元素,包括 `amp-img`、`amp-video` 等。可用空间取决于父元素,也可以使用 `max-width` CSS 进行自定义。必须存在 `width` 和 `height` 属性。 注意:具有 `“layout=responsive”` 的元素没有内在大小。元素的大小由其容器元素确定。为确保您的 AMP 元素显示,您必须为容器元素指定宽度和高度。不要在容器元素上指定 `“display:table”`,因为这会覆盖 AMP 元素的显示,使 AMP 元素不可见。 |
sizes
所有支持 `responsive` 布局的 AMP 元素还支持 `sizes` 属性。此属性的值是 img sizes 中描述的 sizes 表达式,但已扩展到所有元素,而不仅仅是图像。简而言之,`sizes` 属性描述如何根据媒体条件计算元素的宽度。
当 `sizes` 属性与 `width` 和 `height` 一起指定时,`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-width
与sizes
配对使用时,AMP 元素会将sizes
的值传播到元素的底层标记,就像嵌套在amp-img
中的img
一样,不会像sizes
通常在 AMP 中自行设置内联width
一样设置内联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 属性,但有两个主要区别
- 它适用于元素的高度,而不是宽度。
- 允许使用百分比值,例如
86%
。如果使用百分比值,则表示元素宽度的百分比。
当heights
属性与width
和height
一起指定时,layout
默认为responsive
。
示例:使用heights
属性
在下例中,图像的高度将默认为宽度的 80%,但如果视口宽度大于500px
,则高度将限制在200px
。由于heights
属性与width
和height
一起指定,因此布局默认为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
属性
在以下示例中,我们有 2 张图片,它们具有互斥的媒体查询。根据屏幕宽度,将获取并呈现两张图片中的一张。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 类和样式。请注意
- 任何以
-amp-
为前缀标记的 CSS 类和以i-amp-
为前缀的元素都被视为 AMP 内部,不允许在用户样式表中使用它们。它们在此处显示仅供参考。 - 即使表中指定了
width
和height
为必需,但默认规则仍可能适用,例如amp-pixel
和amp-audio
。
布局 | 宽度/ 需要高度? | 定义大小? | 其他元素 | CSS “display” |
---|---|---|---|---|
container | 否 | 否 | 否 | block |
fill | 否 | 是,父元素的大小。 | 否 | block |
fixed | 是 | 是,由 width 和 height 指定。 | 否 | inline-block |
fixed-height | 仅 height ;width 可以是 auto | 是,由父容器和 height 指定。 | 否 | block |
flex-item | 否 | 否 | 是,基于父容器。 | block |
内在 | 是 | 是,基于父容器和 width:height 的纵横比。 | 是,i-amphtml-sizer 。 | block (表现得像一个 替换元素) |
nodisplay | 否 | 否 | 否 | none |
responsive | 是 | 是,基于父容器和 width:height 的纵横比。 | 是,i-amphtml-sizer 。 | block |