Semantics and Structure of Name-Value Pairs

Viewed 36252

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 Answers

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>

dl {
  display: grid;
  grid-template-columns: auto auto;
}

dd {
  margin: 0
}
<dl>
  <dt>key</dt>
  <dd>value</dd>
  <dt>key</dt>
  <dd>value</dd>
</dl>

I used <dl> <dt> <dd> and styled them with grid

Related