表单标签帮助的适当语义标记是什么 sub-text

What is the appropriate semantic markup for form label help sub-text

表单中的某些表单元素可能需要文本来解释所述元素的功能。我想把这段文字封装在一个段落元素中,如下,

label p {
  margin-top: -1px;
  font-size: smaller;
}
<div class="form-group">
  <label for="form-input-1">Label Text
    <p>Label explainer/help text</p>
  </label>
  <input id="form-input-1" />
</div>

我的问题是:<p> 元素是这个用途中最语义化的元素吗?在我看来,标签 sub-text 是 sub-title 的一种类型,有人可能会争辩说它可能需要 <h*> 元素。但是,这些通常用于轮廓,我不认为这在这里会是超级语义。 <span> 在这里有意义吗,因为这些 可能 用于标记内嵌流元素的部分?

请分享您的想法!

在复杂的表格中,有多个部分、标题、提示、帮助文本等用作解释。所以有多种方法可以向表单添加描述和帮助文本:

  1. <span> 是最简单的形式。将其添加到 label-element.
  2. <fieldset><legend> 将字段包装在一起并添加描述。
  3. <section> 可以为表单提供额外的结构和信息。
  4. <p> 可用于添加附加信息,即添加到整个表单或 form-section
  5. <div> 在 Maerial Design 中被 Google 用于文本字段辅助行

经常完成但不用于更深入的解释应该是占位符中的文本。

在你的例子中,我相信 label 中的 span 应该是一个很好的解决方案,它会匹配语义。


补充信息

来自 MDN 的复杂 HTML 代码示例:

    <form method="post">
        <h1>Payment form</h1>
        <p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
        <section>
            <h2>Contact information</h2>
            <fieldset>
              <legend>Title</legend>
              <ul>
                  <li>
                    <label for="title_1">
                      <input type="radio" id="title_1" name="title" value="A">
                      Ace
                    </label>
                  </li>
                  <li>
                    <label for="title_2">
                      <input type="radio" id="title_2" name="title" value="K" >
                      King
                    </label>
                  </li>
                  <li>
                    <label for="title_3">
                      <input type="radio" id="title_3" name="title" value="Q">
                      Queen
                    </label>
                  </li>
              </ul>
            </fieldset>
            <p>
              <label for="name">
                <span>Name: </span>
                <strong><abbr title="required">*</abbr></strong>
              </label>
              <input type="text" id="name" name="username">
            </p>
            <p>
              <label for="mail">
                <span>E-mail: </span>
                <strong><abbr title="required">*</abbr></strong>
              </label>
              <input type="email" id="mail" name="usermail">
            </p>
            <p>
              <label for="pwd">
                <span>Password: </span>
                <strong><abbr title="required">*</abbr></strong>
              </label>
              <input type="password" id="pwd" name="password">
            </p>
        </section>
        <section>
            <h2>Payment information</h2>
            <p>
              <label for="card">
                <span>Card type:</span>
              </label>
              <select id="card" name="usercard">
                <option value="visa">Visa</option>
                <option value="mc">Mastercard</option>
                <option value="amex">American Express</option>
              </select>
            </p>
            <p>
              <label for="number">
                <span>Card number:</span>
                <strong><abbr title="required">*</abbr></strong>
              </label>
                <input type="tel" id="number" name="cardnumber">
            </p>
            <p>
              <label for="date">
                <span>Expiration date:</span>
                <strong><abbr title="required">*</abbr></strong>
                <em>formatted as mm/dd/yyyy</em>
              </label>
              <input type="date" id="date" name="expiration">
            </p>
        </section>
        <section>
            <p> <button type="submit">Validate the payment</button> </p>
        </section>
    </form>

Link 实时查看 MDN 表单:
https://mdn.github.io/learning-area/html/forms/html-form-structure/payment-form.html

Link 更广泛的 MDN 解释:
https://developer.mozilla.org/en-US/docs/Learn/Forms/How_to_structure_a_web_form#common_html_structures_used_with_forms*

Link 示例 Google Material 设计:
https://material.io/develop/web/components/input-controls/text-field/helper-text

<label> elements can only contain phrasing content, which means they can't contain headings or paragraph elements, which are flow content.

此外,MDN 文档指出 headings should not be used within labels 因为这“会干扰多种辅助技术”。

