我应该把输入元素放在标签元素中吗?

是否有关于labelinput超文本标记语言元素嵌套的最佳实践?

经典方式:

<label for="myinput">My Text</label>
<input type="text" id="myinput" />

<label for="myinput">My Text
<input type="text" id="myinput" />
</label>
300773 次浏览

来自W3的HTML4规范

标签本身可以放置在之前,之后或周围 关联控制。


<label for="lastname">Last Name</label>
<input type="text" id="lastname" />

<input type="text" id="lastname" />
<label for="lastname">Last Name</label>

<label>
<input type="text" name="lastname" />
Last Name
</label>

请注意,当表格用于布局时,第三种技术不能使用,标签在一个单元格中,其关联的表单字段在另一个单元格中。

我喜欢使用第一个或第二个例子,因为它给你更多的风格控制。

如果您在标签标签中包含输入标签,则不需要使用'for'属性。

也就是说,我不喜欢在我的标签中包含输入标签,因为我认为它们是独立的,而不是包含实体。

两者都是正确的,但是将输入放在标签中会使它在使用CSS样式时变得不那么灵活。

首先,<label>被限制在它可以包含的元素中。例如,如果<input>不在<label>内,则只能在<input>和标签文本之间放置<div>

其次,虽然有一些变通方法可以使样式更容易,例如用跨度包装内部标签文本,但有些样式将从父元素继承,这会使样式更复杂。

第三方编辑

根据我的理解HTML 5.2标签规范声明标签Content modelPhrasing content。这意味着只有内容模型是措辞内容<label> are allowed inside </label>的标签。

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

大多数被归类为短语内容的元素只能 包含本身被归类为措辞内容的元素, 没有任何流量内容。

就我个人而言,我喜欢将标签保留在外面,就像你的第二个例子一样。这就是For属性存在的原因。原因是我经常会对标签应用样式,比如宽度,以使表单看起来不错(简写如下):

<style>
label {
width: 120px;
margin-right: 10px;
}
</style>


<label for="myinput">My Text</label>
<input type="text" id="myinput" /><br />
<label for="myinput2">My Text2</label>
<input type="text" id="myinput2" />

这样我就可以避免表格和表格中的所有垃圾。

有关W3建议,请参阅http://www.w3.org/TR/html401/interact/forms.html#h-17.9

他们说这两种方法都可以做到。他们将这两种方法描述为显式(使用带有元素id的“for”)和隐式(将元素嵌入标签中):

显式:

for属性将标签与另一个控件显式关联:for属性的值必须与关联控件元素的id属性的值相同。

隐式:

要将标签与另一个控件隐式关联,控件元素必须位于LABEL元素的内容中。在这种情况下,LABEL只能包含一个控件元素。

我通常选择前两个选项。我见过使用第三个选项的场景,当嵌入在标签和css中的无线电选择包含类似的内容时

label input {
vertical-align: bottom;
}

以确保无线电正确的垂直对齐。

我更喜欢

<label>
Firstname
<input name="firstname" />
</label>


<label>
Lastname
<input name="lastname" />
</label>

超过

<label for="firstname">Firstname</label>
<input name="firstname" id="firstname" />


<label for="lastname">Lastname</label>
<input name="lastname" id="lastname" />

主要是因为它使超文本标记语言更具可读性。实际上,我认为我的第一个示例更容易使用CSS设置样式,因为CSS与嵌套元素配合得很好。

这是一个品味的问题,我想。


如果您需要更多样式选项,请添加跨度标记。

<label>
<span>Firstname</span>
<input name="firstname" />
</label>


<label>
<span>Lastname</span>
<input name="lastname" />
</label>

在我看来,代码仍然看起来更好。

一个值得注意的'getcha'规定您永远不应该在具有显式“for”属性的元素中包含多个输入元素,例如:

<label for="child-input-1">
<input type="radio" id="child-input-1"/>
<span> Associate the following text with the selected radio button: </span>
<input type="text" id="child-input-2"/>
</label>

虽然这对于自定义文本值次要于单选按钮或复选框的表单功能可能很诱人,但标签元素的单击焦点功能会立即将焦点抛向其id在其“for”属性中明确定义的元素,使用户几乎不可能单击包含的文本字段以输入值。

