1. 3 HTML 文档的语义,结构,与API
    1. 3.1 文档
      1. 3.1.1 Document 对象
      2. 3.1.2 The DocumentOrShadowRoot interface
      3. 3.1.3 资源元数据管理
      4. 3.1.4 DOM 树访问器
    2. 3.2 元素
      1. 3.2.1 语义
      2. 3.2.2 DOM 中的元素
      3. 3.2.3 HTML 元素构造器
      4. 3.2.4 元素定义
        1. 3.2.4.1 属性
      5. 3.2.5 内容模型
        1. 3.2.5.1 "nothing" 内容模型
        2. 3.2.5.2 内容的种类
          1. 3.2.5.2.1 元数据内容
          2. 3.2.5.2.2 流式内容
          3. 3.2.5.2.3 章节内容
          4. 3.2.5.2.4 标题内容
          5. 3.2.5.2.5 短语内容
          6. 3.2.5.2.6 嵌入内容
          7. 3.2.5.2.7 交互式内容
          8. 3.2.5.2.8 可感知内容
          9. 3.2.5.2.9 脚本支持元素
        3. 3.2.5.3 透明内容模型
        4. 3.2.5.4 段落
      6. 3.2.6 全局属性
        1. 3.2.6.1 title 属性
        2. 3.2.6.2 langxml:lang 属性
        3. 3.2.6.3 translate 属性
        4. 3.2.6.4 dir 属性
        5. 3.2.6.5 style 属性
        6. 3.2.6.6 使用 data-* 属性 嵌入自定义不可见数据
      7. 3.2.7 The innerText getter and setter
      8. 3.2.8 与双向算法相关的要求
        1. 3.2.8.1 双向算法格式化字符的编写一致性标准
        2. 3.2.8.2 用户代理一致性标准
      9. 3.2.9 ARIA 与 平台可访问性 API 相关的要求

3 HTML 文档的语义,结构,与API

3.1 文档

HTML UA 中的每个 XML 和 HTML 文档表示为一个 Document 对象。 [DOM]

Document 对象的 URL 定义在 DOM 标准中。 It is initially set when 当创建 Document 对象时设置,但可以在 Document 的生命期内改变; 例如当用户 导航 到一个页面的一个 片段 并用一个新的 URL 调用 pushState() 方法时就会改变。[DOM]

交互式用户代理通常在其用户界面中显示 Document 对象的 URL。 这是用户用来判断当前网站是否在冒充其他网站的主要机制。

脚本 中使用 createDocument()createHTMLDocument() 创建 Document 时,Document 立即 准备好了执行加载后的任务

文档的 referrer 是一个字符串(表示一个 URL)。 可以在创建 Document 时设置,如果没有明确设置,它的值是空字符串。

3.1.1 Document 对象

DOM 定义了 Document 接口,本规范对它进行了很多扩展:

enum DocumentReadyState { "loading","interactive","complete" };
typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;

[LegacyOverrideBuiltIns]
partial interface Document {
  // 资源元数据管理
  [PutForwards=href, LegacyUnforgeable] readonly attribute Location? location;
  attribute USVString domain;
  readonly attribute USVString referrer;
  attribute USVString cookie;
  readonly attribute DOMString lastModified;
  readonly attribute DocumentReadyState readyState;

  // DOM 树访问器
  getter object (DOMString name);
  [CEReactions] attribute DOMString title;
  [CEReactions] attribute DOMString dir;
  [CEReactions] attribute HTMLElement? body;
  readonly attribute HTMLHeadElement? head;
  [SameObject] readonly attribute HTMLCollection images;
  [SameObject] readonly attribute HTMLCollection embeds;
  [SameObject] readonly attribute HTMLCollection plugins;
  [SameObject] readonly attribute HTMLCollection links;
  [SameObject] readonly attribute HTMLCollection forms;
  [SameObject] readonly attribute HTMLCollection scripts;
  NodeList getElementsByName(DOMString elementName);
  readonly attribute HTMLOrSVGScriptElement? currentScript; // classic scripts in a document tree only

  // 动态标记插入
  [CEReactions] Document open(optional DOMString unused1, optional DOMString unused2); // both arguments are ignored
  WindowProxy? open(USVString url,DOMString name,DOMString features);
  [CEReactions] undefined close();
  [CEReactions] undefined write(DOMString..。 text);
  [CEReactions] undefined writeln(DOMString..。 text);

  // 用户交互
  readonly attribute WindowProxy? defaultView;
  boolean hasFocus();
  [CEReactions] attribute DOMString designMode;
  [CEReactions] boolean execCommand(DOMString commandId,optional boolean showUI = false,optional DOMString value = "");
  boolean queryCommandEnabled(DOMString commandId);
  boolean queryCommandIndeterm(DOMString commandId);
  boolean queryCommandState(DOMString commandId);
  boolean queryCommandSupported(DOMString commandId);
  DOMString queryCommandValue(DOMString commandId);

  // 只适用于 Document 对象的特殊 事件处理器 IDL 属性
  [LegacyLenientThis] attribute EventHandler onreadystatechange;

  // also has obsolete members
};
Document 实现了 GlobalEventHandlersDocument 实现了 DocumentAndElementEventHandlers

Document 有一个 引荐来源策略 (一个 引荐来源策略), 初始为空字符串,它表示由 Document 发起的 获取 的默认 引荐来源策略

Document 有一个 嵌入策略 (一个 嵌入策略))。

Document 有一个 CSP 列表,它是一个在该上下文中活动的 内容安全策略 对象的列表。 该列表在没有指定时是空的。

Document 有一个 权限策略,是一个 初始为空的 权限策略

Document 有一个 模块映射, 是一个初始为空的 模块映射

Document 有一个 跨域 opener 策略,是一个 跨域 opener 策略,初始为 "unsafe-none"。

3.1.2 The DocumentOrShadowRoot interface

DOM defines the DocumentOrShadowRoot mixin, which this specification extends.

partial interface mixin DocumentOrShadowRoot {
  readonly attribute Element? activeElement;
};

3.1.3 资源元数据管理

document . referrer

Document/referrer

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

返回用户导航到此文档的那个 DocumentURL, 除非它被阻止或没有这样的文档,这时返回空字符串。

noreferrer 链接类型可用于阻止引荐来源。

referrer 属性必须返回 该文档的引荐来源


document . cookie [ = value ]

返回适用于该 Document 的 HTTP cookie。如果没有 Cookie 或 Cookie 不适用于该资源, 则返回空字符串。

可以被设置,用来给该元素的 HTTP Cookie 集合添加一个新的 Cookie。

如果内容 被沙盒化到一个唯一的 origin 中 (例如有 sandbox 属性的 iframe), 当读取和设置时抛出 "SecurityError" DOMException

Document/cookie

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

cookie 属性表示由文档的 URL 标识的资源的 Cookie。

满足下列条件的 Document 对象为 cookie-averse 文档 对象

当读取时,如果文档是一个 cookie-averse Document 对象, 那么用户代理必须返回空字符串。否则,如果 Documentorigin 是一个 不透明 origin,用户代理必须抛出 "SecurityError" DOMException。否则,用户代理必须作为 "非HTTP" API 返回 使用 无 BOM 的 UTF-8 解码算法 解码后的, 文档 URLCookie 字符串[COOKIES]

当设置时,如果文档是一个 cookie-averse Document 对象, 则用户代理必须什么都不做。否则,如果 Documentorigin 是一个 不透明 origin,用户代理必须抛出一个 "SecurityError" DOMException。 否则用户代理的行为必须像是通过 "非HTTP" API 为文档的 URL 接收 set-cookie-string 时一样。 其中,set-cookie-string 由一个新的 UTF-8 编码的 值组成。[COOKIES] [ENCODING]

因为在 frame 之间可以访问 cookie 属性, Cookie 的路径限制只是用来帮助管理对站点的哪一部分发送哪些 Cookie 的工具,并不是任何形式的安全特性。

cookie 属性的读取方法和设定方法同步地访问共享状态。 由于没有加锁机制,在多进程用户代理中其他浏览环境可能会在脚本执行中修改 Cookie。 比如一个站点试着读取 Cookie,增加它的值然后写回去,用新的值作为会话的唯一标识; 如果该站点在不同的浏览器窗口中同时做这件事情,两个会话使用的唯一标识可能是相同的,这可能引发灾难性后果。


document . lastModified

Document/lastModified

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

根据服务器的报告返回文档的(用户的本地时区的)最后修改时间,按照这样的格式:"MM/DD/YYYY hh:mm:ss"。

如果不知道最后修改时间,返回当前时间。

当读取 lastModified 属性时, 必须返回 Document 的源文件的最后修改(在用户本地时区的)日期和时间,按照下列格式:

  1. 日期的月。
  2. 一个 U+002F SOLIDUS 字符 (/)。
  3. 日期的日。
  4. 一个 U+002F SOLIDUS 字符 (/)。
  5. 日期的年。
  6. 一个 U+0020 SPACE 字符。
  7. 时间的小时部分。
  8. 一个 U+003A COLON 字符 (:)。
  9. 时间的分钟部分。
  10. 一个 U+003A COLON 字符 (:)。
  11. 时间的秒部分。

上述除了年之外的所有数字数字组件必须以两位 ASCII 数字 的形式给出, 表示十进制数,必要时需要补零。年必须按照最短可能的字符串给出,可能是 4 个或更多的 ASCII 数字,表示十进制数,必要时需要补零。

Document 的源文件的最后修改日期和时间必须从使用的网络协议的相关特性中获取。 比如文档的 HTTP Last-Modified 头部,或者(对于本地文件)文件系统中的元数据。 如果不知道最后修改日期和时间,该属性必须按照上述格式返回当前日期和时间。


document . readyState

Document 正在加载时返回 "loading", 一旦结束解析但仍在加载子资源时返回 "interactive", 一旦加载完成返回 "complete"。

当这个值变化时触发 Document 对象上的 readystatechange 事件。

Document/readyState

Support in all current engines.

Firefox3.6+Safari1+Chrome1+
Opera11+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android11+

每个文档有一个 当前文档就绪状态。 创建 Document 对象时, 如果文档有关联的 HTML 解析器XML 解析器,或 XSLT 处理器, 必须将 当前文档就绪状态 设置为字符串 "loading"; 否则必须将 当前文档就绪状态 设置为字符串 "complete"。 在页面加载过程中很多算法都会影响这个值。当这个值被设置时用户代理必须 在 Document 对象上 触发 一个名为 readystatechange 的事件。

如果文档有关联的 HTML 解析器XML 解析器, 且该解析器还没有 停止中止, 那么就称该 Document 有一个 活动的解析器

