The goal in this exercise is to have some text (that can wrap) align left and have a small part of text text-align right at the very END of the sentence. This came up in a question which wanted a title, which could wrap followed by a right aligned date. This is the solution we're looking for (border for illustration only):
There is nothing straight-forward about this problem. Inline element don't apply the text-align properties. Moreover, floating a subsequent block level element to the right will put it below, and simply margining it into place will not cause the predecessors text to wrap around it.
This page explores three possible solutions.
Before we begin, a severals things to not. To test the cases, just horizontally shrink and enlarge your viewport. Second, I've included borders so that you can see the actual behaviors better. Finally, all the basic solution start with this basic CSS:
/* give our containers borders
and a flexible width */
#moo, #foo, #bar { width: 25%; border: 1px solid #0f0; }
/* remove the default margins
and padding--start clean */
dl, dd, dt {
margin: 0; padding: 0;
}
/* set the line-height so we
know precisely the vertical
offset to bring the floated
date onto the same line */
#moo dl, #bar dl, #foo dl
{ line-height: 1.4em;}
/* make our titles bold, and
get them out of the way of
any previously floated elements */
#moo dt, #bar dt, #foo dt {
font-weight: bold;
clear: both;
/* for illustration */
border: 1px solid #789;
}
/* float the date to the right,
and move it back into line
with the title */
#moo dd.date, #bar dd.date, #foo dd.date {
float: right;
margin-top: -1.4em;
}
This is perhaps is the "first" idea. Apply some right horizontal padding to some inline element surrounding the text. In fact, this works for the most part. IE actually behaves in the way you'd expect. In the case where the title is on a single line, the inline right padding forces a line wrap. However, in FireFox, after a line wrap, the padding is applied to ALL the lines which the span encompasses.
The additional CSS looks like this:
/* #foo's trick */
#foo dt span {
padding-right: 5em;
border: 1px solid #900;
}
Knowing that inline elements will apply the padding to EVERY line on which they interact allows another possible solution: wrap only the very last word with the span. In fact, this works perfectly. However, the big problem with this solution is that it requires more than a simple understanding of the HTML's structure. It does provide us some insight about another possible solution.
The additional CSS looks like this:
/* #bar's trick */
#bar dt span {
padding-right: 5em;
border: 1px solid #900; }
The following applies two techniques. First, it uses the fact that IE applies properties like horizontal margins and padding to inline elements to the exact beginning or the exact end of the element. Second it uses Mozilla's ability to invoke the :after pseudo-class, and then style it, to create a "buffer" between the end of the title and the wall of the box.
The :after child doesn't behave, however, well with the inline-padding as one would like to expect. Adding the inline right padding to the :after element doesn't force text wraps because it does not alter the container's behavior (this might be a bug). So instead, we'll add some alternative content; I chose lots of periods. So that the periods don't show, we simply make the visibility: hidden;
Here's the CSS:
/* #moo's trick */
#moo dt span:after {
/* place holder content */
content: "................";
/* don't actually show it to the browser */
visibility: hidden;
}
/* this is a "hack" which targets
only IE */
* html #moo dt span { margin-right: 5em; }