自定义元素是有效的 HTML5 吗?

Posted

技术标签:

【中文标题】自定义元素是有效的 HTML5 吗?【英文标题】:Are custom elements valid HTML5? 【发布时间】:2012-04-08 08:32:44 【问题描述】:

我一直无法找到自定义标签在 html5 中是否有效的明确答案,如下所示:

<greeting>Hello!</greeting>

我在规范中找不到任何东西:

http://dev.w3.org/html5/spec/single-page.html

自定义标签似乎无法使用 W3C 验证器进行验证。

【问题讨论】:

您可能不想过多关注 4.5 年前写的 HTML5 文章。 Crockford 的文章很奇怪。重要的句子是“这是我的建议,以实现更友好、更温和的 HTML 5”。换句话说,这不是我们今天所知道的 HTML5,而是提出了一个不同的 HTML 5 作为 HTML 4 的继任者的提议。奇怪,因为它的日期是 2007 年 11 月,当时 W3C 已经在 HTML5 上工作了将近一年.他在这里使用“允许”一词令人困惑。自定义标签从未“符合”/“有效”,但浏览器解析器在它们存在的情况下继续工作。无论如何,克罗克福德的提议根本没有任何吸引力。几乎没有任何部分被合并到 HTML5 中。 随着 Web 组件自定义元素的新兴 W3 标准开始登陆 Firefox 和 Chrome,自定义元素正在成为一流:dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/… 至于 Douglas Crockford,我很想相信他所说的一切。 自定义元素的Web浏览器支持表caniuse.com/#feat=custom-elements 【参考方案1】:

Custom Elements specification 在 Chrome 和 Opera 中可用,在 other browsers 中可用。它提供了一种以正式方式注册自定义元素的方法。

自定义元素是新类型的 DOM 元素,可以由 作者。不像decorators,它是无状态和短暂的,自定义 元素可以封装状态,提供脚本接口。

自定义元素是更大的 W3 规范的一部分,称为 Web Components,以及模板、HTML 导入和 Shadow DOM。

Web 组件使 Web 应用程序作者能够定义具有 CSS 无法实现的视觉丰富度和交互性水平 单独使用,并且脚本无法轻松组合和重用 今天的图书馆。

但是,来自 Google Developers 上的 excellent walk through article 关于自定义元素 v1:

自定义元素的名称必须包含破折号 (-)。所以&lt;x-tags&gt;&lt;my-element&gt;&lt;my-awesome-app&gt; 都是有效名称,而&lt;tabs&gt;&lt;foo_bar&gt; 则不是。这个要求是为了让 HTML 解析器可以将自定义元素与常规元素区分开来。它还确保了向 HTML 添加新标签时的前向兼容性。

一些资源

示例 Web 组件可在 https://WebComponents.org 获得 WebComponents.js 充当 Web 组件的 polyfill,直到它们在所有地方都得到支持。另请参阅WebComponents.js github page & web browser support table。

【讨论】:

这是一个很好的答案 (+1),但规则有点循环。 “用户不得做不允许的事情……” @Alohci 你应该在你的引文中添加接下来的 3 个词:“by this specification”。 我也阅读了规范的那一部分,这让我很困惑。原因如下: 1) HTML5 中允许自定义属性。这证实了 Alochi 的循环论证观察。 2) 规范中没有任何地方说不允许使用自定义元素。 这句话充其量是模糊的。 W3C 肯定有更具体的立场吗? 指向 customelements.io 的链接不再有用。您介意更新/删除它吗?【参考方案2】:

这是可能的并且被允许的:

用户代理必须处理他们不处理的元素和属性 理解为语义中性;将它们留在 DOM 中(对于 DOM 处理器),并根据 CSS 设置样式(对于 CSS 处理器), 但没有从中推断出任何意义。

http://www.w3.org/TR/html5/infrastructure.html#extensibility-0

