Semantics and Structure of Name-Value Pairs

2019-01-31 05:38发布

This is a question I have been struggling with for a while. What is the proper way to mark up name/value pairs?

I'm fond of the <dl> element, but it presents a problem: There is no way to separate one pair from another - they have no unique container. Visually, the code lacks definition. Semantically, though, I think this is the correct markup.

<dl>
    <dt>Name</dt>
    <dd>Value</dd>
    <dt>Name</dt>
    <dd>Value</dd>
</dl>

In the above code, it is difficult to properly offset the pairs visually, both in code and rendered. If I wanted to, for instance, but a border around each pair, that would be a problem.

We may point to tables. It could be argued that name-value pairs are tabular data. That seems incorrect to me, but I see the argument. However, the HTML does not differentiate the name from the value, except in position, or with the addition of class names.

<table>
    <tr>
        <td>Name</td>
        <td>Value</td>
    </tr>
    <tr>
        <td>Name</td>
        <td>Value</td>
    </tr>
</table>

This makes much more sense from a visual standpoint, both in code and in CSS. Styling the aforementioned border is trivial. However, as mentioned above, the semantics are fuzzy at best.

Thoughts, comments, questions?

Edit/Update Perhaps this was something I should have explicitly mentioned in relation to structure, but a definition list also has the problem of not semantically grouping the pairs. The ordering and implicit border between a dd and a dt is easily understood, but they still feel slightly off to me.

14条回答
看我几分像从前
2楼-- · 2019-01-31 06:04

Hmm. dt/dd sound best for this and it is possible to offset them visually, although I do agree it's more difficult than for a table.

As for source code readability, how about putting them into one line?

<dl>
    <dt>Name</dt> <dd>Value</dd>
    <dt>Name</dt> <dd>Value</dd>
</dl>

I agree it's not 100% perfect, but seeing as you can use space characters for indentation:

<dl>
    <dt>Property with a looooooooooong name</dt>   <dd>Value</dd>
    <dt>Property with a shrt name</dt>             <dd>Value</dd>
</dl>

it might be the nicest way.

查看更多
一夜七次
3楼-- · 2019-01-31 06:12

This is not my preferred solution, but it is a clever abuse of the semantic element:

Use a new <dl> per <dt>/<dd> pair:

<div class="terms">
    <dl><dt>Name 1</dt><dd>Value 1</dd></dl>
    <dl><dt>Name 2</dt><dd>Value 2</dd></dl>
</div>

An example with css floats and red border on hover:

dt:after { content:":"; }
dt, dd { float: left; }
dd { margin-left: 5px }
dl { float: left; margin-left: 20px; border: 1px dashed transparent; }
dl:hover { border-color: red; }
<div class="terms">
    <dl>
        <dt>Name 1</dt>
        <dd>Value 1</dd>
    </dl><!-- etc -->
    <dl><dt>Name 2</dt><dd>Value 2</dd></dl>
    <dl><dt>Name 3</dt><dd>Value 3</dd></dl>
    <dl><dt>Name 4</dt><dd>Value 4</dd></dl>
    <dl><dt>Name 5</dt><dd>Value 5</dd></dl>
    <dl><dt>Name 6</dt><dd>Value 6</dd></dl>
</div>

查看更多
Fickle 薄情
4楼-- · 2019-01-31 06:13

The line from spec:

Name-value groups may be terms and definitions, metadata topics and values, questions and answers, or any other groups of name-value data.

I assume use of elements <dl>, <dt> and <dd>.

查看更多
Melony?
5楼-- · 2019-01-31 06:14

Following the specification (and further details) provided by Alexandr Antonov: use dl, dt, dd, and optionally div.

A combination of dl, dt, and dd is semantically fine for key-value pairs:

<dl>
    <dt>Key1</dt>
    <dd>Value1</dd>
    <dt>Key2</dt>
    <dd>Value2</dd>
</dl>

For easier styling or parsing, divs can be used as children of dl to group the key-value pairs (and makes dt and dd be grandchildren of dl):

dl { display: table; }
dl > div { display: table-row; }
dl > div > dt, dl > div > dd { display: table-cell; border: 1px solid black; padding: 0.25em; }
dl > div > dt { font-weight: bold; }
<dl>
  <div>
    <dt>Key1</dt>
    <dd>Value1</dd>
  </div>
  <div>
    <dt>Key2</dt>
    <dd>Value2</dd>
  </div>
</dl>

查看更多
迷人小祖宗
6楼-- · 2019-01-31 06:17

I do like Unicron's idea of putting them all on one line, but another option would be to indent the value below the definition name:

<dl>
    <dt>Name</dt>
       <dd>Value</dd>
    <dt>Name</dt>
       <dd>Value</dd>
</dl>

This way might be a little easier on the eye in ridiculously long definitions (although if you're using ridiculously wrong definitions then perhaps a definition list isn't what you really want after all).

As for the rendering on screen, a fat bottom margin applied to the dd is plenty visual separation.

查看更多
Viruses.
7楼-- · 2019-01-31 06:18

it is difficult to properly offset the pairs visually, both in code and rendered. If I wanted to, for instance, but a border around each pair, that would be a problem.

Others before me have dealt (quite well I think) with the problem of providing visual definition in code. Which leaves the problem of rendering and CSS. This can be done quite effectively in most cases. The biggest exception is placing a border around each set of dt/dds, which is admittedly extremely tricky - perhaps impossible to style reliably.

You could do:

dt,dd{ border:solid; }
dt{ margin:10px 0 0 0; border-width:1px 1px 0 1px; }
dd{ margin:0 0 10px 0; border-width:0 1px 1px 1px; padding:0 0 0 10px; }
dd::before{ content:'→ '; }

Which works for key-value PAIRS, but presents problems if you have multiple dds within one "set" like:

<dt>Key1</dt>
  <dd>Val1.1</dd>
  <dd>Val1.2</dd>
<dt>Key2</dt>
  <dd>Val2.1</dd>
  <dd>Val2.2</dd>

However, border-styling limitations aside, doing anything else to associate sets (backgrounds, numbering, etc.) is quite possible with CSS. There's a nice overview here: http://www.maxdesign.com.au/articles/definition/


Another point I think is worth noting, if you're looking to optimally style definition-lists to provide visual separation - CSS's automatic-numbering features (counter-increment and counter-reset) can come in quite handy: http://www.w3.org/TR/CSS2/generate.html#counters

查看更多
登录 后发表回答