当读取时,readyState IDL 属性必须返回 当前文档就绪状态

3.1.4 DOM 树访问器

如果文档是一个 html 元素, 它的 html 元素 就是它的 文档元素, 否则就是 null。


document . head

Document/head

Support in all current engines.

Firefox4+Safari5+Chrome4+
Opera11+Edge79+
Edge (Legacy)12+Internet Explorer9+
Firefox Android4+Safari iOS4+Chrome AndroidYesWebView Android37+Samsung InternetYesOpera AndroidYes

返回 head 元素

文档的 head 元素 是它的 html 元素 的第一个 head 子元素。 如果没有这样的元素,则为 null。

当读取 head 属性时,必须返回 文档的 head 元素(一个 head 元素或 null)。


document . title [ = value ]

返回文档的标题,对于 HTML 由 title 元素 给出, 对于 SVG 由 SVG title 元素给出。

可以被设置来更新文档的标题。如果没有合适的元素来更新,新的值将被忽略。

文档的 title 元素 是文档中的第一个 title 元素(按 树序), 如果没有则为 null。

Document/title

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

当读取时,title 属性必须执行以下算法:

  1. 如果 文档元素 是一个 SVG svg 元素, 那么令 value文档元素 的第一个子 SVG title 元素的 子文本内容

  2. 否则,令 valuetitle 元素子文本内容, 如果 title 元素 是 null 则令 value 为空字符串。

  3. 移除 value 前后和多余的 ASCII 空白

  4. 返回 value

当设置时,必须执行匹配下列第一个条件的对应步骤:

如果 文档元素 是一个 SVG svg 元素
  1. 如果 文档元素 有一个 SVG title 子元素, 令 element 为第一个该元素。

  2. 否则:

    1. element 为给定 文档元素节点文档titleSVG 命名空间 创建一个元素 的结果。

    2. element 作为 第一个子元素 插入到 文档元素 中。

  3. 如同 elementtextContent IDL 属性设置为正在分配的新值一样表现。

如果 文档元素HTML 命名空间
  1. 如果 title 元素 为 null 且 the head 元素 为 null,则中止这些步骤。

  2. 如果 title 元素 不是 null,令 element 为该 title 元素

  3. 否则:

    1. element 为给定 文档元素节点文档titleHTML 命名空间 创建一个元素 的结果。

    2. element 追加head 元素 中。

  4. 如同 elementtextContent IDL 属性设置为正在分配的新值一样表现。

否则

什么都不做。


document . body [ = value ]

Document/body

Support in all current engines.

Firefox60+Safari1+Chrome1+
Opera9.6+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android60+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

返回 body 元素

被设置时替换 body 元素

如果新值不是一个 bodyframeset 元素,这将会抛出一个 "HierarchyRequestError" DOMException

文档的 body 元素html 元素 的第一个是 body 元素或 frameset 元素的子节点,没有的话就是 null。

读取 body 属性时,必须返回 文档的 body 元素(是一个 bodyframeset 元素,或者是 null)。 当设置时,必须执行以下算法:

  1. 如果新值不是一个 bodyframeset 元素则抛出一个 "HierarchyRequestError" DOMException 并中止这些步骤。
  2. 否则,如果新值与 body 元素 相同,什么都不做并中止这些步骤。
  3. 否则, 如果 body 元素 不是 null,就在 body 元素 的父元素中,把 body 元素 替换 为新值并中止这些步骤。
  4. 否则, 如果不存在 文档元素,就抛出一个 "HierarchyRequestError" DOMException 并中止这些步骤.
  5. 否则, body 元素 是 null, 但有一个 文档元素,就把新值 追加文档元素 上。

document . images

Document/images

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

返回一个 Document 中的 img 元素的 HTMLCollection

document . embeds

Document/embeds

Support in all current engines.

Firefox1+Safari10.1+Chrome64+
Opera51+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS10.3+Chrome Android64+WebView Android64+Samsung Internet9.0+Opera Android47+
document . plugins

Document/plugins

Support in all current engines.

Firefox1+Safari10.1+Chrome64+
Opera51+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS10.3+Chrome Android64+WebView Android64+Samsung Internet9.0+Opera Android47+

返回一个 Document 中的 embed 元素的 HTMLCollection

document . links

Document/links

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

返回一个 Document 中的有 href 属性的 aarea 元素的 HTMLCollection

document . forms

Document/forms

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

返回一个 Document 中的 form 元素的 HTMLCollection

document . scripts

Document/scripts

Support in all current engines.

Firefox9+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android9+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

返回一个 Document 中的 script 元素的 HTMLCollection

images 属性必须返回一个 根为 Document 节点的 HTMLCollection ,其过滤器只匹配 img 元素。

embeds 属性必须返回一个 根为 Document 节点的 HTMLCollection ,其过滤器只匹配 embed 元素。

plugins 属性必须返回 与 embeds 属性返回的相同的对象。

links 属性必须返回一个 根为 Document 节点的 HTMLCollection ,其过滤器只匹配 有 href 属性的 a 元素, 以及有 href 属性的 area 元素。

forms 属性必须返回一个 根为 Document 节点的 HTMLCollection ,其过滤器只匹配 form 元素。

scripts 属性必须返回一个 根为 Document 节点的 HTMLCollection ,其过滤器只匹配 script 元素。


collection = document . getElementsByName(name)

Document/getElementsByName

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera5+Edge79+
Edge (Legacy)12+Internet Explorer5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

返回一个 Document 中的 name 属性值为 nameNodeList

getElementsByName(name) 方法接受一个字符串 name,必须返回一个 活的 NodeList, 包含该文档中 name 属性的值(大小写敏感地地)等于 name 参数 的所有 HTML 元素,按照 树序 排列。 在 Document 对象上再次使用同样的参数调用该方法时,用户代理可以返回之前调用时返回的对象。 其他情况必须返回一个新的 NodeList 对象。


document . currentScript

Document/currentScript

Support in all current engines.

Firefox4+Safari6.1+Chrome29+
Opera16+Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android4+Safari iOS8+Chrome Android29+WebView Android37+Samsung Internet2.0+Opera Android16+

返回正在执行的 script 元素或 SVG script 元素, 只要该元素表示一个 经典的脚本。 对于再次进入的脚本,返回还没结束执行的脚本中最近开始执行的那个。

如果 Document 当前没有在执行 scriptSVG script (例如,因为运行的脚本是一个事件处理器或定时器),如果当前执行的 scriptSVG script 元素表示一个 module script 则返回 null。

读取 currentScript 属性时,必须返回最近设置的值。 创建 Document 时,currentScript 必须初始化为 null。

实现和标准社区已经不再青睐这一 API 因为它会全局暴露 scriptSVG script 元素。 因此它在新的环境中不再可用,比如执行 module scripts 时, 或者在 shadow tree 执行中执行脚本时。我们正在寻求一种解决方案, 在这些环境中识别正在执行的脚本,同时又不让它全局可用。参见 Issue:#1013


Document 接口 支持命名属性。 任何时候 Document 对象 document 支持的属性名 包括 (根据贡献的元素按照树序 排列,忽略后续重复项, 对同一元素从 id 属性来的值排在从 name 属性来的值前面):

为了 确定 Document 的命名属性 name 的值,用户代理返回必须执行以下算法得到的值:

  1. elements在文档树中 rootdocument, 且名为 name命名元素 列表。

    按照定义,至少会有一个这样的元素。

  2. 如果 elements 只有一个元素且该元素为 iframe 元素, 且该 iframe 元素的 嵌套浏览环境 不是 null, 则返回该元素的 嵌套浏览环境WindowProxy 对象。

  3. 否则,如果 elements 只有一个元素,返回该元素。

  4. 否则返回一个根为 Document 节点的 HTMLCollection, 其过滤器只匹配名为 name命名元素

上述算法中名为 name命名元素 包括:

如果 embedobject 元素没有 暴露的 object 祖先, 而且对于 object 元素没有显示它的 后备内容 或没有 objectembed 后代,就说它是 暴露的


Document 接口上的 dir 属性 与 dir 内容属性定义在一起。

3.2 元素

3.2.1 语义

HTML 中的元素、属性和属性值(由本规范)定义有确定的含义(语义)。 例如,ol 元素表示一个有序列表, lang 属性表示内容的语言。

这些定义允许诸如 Web 浏览器或搜索引擎的 HTML 处理器可能在作者不曾考虑过的 各种上下文中呈现和使用文档或应用。

作为一个简单的例子,考虑一个由只考虑了桌面电脑 Web 浏览器的作者编写的 Web 页面:

<!DOCTYPE HTML>
<html lang="en">
 <head>
  <title>My Page</title>
 </head>
 <body>
  <h1>Welcome to my page</h1>
  <p>I like cars and lorries and have a big Jeep!</p>
  <h2>Where I live</h2>
  <p>I live in a small hut on a mountain!</p>
 </body>
</html>

因为 HTML 表达了 含义,而不是呈现,同样的页面也可以用于移动电话的小浏览器而不需要改动页面。 比如在桌面浏览器中标题使用大号字体,但在移动浏览器中可能整页使用同样大小的字体,但标题使用粗体。

这不仅仅是屏幕尺寸的差异:同一页面可以通过基于语音合成的浏览器同样地被盲人使用, 这时就不是在屏幕上显示页面,而是将页面朗读给用户,比如使用耳机。 标题可能不再是大号的文本,语音浏览器可能会对它使用不同的音量或较慢的声音。

带来的好处不止于此。由于浏览器知道页面的哪些部分是标题,它们可以创建文档大纲来使得用户可以快速浏览文档, 使用“跳转到下一个标题”或“跳转到上一个标题”的快捷键。 这些功能在语音浏览器中尤其常见,不然用户可能很难快速浏览页面。

甚至除浏览器之外的软件也可以利用这些信息。 搜索引擎可以使用标题更有效地对页面进行索引,或者从结果中提供到页面子部分的快速链接。 而工具可以使用标题来创建一个目录(实际上这个规范的目录就是这样生成的)。

这个例子集中在标题上,但是相同的原则也适用于 HTML 中的所有语义。

作者不得将元素,属性或属性值用于适当的语义目的之外的其他意图,因为这样做会使软件无法正确处理页面。

例如,以下代表公司网站标题的代码片段是不合规范的, 因为第二行不是子部分的标题,而是副标题(同一部分的下级标题)。

<body>
 <h1>ACME Corporation</h1>
 <h2>The leaders in arbitrary fast delivery since 1920</h2>
 ...

hgroup 元素适用于这些情况:

<body>
 <hgroup>
  <h1>ACME Corporation</h1>
  <h2>The leaders in arbitrary fast delivery since 1920</h2>
 </hgroup>
 ...

