Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Align `dt` and `dd` on the last line

Tags:

css

I have this html:

<dl>
    <dt>some text</dt>
    <dd>12.45</dd>
    <dt>some larger text</dt>
    <dd>46.05</dd>
    <dt>some even larger text</dt>
    <dd>46.05</dd>
    <div style="clear:both;"></div>
</dl>

...and this CSS:

dl {
    width: 120px;
}
dt {
    float: left;
    clear: both;
}
dd {
    float: right;
}

And it's producing this (I added some unimportant extra styles to show what's going on):

wrong alignment

The problem is, the last dd is not aligned to the last dt. How can I make the number align to the last line of the text? (The second dt/dd is fine)

Here is a jsfiddle with my predicament.

EDIT: To be perfectly clear, this is what I want:

corrected

like image 253
cambraca Avatar asked Feb 03 '12 14:02

cambraca


People also ask

How do you style DT and DD so on the same line?

This can be accomplished by adding a DIV element with the CSS overflow: hidden; around the content of the DD tag. You can omit this extra DIV , but the content of the DD tag will wrap under the floated DT .

What is dt and dd tag in HTML?

The <dd> tag is used to describe a term/name in a description list. The <dd> tag is used in conjunction with <dl> (defines a description list) and <dt> (defines terms/names). Inside a <dd> tag you can put paragraphs, line breaks, images, links, lists, etc.

What is the closing tag for DD?

The DD element provides the definition of a term in a definition list. The closing tag for DD is optional, but its use prevents common browser bugs with style sheets. A DD element should generally be preceded by a DT element that gives the term defined by the DD.


2 Answers

Brief moan

A flexible approach to this has been a known gap in CSS for 15 years. It would be solved but for a 15-year-old Firefox bug relating to CSS 2, and may have been possible if the tab-stops specification suggested 17 years ago ever got off the ground. See the updates below for more details if you're interested.

A limited solution

I found a few different ways of doing this without changing the markup by using pseudo-elements. All of them have significant drawbacks, but if you can reliably establish a maximum width for the dd text, this is probably the best way:

dl {
    line-height: 1.3em;
    overflow: auto;
    width: 140px;
}

dt {
    float: left;
    width: 100%;
}

dd {
    float: right;
    margin-top: -1.3em; /* i.e. minus line-height */
}

dt:after{
    content: '';
    display: inline-block;
    width: 3.5em; /* Max width of a dd element */
}

Example: http://jsfiddle.net/Jordan/p4mMa/3/

Here, the :after pseudo-element takes up extra space in each dt, causing it to break onto a new line if there won't be enough room for the dd element to fit on the end of the current one. (You will also need to reset your margins and padding on the elements, I've left that stuff out for concision.)

Alternatives

Other approaches I considered included display: inline on the dt and using the :before pseudo-element with display: block to break the line (WebKit doesn't like this) and the same approach, but using display: inline-block and width: 100% to appease WebKit browsers (works, but you have indelible empty lines before each dt).

It bears mentioning that IE7 and IE8 are out, since they don't support pseudo-elements. If you're up for progressive enhancement, just remove the negative margin on the dd element in a conditional stylesheet and the prices will always be displayed on a separate line in those browsers.


UPDATE (2013-04-18): I know this is an old answer, but a recent Twitter conversation reminded me of something I think is worth mentioning. There's another way of doing this that doesn't require guesstimating a width for the dd: the little-known display: run-in essentially allows you to treat a block-level element as inline content of its next sibling. The only compromise is wrapping your dd content with a span; other than that, it's a relatively elegant solution that works in most modern browsers—and even IE8!

The problem? A 15-year-old Firefox bug, filed on Christmas Eve 1998 and unlikely to be addressed any time soon.

It's understandable: run-in boxes are "horribly underspecified", there aren't so many use cases and there are more important/useful things to work on. Still, it seems to have slipped through the cracks to an extent, and I can't help but wonder if more people would use it given reliable support.


UPDATE (2013-11-13): This exact use case was described on a list of suggested extensions to CSS published by the W3C in December 1998. Also, way back in January 1997, Dave Raggett authored proposal for a tab-stops property that would have worked admirably here. Sadly, neither the use case nor the proposal gained much traction.

like image 72
Jordan Gray Avatar answered Oct 04 '22 02:10

Jordan Gray


Your problem becomes no problem if you don't mind switching to ul/li/span:

http://jsbin.com/acunew/3/edit#html,live

<ul>
    <li>some text <span>12.45</span></li>
    <li>some larger text <span>46.05</span></li>
    <li>some even larger text <span>46.05</span></li>
</ul>

The new HTML isn't quite as semantic as yours was, but I think it's fine.

The CSS is almost the same:

ul {
    width: 120px;
    padding: 0;
    list-style: none;
    overflow: hidden;
}
li {
    clear: both;
}
span {
    float: right;
}
like image 44
thirtydot Avatar answered Oct 04 '22 01:10

thirtydot