但是,如果您打算添加交互性,则需要使您的文档无效(但仍然可以正常工作)以适应 IE 的 7 和 8。

见http://blog.svidgen.com/2012/10/building-custom-xhtml5-tags.html(我的博客)

【讨论】:

看起来您没有阅读整个部分。它不仅主要是关于属性,甚至强烈反对那里的自定义。 重复我的其他 cmets,是的,很抱歉我不知道表明这是我的博客。我认为这很明显。这篇文章是直接相关的。我要补充一点,它并不是为了支持我提出的任何“声明”,而是以更长的格式显示如何这样做,以便它起作用。跨度> 重点很简单:规范明确允许这些事情。在大多数令人沮丧行为的情况下,该规范非常清楚地是针对用户代理供应商,而不是 HTML 作者。 以上引用的这一声明似乎已在w3.org/TR/html5/introduction.html#extensibility 的最新版本中被删除。到目前为止,我仍然找不到任何文档说明使用非连字符的自定义 HTML 元素是否有效,或者您是否需要 JS 语句来验证连字符的自定义 HTML 元素(html5rocks.com/en/tutorials/webcomponents/customelements)。 @JohnSlegers 是的,看起来文档和/或锚定被重新安排了一点。我已经更新了链接。我的回答中的引用位于链接到 Extensibility 部分的底部附近。【参考方案3】:

注意下面的答案在 2012 年编写时是正确的。从那时起,事情发生了一些变化。 HTML 规范现在定义了两种类型的自定义元素——“自主自定义元素”和“自定义内置元素”。前者可以去任何需要短语内容的地方;这是身体内部的大多数地方,但不是例如ul 或 ol 元素的子元素,或在 td、th 或标题元素之外的 table 元素中。后者可以去任何他们扩展的元素可以去的地方。


这其实是元素内容模型积累的结果。

例如,the root element must be an html element.

html 元素只能包含A head element followed by a body element.

body 元素只能包含 Flow content,其中流内容定义为以下元素: a, abbr, address, area (if it is a descendant of a map element), article, aside, audio, b, bdi, bdo, blockquote, br, button, canvas, cite, code, command, datalist, del, details, dfn, div dl, em, embed, fieldset, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, i, iframe, img, input, ins, kbd, keygen, label, map, mark, math, menu, meter, nav, noscript, object, ol, output, p, pre, progress, q, ruby, s, samp, script, section, select, small, span, strong, style (if the scoped attribute is present), sub, sup, svg, table, textarea, time, u, ul, var, video, wbr and Text

等等。

内容模型绝不会说“您可以将任何您喜欢的元素放入其中”,这对于自定义元素/标签来说是必需的。

【讨论】:

好的,所以我们可以假设如果没有提到自定义元素,那么它们也是不允许的。这似乎很公平。 这个答案现在无效,新兴的 W3 Web Components Custom Elements 标准现在开始登陆浏览器:dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/… @csuwldcat - 实际上没有。 HTML5 或更高版本的标准仍需要以某种方式进行更新,以允许此类自定义元素成为其内容模型的一部分。不过这是个有趣的消息。我可以在哪些浏览器上使用它们? @Alochi - 显然任何其他旧语言规范都需要更新以反映这一新现实,但 HTML 是一种生活标准,不会阻止其他规范 - 一旦我们移动到标准轨道的下一个阶段。您可以在 Chrome Canary 和 Firefox Aurora 中使用 Web 组件的本机实现。此外,4 个 Web 组件规范中的 3 个可使用 polyfill,它们在当今所有现代浏览器中都能很好地工作 - 这包括自定义元素规范/功能。 那么自定义元素可以放在某些地方吗?或者你是说他们根本不允许?【参考方案4】:

基本的自定义元素和属性

自定义元素和属性在 HTML 中有效,前提是:

元素名称为小写并以x- 开头 属性名称为小写,以data-开头

例如,&lt;x-foo data-bar="gaz"/&gt;&lt;br data-bar="gaz"/&gt;