下一个例子中的文档类似,也不合规范。尽管语法是正确的, 因为放在单元格中的数据显然不是表格数据,而且误用了 cite 元素:

<!DOCTYPE HTML>
<html lang="en-GB">
 <head> <title> Demonstration </title> </head>
 <body>
  <table>
   <tr> <td> My favourite animal is the cat. </td> </tr>
   <tr>
    <td>
     —<a href="https://example.org/~ernest/"><cite>Ernest</cite></a>,
     in an essay from 1992
    </td>
   </tr>
  </table>
 </body>
</html>

这将使得依赖于这些语义的软件出错: 例如支持盲人浏览文档中的表格的语音浏览器将把上述引用误报为表格,这会使用户困惑; 同样地,从网页中提取作品标题的工具也会将“Ernest”提取为作品的标题,即使它实际上是一个人名而不是标题。

这个文档的更正版本可能是:

<!DOCTYPE HTML>
<html lang="en-GB">
 <head> <title> Demonstration </title> </head>
 <body>
  <blockquote>
   <p> My favourite animal is the cat. </p>
  </blockquote>
  <p>
   —<a href="https://example.org/~ernest/">Ernest</a>,
   in an essay from 1992
  </p>
 </body>
</html>

作者不得使用本规范或 其他适用规范 不允许的元素,属性或属性值,因为这样做会使以后的语言扩展变得更加困难。

下一个示例中有一个不符合规范的属性值(“carpet”)和不符合规范的属性(“texture”),这是本规范不允许的:

<label>Carpet: <input type="carpet" name="c" texture="deep pile"></label>

以下是标记这一内容的正确的替代方式:

<label>Carpet: <input type="text" class="carpet" name="c" data-texture="deep pile"></label>

节点文档 不具有 浏览环境 的 DOM 节点 不受 HTML 语法 要求和 XML 语法 要求之外的所有文档一致性要求的限制。

特别地,template 元素的 模板内容节点文档 没有浏览上下文。 例如,内容模型 要求 和属性值微语法要求不适用于 template 元素的 模板内容。 在此示例中,img 元素的属性值是占位符,如果在 template 元素外就是无效的。

<template>
 <article>
  <img src="{{src}}" alt="{{alt}}">
  <h1></h1>
 </article>
</template>

但是,如果上述标记省略了 </h1> 结束标记,将会违反 HTML 语法,会被符合性检查器标记为错误。

通过脚本和使用其他机制,在用户代理处理文档时,属性值,文本以及文档的整体结构都可能会动态变化。 某一时刻文档的语义由这一时刻的文档的状态来表示,因此文档的语义会随时间变化。 当这种情况发生时,用户代理 must 更新文档的显示。

HTML 有一个表示进度条的 progress 元素。 如果其 “value” 属性由脚本动态地更新,那么 UA 将更新呈现以显示进度变化。

3.2.2 DOM 中的元素

在 DOM 中表示 HTML 元素 的节点 必须 实现本规范相关章节中的对应接口,并暴露给脚本。这包括 XML 文档 中的 HTML 元素, 即使那些文档在另外的上下文中(比如在一个 XSLT 转换中)。

DOM 中的元素 表示着 事物; 也就是说它们具有内在的 意义,也被称为语义。

例如一个 ol 元素表示一个有序列表。

元素可以被显式地或者隐式地 引用。 一种显式地引用 DOM 中元素的方式是给该元素一个 id 属性, 然后创建一个 超链接, 用那个 id 属性值作为该 超链接href 属性值的 片段。其实引用不需要超链接的存在,任何其他引用元素的方式都是足够的。

考虑下面的 figure 元素,给了它一个 id 属性:

<figure id="module-script-graph">
  <img src="module-script-graph.svg"
       alt="Module A depends on module B, which depends
            on modules C and D.">
  <figcaption>Figure 27: a simple module graph</figcaption>
</figure>

可以用 a 元素创建基于 超链接引用,像这样:

As we can see in <a href="#module-script-graph">figure 27</a>, ...

但是也有很多其他 引用 figure 元素的方式,比如:

所有 HTML 元素 的接口都继承自一个基本接口,没有额外要求的元素必须使用这一接口。这就是 HTMLElement 接口。

HTMLElement

Support in all current engines.

Firefox1+Safari1.3+Chrome1+
Opera8+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

HTMLUnknownElement

Support in all current engines.

Firefox1+Safari6+Chrome15+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer9+
Firefox Android4+Safari iOS6+Chrome Android18+WebView Android37+Samsung Internet1.0+Opera Android12.1+
[Exposed=Window,
 HTMLConstructor]
interface HTMLElement : Element {
  // 元数据属性
  [CEReactions] attribute DOMString title;
  [CEReactions] attribute DOMString lang;
  [CEReactions] attribute boolean translate;
  [CEReactions] attribute DOMString dir;
  [SameObject] readonly attribute DOMStringMap dataset;

  // 用户交互
  [CEReactions] attribute boolean hidden;
  void click();
  [CEReactions] attribute long tabIndex;
  void focus(optional FocusOptions options);
  void blur();
  [CEReactions] attribute DOMString accessKey;
  readonly attribute DOMString accessKeyLabel;
  [CEReactions] attribute boolean draggable;
  [CEReactions] attribute boolean spellcheck;
  [CEReactions] attribute DOMString autocapitalize;

  [CEReactions] attribute [TreatNullAs=EmptyString] DOMString innerText;
};

HTMLElement includes GlobalEventHandlers;
HTMLElement includes DocumentAndElementEventHandlers;
HTMLElement includes ElementContentEditable;

// 注意:有意 不是 [HTMLConstructor]
[Exposed=Window]
interface HTMLUnknownElement : HTMLElement { };

HTMLElement 接口保存着很多不同功能的方法和属性,因此该接口的成员在本规范的不同部分中描述。


HTML 命名空间 中名为 name 的元素的 元素接口 这样决定:

  1. 如果 nameappletbgsoundblinkisindexkeygenmulticolnextid, 或 spacer, 则返回 HTMLUnknownElement

  2. 如果 nameacronymbasefontbigcenternobrnoembednoframesplaintextrbrtcstrike,或 tt,则返回 HTMLElement

  3. 如果 namelistingxmp,则返回 HTMLPreElement

  4. 否则,如果本规范定义了一个 local name name 对应的 元素类型 的接口,则返回那个接口。

  5. 如果 其他适用规范name 定义了一个合适的接口, 则返回他们定义的接口。

  6. 如果 name 是一个 合法的 Custom Element 名字, 则返回HTMLElement

  7. 返回 HTMLUnknownElement

合法的 Custom Element 名 时, 使用 HTMLElement 而不是 HTMLUnknownElement 是为了确保任何将来可能的 升级 只造成元素原型链的线性转变, 从 HTMLElement 到一个子类,而不是后者从 HTMLUnknownElement 到一个不相关的子类。

HTML 和 SVG 元素共同的特性使用 HTMLOrSVGElement 接口 mixin: [SVG]

interface mixin HTMLOrSVGElement {
  [SameObject] readonly attribute DOMStringMap dataset;
  attribute DOMString nonce;

  [CEReactions] attribute long tabIndex;
  void focus(optional FocusOptions options);
  void blur();
};
HTMLElement includes HTMLOrSVGElement;
SVGElement includes HTMLOrSVGElement;

3.2.3 HTML 元素构造器

为支持 Custom Element 特性, 所有 HTML 元素都有特定的构造器行为。该行为 [HTMLConstructor] IDL 扩展属性 表示。 它指示着给定接口的接口对象将在调用时具有特定的行为,如下所述:

[HTMLConstructor] 扩展属性必须接受无参数, 不得出现在非接口的对象上。它在接口上必须只出现一次,且该接口不得以 [Constructor][NoInterfaceObject] 扩展属性标注。(但是该接口可以用 [NamedConstructor] 标注,这里没有冲突。)它不得作为回调接口使用。

[HTMLConstructor] 扩展属性标注的接口的 接口对象 必须作为相应 JavaScript 函数对象的 [[Call]] 和 [[Construct]] 调用的函数体行为运行以下步骤。从 [[Call]] 调用时,NewTarget 值未定义,因此下面的算法将立即抛出异常。 从 [[Construct]] 调用时,[[Construct]] 的 newTarget 参数提供了 NewTarget 值。

  1. registry当前全局对象CustomElementRegistry 对象。

  2. 如果 NewTarget 等于 活动的函数对象,则抛出一个 TypeError 并中止这些步骤。

    这在使用 元素接口 作为构造器定义 Custom Element 时可能发生:

    customElements.define("bad-1",HTMLButtonElement);
    new HTMLButtonElement();          // (1)
    document.createElement("bad-1");  // (2)

    在这种情形下,HTMLButtonElement(可能是显式地,比如 1,也可能是隐式地,比如 2)的执行期间, 活动的函数对象 和 NewTarget 都是 HTMLButtonElement。 如果没有这项检查,就可能会创建一个 local name 是 bad-1HTMLButtonElement 实例。

  3. definitionregistryconstructor 等于 NewTarget 的条目。 如果没有这样一个定义,则抛出一个 TypeError 并中止这些步骤。

    由于 registry 中没有 constructor 是 undefined 的条目, 这一步可以防止 HTML 元素构造器作为函数被调用(在该情况下 NewTarget 将是 undefined)。

  4. 如果 definitionlocal name 等于 definitionname (即 definition 是一个 自主的 Custom Element),则:

    1. 如果 活动的函数对象 不是 HTMLElement,则抛出一个 TypeError 并中止这些步骤。

      当 Custom Element 定义时没有扩展任何 local name 但继承了非 HTMLElement 类时就会发生这种情况:

      customElements.define("bad-2",class Bad2 extends HTMLParagraphElement {});

      这种情形下,在(隐含地)在创建 Bad2 实例的 super() 调用期间, 活动的函数对象HTMLParagraphElement 而不是 HTMLElement

  5. 否则(如果 definition 是一个 定制的内建元素):

    1. valid local name 为本规范 或 其他适用规范 中定义的 使用 活动的函数对象 作为 元素接口 的元素的 local name 列表。

    2. 如果 valid local names 不包含 definitionlocal name,则抛出一个 TypeError 并中止这些步骤。

      这在定义扩展了给定 local name 但继承了错误的类的 Custom Element 时会发生:

      customElements.define("bad-3",class Bad3 extends HTMLQuoteElement {},{ extends: "p" });

      这种情形下,在(隐含地)在创建 Bad3 实例的 super() 调用期间, valid local names 列表包含 qblockquote,但 definitionlocal namep,不在这个列表中。

  6. prototypeGet(NewTarget,"prototype")。 重新抛出任何异常。

  7. 如果 Type(prototype) 不是 Object,则:

    1. realmGetFunctionRealm(NewTarget)。

    2. 设置 prototyperealm 中 接口与 活动函数对象 的接口相同的 的 接口原型对象

    活动函数对象 的 realm 可能不是 realm,所以我们用更通用的概念 "Realms 中同样的接口" 而不寻找 相等的 接口对象。设计这个退化行为是为了匹配 JavaScript 内建对象的类似行为, 包括使用 NewTarget 的 Realm 以及在那里查找合适的原型。

  8. 如果 definition构造栈 为空,则:

    1. element 为实现了 活动函数对象 对应接口的新元素, 没有属性,命名空间设为 HTML 命名空间,local name 设为 definitionlocal name节点文档 设为 当前全局对象关联 Document

    2. 执行 element.[[SetPrototypeOf]](prototype)。重新抛出任何异常。

    3. 设置 elementCustom Element 状态 为 "custom"。

    4. 设置 elementCustom Element 定义definition

    5. 返回 element

    当作者脚本直接构建了一个新的 Custom Element 时(例如通过 new MyCustomElement()),就会发生这种情况。

  9. elementdefinition构造栈 中的最后一个条目。

  10. 如果 element 是一个 已经构造 标记, 则抛出一个 "InvalidStateError" DOMException 并中止这些步骤。

    Custom Element 构造器 中的作者代码 在调用 super() 之前 不合规范地 创建了 正在创建的类的另一个实例时,就会发生这种情况:

    let doSillyThing = false;
    
    class DontDoThis extends HTMLElement {
      constructor() {
        if (doSillyThing) {
          doSillyThing = false;
          new DontDoThis();
          // 现在构造栈将会包含一个 已经构造 标记。
        }
    
        // 这将会失败并抛出 "InvalidStateError" DOMException:
        super();
      }
    }

    Custom Element 构造器 中的作者代码 不合规范地 调用两次 super() 时也会发生。 因为根据 JavaScript 规范,这确实会在抛出异常前执行两次父类构造器(即当前这个算法):

    class DontDoThisEither extends HTMLElement {
      constructor() {
        super();
    
        // 这将会抛出异常,但这时已经调用进入了 HTMLElement 构造器
        super();
      }
    }
  11. 执行 element.[[SetPrototypeOf]](prototype)。重新抛出任何异常。

  12. definition构造栈 中的最后一个条目替换为一个 已经构造 标记

  13. 返回 element

    升级 Custom Element 时就会自然地进入这一步, 返回现有元素,以便 Custom Element 构造器 中的 super() 调用将该现有元素赋值给 this


