AMP

AMP HTML 规范

重要提示:此文档不适用于您当前选择的格式 stories

AMP HTML 是 HTML 的一个子集,用于编写内容页面(例如新闻文章),以保证某些基准性能特征。

作为 HTML 的一个子集,它对 HTML 提供的所有标签和功能设置了一些限制,但它不需要开发新的渲染引擎:现有的用户代理可以像渲染所有其他 HTML 一样渲染 AMP HTML。

如果您主要对 AMP 中允许什么和不允许什么感兴趣,请观看我们的AMP 限制入门视频

此外,AMP HTML 文档可以像任何其他 HTML 文档一样上传到 Web 服务器并提供服务;服务器不需要进行特殊配置。但是,它们也被设计为可以选择通过专门的 AMP 服务系统提供服务,这些系统代理 AMP 文档。这些文档从它们自己的来源提供服务,并且允许对文档应用转换,从而提供额外的性能优势。此类服务系统可能执行的不完整优化列表为

  • 将图像引用替换为大小适合查看器视口的图像。
  • 内联视口上方可见的图像。
  • 内联 CSS 变量。
  • 预加载扩展组件。
  • 缩小 HTML 和 CSS。

AMP HTML 使用一组贡献但集中管理和托管的自定义元素来实现高级功能,例如可能在 AMP HTML 文档中找到的图像库。虽然它允许使用自定义 CSS 设置文档样式,但除了通过自定义元素提供的之外,它不允许作者编写的 JavaScript 来实现其性能目标。

通过使用 AMP 格式,内容生产者可以使 AMP 文件中的内容可被第三方抓取(受 robots.txt 限制)、缓存和显示。

性能

可预测的性能是 AMP HTML 的关键设计目标。主要目标是缩短用户可以消费/使用页面内容的时间。具体来说,这意味着

  • 应最大限度地减少渲染和完全布局文档所需的 HTTP 请求。
  • 仅当用户可能看到资源时才应下载资源,例如图像或广告。
  • 浏览器应该能够在不获取该资源的情况下计算页面上每个资源所需的空间。

AMP HTML 格式

示例文档

<!DOCTYPE html>
<html  lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Sample document</title>
    <link rel="canonical" href="./regular-html-version.html" />
    <meta
      name="viewport"
      content="width=device-width,minimum-scale=1,initial-scale=1"
    />
    <style amp-custom>
      h1 {
        color: red;
      }
    </style>
    <script type="application/ld+json">
      {
        "@context": "http://schema.org",
        "@type": "NewsArticle",
        "headline": "Article headline",
        "image": ["thumbnail1.jpg"],
        "datePublished": "2015-02-05T08:00:00+08:00"
      }
    </script>
    <script
      async
      custom-element="amp-carousel"
      src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"
    ></script>
    <script
      async
      custom-element="amp-ad"
      src="https://cdn.ampproject.org/v0/amp-ad-0.1.js"
    ></script>
    <style amp-boilerplate>
      body {
        -webkit-animation: -amp-start 8s steps(1, end) 0s 1 normal both;
        -moz-animation: -amp-start 8s steps(1, end) 0s 1 normal both;
        -ms-animation: -amp-start 8s steps(1, end) 0s 1 normal both;
        animation: -amp-start 8s steps(1, end) 0s 1 normal both;
      }
      @-webkit-keyframes -amp-start {
        from {
          visibility: hidden;
        }
        to {
          visibility: visible;
        }
      }
      @-moz-keyframes -amp-start {
        from {
          visibility: hidden;
        }
        to {
          visibility: visible;
        }
      }
      @-ms-keyframes -amp-start {
        from {
          visibility: hidden;
        }
        to {
          visibility: visible;
        }
      }
      @-o-keyframes -amp-start {
        from {
          visibility: hidden;
        }
        to {
          visibility: visible;
        }
      }
      @keyframes -amp-start {
        from {
          visibility: hidden;
        }
        to {
          visibility: visible;
        }
      }
    </style>
    <noscript
      ><style amp-boilerplate>
        body {
          -webkit-animation: none;
          -moz-animation: none;
          -ms-animation: none;
          animation: none;
        }
      </style></noscript
    >
    <script async src="https://cdn.ampproject.org/v0.js"></script>
  </head>
  <body>
    <h1>Sample document</h1>
    <p>
      Some text
      <amp-img src="sample.jpg" width="300" height="300"></amp-img>
    </p>
    <amp-ad
      width="300"
      height="250"
      type="a9"
      data-aax_size="300x250"
      data-aax_pubname="test123"
      data-aax_src="302"
    >
    </amp-ad>
  </body>