元素的通用约定是x-foo;推荐x-vendor-feature

这可以处理大多数情况,因为可以说开发人员很少需要注册其元素所附带的所有功能。语法也足够有效和稳定。更详细的解释如下。

高级自定义元素和属性

自 2014 年起,注册自定义元素和属性有了一种经过大幅改进的新方法。它不适用于 IE 9 或 Chrome/Firefox 20 等旧版浏览器。但它允许您使用标准的HTMLElement 接口,防止冲突,使用非x-* 和非data-* 名称,并定义浏览器要遵守的自定义行为和语法。它需要一些花哨的 javascript,详见下面的链接。

HTML5 Rocks - Defining New Elements in HTMLWebComponents.org - Introduction to Custom ElementsW3C - Web Components: Custom Elements

关于基本语法的有效性

data-* 用于自定义属性名称已经完全有效一段时间了,甚至适用于旧版本的 HTML。

W3C - HTML5: Extensibility

对于自定义(未注册)元素名称,W3C 强烈建议不要使用它们,并认为它们不符合标准。但是浏览器需要支持它们,x-* 标识符不会与未来的 HTML 规范冲突,x-vendor-feature 标识符不会与其他开发人员冲突。自定义 DTD 可用于解决任何挑剔的浏览器。

以下是官方文档的一些相关摘录:

“适用的规范可以定义新的文档内容(例如 foob​​ar 元素)[...]。如果给定的语法和语义 使用适用的 HTML5 文档不会改变 规范,那么该文档仍然是符合 HTML5 的 文件。”

“用户代理必须处理他们不处理的元素和属性 理解为语义中性;将它们留在 DOM 中(对于 DOM 处理器),并根据 CSS 设置样式(对于 CSS 处理器), 但没有从中推断出任何意义。”

“用户代理不能随意处理不符合要求的文档,因为它们 请;本规范中描述的处理模型适用 无论输入的一致性如何实现 文件。”

"HTMLUnknownElement 接口必须用于 HTML 元素 本规范未定义。”

W3C - HTML5: Conforming DocumentsWhatWG - HTML Standard: DOM Elements

【讨论】:

【参考方案5】:

我想指出,“有效”这个词在这种情况下可以有两种不同的含义,其中任何一种都是潜在的,嗯,有效的。

    是否应将带有自定义标签的 HTML 文档视为有效的 HTML5? 答案显然是“不”。 The spec 准确列出了哪些标签在哪些上下文中有效。这就是为什么 HTML 验证器不会接受带有自定义标签的文档,或者在错误位置(例如标题中的“img”标签)带有标准标签的文档。

    是否可以跨浏览器以标准、明确定义的方式解析和呈现带有自定义标签的 HTML 文档? 在这里,也许令人惊讶的是,答案是“是的”。尽管该文档在技术上不会被视为有效的 HTML5,但 HTML5 规范 does specify 正是浏览器在看到自定义标签时应该做的事情:简而言之,自定义标签的行为有点像 &lt;span&gt; - 它没有任何意义默认情况下什么也不做,但可以通过 HTML 设置样式并通过 javascript 访问。

【讨论】:

【参考方案6】:

自定义 HTML 元素是一个新兴的 W3 标准,我一直致力于它使您能够使用解析器声明和注册自定义元素,您可以在此处阅读规范:W3 Web Components Custom Elements spec。此外,Microsoft 支持一个名为 X-Tag 的库(由前 Mozilla 开发人员编写),它使使用 Web 组件变得更加容易。

【讨论】:

部分内容已登陆 Firefox 和 Chrome - 我们正在密切合作,预计将在 2013 年底之前完成完整的实施。 现在是 2014 年,有完整的实现吗? 但是等等,我为什么要声明它们?我不能只输入它们并且它们是动态定义的吗? @JamieHutber 并在一年后看到您的网页在最新的浏览器中中断。浏览器互操作性规则 #1:按规则行事。 @HasibMahmud 规格现已最终确定,将在几周内登陆 Chrome Beta,在大约 6 周内登陆 Firefox Aurora。您现在可以通过将配置标志 dom.webcomponents.enabled 翻转为 true 在 Firefox Aurora 中使用它们。【参考方案7】:

提供反映现代页面的更新答案。

自定义标签在任一情况下都有效,

1) 它们包含一个破折号

<my-element>

2) 它们是嵌入的 XML

<greeting xmlns="http://example.com/customNamespace">Hello!</greeting>

假设您使用的是 HTML5 文档类型 &lt;!doctype html&gt;

考虑到这些简单的限制,现在尽最大努力保持您的 HTML 标记有效是有意义的(请停止关闭标签,如 &lt;img&gt;&lt;hr&gt;,除非您使用 XHTML 文档类型,否则这是愚蠢和不正确的,您可能有不需要)。

鉴于 HTML5 明确定义了解析规则,兼容的浏览器将能够处理您向其抛出的任何标签,即使它不是严格有效的。

【讨论】:

【参考方案8】:

引用Extensibility section of the HTML5 specification:

对于可能仅限于 XML 序列化且 HTML 序列化不需要支持的标记级功能,供应商应使用命名空间机制定义自定义命名空间,其中支持非标准元素和属性。

因此,如果您使用的是 HTML5 的 XML 序列化,那么您可以合法地执行以下操作:

<greeting xmlns="http://example.com/customNamespace">Hello!</greeting>

但是,如果您使用的是 HTML 语法,您可以做的事情就会受到更多限制。

对于旨在与 HTML 语法一起使用的标记级功能,应将扩展限制为“x-vendor-feature”形式的新属性 [...] 不应创建新元素名称。

但这些说明主要针对浏览器供应商,他们假定他们会为他们选择创建的任何自定义元素提供视觉样式和功能。

尽管如此,对于作者来说,虽然在页面中嵌入自定义元素可能是合法的(至少在 XML 序列化中),但除了 DOM 中的一个节点之外,您不会得到任何东西。如果您希望自定义元素实际执行某些操作,或以某种特殊方式呈现,您应该查看Custom Elements specification。

有关该主题的更温和的入门知识,请阅读Web Components Introduction,其中还包含有关 Shadow DOM 和其他相关规范的信息。这些规范目前仍处于草稿阶段 - 您可以查看当前状态 here - 但它们正在积极开发中。

例如,greeting 元素的简单定义可能如下所示:

<element name="greeting">
  <template>
    <style scoped>
      span  color:gray; 
    </style>
    <span>Simon says:</span>
    <q><content/></q>
  </template>
</element>

这告诉浏览器用引号渲染元素内容,并以文本“Simon says:”为前缀,该文本的样式为灰色。通常,像这样的自定义元素定义将存储在单独的 html 文件中,您可以通过链接导入该文件。

<link rel="import" href="greeting-definition.html" />

虽然您也可以根据需要将其包含在内。

我使用 Polymer polyfill 库创建了上述定义的工作演示,您可以看到 here。请注意,这是使用旧版本的 Polymer 库 - 较新版本的工作方式完全不同。但是,由于规范仍在开发中,我不建议在生产代码中使用它。

【讨论】:

【参考方案9】:

只使用你想要的任何东西,不需要任何 dom 声明

<container>content here</container>

添加您自己的样式(显示:块),它将适用于任何现代浏览器

【讨论】:

【参考方案10】:

data-* 属性在 HTML5 中有效,甚至在 HTML4 中,所有用于尊重它们的网络浏览器也是如此。 添加新标签在技术上是可以的,但不建议仅仅因为:

    它可能与将来添加的内容冲突,并且 使 HTML 文档无效,除非通过 JavaScript 动态添加。

