tags:

views:

915

answers:

7

For explanation imagine a simple address. Written in a HTML paragraph with line breaks it would like this:

Street: Example Street 1
City: Vienna
Zip Code: 1010
Country: Austria

Most of the time that's completely okay, but sometimes I have to achieve the following output:

Street:   Example Street 1
City:     Vienna
Zip Code: 1010
Country:  Austria

My thoughts so far:

  1. Should be valid XHTML and work or degrade gracefully in all major browsers
  2. Using tags in a semantically correct way is strongly preferred
  3. Because of point two: I hope there's a better solution than tables
  4. The problem is not limited to addresses - would be useful in other situation too

How do you achieve this output (using HTML and/or CSS)?

+2  A: 

Tables are the way to go.

Henrik Paul
+13  A: 

I think you've taken "tables are bad" concept to the extreme.

  • Tables used purely for layout (when other element would be more semantic) are bad.
  • Tables for tabular data are good. They were intended for that purpose!

What you've got fits very nicely into concept of rows and columns, with headers (<th>) and data (<td>) – based on semantics, not only layout.

If you want to make it more explicit that it's an address, then use adr Microformat or add a <caption>.

Wrong approaches:

  • <dl>: "1010" is not a definition of "Zip Code". The other way round it makes a bit more sense, but the relationship is just as clear with <th><td>, it doesn't rely on CSS, and will look perfect regearless of user's font size.
    If you use <th> will be perfectly rendered even in lynx! Address in <dl> without CSS trick will look weird.
  • HTML's <address> element may not be appropriate for this, because it is intended only for page author's/maintainer's contact information. It also allows inline content only, so you would lose structure of the address.
porneL
Tables are bad when you *don't* use them for tabular layout ;-)
Chris Noe
@Chris, I 100% agree. It drives me mad that anti-table fever is so bad these days, people go to ridiculous lengths to avoid using tables for tabular data.
David Arno
I once wrote a tableless spreadsheet to respond to a post claiming tables should "never" be used. Never again...
Ross
Tables can be bad simply because the markup is ridiculously verbose. I hate the "tables are bad" extremists, but sometimes they can be write, even for tabular data, if that tabular data can be created more simply with alternative markup.
Dan Herbert
@porneL: See http://www.maxdesign.com.au/presentation/definition
Christoph Schiessl
@porneL: that link you've added (the one right above this comment) supports the view that dl is the right tool for this job. Just sayin'. From TFA: "Definition lists can be used to tie together any items that have a direct relationship with each other (name/value sets)"
nickf
+7  A: 

I find that definition lists make much more sense than tables here. Float the dt to the left with a specific width and have it clear on the left. If either the label or the data are going to wrap, you'll have to do some post-element-float-clearing trickery to make this work, but it doesn't sound like you'll need that. (I think it's worth it, anyway; plus, do it once and you'll never have to do it again.)

You can even use :after to add the colons automatically, if you don't mind brushing off IE6.

Eevee
I haven't thought about that yet ;) I like the idea very much!
Christoph Schiessl
I have changed my mind on this one. Initially I down-voted it as it seemed a misuse of dt/dd's. Upon reflection though, the data in the question is a classic case of data that fits the dt/dd model perfectly, so it's now upvoted :)
David Arno
If you like it Christoph, then you ought to mark it as the "right" answer.
David Arno
@David Arno: I know that. Just waiting a little longer - maybe someone has a even better solution ;) Besides: The exchange in the comments is quite interesting...
Christoph Schiessl
This makes sense to me - wrap it in an address block as well for extra semanticity =)
Ross
This is a valid solution, but I have to agree with others that this is no better than a tables solution. Even a UL would be incorrect. The data isn't a list at all, its just data.
Abyss Knight
Problem with DL: DT "column" doesn't autosize to longest item, so you have to use known names of fields (IE, lines could break if users are able to add field with long name).On the other side, table with TH for headers and TD for content are OK, semantically more suitable, and will autosize.
Tomáš Kafka
A: 

No need for tables (not that tables would be really inappropriate in this setting). I do this kind of thing all the time.

<div class=DetailsRow>
  <div class=DetailsLabel>Street</div>
  <div class=DetailsContent>123 Main Street</div>
</div>
<div class=DetailsRow>
  <div class=DetailsLabel>City</div>
  <div class=DetailsContent>Vienna</div>
</div>
  ...etc

and

div.DetailsRow
{
clear:both;
}

div.DetailsLabel
{
float:left;
width:100px;
color:gray;
}