</html>

必需的标记

AMP HTML 文档必须

  • 以文档类型 <!doctype html> 开头。 🔗
  • 包含一个顶级 <html ⚡> 标签(也接受 <html amp>)。 🔗
  • 包含 <head><body> 标签(它们在 HTML 中是可选的)。 🔗
  • 在其 head 标签内包含一个 <link rel="canonical" href="$SOME_URL"> 标签,该标签指向 AMP HTML 文档的常规 HTML 版本,如果不存在这样的 HTML 版本,则指向自身。 🔗
  • 在其 head 标签中包含一个 <meta charset="utf-8"> 标签作为第一个子标签。 🔗
  • 在其 head 标签内包含一个 <meta name="viewport" content="width=device-width"> 标签。还建议包括 minimum-scale=1initial-scale=1🔗
  • 在其 head 标签内包含一个 <script async src="https://cdn.ampproject.org/v0.js"></script> 标签。 🔗
  • 在其 head 标签中包含 AMP 样板代码head > style[amp-boilerplate]noscript > style[amp-boilerplate])。 🔗

元数据

鼓励使用标准元数据注释 AMP HTML 文档:Open Graph ProtocolTwitter Cards 等。

我们还建议使用 schema.org/CreativeWork 或其任何更具体的类型(例如 schema.org/NewsArticleschema.org/BlogPosting)标记 AMP HTML 文档。

HTML 标签

HTML 标签可以在 AMP HTML 中保持不变地使用。某些标签具有等效的自定义标签(例如 <img><amp-img>),而其他标签则被完全禁止

标签 在 AMP HTML 中的状态
script 禁止,除非类型为 application/ld+jsonapplication/jsontext/plain。(可能会根据需要添加其他不可执行的值。)例外情况是加载 AMP 运行时的强制性 script 标签和加载扩展组件的 script 标签。
noscript 允许。可以在文档中的任何位置使用。如果指定,如果用户禁用 JavaScript,则会显示 <noscript> 元素内的内容。
base 禁止。
img 替换为 amp-img
请注意:根据 HTML5,<img> 是一个 Void 元素,因此它没有结束标签。但是,<amp-img> 有一个结束标签 </amp-img>
picture 禁止。通过使用 fallback 属性提供不同的图像格式,或在 <amp-img> 上提供多个 srcset
video 替换为 amp-video
audio 替换为 amp-audio
iframe 替换为 amp-iframe
frame 禁止。
frameset 禁止。
object 禁止。
param 禁止。
applet 禁止。
embed 禁止。
form 允许。需要包含 amp-form 扩展。
input 元素 大多数情况下允许,但 某些输入类型例外,即 <input type=button><button type=image> 无效。也允许使用相关标签:<fieldset><label>
button 允许。
style amp-boilerplate 的必需 style 标签。head 标签中允许一个额外的 style 标签,用于自定义样式设置。此 style 标签必须具有属性 amp-custom🔗
link 允许使用 microformats.org 上注册的 rel 值。如果我们的允许列表中缺少 rel 值,请提交错误报告。不允许使用 stylesheet 和其他值(如 preconnectprerenderprefetch),这些值在浏览器中具有副作用。从允许的字体提供商处获取样式表有一个特殊情况。
meta http-equiv 属性可以用于特定的允许值;有关详细信息,请参阅 AMP 验证器规范
a href 属性值不能以 javascript: 开头。如果设置,则 target 属性值必须为 _blank。否则允许。 🔗
svg 允许使用大多数 SVG 元素。

验证器实现应使用基于 HTML5 规范的允许列表,并删除上述标签。请参阅 AMP 标签附录

注释

不允许使用条件 HTML 注释。

HTML 属性

AMP HTML 中不允许使用以 on 开头的属性名称(例如 onclickonmouseover)。允许使用文字名称为 on(无后缀)的属性。