我只在 Google 不关心的地方使用自定义标签,对于游戏引擎 iframe 中的 ecample,我制作了一个包含 &lt;msg&gt;&lt;error&gt;&lt;warning&gt;&lt;log&gt; 标签 - 但通过 仅限 JavaScript。根据验证者的说法,它是完全有效的。它甚至可以在 Internet Explorer 中使用它的样式! ;]

【讨论】:

它对验证器有效,因为您使用 JavaScript 创建了这些元素,而验证器没有看到它们,因为它不运行您的 JavaScript。它只会看到第一次加载时出现的页面。 没错。虽然不是有效的 HTML,但自定义标签仍然是有效的 SGML,而 HTML 终究是 SGML。 CSS 可用于设置自定义标签的样式,并且在 IE 中完美运行。 :) 此外,您可以在 DOCTYPE 规范中使用您自己的自定义元素指定您自己的 DTD,因此即使没有 JavaScript,我的自定义标签实际上也可以得到验证——但我不在乎它们——游戏引擎 GUI 系统绝对不是谷歌工作:) 嗯,有一个问题。你不能随便扔进自定义元素。您必须在 DTD 中定义和注册它们,才能将它们视为“有效”HTML。仅仅因为某些东西有效并不意味着它是有效的。 如果您只是在元素名称中添加限定符,例如 等,那么您将遵守 Web 组件/自定义元素规范。 在 Webkit 仅用于渲染动态 GUI 的游戏引擎中,没有人会关心 DTD。 HTML 的任何未知标记都是 JS 的 HTMLUnknownElement,仍然可以与 JQuery 和 CSS 完美配合,因此您的 GUI 最后会获得一些语义:&lt;inventory&gt;&lt;item type="potion" sprite="2"&gt; - 所以最好称为 SGML + CSS 而不是 HTML,尽管具有定义的 HTML 元素按原样工作 - 按钮、列表、...【参考方案11】:

自定义标签在 HTML5 中无效。但目前浏览器支持解析它们,您也可以使用 css 使用它们。因此,如果您想为当前浏览器使用自定义标签,那么您可以。但是一旦浏览器严格执行 W3C 标准来解析 HTML 内容,这种支持可能会被取消。

【讨论】:

当他们停止支持 &lt;center&gt;&lt;marquee&gt; 时,也许会发生这种情况?【参考方案12】:

我知道这个问题很老,但我一直在研究这个主题,虽然上面的一些陈述是正确的,但它们并不是创建自定义元素的唯一方法。例如:

<button id="find">click me</button>
<Query? ?attach="find" ?content="alert( find() );" ?prov="Hello there :D" >
I won't be displayed :D
</Query?>

<style type="text/css">

[\?content] 

display: none;



</style>

<script type="text/javascript">

S = document.getElementsByTagName("Query?")[0];

Q = S.getAttribute("?content");

A = document.getElementById( S.getAttribute("?attach") );

function find() 

  return S.getAttribute("?prov");



(function() 

A.setAttribute("onclick", Q);

)();

</script>

可以正常工作(到目前为止,在较新版本的 Google Chrome、IE、FireFox 和移动 Safari 中)。您只需要一个字母字符(a-z、A-Z)来开始标记,然后您可以在之后使用任何非字母字符。如果在 CSS 中,您必须使用“\”(反斜杠)才能找到元素,例如需要 Query\^ ... 。但是在 JS 中,你只是按照你的看法来称呼它。我希望这会有所帮助。见例子here

-水貂CBOS

【讨论】:

这是我最近看到的最奇怪的 HTML :)

以上是关于自定义元素是有效的 HTML5 吗?的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 自定义数据属性在 IE 6 中是不是“有效”?

属性html5自定义标签都有哪些

与 AngularJS 相比,在 Polymer 中创建自定义 HTML5 元素/小部件的优缺点是啥

在 HTML5 视频上全屏显示时,自定义控件仍然适用吗?

INPUT 和 SELECT 元素自定义大小

关于HTML5如何自定义属性