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

时间:2009-04-21 18:52:06

标签: html html5 semantics

是否有关于labelinput HTML元素嵌套的最佳做法?

经典方式:

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

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

15 个答案:

答案 0 :(得分:478)

From w3:标签本身可以位于相关控件之前,之后或周围。

<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>

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

任何一个都有效。我喜欢使用第一个或第二个例子,因为它为你提供了更多的样式控制。

答案 1 :(得分:56)

我更喜欢

<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" />

主要是因为它使HTML更具可读性。我实际上认为我的第一个例子更容易使用CSS,因为CSS与嵌套元素的效果非常好。

但我认为这是一个品味问题。


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

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

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

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

答案 2 :(得分:37)

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

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

答案 3 :(得分:35)

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

如果单击标签和输入之间的空间,只有标签包含输入时才会激活输入。

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

&#13;
&#13;
<p>Inside:</p>

<label>
  <input type="checkbox" />
  |&lt;----- Label. Click between me and the checkbox.
</label>

<p>Outside:</p>

<input type="checkbox" id="check" />
<label for="check">|&lt;----- Label. Click between me and the checkbox.</label>
&#13;
&#13;
&#13;

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

  • 更容易点击
  • 不太清楚事情的起点和终点

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

  

支持复选框和无线电使用,以支持基于HTML的表单验证,并提供简洁,可访问的标签。因此,我们的<input><label>是兄弟元素,而不是<input>中的<label>。由于您必须指定ID以及与<input><label>相关联的属性,因此稍微详细一些。

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

答案 4 :(得分:15)

我个人喜欢把标签放在外面,就像你的第二个例子一样。这就是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" />

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

答案 5 :(得分:14)

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

他们说这可以通过任何一种方式完成。他们将两种方法描述为显式(使用带有元素id的“for”)和隐式(将元素嵌入标签中):

明确:

  

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

隐含:

  

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

答案 6 :(得分:10)

两者都是正确的,但将输入放在标签内会使用CSS样式时灵活性降低。

首先,a <label> is restricted in which elements it can contain。例如,如果<div>不在<input>内,则只能在<input>和标签文字之间加<label>

其次,虽然有一些变通方法可以使样式化更容易,比如用span填充内部标签文本,但是某些样式将继承父元素,这会使样式更复杂。

答案 7 :(得分:6)

一个值得注意的'gotcha'指示你不应该在&lt; label&gt;中包含多个输入元素。具有明确“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的元素上。对于'属性,使用户几乎不可能单击所包含的文本字段来输入值。

就个人而言,我试图避免使用输入子元素的标签元素。对于标签元素而言,在语义上不适合包含比标签本身更多的内容。如果您为了达到某种美感而在标签中嵌套输入,那么您应该使用CSS。

答案 8 :(得分:4)

我通常选择前两个选项。我已经看到了使用第三个选项的场景,当无线电选择嵌入标签时,css包含类似

的内容
label input {
    vertical-align: bottom;
}

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

答案 9 :(得分:4)

正如大多数人所说,两种方式确实有效,但我认为只有第一种应用。由于语义严格,标签不会“包含”输入。在我看来,标记结构中的包含(父/子)关系 应该反映视觉输出中的包含 。即,应该在浏览器中的周围绘制另一个中的标记元素。根据这个,标签应该是输入的兄弟,而不是它的父母。因此,第二个选项是任意的,令人困惑。阅读Zen of Python的每个人都可能会同意(Flat比嵌套更好,Sparse比密集更好,应该有一个 - 最好只有一个 - 明显的方式来做...)。

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

答案 10 :(得分:2)

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

使用以下结构:

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

当用户单击“标签文本”时,将触发一次checkCheckbox()函数。

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

然后,您的checkboxState中可能存在一些错误。

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

答案 11 :(得分:1)

参考 WHATWG Writing a form's user interface),将输入字段放在标签内是没有错的。这样可以节省代码,因为不再需要for中的label属性。

答案 12 :(得分:1)

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

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

答案 13 :(得分:0)

将输入嵌套到标签中有几个优点,尤其是单选框/复选框字段,

.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>

从演示中可以看出,先嵌套输入字段,然后再嵌套其他元素,

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

此外,HTML std 允许 multiple labels 与输入字段相关联,但是这会混淆屏幕阅读器,解决此问题的一种方法是将输入字段和其他元素嵌套在单个标签元素中。

答案 14 :(得分:-1)

input放在label内的主要优点是对人类的打字效率和对计算机的字节存储。

@Znarkus在对OP的评论中说,

<input />放在<label>中的一大优点是,您可以在示例中省略forid<label>My text <input /></label>。好多了!

注意:在@Znarknus代码中,包括了未在注释中明确说明的另一种效率。也可以省略type="text",并且input将默认显示一个文本框。

按键和字节[1]的并排比较。

31次击键,31个字节

<label>My Text<input /></label>

58次击键,58个字节

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

否则,这些片段在视觉上是相等的,并且它们提供相同级别的用户可访问性。用户可以单击或点击标签以将光标放置在文本框中。

[1]在Windows的记事本中创建的文本文件(.txt),Windows文件资源管理器属性中的字节数