AMP HTML 中不允许使用与 XML 相关的属性,例如 xmlns、xml:lang、xml:base 和 xml:space。

AMP HTML 中不允许使用以 i-amp- 为前缀的内部 AMP 属性。

AMP HTML 中不允许使用以 -amp-i-amp- 为前缀的内部 AMP 类名称。

请参阅 AMP 文档,了解以 amp- 为前缀的类名称的含义。允许使用这些类,目的是允许自定义 AMP 运行时和扩展的某些功能。

AMP HTML 标记中允许使用所有其他创作的类名称。

ID

AMP HTML 中不允许使用某些 ID 名称,例如以 -amp-i-amp- 为前缀的 ID,这些 ID 可能与内部 AMP ID 冲突。

在使用 amp-AMP ID 之前,请查阅 AMP 文档中关于特定扩展程序的说明,以避免与这些扩展程序提供的功能(例如 amp-access)发生冲突。

要查看不允许的 ID 名称的完整列表,请在此处搜索 mandatory-id-attr 此处

不允许使用 javascript: 模式。

样式表

主要的语义标签和 AMP 自定义元素都带有默认样式,以便轻松编写响应式文档。未来可能会添加选择退出默认样式的选项。

@-规则

以下 @-规则在样式表中是允许的:

@font-face@keyframes@media@page@supports

不允许使用 @import。 未来可能会添加其他规则。

作者样式表

作者可以使用文档头部中的单个 <style amp-custom> 标签或内联样式向文档添加自定义样式。

@keyframes 规则允许在 <style amp-custom> 中使用。但是,如果规则过多,建议将它们放在额外的 <style amp-keyframes> 标签中,该标签必须位于 AMP 文档的末尾。有关详细信息,请参阅本文档的 关键帧样式表 部分。

选择器

以下限制适用于作者样式表中的选择器:

类名和标签名

作者样式表中的类名、ID、标签名和属性不得以字符串 -amp-i-amp- 开头。这些是 AMP 运行时内部使用的保留名称。因此,用户的样式表不能引用 -amp- 类、i-amp- ID 和 i-amp- 标签和属性的 CSS 选择器。这些类、ID 和标签/属性名称不应由作者自定义。但是,作者可以覆盖 amp- 类和标签的样式,用于这些组件规范中未明确禁止的任何 CSS 属性。

为了防止使用属性选择器绕过类名限制,通常不允许 CSS 选择器包含以 -amp-i-amp- 开头的标记和字符串。

重要

不允许使用 !important 限定符。这是 AMP 能够强制执行其元素大小不变性的必要条件。

属性

AMP 仅允许常见浏览器中可以进行 GPU 加速的属性的过渡和动画。我们目前允许:opacitytransform (也包括 -vendorPrefix-transform)。

在以下示例中,<property> 需要在上面允许的列表中。

  • transition <property> (也包括 -vendorPrefix-transition)
  • @keyframes name { from: {<property>: value} to {<property: value>} } (也包括 @-vendorPrefix-keyframes)

最大尺寸

如果作者样式表或内联样式总共大于 75,000 字节,则会出现验证错误。

关键帧样式表

除了 <style amp-custom> 之外,作者还可以添加 <style amp-keyframes> 标签,该标签专门用于关键帧动画。

以下限制适用于 <style amp-keyframes> 标签:

  1. 只能作为文档 <body> 元素的最后一个子元素放置。
  2. 只能包含 @keyframes@media@supports 规则及其组合。
  3. 大小不得超过 500,000 字节。

存在 <style amp-keyframes> 标签的原因是,即使对于中等复杂的动画,关键帧规则通常也很庞大,这会导致 CSS 解析速度缓慢和首次内容绘制速度缓慢。但是,此类规则通常会超过 <style amp-custom> 的大小限制。将此类关键帧声明放在文档底部的 <style amp-keyframes> 中可以使其超出大小限制。并且由于关键帧不会阻止渲染,它还可以避免阻止首次内容绘制来解析它们。

示例

<style amp-keyframes>
@keyframes anim1 {}

@media (min-width: 600px) {
  @keyframes anim1 {}
}
</style>
</body>

自定义字体

作者可以包含自定义字体的样式表。支持的 2 种方法是指向允许列表中的字体提供商的链接标签和包含 @font-face

示例

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Tangerine"
/>

