问题描述:

I use a lot of forms in my app, and want to have a common markup (and formatting) scheme for all kinds of cases. What is also important that these forms can contain "readonly" data, so that there is only text, not some form controls.

To solve this, I have thought of definition lists, and combine them with my form elements, like so:

<form>

<fieldset>

<legend>The Legend</legend>

<dl>

<dt><label for="changeable">Label A</label></dt>

<dd><input id="changeable" value="This can be changed"></dd>

<dt>Label B</dt>

<dd>Readonly value</dd>

</dl>

</fieldset>

<fieldset> ... more ... </fieldset>

<menu><input type="submit"> ... other actions ...</menu>

</form>

So the big advantage would be that the markup wouldn't change with different kinds of data. Also seems semantically correct.

However, due to formatting reasons, I need to wrap each pair in a layer. So I could do it like this:

<dl>

<div class="wrapper">

<dt><label for="changeable">Label A</label></dt>

<dd><input id="changeable" value="This can be changed"></dd>

</div>

<div class="wrapper">

<dt>Label B</dt>

<dd>Readonly value</dd>

</div>

</dl>

But I also could use a separate list, and use the <dl> as outer Layer. However this would create a lot of single lists, containing just one item, but would save me some markup:

<dl>

<dt><label for="changeable">Label A</label></dt>

<dd><input id="changeable" value="This can be changed"></dd>

</dl>

<dl>

<dt>Label B</dt>

<dd>Readonly value</dd>

</dl>

So, the question is: does this make sense and is still valid HTML5? Or would there be better options for expressing a mixed form that contains editable elements as well as "read only" elements? Would be important for me that the solution uses more or less the same layout and markup, and still makes sense from a semantic standpoint.

网友答案:

Your second example is invalid, you can't have div elements as direct children of dl elements.

Ideally you'd be able to just use dl, dt, and dd elements as-is, with flexbox to align the elements, but unfortunately flexbox isn't cross-browser compatible enough for me to recommend it as a solution (yet, give it 3-5 years).

If you're going to use <dl> elements, you should be leaving it as one consistent list, because the items belong together as part of the same list:

<dl>
  <dt>...</dt>
  <dd>...</dd>
  <dt>...</dt>
  <dd>...</dd>
  ...
</dl>

When I see a structure as:

<parent>
  <wrapper>
    <key>
    <value>
  </wrapper>
  <wrapper>
    <key>
    <value>
  </wrapper>
  ...
</parent>

I immediately think of using a <table>:

<table>
  <tbody>
    <tr>
      <th scope="row">...</th>
      <td>...</td>
    </tr>
    <tr>
      <th scope="row">...</th>
      <td>...</td>
    </tr>
    ...
  </tbody>
</table>

But that's only because the data is tabular.

If you want to avoid the CSS nightmare that is tables (and I don't blame you if you do), then I'd suggest sticking with <div> elements to produce the structure you want.

<div class="fields">
  <div class="wrapper">
    <div class="key">...</div>
    <div class="value">...</div>
  </div>
  <div class="wrapper">
    <div class="key">...</div>
    <div class="value">...</div>
  </div>
  ...
</div>

<div> elements are semantically meaningless by themselves, so if you're still interested in conveying meaning along with those elements, I recommend adding ARIA roles.

I believe an appropriate role for this case would be grid

<div role="grid">
  <div role="row">
    <div role="rowheader">...</div>
    <div role="gridcell">...</div>
  </div>
  <div role="row">
    <div role="rowheader">...</div>
    <div role="gridcell">...</div>
  </div>
  ...
</div>

This will give you similar semantics to an HTML <table>*, while also giving you the flexibility of <div> elements in CSS.

It's important to remember that <label> and <input> elements will semantically link to each other, so even without the ARIA roles, it will be understood that the form fields are paired together.

* Unfortunately there isn't a role equivalent of key-value lists, otherwise I'd recommend using that instead.

相关阅读:
Top