除了 [HTMLConstructor] 隐含的构造器行为之外, 有些元素还有 命名的构造器(其实是改过 prototype 属性的工厂函数)。

当定义 Custom Element 构造器 时, HTML 元素的命名构造器也可以用于 extends 子句中:

class AutoEmbiggenedImage extends Image {
  constructor(width,height) {
    super(width * 10,height * 10);
  }
}

customElements.define("auto-embiggened",AutoEmbiggenedImage,{ extends: "img" });

const image = new AutoEmbiggenedImage(15,20);
console.assert(image.width === 150);
console.assert(image.height === 200);

3.2.4 元素定义

在本规范中的每个元素都有一个定义,包含以下信息:

类别

该元素所属的 类别 列表。 在为每个元素定义 内容模型 时用到。

可以使用该元素的上下文

该元素可以在哪里使用的 非规范化的 描述。 该信息与允许该元素为子元素的元素内容模型之间存在冗余,只是为了方便而提供。

为了简单起见,只列出最具体的元素规则。

例如,所有 短语内容 都是 流内容。 因此 短语内容 元素只会列在 "需要是 短语内容 的地方", 因为这样更具体。任何需要 流式内容 的地方也可以用 短语内容, 因为它也符合规则。

内容模型

必须包含哪些内容作为子元素和后代元素的规范性描述。

text/html 中的标签省略

非规范性的 描述:在 text/html 语法中, 是否可以忽略 开始结束 标签。 该信息与 可选标签 部分给出的规范性要求之间存在冗余, 在元素定义中提供只是为了方便。

内容属性

可以在该元素上指定的(除了不允许的情况)一个规范性的属性列表, 以及对这些属性的非规范性的描述。(破折号左侧是规范性的,右侧是非规范性的。)

可访问性考虑

对于使用方:遵循 ARIA in HTML 定义的 ARIA rolearia-* 属性的要求。 [ARIA] [ARIAHTML]

对于实现方:用户代理实现可访问性 API 语义的要求定义在 HTML Accessibility API Mappings[HTMLAAM]

DOM 接口

一个关于这样的元素必须实现的 DOM 接口的规范性的定义。

之后是更多的描述:元素所 代表 的内容, 以及可能适用于作者 和实现 的任何其他规范性的一致性标准,有时也包括实例。

3.2.4.1 属性

一个属性值是一个字符串。 除非另有说明,HTML 元素 上的属性值可以是任何字符串值, 包括空字符串,而且对这些属性值中可以指定的文本没有任何限制。

3.2.5 内容模型

本标准中定义的每个元素都有内容模型:描述了元素期望的 内容HTML 元素 的内容必须匹配元素内容模型的要求。 元素的 内容 是它在 DOM 中的子节点。

元素之间总是允许 ASCII 空白。用户代理将源码标记中元素之间的字符表示为 DOM 中的 Text 节点。 空的 Text 节点和 只包含那些字符序列的 Text 节点都被认为是 元素间空白

当决定元素内容是否匹配元素内容模型的要求时必须忽略 元素间空白, 注释节点,以及处理指令节点。 在执行定义文档和元素语义的算法时也必须忽略这些节点。

因此,元素 A 与元素 B 相邻 是指 AB 有相同的父节点且它们之间没有元素节点或 Text 节点 (元素间空白 除外)。 类似地,元素的 唯一子节点 是指其父元素只包含 元素箭空白, 注释节点,以及处理指令节点。

作者不得随意使用 HTML 元素,除非明确允许(每个元素都有定义), 或其他规范有明确要求。对于 XML 复合文档,如果这些元素定义为提供相关上下文,那么这些上下文可以位于其他命名空间的元素之内。

例如 Atom 规范定义了一个 content 元素。当它的 type 属性值为 xhtml 时,Atom 规范要求它包含单个 HTML div 元素。因此该上下文中允许出现一个a div 元素,虽然本规范没有明确地声明这一点。[ATOM]

此外,HTML 元素 可能是孤立节点(即没有父节点)。

例如创建一个 td 元素并把它存储为脚本中的全局变量是符合规范的,即使 td 元素只期望用于 tr 元素中。

var data = {
  name: "Banana",
  cell: document.createElement('td'),
};
3.2.5.1 "nothing" 内容模型

当元素的内容模型是 nothing 时, 该元素不得包含 Text 节点(元素间空白 除外) 和元素节点。

方便起见,多数内容模型为 “nothing” 的 HTML 元素同时也是 void 元素HTML 语法 中没有 结束标签 的元素)。 但是,这些是完全独立的概念。

3.2.5.2 内容的种类

HTML 中的每个元素都属于一个或多个 类别 一个类别中的元素有着相似的特点。本规范使用以下几个大类:

有些元素属于其他类别,这些类别定义在本规范的其他部分。

这些类别之间的关系如下:

章节内容,标题内容,短语内容,嵌入内容和交互式内容都是流式内容。元数据有时也是流式内容。 元数据和交互式内容有时是短语内容。嵌入内容也是短语内容,有时也是交互式内容。

有时为了特定意图也会使用其他的类别,比如为了定义通用要求,为表单控件指定了多种类别。 有些元素有独特的要求,不属于任何特定类别。

3.2.5.2.1 元数据内容

元数据内容 是设置其余内容的呈现或行为, 设置文档与其他文档的关系,传达其他“带外”信息的内容。

其语义主要与元数据相关的其他命名空间的元素(比如 RDF) 也是 元数据内容

因此在 XML 序列化中,可以像这样使用 RDF:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xml:lang="en">
 <head>
  <title>Hedral's Home Page</title>
  <r:RDF>
   <Person xmlns="http://www.w3.org/2000/10/swap/pim/contact#"
           r:about="https://hedral.example.com/#">
    <fullName>Cat Hedral</fullName>
    <mailbox r:resource="mailto:hedral@damowmow.com"/>
    <personalTitle>Sir</personalTitle>
   </Person>
  </r:RDF>
 </head>
 <body>
  <h1>My home page</h1>
  <p>I like playing with string, I guess. Sister says squirrels are fun
  too so sometimes I follow her to play with them.</p>
 </body>
</html>

然而,这在 HTML 序列化中是不可能的。

3.2.5.2.2 流式内容

多数文档和应用的 body 中的元素都归类为 流式内容

3.2.5.2.3 章节内容

章节内容 是定义了 标题页脚 范围的内容。

每个 章节内容 元素可能具有标题和 大纲。 有关详细信息请参阅 标题和章节

有些元素属于 章节根元素。 它们与 章节内容 不同,但也可以有 大纲

3.2.5.2.4 标题内容

标题内容 定义了章节的标题 (可以显式地用 章节内容 元素标记, 也可以隐式地用标题内容自己来标记)。

3.2.5.2.5 短语内容

短语内容 是文档中的文本, 以及标记该文本的段内级别的元素。 多个 短语内容 形成 段落

多数短语内容元素只能包含短语内容元素,而不是任何流式内容元素。

内容模型中的 文本内容 意味着什么都没有, 或者有 Text 节点。有时 文本内容 自身就是 一种内容模型,但它也是 短语内容, 也可以是 元素间空白 (如果 Text 节点为空或者只包含 ASCII 空白)。

Text 节点和属性值必须由 标量值 组成,不包含 非字符, 以及除 ASCII 空白 之外的 控制字符。 本规范对 Text 节点的值和属性的值,基于其确切的上下文会有额外的约束。

3.2.5.2.6 嵌入内容

嵌入内容 是指 引入其他资源的内容,或插入到文档的其他词汇表的内容。

来自除 HTML 命名空间 之外的,表达内容而不是元数据的元素, 是 嵌入内容,用于本规范定义的内容模型 (例如 MathML 或 SVG。)

有些嵌入内容元素可以包含 fallback 内容: 在不能使用外部资源时使用的内容(例如,因为它是不受支持的格式)。 如果有 fallback 内容的话,元素定义会加以说明。

3.2.5.2.7 交互式内容

交互式内容 是专门用于用户交互的内容。

tabindex 属性也可以让任何元素变成 交互式内容

3.2.5.2.8 可感知内容