如果需要额外的表单字段说明,超出标签内的合理范围,您应该在标签之外使用单独的元素,并使用 aria-describedby 属性将其绑定到输入,如概述在 W3C 的 Web Accessibility Tutorial on Form Instructions.

这是该方法的一个示例:

form {
  display: grid;
  grid-gap: 0.5rem;
  padding: 0.5rem;
}
<form>
  <label for="input">Label Text</label>
  <span id="instructions">Additional instructions lorem ipsum</span>
  <input id="input" aria-describedby="instructions" type="text">
</form>

似乎没有任何确定的答案或资源,因此您只能征求意见。这是我的:

我首先考虑如何标记整个表单。我认为 the semantic form style described in MDN article 是一个很好的起点。特别是表单在逻辑上是表单控件列表的部分,因此您应该有 <ul><li> 元素按语义顺序包装控件。但是,我认为它有一个有问题的部分,它使用逻辑标记

<label><input>text</label>

用于单选按钮,但是

<label>text<input></label>

用于文本输入。我非常希望标记顺序不会根据输入类型而改变(checkbox/radio 按钮与 text/email/password)。要在实践中做到这一点,您可能希望始终使用

这样的标记
<li class="checkbox">
  <label for=id1>text</label>
  <input id=id1>
</li>

然后您可以使用例如li.checkbox { display: flex; ... } 并根据需要重新排序标签和视觉输入。显然 class 只需要样式,但不需要语义。如果浏览器曾经实现 :has() 那么就根本不需要 class

至于输入的帮助文本,理论上,你会想要使用

<li class="checkbox">
  <label for=id1>text</label>
  <input id=id1>
  <label for=id1 class=help>help content here</label>
</li>

因为根据规范,应该可以将多个标签附加到单个输入。但是,据我所知,这实际上不适用于需要辅助功能的盲人常用的软件。

因此,下一个问题是您认为以下所有组应该如何使用此帮助文本?

  1. 有视力但没有 JavaScript 支持的用户。 (请注意,该组包括大多数搜索引擎。)
  2. 没有 JavaScript 支持的盲人。
  3. 有远见的用户 JavaScript 支持。 (请注意,该组包括一些搜索引擎。)

据我所知,没有一个好的答案可以完美地满足所有 3 个群体。请注意,对于另一组“具有 JavaScript 支持的盲人”的实际支持,您可以使用任何您想要的标记并使用 ARIA 属性使其可访问。总的来说,我能想到的最好的是:

<li class="checkbox">
  <label for=id1>text</label>
  <input id=id1 aria-describedby=id2>
  <aside id=id2>help content here</aside>
</li>

这应该足以将帮助内容附加到辅助工具的输入中,帮助内容是语义上的附加内容,因此 <aside> 对于盲人和视觉用户来说应该没问题,您可以使用 CSS only 使 <aside> 仅在输入聚焦时可见。另请注意,<aside> 允许任何帮助内容,包括 iframe 中的视频,而不仅仅是文本。当然,如果您需要用户在 <aside> 元素内单击,您不能使用 input:focus 来切换元素可见,但您需要使用某种 JavaScript 支持。确切的细节取决于您最想满足哪个群体的需求,以及您是否希望所有群体都可以使用帮助文本。

此标记还包含 JavaScript 需要的所有信息。对于某些非 JavaScript 样式选项,您可能希望将标签和输入包装在一些包装器元素中,以便您可以将它们作为一个组与 <aside> 元素分开。在那种情况下,标记如

<li class="checkbox">
  <div>
    <label for=id1>text</label>
    <input id=id1 aria-describedby=id2>
  </div>
  <aside id=id2>help content here</aside>
</li>

可能是个不错的选择。如果需要,您可以通过选择器 form li.checkbox>div 定位无类 <div> 元素。然后可以使用例如display:gridsubgrid 表示 li.checkbox,例如display:flexli.checkbox>div 很好地定位所有内容。但是,如果你这样做,你不能仅仅通过使用像 input:not(:focus) + aside { display: none; } 这样的样式来很好地切换帮助文本的可见性。我认为如果你将 display:grid 用于 li.checkbox,你可以在没有包装器 <div> 元素的情况下生存,因为与 flex.

不同,这允许在 2D 中定位内容

而如果你需要支持有远见的用户却没有CSS的支持,那我也没有很好的解决方案。使用上面提到的语义列表标记除了表单输入之外还会产生项目符号点,这对于非 CSS 用户来说可能看起来非常混乱。