【问题标题】:What is the appropriate semantic markup for form label help sub-text表单标签帮助子文本的适当语义标记是什么
【发布时间】:2021-02-24 16:22:08
【问题描述】:

表单中的某些表单元素可能需要文本来解释所述元素的功能。我正在考虑将此文本封装在一个段落元素中,如下所示,

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>

我的问题是:&lt;p&gt; 元素是最符合此用途的语义元素吗?在我看来,标签子文本是一种子标题,有人可能会争辩说它可能需要&lt;h*&gt; 元素。但是,这些通常用于轮廓,我不相信这会是超级语义。 &lt;span&gt; 在这里有意义吗,因为这些可能用于标记内联流元素的一部分?

请分享你的想法!

【问题讨论】:

  • 我想说 span 元素绰绰有余,因为它没有关联的含义,而且 label 元素本身已经为其各自的输入提供了一些细节。

标签: html semantic-markup


【解决方案1】:

&lt;label&gt; 元素只能包含phrasing content,这意味着它们不能包含标题或段落元素,即flow content

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

如果需要额外的表单字段说明,超出了标签的合理范围,您应该在标签之外使用单独的元素,并使用 aria-describedby 属性将其绑定到输入,如 W3C 的 @ 中所述987654325@.

这是该方法的一个示例:

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>

【讨论】:

  • Sean,请注意,如果我们将元素放在&lt;label&gt; 元素的之外,那么,我们将失去label 的类似标签的点击转发行为说明,这就是我要追求的。此外,适合标签的“合理”数量的文本是多少?我们可以扩展标签的概念以包含说明文本吗?
  • 如果您的附加说明从不需要包含交互式内容(例如链接),您可以将其全部包含为标签,前提是它只标有短语内容。另请注意,单个input 可以有多个 标签,只要它们不嵌套即可。 @seebiscuit
  • 嘿,肖恩,再次阅读Flow Content 列表,我注意到&lt;label&gt; 也在其中,
  • @seebiscuit 是的,标签是流内容。但它们只能包含短语内容。
  • 刚刚注意到,Technical Summary on the label doc page 它有效地验证了您分享的内容!感谢您帮助我更好地理解&lt;label&gt; 元素?
【解决方案2】:

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

  1. &lt;span&gt; 是最简单的形式。将其添加到标签元素中。
  2. &lt;fieldset&gt;&lt;legend&gt; 将字段包装在一起并添加描述。
  3. &lt;section&gt; 可以为表单提供额外的结构和信息。
  4. &lt;p&gt; 可用于添加附加信息,即添加到整个表单或表单部分
  5. &lt;div&gt; 被 Google 在 Maerial Design 中用于文本字段辅助线

经常使用但不用于更详细的解释应该是占位符中的文本。

在您的示例中,我相信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>

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

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

Google Material Design 示例链接:
https://material.io/develop/web/components/input-controls/text-field/helper-text

【讨论】:

  • 感谢您花时间发布此答案。虽然您指出了表格中一些有趣的部分,但不幸的是,您没有指出任何标准或理由来描述我要询问的特定问题。你看,我的问题是关于表单文档的一般问题。我不打算改变我们目前的设计。相反,这是一个关于在我们的要求中使用的具体问题。再次感谢您的周到回复!
【解决方案3】:

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

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

<label><input>text</label>

单选按钮,但是

<label>text<input></label>

用于文本输入。我非常希望标记顺序不会根据输入类型(复选框/单选按钮与文本/电子邮件/密码)而改变。要在实践中做到这一点,您可能希望始终使用标记,如

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

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

此标记还包含您根据 JavaScript 的需要对其进行整理所需的所有信息。对于某些非 JavaScript 样式选项,您可能希望将标签和输入包装在一些包装器元素中,以便您可以将它们定位为与 &lt;aside&gt; 元素分开的组。在这种情况下,标记就像

<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&gt;div 定位该无类 &lt;div&gt; 元素。然后可以使用例如display:gridsubgrid 用于 li.checkbox 和例如display:flex li.checkbox&gt;div 可以很好地定位所有内容。但是,如果您这样做,您将无法简单地通过使用input:not(:focus) + aside { display: none; } 之类的样式来很好地切换帮助文本的可见性。如果您将display:grid 用于li.checkbox,我认为您可以在没有包装器&lt;div&gt; 的情况下生存,因为与flex 不同,它允许在2D 中定位内容。

如果您需要支持有远见的用户但不支持 CSS,那么我没有好的解决方案。使用上面提到的语义列表标记会导致除表单输入之外的项目符号,这对于非 CSS 用户来说可能看起来很混乱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-03
    • 2022-01-17
    • 2014-09-12
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    相关资源
    最近更新 更多