如果字体提供商支持仅限 CSS 的集成并通过 HTTPS 提供服务,则可以将其列入允许列表。目前允许以下来源通过链接标签提供字体服务:

  • Fonts.com: https://fast.fonts.net
  • Google Fonts: https://fonts.googleapis.com
  • Font Awesome: https://maxcdn.bootstrapcdn.com, https://use.fontawesome.com
  • Typekit: https://use.typekit.net/kitId.css (相应地替换 kitId)

实现者须知:添加到此列表需要更改 AMP 缓存 CSP 规则。

作者可以自由地通过自定义 CSS 中的 @font-face CSS 指令包含所有自定义字体。通过 @font-face 包含的字体必须通过 HTTP 或 HTTPS 方案获取。

AMP 运行时

AMP 运行时是一段 JavaScript 代码,它在每个 AMP 文档中运行。它为 AMP 自定义元素提供实现,管理资源加载和优先级,并且可选地包括在开发期间使用的 AMP HTML 运行时验证器。

AMP 运行时通过 AMP 文档 <head> 中的强制性 <script src="https://cdn.ampproject.org/v0.js"></script> 标签加载。

可以将 AMP 运行时置于任何页面的开发模式。开发模式将触发嵌入页面上的 AMP 验证,这会将验证状态和任何错误输出到 JavaScript 开发人员控制台。可以通过将 #development=1 附加到页面的 URL 来触发开发模式。

资源

诸如图像、视频、音频文件或广告之类的资源必须通过自定义元素(例如 <amp-img>)包含到 AMP HTML 文件中。我们将它们称为“托管资源”,因为它们是否以及何时加载并显示给用户由 AMP 运行时决定。

AMP 运行时的加载行为没有特别的保证,但它通常应努力足够快地加载资源,以便在用户想要看到它们时尽可能加载它们。运行时应优先加载当前在视口中的资源,并尝试预测视口的更改并相应地预加载资源。

AMP 运行时可以随时决定卸载当前不在视口中的资源,或者重用 iframe 等资源容器以减少整体 RAM 消耗。

AMP 组件

AMP HTML 使用称为“AMP 组件”的自定义元素来替代内置的资源加载标签(例如 <img><video>),并实现具有复杂交互的功能,例如图像灯箱或轮播。

有关支持的组件的详细信息,请参阅 AMP 组件规范

支持两种类型的 AMP 组件:

  1. 内置
  2. 扩展

内置组件始终在 AMP 文档中可用,并具有专用的自定义元素,例如 <amp-img>。扩展组件必须明确包含在文档中。

常用属性

layoutwidthheightmediaplaceholderfallback

这些属性定义元素的布局。此处的关键目标是确保在下载任何 JavaScript 或远程资源之前,可以显示元素并正确保留其空间。

有关布局系统的详细信息,请参阅 AMP 布局系统

on

on 属性用于在元素上安装事件处理程序。支持的事件取决于元素。

语法的格式是以下形式的简单特定领域语言:

eventName:targetId[.methodName[(arg1=value, arg2=value)]]

示例:on="tap:fooId.showLightbox"

如果省略 methodName,则如果为元素定义了默认方法,则会执行该方法。示例:on="tap:fooId"

某些操作(如果已记录)可能会接受参数。参数在括号之间以 key=value 符号定义。接受的值包括:

  • 简单的未加引号的字符串:simple-value
  • 加引号的字符串:"string value"'string value'
  • 布尔值:truefalse
  • 数字:111.1

您可以通过分号 ; 分隔两个事件来监听元素上的多个事件。

示例:on="submit-success:lightbox1;submit-error:lightbox2"

阅读有关 AMP 操作和事件的更多信息。

扩展组件

扩展组件是不一定随 AMP 运行时提供的组件。相反,必须将其明确包含在文档中。

通过在文档的头部包含 <script> 标签来加载扩展组件,如下所示:

<script
  async
  custom-element="amp-carousel"
  src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"
></script>

<script> 标签必须具有 async 属性,并且必须具有引用元素名称的 custom-element 属性。

运行时实现可以使用该名称来为这些元素呈现占位符。

脚本 URL 必须以 https://cdn.ampproject.org 开头,并且必须遵循 /v\d+/[a-z-]+-(latest|\d+|\d+\.\d+)\.js 的非常严格的模式。