div.DetailsContent
{
float:left;
width:400px;
}
Herb Caudill
so you regularly write reams of code to bodge div's into behaving like a poor implementation of tables. Why? You are even using fixed pixel-based widths, so your solution is crap in accessibility terms...
David Arno
fixed width divs != bad accessibility.
nickf
You've got divitis. http://csscreator.com/?q=divitis
porneL
With divs being block level elements, I don't think this degrades particularly nicely.
SpoonMeiser
1. Fixed widths are not "crap in accessibility terms." If the text is too big for the horizontal width, it wraps. No harm done.
Herb Caudill
2. The situation given here isn't a table. It's not a definition list either. Since there's not an HTML element that matches the situation precisely, I think divs are no better or worse than the alternatives.
Herb Caudill
3. This degrades fine. If CSS is turned off, this is perfectly readable.
Herb Caudill
What I meant was that your labels and data appear on separate lines and don't necessarily appear related. I think getting down voted is a bit harsh though.
SpoonMeiser
+2  A: 

Don't listen to the people saying that this is tabular data. Just because something has been presented in rows, it doesn't make it a table!

This is a great situation to use the dl, dt and dd tags. It's a bit of a stretch from what they're originally intended for, but it's still much more meaningful than a table, spans or divs.

<dl>
    <dt>Street</dt>
    <dd>Example Street 1</dd>
    <dt>City</dt>
    <dd>Vienna</dd>
    <dt>Zip Code</dt>
    <dd>1010</dd>
    <dt>Country</dt>
    <dd>Austria</dd>
</dl>

And the CSS:

dt {
    width: 150px;
    float: left;
    clear: left
}
dd {
    float: left;
}

That's fairly basic CSS - it probably won't hold up to a lot of situations (eg: two dd's in a row, a really long dt), but it's a start. Look at the inline-block property for the dt, and perhaps instead of using floating, you could set a left-margin of 150px on the dd.

nickf
If you look up "Zip Code" in dictionary, you won't find "1010" as a definition (unless it's a Big Bender's Binary Dictionary). You've got term/definition backwards.
porneL
This is fine, but I just don't agree that dl/dt/dd is more semantically appropriate here than the alternatives. These aren't definitions: They're label/value pairs. Since there's no corresponding entity in HTML, the alternative approaches suggested here (divs, tables, definitions) are equally fine.
Herb Caudill
The problem with this approach is that you have to define a with for the labels. I would rater set a margin that insures a minimum space between the labels and the two columns of text, but I think that this is only possible using tables.
Jan Aagaard
“it's still much more meaningful than a table” — I disagree it’s more meaningful than a table. A properly marked up table would be slightly more meaningful than the `<dl>` version if you had column headers. Of course, the definition list is fine too.
Paul D. Waite
A: 

As others have mentioned, floated elements are the way to go here.

This would be my solution:

<p class="details">
    <span class="label">Street:</span>
    Some Street or other.
    <br />

    <span class="label">City:</span>
    A City.
    <br />
</p>

With CSS that looks like this:

p.details {
    padding-left: 200px;
}

p.details span.label {
    float: left;
    clear: left;
    width: 200px;
    margin-left: -200px;
}

Because the main text isn't floating, this avoid any issues where that text is long and needs to wrap; it stops the floating element becoming to wide and then floating below the label. This means that no special cases are needed for when this text is multi-line either, say, if you wanted to have a multi-line address.

Similarly, this method also works if the label data needs to wrap over multiple lines, since the next label clears the previous float.

Having the line breaks in there means it also degrades nicely and looks like you would expect when not using CSS.

This method works very well for laying out forms, where <label> elements are used instead of the spans, and the paragraphs can be selected in the CSS as any paragraph that is the child of a <form>.

SpoonMeiser
A: 

Or you can throw away all sanity (and semantics) and recreate tables using CSS (tested in Firefox and Chrome):

<html>
<head>
<title>abusing divs</title>
<style type="text/css">
div.details {
    display: table;
}
div.details > div {
    display: table-row;
}
div.details > div > div {
    display: table-cell;
    padding-left: 0.25em;
    padding-right: 0.25em;
}
</style>
</head>
<body>
<div class="details">
    <div>
        <div>Street</div>
        <div>123 Main Street</div>
    </div>
    <div>
        <div>City</div>
        <div>Vienna</div>
    </div>
    <div>
        <div>This is a very very loooong label</div>
        <div>...</div>
    </div>
</div>
</body>
</html>

Just kidding.

panzi