0

I want to use DL/DT/DD approach to organize my forms. I need to structure them as tables (a column for label and a column for value). The following html+css works fine but till I add margin or padding to dt and/or dd.

<html><head>
<style>
dl {
  width: 100%;
  overflow:hidden;
}

dt {
  float: left;
  width: 50%;
  margin: 0px;
  padding: 0px;
}
dd {
  float: left;
  width: 50%;
  margin: 0px;
  padding: 0px;
}
</style></head>
<body>
<dl>
  <dt>first name</dt>
  <dd><input />
</dl>
</body></html>

If I replace "margin: 0px" in dt's style with "margin: 5px" or the same for padding then dd element jumps on next row.

I need:

  • 2-column table layout for DL
  • do not use absolute widths (that's because I'm using "50%" as columns' widths)
  • add some margin/padding to dt/dd

How to add margin/padding and keep relative widths (50%/50%)?

p.s. I've seen many similar questions about DL and table layout, but my question about combination of dl + table layout + relative widths + paddings. I can get it working with relative widths or paddings but not both.

Shrike
  • 9,218
  • 7
  • 68
  • 105

5 Answers5

1

All you need is to specify the magical property: box-sizing: border-box. You can then use padding all you want without increasing the width.

JSFiddle Demo

See also: box-sizing support in ie7

box-sizing addresses padding and borders, but not margins. If you want to use margin as well, use calc() to subtract the margin from the width. For example, if you want a 5px left margin:

dd {
    margin: 0 0 0 5px;
    width: calc(50% - 5px);
}

But, calc() does not work in IE8 or earlier.

more on calc()

Community
  • 1
  • 1
gilly3
  • 87,962
  • 25
  • 144
  • 176
1

I found a solution now (under the shower!)

Give the outer DL display:block and some padding to the left and right that add up to the margins and padding the DT and DD. Now the 100% of the DL are the basis for the 50% of the inner elements. Now give these your desired margins and paddings. Until now it won't work as desired. Yet there's things still to come. Add up all the margins and paddings of the DT and the DDrespectively. And give each a negative margin (the DT to the left and the DD to the right) so all the margins and paddings of them add up to zero/naught/niente/nada. E Voilà! Now you can have any combination of percentage you want, e.g. 30% - 70%.

dl {
    display: block;
    overflow:hidden;
    padding: 5px 15px 5px 20px;

}

/* the -15px in the margin is to compensate for the 5px in the margin and the 2 x 5px in the padding */
dt {
    float: left;
    width: 30%;
    margin: 0px 5px 0 -15px;
    padding: 5px;
    background: yellow;
}
/* the -10px in the margin is to compensate for the 2 x 5px in the padding */
dd {
    float: left;
    width: 70%;
    margin: 0px -10px 0 0px;
    padding: 5px;
    background: yellow;
}

http://jsfiddle.net/HerrSerker/AADG7/

yunzen
  • 32,854
  • 11
  • 73
  • 106
  • Nice solution. But speaking of dl/dt/dd I found to pretty hard to use. Try to the following markup:
    first
    name
    Last name
    but, it's indeed isn't related the original question.
    – Shrike Dec 19 '11 at 11:06
1

You just need to make sure that each dt clears the previous alignment;

add

dt {
    clear:both;
}

to the css defined above

see http://jsfiddle.net/Nd2sH/

pflangan
  • 21
  • 1
0

I would use nested DIVs or spans, inside the and elements. Right now, the 50% width is conflicting with the need for a padding or a margin.

Something like this would accomplish the same thing.

  <dt><div style="margin:5px;">first name</div></dt>
  <dd><div style="margin:5px;"><input /></div></dd>
Brian Hoover
  • 7,861
  • 2
  • 28
  • 41
0

The only things about it you can do:

Use JavaScript to get the width of the DL and then calculate the width of the DT and the DD so that the width of these plus the margin and the padding add up to the 100% of the DL

Or set a fixed width for the first column and no width for the second

Or wrap the content of each DT and DD with a DIV and give this the margin and padding

yunzen
  • 32,854
  • 11
  • 73
  • 106