views:

72

answers:

6

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.

+1  A: 

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.

Unicron
A: 

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.

hollsk
+1  A: 

I think a definition list is probably a bad idea. Semantically, they are used for definitions. Other key-value lists will often differ from definition titles and descriptions.

A table is one way to go, but what about an unordered list?

<ul>
    <li class="key-value-pair">
        <span class="key">foo</span>
        <span class="value">bar</span>
    </li>
</ul>
Bauer
Definition lists may be slightly poorly named in this regard, but they are not intended purely for definitions (they would be of fairly limited use case if they were) - the W3C spec. that defines them actually has an example of using them for marking up a dialogue.
lucideer
Thinking about it from an object-oriented standpoint, I suppose what I'm looking for is "an unordered list of name-value pairs", but I'm not sure this is the best answer (for now). +1
Ryan Kinal
@Bauer This is kind of microformat approach, but in default browser rendering or screen reader, you will get `foo bar`, like `foo bar` without any tags at all. One of the spans needs to be more than a span. Maybe `<strong>`? Then the second one is not needed.
takeshin
A: 

How about just placing a blank line btween pairs? This requires no special hanling for long values.

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

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

    <dt>Name</dt> 
    <dd>Value</dd> 
</dl> 
Philip Smith
+1  A: 

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

lucideer
+2  A: 

Thanks for this interesting question. There are few more things to consider here.

What is a pair? Two elements together. So we need need a tag for this. Let's say it is pair tag.

 <pair></pair>

The pair contains the key, and the corresponding value:

 <pair><key>keyname</key><value>value</value></pair>

Then, we need to list the pairs:

<pairlist>
     <pair><key>keyname</key><value>value</value></pair>
     <pair><key>keyname</key><value>value</value></pair>
</pairlist>

The next thing to consider, is the display of the pairs. The usual layout is the tabular one:

key value
key value

and the optional separator, which is usually colon:

key : value
key : value

The colons can be easily added via CSS, but this certainly won't work in IE.

Case described above is the ideal one. But there is no valid HTML markup to fit in this easily.


To sum up:

dl is semantically closest, for simple cases of key and value, but is hard to apply visual styles (eg. to display the pairs inline or to add red border to just hovered pair). The case which fits most for dl is glossary. But this is not the case we discuss.

The only alternative I can see in this case is to use table, like this:

<table summary="This are the key and value pairs">
    <caption>Some notes about semantics</caption>
    <thead class="aural if not needed">
        <tr><th scope="col">keys</th><th scope="col">values</th></tr>
    </thead>
    <tbody class="group1">  
        <tr scope="row"><th>key1</th><td>value1</td></tr>
        <tr scope="row"><th>key2</th><td>value2</td></tr>
    </tbody>
    <tbody class="group2">
        <tr scope="row"><th>key3</th><td>value3</td></tr>
        <tr scope="row"><th>key4</th><td>value4</td></tr>
    </tbody>
</table>

One more:

<ul>
  <li><strong>key</strong> value</li>
  <li><strong>key</strong> value</li>
</ul>

or:

<ul>
  <li><b>key</b> value</li>
  <li><b>key</b> value</li>
</ul>

or, when the keys may be linked:

<ul>
  <li><a href="/key1">key1</a> value</li>
  <li><a href="/key2">key1</a> value</li>
</ul>

The key and value pairs are usually stored in database, and those usually store tabular data, so the table would fit best IMHO.

What do you think?

takeshin
Very thorough answer. I like how you showed your line of thought. +1
Ryan Kinal