作为一般规则,其内容模型允许任何 流式内容短语内容 的元素应在其 内容 中至少包含一个 可感知内容 的节点,并且它没有指定 hidden 属性。

可感知内容 通过提供一些非空的后代 文本, 可以听到(audio 元素)或看到(videoimgcanvas 元素), 或可以与之交互的内容(例如可交互的表单控件)来让一个元素变得非空。

但这个要求并不是一个硬性要求,因为有许多情况下空元素是合理的,比如当它被用作一个占位符之后用脚本填充, 或者对于模板元素,大多数页面都会填充,只有某些页面表现为空白,这也无关紧要。

推荐一致性检查工具为作者提供工具,来定位不遵守该要求的元素,帮助作者的代码编写。

下列元素是可感知内容:

3.2.5.2.9 脚本支持元素

脚本支持元素 是指那些本身不 表示 任何东西(即它们不被渲染),但是被用于支持脚本, 为用户提供功能。

下列元素是脚本支持元素:

3.2.5.3 透明内容模型

有些元素被描述为 透明的;它们的内容模型描述中有 "透明" 一词。 透明 元素的内容模型从其父元素的内容模型派生: “透明”的内容模型中某一部分所要求的元素与父元素的内容模型中对应部分所要求的元素相同。

例如,ruby 元素中的 ins 元素不可包含 rt 元素, 因为 ruby 元素的内容模型中允许 ins 元素的部分就是允许 短语内容 的那一部分, rt 元素不是 短语内容

在有些情况下,透明元素互相嵌套时,必须迭代地应用这个过程。

考虑下面的标记片段:

<p><object><param><ins><map><a href="/">Apples</a></map></ins></object></p>

为了检查 a 元素中是否允许 "Apples",要检查内容模型。 a 元素的内容模型是透明的,map 元素也是, ins 元素也是,object 元素中 ins 元素所在的部分也是。 object 元素位于 p 元素中,后者的内容模型是 短语内容。 因此 "Apples" 是允许的,因为文本是短语内容。

当透明元素秘佑父元素时,它的内容模型中透明的那一部分必须被当做可以接受任何 流式内容

3.2.5.4 段落

本小节定义的术语 段落 的用途不止是 p 元素的定义。这里定义的 段落 概念用于描述如何解释文档。 p 元素仅仅是标记 段落 的一种方式。

一个 段落 通常是由一系列 短语内容 形成的一个文本块, 在排版中可能包含一个或多个句子,讨论一个特定的主题(也可以用于更一般的专题分组)。 例如,一个地址也可以是一个段落,可以是表单的一部分,一行署名,或者一首诗中的一节。

下面的例子中,一个章节中有两段话。还有一个标题,它包含的短语内容不构成段落。 注意注释和 元素间空白 也不构成段落。

<section>
  <h1>Example of paragraphs</h1>
  This is the <em>first</em> paragraph in this example.
  <p>This is the second.</p>
  <!-- This is not a paragraph. -->
</section>

流式内容 中的段落相对于文档的样子来定义,与 ainsdel,和 map 元素造成的复杂情况无关。 因为那些元素的混合内容模型使它们可以跨越段落边界,就像下面两个例子那样。

通常来讲,最好避免让元素跨越段落边界。这样的标记很难维护。

下面的例子取自前一个例子中的标记,在某些标记处加入了 insdel 元素, 用来展示文本的变更(尽管这种情况下,这一变更确实没啥意义)。注意这个例子中的段落与上一个例子完全相同, 尽管插入了 insdel 元素 — ins 元素跨越了标题和第一个段落, del 元素跨越了两个段落的边界。

<section>
  <ins><h1>Example of paragraphs</h1>
  This is the <em>first</em> paragraph in</ins> this example<del>.
  <p>This is the second.</p></del>
  <!-- This is not a paragraph. -->
</section>

view 为 DOM 的一个视图,将文档中所有的 a, ins, del, 和 map 元素替换为它们的 内容。然后对 view 中除了接受 短语内容 还接受非 短语内容 的元素中的每一个没有被其他类型内容打断的 短语内容 节点序列, 令 first 为序列中第一个节点,令 last 为序列中最后一个节点。 对每一个上述序列中,包含至少一个非 嵌入内容元素间空白 节点的序列,在原始 DOM 中从 first 前面到 last 后面形成了一个段落。(因此段落可以横跨 a, ins, del, 和 map 元素。)

一致性检查器可以在段落相互重叠时警告作者( 在 object, video, audio, 和 canvas 元素中有可能发生这种情况, 允许再次嵌入 HTML 的其他命名空间的元素也可能间接地发生这种情况,比如 SVG svgMathML math)。

p 元素也显式地生成了 段落

p 元素可以用于包裹普通的短语内容来形成相互独立的段落。

在下面的例子中,链接横跨了半个第一个段落,分离两个段落的标题,以及半个第二个段落。它同时横跨了段落和标题。

<header>
 Welcome!
 <a href="about.html">
  This is home of...
  <h1>The Falcons!</h1>
  The Lockheed Martin multirole jet fighter aircraft!
 </a>
 This page discusses the F-16 Fighting Falcon's innermost secrets.
</header>

这是上述标记的另一种写法,这次显式地声明了段落,将一个链接分割成三部分:

<header>
 <p>Welcome! <a href="about.html">This is home of...</a></p>
 <h1><a href="about.html">The Falcons!</a></h1>
 <p><a href="about.html">The Lockheed Martin multirole jet
 fighter aircraft!</a> This page discusses the F-16 Fighting
 Falcon's innermost secrets.</p>
</header>

当使用某些元素来定义 fallback 内容时,段落可以重叠。例如下面的章节:

<section>
 <h1>My Cats</h1>
 You can play with my cat simulator.
 <object data="cats.sim">
  To see the cat simulator, use one of the following links:
  <ul>
   <li><a href="cats.sim">Download simulator file</a>
   <li><a href="https://sims.example.com/watch?v=LYds5xY4INU">Use online simulator</a>
  </ul>
  Alternatively, upgrade to the Mellblom Browser.
 </object>
 I'm quite proud of it.
</section>

共有5个段落:

  1. 第一段说:"You can play with my cat simulator. object I'm quite proud of it.",其中 objectobject 元素。
  2. 第二段说:"To see the cat simulator, use one of the following links:"。
  3. 第三段说:"Download simulator file"。
  4. 第四段说:"Use online simulator"。
  5. 第五段说:"Alternatively, upgrade to the Mellblom Browser."。

第一个段落与后面4个重叠。支持 "cats.sim" 资源的用户代理只会显示第一个段落,但显示 fallback 的用户代理就会 将第一个段落的第一句话与第二段显示为一个段落,最后一个段落会显示在第一个段落的第二个句子之前。

为避免困惑,可以显式地使用 p 元素。例如:

<section>
 <h1>My Cats</h1>
 <p>You can play with my cat simulator.</p>
 <object data="cats.sim">
  <p>To see the cat simulator, use one of the following links:</p>
  <ul>
   <li><a href="cats.sim">Download simulator file</a>
   <li><a href="https://sims.example.com/watch?v=LYds5xY4INU">Use online simulator</a>
  </ul>
  <p>Alternatively, upgrade to the Mellblom Browser.</p>
 </object>
 <p>I'm quite proud of it.</p>
</section>

3.2.6 全局属性

下列属性是通用的,所有 HTML 元素 都可以指定。 (即使是本规范中没有定义的那些元素):

本规范定义的这些属性只用于 HTML 元素 的属性。 当本规范引用具有这些属性的元素时, 没有定义这些属性的命名空间下的元素不得当作具有这些属性的元素处理。

例如,在下面的 XML 片段中,根据本标准的定义 "bogus" 元素没有 dir 属性,尽管它字面上有一个名为 "dir" 的属性。因此,最里面的 span 元素的 方向 是 'rtl', 通过 "bogus" 元素间接地继承自 div 元素。

<div xmlns="http://www.w3.org/1999/xhtml" dir="rtl">
 <bogus xmlns="https://example.net/ns" dir="ltr">
  <span xmlns="http://www.w3.org/1999/xhtml">
  </span>
 </bogus>
</div>

Global_attributes/slot

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera40+Edge79+
Edge (Legacy)NoInternet Explorer?
Firefox Android63+Safari iOS10+Chrome Android53+WebView Android53+Samsung Internet6.0+Opera Android41+

WHATWG DOM 标准为任何命名空间下的任何元素的 classid,和 slot 属性定义了用户代理的要求。[DOM]

classid,和 slot 属性可以在任何 HTML 元素 上指定。

HTML 元素 上指定了 class 属性时,该属性的值必须是 一组空格分隔的令牌, 表示该元素所属的各种类。

设置元素的类会影响 CSS 选择符的匹配,DOM 的 getElementsByClassName() 方法, 以及其他这类特性。

作者在 class 属性中可以使用的令牌没有额外的限制, 但鼓励作者使用描述内容本质的取值,而不是描述内容表示的取值。

HTML 元素 上指定了 id 属性时, 该属性的值必须在该元素所在的 的所有 IDs 中是唯一的, 必须至少包含一个字符,且不得包含任何 ASCII 空白

id 属性指定了该元素的 唯一标识符(ID)

对 ID 的形式没有其他限制;ID 甚至可以只包含数字,以数字起始,以下划线起始,或者只包含标点等等。

元素的 唯一标识符 有很多用途, 最值得一提的是通过 URL 片段 链接到文档的特定部分, 在脚本中指向元素的一种方式,以及从 CSS 中指定特定元素的样式。

标识符是不透明的字符串。不得通过 id 属性的值来推断特定的含义。

HTML 元素slot 属性没有符合性要求。

slot 属性用于为元素 设置一个槽:具有 slot 属性的元素会被 指定到 name 属性值匹配该 slot 属性值的 slot 元素创建的 slot 中。 — 但条件是 slot 元素所在的 shadow treeroothost 有相应的 slot 属性值。


为了使辅助技术产品提供相比于 HTML 元素和属性更加细粒度的界面,有一组 用于辅助技术产品的注解 可以指定 (ARIA rolearia-* 属性)。[ARIA]


下面的 事件处理器内容属性 可以在任何 HTML 元素 上指定:

用星号标记的属性在用于 body 元素时有不同的含义, 因为该元素暴露了 Window 对象上同名的 事件处理器

虽然这些属性适用于所有元素,但并不是对所有元素都有用。 例如,只有 媒体元素 才会接收到用户代理触发的 音量变化 事件。


任何 HTML 元素 都可以指定 自定义数据属性 (例如 data-foldernamedata-msgid), 用于存储页面相关的自定义数据,状态,注解这样的东西。


