views:

199

answers:

5

I'd like to use a definition list as simple as:

<dl>
  <dt>name:</dt>
  <dd>Tomas</dd>

  <dt>address:</dt>
  <dd>this is a very long wrapping address</dd>

  <dt>age:<dt>
  <dd>29</dd>
<dl>

to render something like:

name: Tomas
address: this is a very long
wrapping address
age: 29

The definition list seems semantically the best option here.

Using the new run-in display style will do the trick:

<style> dt { display: run-in; } </style>

But this isn't widely supported yet. How can I style my definition list for better cross-browser support (ie6 not necessary), without changing the html (currently I use display inline and add ugly br's) ?

Edit to clarify :

dt { clear: left; }
dd { float: left; }

won't work because it would render as:

name: Tomas
address: this is a very long
         wrapping address
age: 29

The design specifies that these multi-line field should wrap to the start of line to preserve space.

A: 

You could just float the dd to the left of the previous element like so.

dt { clear: left; }
dd { float: left; }

You could also add a width attribute to either for extra alignment.

dt { clear: left; width: 20%; }
dd { float: left; }
GateKiller
Won't work because this will left-align the dd content if it wraps over multiple lines. The specified design wants the dd data to wrap to the start of the line as shown in "address" example in the question.
Tomas
+4  A: 

I think this would work:

dt {
  float: left;
  clear: left;
  margin: 0;
  padding: 0 .5em 0 0;
}
dd {
  margin: 0;
  padding: 0;
}

Another option that is useful is the :after pseudo-class. You could skip the colon on each of the dt elements and have:

dt:after {
  content: ":";
}

This makes it more flexible and you can change that character across the list and website as a whole, or get rid of it if you felt like it.

To solve the wrapping problem you mentioned, you'll need to set widths on both the dt and dd elements. Or, use a table, with th for name/address etc and td for the "data". IMO a table is a semantically acceptable solution here - it is tabular data.

DisgruntledGoat
Your solution seems to work nicely with one caveat: If a dd is empty the dd below it will shift up to the wrong field! However for my application this is no problem as empty lines will not occur. Thanks!
Tomas
If you didn't know, you can have multiple `dt` elements per `dd` and vice-versa (the idea being a "term" can have multiple definitions and the same definition can be used for multiple terms). The problem you mentioned occurs because an empty `dd` is ignored, therefore the `dt` for that is grouped with the next `dt` and both associated with the latter `dd`.
DisgruntledGoat
Ooh, found a solution: remove the `clear:left` on the `dt` and add this as a separate rule: `dd:after { content: "."; visibility: hidden; clear: left; }`
DisgruntledGoat
That makes sense. Thanks alot!
Tomas
A: 

Well, you could simply let dt float: left

dt { float: left; }

or else let dt display inline:

dt { display: inline; }
Augenfeind
dt { display: inline; } doesn't work cause dd is still a block (try it). dt {float: left; } doesn't work as clarified in the question
Tomas
I'm sorry I mixed up floating dd as suggested by GateKiller, and floating dt as suggested by you and DisgruntledGoat. This seems to work..
Tomas
A: 

I think this (uncomment first line to test for small width):

dl, dd, dt { margin: 0; }
/*dl { width: 80px; }*/
dl dt, dl dd { display: inline; }
dl dd:after { content: ' '; padding-left: 100%; }
tig
A: 

You need to remove the default left margin from the dd.

dt {float:left;clear:left;margin-right:5px;}
dd {margin:0;}
Emily