严格的文档类型声明 - 表单和输入元素

6

有人知道为什么严格的文档类型不允许将输入元素直接作为表单元素的子元素吗?我发现我必须将提交按钮(一个块级元素)包装在另一个块级元素(如fieldset或div)中,这让我很烦恼。然而,我无法找到任何关于为什么这样做的答案。

1个回答

2
如果您试图直接将输入放入没有容器元素的表单中,并在xhtml 1.0 strict下进行验证,您会收到以下警告:

文档类型不允许出现元素"input";缺少其中之一:"p"、"h1"、"h2"、"h3"、"h4"、"h5"、"h6"、"div"、"pre"、"address"、"fieldset"、"ins"、"del"的开始标签。✉ 所提到的元素不允许出现在您放置它的上下文中;其他提到的元素是唯一允许在那里出现并可以包含所提到的元素。这可能意味着您需要一个包含元素,或者可能是您忘记关闭先前的元素。

导致此消息的一个可能原因是,您尝试将块级元素(如"<p>"或"<table>")放入内联元素(如"<a>"、"<span>"或"<font>")中。

如果您在这里查看W3C对表单元素的定义(http://www.w3.org/TR/html4/interact/forms.html#h-17.3),您会发现该元素的内容模型被定义为“%block”。

<!ELEMENT FORM - - (%block;|SCRIPT)+ -(FORM) -- interactive form -->

如果您跟随“%block”链接(http://www.w3.org/TR/html4/sgml/dtd.html#block),就会找到那些被定义为此类元素的元素。这些元素包括:
<!ENTITY % block
     "P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT |
      BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS">

因此,正如您可以看到的那样,W3C 并未将输入框或按钮定义为块级元素。您可以在该页面搜索“input”,并发现它的内容类型为“formctrl”:
<!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">

“实际上,考虑到输入元素不会在它们之前/之后引起换行,因此输入元素的默认显示方式更像是内联块而不是块级元素。因此,除了内联元素和块级元素之外,还有其他类型的元素。”
“因此,最终,一个表单需要其直接子元素是块级元素,而输入元素不符合要求。希望这能解决所有问题。”

是的,它确实提供了更多关于推理的见解,但我想我代表大多数开发人员,输入元素被视为块元素,并在几乎所有浏览器和设置中都是如此。 - David
是的,人们往往认为元素要么是块级的,要么是内联的,但实际上它们有更多的变化。输入元素是块级的,因为它们具有可以调整的高度和宽度,但如果你有像“输入名称:<input />”这样的东西,它们都会出现在同一行而不需要进行任何浮动,所以在这方面它的行为就像一个内联元素。我个人认为它们是内联块级元素。虽然我同意 <div> 或 <p> 或任何其他块级元素不应该用于验证 <input>,但我认为将其放在 <form> 中应该是可以的。 - RussellUresti
1
这个答案归根结底就是“规范这么说”。我觉得这样的回答非常不令人满意。1)如果有“formctrl”选项可用,限制表单的“内容模型”为块级元素会有什么现实世界的原因呢?!2)我经常使用事实上是内联的表单。我很生气必须要围绕块级元素进行CSS处理。 - Brock Adams
@Brock,“为什么会这样”问题的答案是因为运营W3C和HTML工作组的人决定应该这样,但这是一个可怕的答案。此外,所有标签都有定义的内容模型,这就是验证如何确定的,将正确的标签放在正确的位置上。它提供了结构。 - RussellUresti
1
实际上,我认为标准在这里做得很对。如果将输入定义为块级元素,那意味着,比如说,一个单选按钮会默认显示在一行上,而该单选按钮的标签文本会默认显示在下一行(无需特定的CSS来设置浮动/宽度等等)。输入被定义为内联元素,因为通常它们自然地位于块级元素中的解释性文本流中。要创建一个有效的表单,只需将每个输入/标签组合(你确实使用标签了吧?)放入一个块级元素,比如div或p,放在form元素内。在我看来,这样做没有任何问题。 - mattandrews
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接