HTML 文档 中,HTML 命名空间 中的元素可以指定一个 xmlns 属性,但它的值只能是 "http://www.w3.org/1999/xhtml" 。这不适用于 XML 文档

在 HTML 中,xmlns 属性完全没有效果,它只是一个标志。 它的存在只是为了方便 XML 与 HTML 之间的迁移。 被 HTML 解析器 解析时,该属性的结果是没有命名空间, 而不是像 XML 中的命名空间声明那样,解析为 "http://www.w3.org/2000/xmlns/" 命名空间。

在 XML 中,xmlns 属性是命名空间机制的一部分, 没有指定命名空间时,元素不能有 xmlns 属性。


XML 文档 中的任何元素上,XML 也遵循 XML 命名空间 中的 xml:space 属性的使用。 该属性在 HTML 元素 上没有作用,因为 HTML 的默认行为就是保留空白。 [XML]

text/html 语法中,无法序列化 HTML 元素xml:space 属性。

3.2.6.1 title 属性

title 属性 表示 元素的建议信息,比如适用于工具提示。 在链接上,这可能是目标资源的标题或描述;在图片上,它可以是图片来源或图片的描述; 在段落上,它可能是文本的脚注或评论;在引用上,可以是来源的进一步信息; 在 交互式内容 上,它可能是元素的标签或使用说明; 等等。值为文本。

目前不鼓励依赖于 title 属性, 因为许多用户代理不按照本规范中要求的可访问的方式来暴露该属性 (例如,要求像鼠标这样的定点设备来触发工具提示,这排除了纯键盘用户和触摸设备用户,比如手机或平板电脑的用户)。

如果从元素中省略此属性,则默认关联到离该元素最近的设置了 title 属性的 祖先 HTML 元素。 设置该属性可以覆盖这一行为,显式地声明了任何祖先的建议信息与此元素无关。 将属性设置为空字符串表示该元素没有建议信息。

如果 title 属性值包含 U+000A LINE FEED (LF)字符, 其内容将被分割为多行。每个 U+000A LINE FEED (LF) 字符表示一个换行。

title 属性中使用换行要多加小心。

比如下面的代码片段其实定义了一个缩写的解释,其中包含一个换行

<p>My logs show that there was some interest in <abbr title="Hypertext
Transport Protocol">HTTP</abbr> today.</p>

有些元素比如 linkabbr,和 inputtitle 属性定义了额外的语义。

元素的 建议信息 是下面算法的返回值, 只要有值返回算法就中止。当该算法返回空字符串时,没有任何建议信息。

  1. 如果该元素是一个 linkstyledfn,或 abbr 元素,那么:如果该元素有 title 属性, 返回该属性的值,否则返回空字符串。

  2. 否则,如果该元素有一个 title 属性则返回它的值。

  3. 否则,如果该属性有父元素,则返回父元素的 建议信息

  4. 否则,返回空字符串。

当元素有 建议信息 时, 用户代理应该通知用户,不然就无法发现该信息。


HTMLElement/title

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android12.1+

title IDL 属性必须 反映 title 内容属性。

3.2.6.2 langxml:lang 属性

Global_attributes/lang

Support in all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)12+Internet ExplorerYes
Firefox AndroidYesSafari iOSYesChrome AndroidYesWebView AndroidYesSamsung InternetYesOpera AndroidYes

lang 属性(没有命名空间)指定了该元素内容, 以及该元素包含文本的属性的主要语言。它的值必须是一个合法的 BCP 47 语言标签, 或者空字符串。将该属性设置为控制付出表示主要语言是未知的。 [BCP47]

XML 命名空间 中的 lang 属性 定义在 XML 中。 [XML]

如果元素省略了这些属性,该元素的语言就是其父元素的语言(如果有的话)。

没有命名空间的 lang 属性可以用于任何 HTML 元素

XML 命名空间 中的 lang 属性 可以用于 XML 文档 中的 HTML 元素, 也可以用户其他命名空间中的元素,只要相关规范允许(特别低, MathML 和 SVG 允许其元素上指定 XML 命名空间 中的lang 属性 )。如果同时在同一个元素上指定了 无命名空间的 lang 属性,和 XML 命名空间 中的 lang 属性, 它们必须有 ASCII 大小写不敏感的 同样的值。

作者不得在 HTML 文档 中的 HTML 元素 上使用 XML 命名空间 中的 lang 属性。 为了便于与 XML 之间迁移,作者可以在 HTML 文档 中的 HTML 元素 上 指定一个没有命名空间的,没有前缀的属性,其 localname 为 "xml:lang", 但指定该属性时必须同时指定一个无命名空间的 lang 属性, 它们必须有 ASCII 大小写不敏感的 同样的值。

没有命名空间没有前缀的 localname 是 "xml:lang" 的属性对语言处理没有任何影响。


确定节点的 language,用户代理必须寻找设置了 XML 命名空间 中的 lang 属性 或无命名空间的 lang 属性的, 最近的祖先元素(包括该元素自身,如果该节点是元素的话)。 该属性指定了节点的语言(不管它的值是什么)。

如果同时在同一个元素上指定了 无命名空间的 lang 属性,和 XML 命名空间 中的 lang 属性, 在确定元素的语言时,用户代理必须使用 XML 命名空间 中的 lang 属性, 必须 忽略 无命名空间的 lang 属性。

如果节点的 包括自身在内的祖先 两个属性都没设置, 但是设置了一个 编译指示的默认语言,那么这就是该节点的语言。 如果没有设置 编译指示的默认语言, 那么必须使用上级协议(比如 HTTP)的语言信息(如果有的话)作为最终的 fallback 语言。 如果没有该语言信息,或者上级协议报告了多种语言,该节点的语言就是未知的,对应的语言标签是空字符串。

如果结果值不是可识别的的语言标签,那么它必须被视为具有给定语言标签的未知语言,区别于所有其他语言。 为了与预期该语言标签的其他服务进行往返或通信,用户代理应通过未修改的方式传递未知语言标签, 并将其标记为 BCP 47 语言标签,以防后续服务将数据解释为另一种语言描述。 [BCP47]

因此,例如具有 lang="xyzzy" 的元素将被选择器 :lang(xyzzy) 匹配(例如在 CSS 中), 但是它不会被 :lang(abcde) 匹配,虽然两者都是无效的。 类似地,如果要 Web 浏览器和屏幕阅读器一致地传达关于元素的语言, 则浏览器将告诉屏幕阅读器该语言是 “xyzzy”,即使它知道这个语言是无效的, 以防屏幕阅读器实际上支持该标签的语言。即使屏幕阅读器支持 BCP 47 和用于编码语言名称的另一语法, 比如在这一语法中字符串 “xyzzy” 表示白俄罗斯语言,那么屏幕阅读器将会 错误地 把文本当做白俄罗斯语言处理, 因为 “xyzzy” 不是 BCP 47 规范中描述的白俄罗斯语言(BCP 47 使用 “be” 表示白俄罗斯语言)。

如果结果值是空字符串,那么必须把它解释为该节点的语言显式地声明为未知。


用户代理可以使用元素的语言来决定适当的处理和渲染(例如选择合适的字体和标点, 选择合适的字典,或者用于表单控件的 UI 比如日期选择器)。


HTMLElement/lang

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android12.1+

lang IDL 属性必须 反映 无命名空间的 lang 内容属性。

3.2.6.3 translate 属性

Global_attributes/translate

FirefoxNoSafari6+Chrome19+
Opera15+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox AndroidNoSafari iOS6+Chrome Android25+WebView Android4.4+Samsung Internet1.5+Opera Android14+

translate 属性是一个 枚举属性,用于指定元素在本地化时应该翻译其属性值和 Text 子节点的值,还是让它们保持不变。

该属性的关键字是空字符串,yes,和 no。 空字符串和 yes 关键字映射为 yes 状态。 no 关键字映射为 no 状态。 此外还有第三种状态,inherit 状态,这是 缺失值默认 (以及 非法值默认)。

每个元素(甚至非 HTML 元素)都有 翻译模式,处于 启用翻译 状态或者 不翻译 状态。 如果 HTML 元素translate 属性处于 yes 状态,那么该元素的 翻译模式 处于 启用翻译 状态;否则该元素的 translate 属性处于 no 状态,那么该元素的 翻译模式 处于 不翻译 状态。 否则,元素的 translate 属性处于 inherit 状态,或者该元素不是 HTML 元素 因此没有 translate 属性;任何一种情况下该元素的 翻译模式 都将与其父元素处于同样的状态(如果有父元素的话), 否则该元素是一个 文档元素,则处于 启用翻译 状态。

当元素处于 启用翻译 状态时,该元素的 可翻译的属性 及其 Text 子节点的值将会在页面本地化时进行翻译。

当元素处于 不翻译 状态时,该元素的属性值及其 Text 子节点的值将会在页面本地化时保留原样。例如因为该元素包含人名或者计算机程序名。

下面的属性是 可翻译属性

其他规范可能会定义其他 可翻译的属性。例如 ARIA 可能会把 aria-label 属性定义为可翻译的。


在读取时,translate IDL 属性必须返回 true 如果元素的 翻译模式启用翻译; 否则返回 false。当设置时,它必须设置该内容属性的值为 "yes" 如果新值为 true; 否则设置该内容属性的值为 "no"。

在这个例子中,在本地化时文档中的所有东西都会被翻译,除了示例键盘输入和示例程序输出:

<!DOCTYPE HTML>
<html lang=en> <!-- default on the document element is translate=yes -->
 <head>
  <title>The Bee Game</title> <!-- implied translate=yes inherited from ancestors -->
 </head>
 <body>
  <p>The Bee Game is a text adventure game in English.</p>
  <p>When the game launches,the first thing you should do is type
  <kbd translate=no>eat honey</kbd>。 The game will respond with:</p>
  <pre><samp translate=no>Yum yum! That was some good honey!</samp></pre>
 </body>
</html>
3.2.6.4 dir 属性

dir 属性指定了元素的文本方向。 该属性是一个 枚举属性 关键字和状态如下:

ltr 关键字,映射到 ltr 状态

表示该元素的内容是明确的独立方向隔离的从左到右的文本。

rtl 关键字,映射到 rtl 状态

表示该元素的内容是明确的独立方向隔离的从右到左的文本。

auto 关键字,映射到 auto 状态

表示该元素的内容是明确的方向隔离的文本,但其方向需要通过元素的内容以编程方式确定(描述如下)。

这种状态使用的启发式是非常粗糙的(类似于双向算法中的段落级别确定,查看第一个具有较强方向性的字符)。 强烈建议作者只有在文本的方向是未知,并且服务器端没有更好的启发式算法的情况下才使用该值作为最后的手段。 [BIDI]

对于 textareapre 元素,该启发式算法按段落级别生效。