就我个人而言,我尽量避免使用带有输入子元素的标签元素。标签元素包含的内容超过标签本身似乎在语义上是不合适的。如果您在标签中嵌套输入以实现某种美感,则应该使用CSS代替。

参考WHATWG编写表单的用户交互界面),将输入字段放在标签内没有错。这节省了您的代码,因为不再需要label中的for属性。

行为差异:点击标签和输入之间的空格

如果您单击空格之间标签和输入,它仅在标签包含输入时激活输入。

这是有道理的,因为在这种情况下,空格只是标签的另一个字符。

div {
border: 1px solid black;
}
label {
border: 1px solid black;
padding: 5px;
}
input {
margin-right: 30px;
}
<p>Inside:</p>
<label>
<input type="checkbox" />
Label. Click between me and the checkbox.
</label>


<p>Outside:</p>
<input type="checkbox" id="check" />
<label for="check">Label. Click between me and the checkbox.</label>

能够在标签和框之间单击意味着它是:

  • 更容易点击
  • 不太清楚事情的开始和结束

Bootstrap复选框v3.3示例使用内部的输入:http://getbootstrap.com/css/#forms跟随他们可能是明智的。但是他们在v4.0https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios中改变了主意,所以我不知道什么是明智的了:

复选框和无线电用于支持基于超文本标记语言的表单验证并提供简洁、可访问的标签。因此,我们的<input><label>是兄弟元素,而不是<label>中的<input>。这稍微冗长一些,因为您必须指定id和属性来关联<input><label>

详细讨论这一点的用户体验问题:https://ux.stackexchange.com/questions/23552/should-the-space-between-the-checkbox-and-label-be-clickable

正如大多数人所说,这两种方式都有效,但我认为只有第一种应该。由于语义严格,标签不“包含”输入。在我看来,包含(父/子)关系在标记结构应该反映包含在视觉输出。即,一个围绕另一个元素在标记的元素应该围绕那个在浏览器绘制。根据这一点,标签应该是输入的兄弟姐妹,而不是它的父元素。所以选项二是武断且令人困惑的。每个读过Python之禅的人都可能会同意(扁平比嵌套好,稀疏比密集好,应该有一种最好只有一种明显的方法来做到这一点……)。

由于像W3C和主要浏览器供应商这样的决定(允许“以你喜欢的方式做”,而不是“以正确的方式做”),今天的网络是如此混乱,我们开发人员必须处理纠结和多样化的遗留代码。

我非常喜欢将元素包装在我的<label>中,因为我不必生成id。

我是一名Javascript开发人员,React或Angular用于生成可以被我或其他人重用的组件。然后页面中会出现容易复制id,导致出现奇怪的行为。

您需要考虑的一件事是复选框和单选输入与javascript的交互。

使用以下结构:

<label>
<input onclick="controlCheckbox()" type="checkbox" checked="checkboxState" />
<span>Label text</span>
</label>

当用户点击“标签文本”控件时,Checkbox()函数将被触发一次。

但是当单击输入标签时,在某些较旧的浏览器中,控制器Checkbox()函数可能会被触发两次。这是因为输入和标签标签都会触发附加到复选框的onClick事件。

那么您的复选框状态中可能有一些错误。

我最近在IE11上遇到了这个问题。我不确定现代浏览器是否有这种结构的问题。

将输入嵌套到标签中有几个优点,特别是使用无线电/复选框字段,

.unchecked, .checked{display:none;}
label input:not(:checked) ~ .unchecked{display:inline;}
label input:checked ~ .checked{display:inline;}
<label>
<input type="checkbox" value="something" name="my_checkbox"/>
<span class="unchecked">Not Checked</span>
<span class="checked">Is Checked</span>
</label>

正如您从演示中看到的,嵌套输入字段首先紧跟其他元素允许,

  • 要单击以激活字段的文本
  • 输入字段后面的元素将根据字段的状态动态设置样式。

此外,超文本标记语言std允许多个标签与输入字段相关联,但是这会使屏幕阅读器感到困惑,并且绕过这一点的一种方法是将输入字段和其他元素嵌套在单个标签元素中。