URL

扩展组件的 URL 格式为:

https://cdn.ampproject.org/$RUNTIME_VERSION/$ELEMENT_NAME-$ELEMENT_VERSION.js
版本控制

请参阅 AMP 版本控制策略

模板

模板根据特定于语言的模板和提供的 JSON 数据呈现 HTML 内容。

有关支持的模板的详细信息,请参阅 AMP 模板规范

模板不随 AMP 运行时提供,必须像扩展元素一样下载。通过在文档的头部包含 <script> 标签来加载扩展组件,如下所示:

<script
  async
  custom-template="amp-mustache"
  src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"
></script>

<script> 标签必须具有 async 属性,并且必须具有引用模板类型的 custom-template 属性。脚本 URL 必须以 https://cdn.ampproject.org 开头,并且必须遵循 /v\d+/[a-z-]+-(latest|\d+|\d+\.\d+)\.js 的非常严格的模式。

模板在文档中声明如下:

<template type="amp-mustache" id="template1">
  Hello {{you}}!
</template>

需要 type 属性,并且必须引用已声明的 custom-template 脚本。

id 属性是可选的。单个 AMP 元素会发现它们自己的模板。典型的情况是,AMP 元素在其子元素中查找 <template> 或按 ID 引用它。

模板元素中的语法取决于特定的模板语言。但是,模板语言可能会在 AMP 中受到限制。例如,按照“template”元素,所有产品都必须在有效的格式正确的 DOM 上进行。所有模板输出也都要进行清理,以确保输出 AMP 有效。

要了解模板的语法和限制,请访问 模板的文档

URL

扩展组件的 URL 格式为:

https://cdn.ampproject.org/$RUNTIME_VERSION/$TEMPLATE_TYPE-$TEMPLATE_VERSION.js
版本控制

有关更多详细信息,请参阅自定义元素的版本控制。

安全性

当使用不包含关键字 unsafe-inlineunsafe-eval 的内容安全策略提供服务时,AMP HTML 文档不得触发错误。

AMP HTML 格式的设计确保始终如此。

所有 AMP 模板元素都必须经过 AMP 安全审查,然后才能提交到 AMP 存储库。

SVG

目前,允许使用以下 SVG 元素:

  • 容器元素:“clipPath”、“defs”、“g”、“marker”、“mask”、“pattern”、“svg”、“switch”和“symbol”。
  • 结构元素: "defs", "g", "svg", "symbol", 和 "use"。
  • 图形元素: "circle", "ellipse", "foreignObject", "image", "line", "path", "polygon", "polyline", "rect", "text", "textPath", 和 "tspan"。
  • 文本内容元素: "text", "textPath", 和 "tspan"。
  • 着色服务器元素: "linearGradient", "pattern", 和 "radialGradient"。
  • 描述性元素: "desc", "metadata", 和 "title"。
  • 滤镜原语元素: "feColorMatrix", "feComposite", "feGaussianBlur", "feMerge", "feMergeNode", 和 "feOffset"。
  • 未分类元素: "view", 和 "filter"。
  • 已弃用元素: "glyph", "glyphRef", "hkern", "tref", 和 "vkern"

以及这些属性

  • "xlink:href": 只允许以 "#" 开头的 URI
  • "style"

AMP 文档发现

以下描述的机制提供了一种标准化的方法,让软件可以发现规范文档是否存在 AMP 版本。

如果存在一个 AMP 文档,它是规范文档的替代表示,则规范文档应通过带有 关系 "amphtml"link 标签指向该 AMP 文档。

示例

<link rel="amphtml" href="https://www.example.com/url/to/amp/document.html" />

AMP 文档本身应该通过带有关系 "canonical" 的 link 标签指回其规范文档。

示例

<link
  rel="canonical"
  href="https://www.example.com/url/to/canonical/document.html"
/>

(如果单个资源同时是 AMP *和*规范文档,则 canonical 关系应指向自身 - 不需要 "amphtml" 关系。)

请注意,为了与 AMP 消费系统实现最广泛的兼容性,应该可以在不执行 JavaScript 的情况下读取 "amphtml" 关系。(也就是说,该标签应存在于原始 HTML 中,而不是通过 JavaScript 注入。)