该属性没有 非法值默认缺失值默认


元素(任意元素,不仅是 HTML 元素)的 方向 或者是 'ltr',或者是'rtl', 由下列列表中第一个适用的步骤确定:

如果该元素的 dir 属性处于 ltr 状态
如果该元素是一个 文档元素dir 属性不处于已定义状态(即未出现或具有非法值)
如果该元素是一个 input 元素 type 属性处于 电话 状态, 且 dir 属性不处于已定义状态(即未出现或具有非法值)

元素的 方向 为 'ltr'。

如果该元素的 dir 属性处于 rtl 状态

元素的 方向 为 'rtl'。

如果该元素是 input 元素,且它的 type 属性处于 文本搜索电话URL,或 E-mail 状态, 且 dir 属性处于 auto 状态
如果该元素是 textarea 元素,且它的 dir 属性处于 auto 状态

如果该元素的 value 包含一个双向字符类型 AL 或 R 的字符, 且它之前不包含双向字符类型 L 的字符,则该元素的 方向 为 'rtl'。 [BIDI]

否则,如果该元素的 value 不是空字符串, 或者该元素是一个 文档元素,该元素的 方向 为 'ltr'。

否则,该元素的 方向 与该元素的父元素的 方向 相同。

如果该元素的 dir 属性处于 auto 状态
如果该元素是一个 bdi 元素且 dir 属性不处于已定义状态(即未出现或具有非法值)

找到按照 树序 的第一个匹配下列条件的字符:

如果找到了这样的字符且它属于双向字符类型 AL 或 R,该元素的 方向rtl'。

如果找到了这样的字符且它属于双向字符类型 L,该元素的 方向ltr'。

否则,如果该元素是 文档元素, 该元素的 方向ltr'。

否则,该元素的 方向 与该元素的父元素的 方向 相同。

如果有父元素且 dir 属性处于未定义状态 (即未出现或具有非法值)

该元素的 方向 与该元素的父元素的 方向 相同。

因为只有 HTML 元素 定义有 dir 属性, 它不得出现在其他命名空间的元素上。所以其他命名空间的元素只从它们的父元素继承 方向,如果没有父元素则默认为 'ltr'。

该属性 有涉及双向算法的渲染要求


当该属性的文本用于渲染过程时,HTML 元素 属性的方向 由第一个合适的步骤决定:

如果该属性是一个 有方向的属性 且该元素的 dir 属性处于 auto 状态

找到该属性值中第一个属于双向字符类型 L,AL,或 R (按照逻辑顺序)的字符。 [BIDI]

如果找到了这样一个字符,且它的双向字符类型是 AL 或 R, 该属性的方向 为 'rtl'。

否则,该属性的方向 为 'ltr'。

否则
该属性的方向 与该元素的 方向 相同。

下列属性属于 有方向的属性


document . dir [ = value ]

返回 html 元素dir 属性值,如果有的话。

可以设置为 "ltr","rtl",或 "auto" 来替换掉 html 元素dir 属性值。

如果不存在 html 元素,则返回空字符串,忽略新的值。

HTMLElement/dir

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android12.1+

元素的 dir IDL 属性必须 反映dir 内容属性, 仅限于已知值

Document/dir

Support in all current engines.

Firefox1+Safari10.1+Chrome64+
Opera51+Edge79+
Edge (Legacy)12+Internet Explorer5+
Firefox Android4+Safari iOS10.3+Chrome Android64+WebView Android64+Samsung Internet9.0+Opera Android47+

Document 对象上的 dir IDL 属性必须 反映 html 元素dir 内容属性,如果有的话, 仅限于已知值。如果没有这样的元素, 该属性必须返回空字符串,且在设置时什么都不做。

强烈建议作者使用 dir 属性而不是 CSS 来指明文本方向。因为这样的话即使没有 CSS 文档也会正确地渲染。 (例如被搜索引擎解释时)。

这个标记片段是关于 IM 对话的。

<p dir=auto class="u1"><b><bdi>Student</bdi>:</b> How do you write "What的 your name?" in Arabic?</p>
<p dir=auto class="u2"><b><bdi>Teacher</bdi>:</b> ما اسمك؟</p>
<p dir=auto class="u1"><b><bdi>Student</bdi>:</b> Thanks.</p>
<p dir=auto class="u2"><b><bdi>Teacher</bdi>:</b> That的 written "شكرًا".</p>
<p dir=auto class="u2"><b><bdi>Teacher</bdi>:</b> Do you know how to write "Please"?</p>
<p dir=auto class="u1"><b><bdi>Student</bdi>:</b> "من فضلك",right?</p>

给定 p 元素合适的样式表和默认对齐样式,也就是说把文本对齐到段落 起始端,渲染结果可能是这样的:

Each paragraph rendered as a separate block,with the paragraphs left-aligned except the second paragraph and the last one,which would  be right aligned,with the usernames (的tudent' and 'Teacher' in this example) flush right,with a colon to their left,and the text first to the left of that.

就像之前提到的,auto 值不是万能药。 这个例子中最后一个段落被错误地解释为从右向左的文本, 因为它以一个阿拉伯字符开始,这会导致 "right?" 出现在阿拉伯文字的左边。

3.2.6.5 style 属性

所有 HTML 元素 都可以设置 style 内容属性。 这个 style 属性 定义在 CSS Style Attributes 规范中。 [CSSATTR]

在支持 CSS 的用户代理中,当添加或改变这个属性时必须 , 根据 style 属性 的规则解析该属性的值。 [CSSATTR]

但是如果 是否应该根据内容安全策略禁止元素的内联行为 算法对 属性的 元素,"style attribute",和属性值返回了 "Blocked" , 那么该属性值中定义的样式规则不得应用于该 元素[CSP]

在任何元素上使用了 style 属性的文档必须 在那些属性移除之后仍然可以理解和使用。

特别是使用 style 属性来隐藏和显示内容, 或者传达文档中本没有的含义,这些都是不合规范的。 (隐藏和显示内容,可以使用 hidden 属性)


element . style

返回该元素的 style 属性的 CSSStyleDeclaration 对象。

style IDL 属性定义在 CSS Object Model (CSSOM) 规范中。 [CSSOM]

下面的例子中,使用 span 元素和 style 属性 来标记指代颜色的词,来让它们在视觉媒体中显示相关的颜色。

<p>My sweat suit is <span style="color: green; background:
transparent">green</span> and my eyes are <span style="color: blue;
background: transparent">blue</span>.</p>
3.2.6.6 使用 data-* 属性 嵌入自定义不可见数据

Global_attributes/data-*

Support in all current engines.

FirefoxYesSafariYesChromeYes
OperaYesEdgeYes
Edge (Legacy)12+Internet ExplorerYes
Firefox AndroidYesSafari iOSYesChrome AndroidYesWebView AndroidYesSamsung InternetYesOpera AndroidYes

自定义数据属性 是一个无命名空间的属性,其名字以 字符串 "data-" 起始,连字符后有至少一个字符, 兼容于 XML,且不得包含非 ASCII 大写字母

HTML 文档HTML 元素 上所有属性名都会被自动 ASCII 小写化,所以 ASCII 大写字母的限制不会影响这种文档。

自定义数据属性 用于存储页面或应用私有的,自定义的数据、状态、注解和类似东西,只有在找不到更合适的属性或元素时才能使用。

这些属性不适用于所属站点管理员不知道的软件。对于很多独立工具使用的通用扩展, 或者需要扩展本规范来显式地提供该特性,或者应该使用类似 microdata 的技术(使用标准化的词汇)。

例如一个音乐相关的站点可能会在表示专辑音轨的列表项中, 使用自定义数据属性来表示每个音轨的长度。 用户可能会用该信息对列表进行排序,或者按照某个长度来过滤列表。

<ol>
 <li data-length="2m11s">Beyond The Sea</li>
 ..。
</ol>

但是用户使用与这个音乐站点不相关的通用软件来根据这个数据搜索某个长度的音轨是不合适的。

这是因为这些属性只适用于该站点自己的脚本,并不是一种公众可用的元数据的通用扩展机制。

类似地,页面作者可能会编写一些标记来为他们打算使用的翻译工具提供一些信息:

<p>The third <span data-mytrans-de="Anspruch">claim</span> covers the case of <span
translate="no">HTML</span> markup.</p>

这个例子中,"data-mytrans-de" 属性给出的文字 提供给 MyTrans 产品使用,把 "claim" 翻译到德语。但是标准的 translate 属性用于指示, 在所有语言环境中 "HTML" 要保持不变。当有标准属性可用时,就没必要使用 自定义数据属性 了。

在这个例子中,自定义数据属性用于存储 PaymentRequest 特性探测的结果,可能会用于 CSS 中,对付款页面做特殊的样式。

<script>
 if ('PaymentRequest' in window) {
   document.documentElement.dataset.hasPaymentRequest = '';
 }
</script>

这里 data-has-payment-request 属性被当做 布尔属性 来使用;检查该属性是否出现就足够了。 但是如果作者希望,它后续也可以填充一些值,比如用来标识该特性的功能限制。

每个 HTML 元素 都可以指定任意个 自定义数据属性,指定为任意值。

作者应该仔细地设计这样的扩展,当属性被忽略或者任何相关 CSS 被丢弃时,页面仍然可用。

用户代理不得从这些属性和值腿短任何实现行为。用户代理的相关规范不得为这些属性定义任何有意义的值。

JavaScript 库可以使用 自定义数据属性,因为它们也是页面的一部分。 鼓励有很多人用的库的作者在属性名中包含名字,来减小冲突的风险。 如果可行的话,鼓励库的作者支持自定义实际在用的名字,这样不小心选了重复名字的库也可以用于同一个页面, 同一个库的多个版本也可以用于同一个页面,即使它们互相不兼容。

例如一个叫做 "DoQuery" 的库可能会使用叫做 data-doquery-range 的属性名, 另一个叫做 "jJo" 的库可能会使用叫做 data-jjo-range 的属性名。 jJo 库也可以提供一个 API 来设置使用哪个前缀(例如 J.setDataPrefix('j2'), 使属性的名字变成 data-j2-range)。


element . dataset

HTMLOrForeignElement/dataset

Support in all current engines.

Firefox6+Safari5.1+Chrome8+
Opera11+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android6+Safari iOS5+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android11+

HTMLOrForeignElement/dataset

Support in all current engines.

Firefox51+Safari5.1+Chrome55+
Opera41+Edge79+
Edge (Legacy)17+Internet ExplorerNo
Firefox Android51+Safari iOS5+Chrome Android55+WebView Android55+Samsung Internet6.0+Opera Android41+

返回该元素的 data-* 属性的 DOMStringMap 对象。

连字符连接的名字会变成驼峰的。例如 data-foo-bar="" 变成了 element.dataset.fooBar

dataset IDL 属性 为元素上的所有 data-* 属性提供了便利访问器。 当读取时,dataset IDL 属性必须返回一个与该元素关联的 DOMStringMap

DOMStringMap 接口用于 dataset 属性。每个 DOMStringMap 有一个 关联的元素

[OverrideBuiltins]
interface DOMStringMap {
  getter DOMString (DOMString name);
  [CEReactions] setter void (DOMString name,DOMString value);
  [CEReactions] deleter void (DOMString name);
};

获取 DOMStringMap 的键值对,需呀执行以下算法:

  1. list 为一个键值对的空列表。

  2. 对于 DOMStringMap关联元素 上的每个前五个字符是 "data-" 且剩余字符(如果有的话)不包含任何 ASCII 大写字母 的内容属性, 按照这些属性在 属性列表 中出现的顺序, 在 list 中新增一个键值对,属性名移除前五个字符后作为键,属性值作为值。

  3. list 中的每个键中的每个后面跟随着一个 ASCII 小写字母 的 U+002D HYPHEN-MINUS 字符 (-) ,移除这个 U+002D HYPHEN-MINUS 字符 (-)并且将后面的这个字符替换为 同一个字母 转换为 ASCII 大写 的结果。

  4. 返回 list

任一时刻,DOMStringMap 对象上 支持的属性名 都是那一时刻 获取 DOMStringMap 的键值对 返回的每个键值对的键构成的列表,并按照返回的顺序排序。

对一个 DOMStringMap 确定命名属性 name 的值获取 DOMStringMap 的键值对 返回的列表中键是 name 的键值对的值。

给定属性名 name 和一个新值 value, 为一个 DOMStringMap 设置一个新命名属性的值设置已有属性的值 ,需要执行以下步骤:

  1. 如果 name 包含一个 U+002D HYPHEN-MINUS 字符(-) 紧跟着 ASCII 小写字母, 则抛出一个 "SyntaxError" DOMException 并中止这些步骤。

  2. 对每一个 name 中的 ASCII 大写字母 , 在该字符前插入一个 U+002D HYPHEN-MINUS 字符(-),并把这个字母替换为同一字母 转换为 ASCII 小写 的结果。

  3. name 之前插入字符串 data-

  4. 如果 name 不匹配 XML Name 生成式, 抛出一个 "InvalidCharacterError" DOMException 并中止这些步骤。

  5. 使用 namevalueDOMStringMap关联元素 设置属性值

为一个 DOMStringMap 删除一个既有命名属性 name ,需要执行以下步骤:

  1. 对每一个 name 中的 ASCII 大写字母 , 在该字符前插入一个 U+002D HYPHEN-MINUS 字符(-),并把这个字母替换为同一字母 转换为 ASCII 小写 的结果。

  2. name 之前插入字符串 data-

  3. 给定 nameDOMStringMap关联元素 通过属性名移除属性

Web IDL 规范只会使用前述 获取 DOMStringMap 的键值对 算法给出的名字调用该算法。 [WEBIDL]

如果一个 Web 页面想要一个元素来表示宇宙飞船,比如作为游戏的一部分,他可能必须同时使用 class 属性与 data-* 属性:

<div class="spaceship" data-ship-id="92432"
     data-weapons="laser 2" data-shields="50%"
     data-x="30" data-y="10" data-z="90">
 <button class="fire"
         onclick="spaceships[this.parentNode.dataset.shipId].fire()">
  Fire
 </button>
</div>

注意连字符连接的属性名在 API 中变成了驼峰命名的。

给定下面的相似构造的片段和元素:

<img class="tower" id="tower5" data-x="12" data-y="5"
     data-ai="robotarget" data-hp="46" data-ability="flames"
     src="towers/rocket.png" alt="Rocket Tower">

...可能会想到用一个 splashDamage() 函数,它接受的第一个参数是被处理的元素:

function splashDamage(node,x,y,damage) {
  if (node.classList.contains('tower') && // checking the 'class' attribute
      node.dataset.x == x && // reading the 'data-x' attribute
      node.dataset.y == y) { // reading the 'data-y' attribute
    var hp = parseInt(node.dataset.hp); // reading the 'data-hp' attribute
    hp = hp - damage;
    if (hp < 0) {
      hp = 0;
      node.dataset.ai = 'dead'; // setting the 'data-ai' attribute
      delete node.dataset.ability; // removing the 'data-ability' attribute
    }
    node.dataset.hp = hp; // setting the 'data-hp' attribute
  }
}

3.2.7 The innerText getter and setter

HTMLElement/innerText

Support in all current engines.

Firefox45+Safari3+Chrome1+
Opera9.6+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android45+Safari iOS1+Chrome Android18+WebView Android4.4+Samsung Internet1.0+Opera Android10.1+
element . innerText [ = value ]

Returns the element's text content "as rendered".

Can be set, to replace the element's children with the given value, but with line breaks converted to br elements.

The innerText getter steps are:

  1. If this is not being rendered or if the user agent is a non-CSS user agent, then return this's descendant text content.

    This step can produce surprising results, as when the innerText getter is invoked on an element not being rendered, its text contents are returned, but when accessed on an element that is being rendered, all of its children that are not being rendered have their text contents ignored.

  2. Let results be a new empty list.

  3. For each child node node of this:

    1. Let current be the list resulting in running the inner text collection steps with node. Each item in results will either be a string or a positive integer (a required line break count).

      Intuitively, a required line break count item means that a certain number of line breaks appear at that point, but they can be collapsed with the line breaks induced by adjacent required line break count items, reminiscent to CSS margin-collapsing.

    2. For each item item in current, append item to results.

  4. Remove any items from results that are the empty string.

  5. Remove any runs of consecutive required line break count items at the start or end of results.

  6. Replace each remaining run of consecutive required line break count items with a string consisting of as many U+000A LINE FEED (LF) characters as the maximum of the values in the required line break count items.

  7. Return the concatenation of the string items in results.

The inner text collection steps, given a node node, are as follows:

  1. Let items be the result of running the inner text collection steps with each child node of node in tree order, and then concatenating the results to a single list.

  2. If node's computed value of 'visibility' is not 'visible', then return items.

  3. If node is not being rendered, then return items. For the purpose of this step, the following elements must act as described if the computed value of the 'display' property is not 'none':

    items can be non-empty due to 'display:contents'.

  4. If node is a Text node, then for each CSS text box produced by node, in content order, compute the text of the box after application of the CSS 'white-space' processing rules and 'text-transform' rules, set items to the list of the resulting strings, and return items. The CSS 'white-space' processing rules are slightly modified: collapsible spaces at the end of lines are always collapsed, but they are only removed if the line is the last line of the block, or it ends with a br element. Soft hyphens should be preserved. [CSSTEXT]

  5. If node is a br element, then append a string containing a single U+000A LINE FEED (LF) character to items.

  6. If node's computed value of 'display' is 'table-cell', and node's CSS box is not the last 'table-cell' box of its enclosing 'table-row' box, then append a string containing a single U+0009 CHARACTER TABULATION (tab) character to items.

  7. If node's computed value of 'display' is 'table-row', and node's CSS box is not the last 'table-row' box of the nearest ancestor 'table' box, then append a string containing a single U+000A LINE FEED (LF) character to items.

  8. If node is a p element, then append 2 (a required line break count) at the beginning and end of items.

  9. If node's used value of 'display' is block-level or 'table-caption', then append 1 (a required line break count) at the beginning and end of items. [CSSDISPLAY]

    Floats and absolutely-positioned elements fall into this category.

  10. Return items.

Note that descendant nodes of most replaced elements (e.g., textarea, input, and video — but not button) are not rendered by CSS, strictly speaking, and therefore have no CSS boxes for the purposes of this algorithm.

This algorithm is amenable to being generalized to work on ranges. Then we can use it as the basis for Selection's stringifier and maybe expose it directly on ranges. See Bugzilla bug 10583.

The innerText setter steps are:

  1. Let document be this's node document.

  2. Let fragment be a new DocumentFragment object whose node document is document.

  3. Let input be the given value.

  4. Let position be a pointer into input, initially pointing at the start of the string.

  5. Let text be the empty string.

  6. While position is not past the end of input:

    1. Collect a sequence of code points that are not U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR) characters from input given position. Set text to the collected characters.

    2. If text is not the empty string, then append a new Text node whose data is text and node document is document to fragment.

    3. While position is not past the end of input, and the character at position is either a U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR) character:

      1. If the character at position is a U+000D CARRIAGE RETURN (CR) character and the next character is a U+000A LINE FEED (LF) character, then advance position to the next character in input.

      2. Advance position to the next character in input.

      3. Append the result of creating an element given document, br, and the HTML namespace to fragment.

  7. Replace all with fragment within this.

3.2.8 与双向算法相关的要求

3.2.8.1 双向算法格式化字符的编写一致性标准

内容 中包含 Text 节点的 HTML 元素 中的 文本内容, 以及允许自由文本的 HTML 元素 属性中的文本, 可以包含 U+202A 到 U+202E,和 U+2066 到 U+2069 (双向算法的格式化字符) 范围内的字符。 [BIDI]

鼓励作者使用 dir 属性, bdo 元素,以及 bdi 元素, 而不是手动地维护双向算法字符。双向算法格式化字符与 CSS 的交互性很差。

3.2.8.2 用户代理一致性标准

用户代理必须实现 Unicode 双向算法,以便在渲染文档或文档部分时确定合适的字符顺序。[BIDI]

HTML 到 Unicode 双向算法的映射必须以这三种方式中的任何一种来完成。 一,用户代理必须实现 CSS,特别是 CSS 'unicode-bidi''direction',和 'content' 属性, 并且在其用户代理样式表中必须包含在本规范的 渲染 章节中给出的用到了这些属性的规则。 二,用户代理必须表现得就像实现了前述属性一样,并且用户代理样式表中包含所有前述规则,但没有让文档中指定的样式表覆盖它们。 三,用户代理必须实现另一种具有等价语义的样式语言。 [CSSGC]

以下元素和属性具有由 渲染 部分定义的要求, 由于本节中的要求,那些要求对所有用户代理都有效(不仅仅是那些 支持建议默认渲染的):

3.2.9 ARIA 与 平台可访问性 API 相关的要求

HTML 元素 上实现可访问性 API 语义的用户代理要求定义在 HTML Accessibility API Mappings 中。 [HTMLAAM]

对一致性检查器检查 HTML 元素 上 ARIA rolearia-* 属性的使用 的相关要求定义在 ARIA in HTML[ARIAHTML]