How Do I Show A String In HTML Without Wrapping?
Solution 1:
Yes it can!
Since you can't know ahead of time which string is going to fit, the trick is to put all the strings in the DOM and let the browser's flow rules determine which string will fit. I'll describe what HTML and CSS are required, and the corresponding server-side code should become clear.
Overview
Suppose you have a div
(the "gadget", described below) that's only visible if the string inside it fits without wrapping. Then you can show the longest string that fits by vertically stacking these gadgets in reverse order of string length:
*-----------*
| AZ | \
*--\--------*
\ \
\
\ *-----------*
| D'backs | \
*--\--------*
\ \
\
\ *-----------*
| | \ <-- Empty because "Diamondbacks" doesn't fit.
*--\--------*
\ \
\
\ *-----------*
| | <-- Empty because "Arizona Diamondbacks" doesn't
*-----------* fit.
Stacked on top of each other on the page, you'll only see the first string that fits. For instance, in the above example, the first two gadgets would be invisible and you'd see
*-----------*
| D'backs |
*-----------*
because AZ
would be covered.
With me so far? Great. But the question remains: how do you make a div
that's only visible when the string inside it fits? In other words, how do you make...
The Gadget
Here's some real CSS magic. You'll have to stare at it for a few minutes to think about why it works. Imagine a smaller "viewing window" (div A
) with a larger div positioned immediately behind it that was twice as wide (div B
). Inside div B
is a spacer (div C
) and the text (div D
). The whole thing looks like this:
|-div B-----------------*------------------*
||-div C---------------||-div D---------| |
|| (hidden fixed-width ||\ | | \
|| spacer div) || D ' b a c k s | |
||_____________________|*__\____________| * \
| |
| \ \ | \
| |
| \ \ | \
| |
| \ \ | \
| |
|______________________________\___\_______| \
\ \ \
\ *-div A-------------*
| |
\ | |
*___________________*
div A
is overflow hidden, so when it's all stacked vertically, you'll only see whatever happens to sit behind div A
: in this case, the contents of div D
:
| div B - - - - - - *-div A-----------*
| div C - - - - - |/-div D--------\ | <-- Most of div B and all of div C
||D ' b a c k s | | are hidden because div A is
|\______________/ | set to overflow hidden.
| - - - - - - - |-----------------|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
Note that div C
and div D
are both set to float left inside of div B
. If the string inside div D
is too long, it will flow underneath div C
instead, and it will be invisible:
| div B - - - - - - *-div A-----------*
| div C - - - - - | | <-- Most of div B and all of div C
| | are hidden because div A is
| | set to overflow hidden.
| - - - - - - - |-----------------|
/-div D--------------------\
| D i a m o n d b a c k s |
\--------------------------/
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
And that's the gadget!
Here's some example CSS to make it more clear:
.divA {
position: relative;
overflow: hidden;
}
.divB {
position: absolute;
top: 0;
right: 0;
width: 200%;
height: 1000px /* arbitrarily large */
}
.divC {
width: 50%;
height: 50%;
float: left;
}
.divD {
float: left;
background-color: white;
}
and the DOM:
<div class="divA">
<div class="divB">
<div class="divC"></div>
<div class="divD">AZ</div>
</div>
<div class="divB">
<div class="divC"></div>
<div class="divD">D'backs</div>
</div>
<div class="divB">
<div class="divC"></div>
<div class="divD">Diamondbacks</div>
</div>
</div>
Complete Solution
Here's a working example of the entire example given here: http://jsfiddle.net/sFjdL/
(Note that there are some minor modifications to make the heights flow naturally, which I don't describe here.)
ARrrgh. Does it have to be so complicated? Why can't I just...
approximate that each character is N
pixels wide?
You can -- but to be safe you'll have to overestimate the space you need, so it may be sub-optimal. Choosing the smallest "safe" value for N
is hard, and always results in waste. Furthermore, you won't be able to handle large font sizes for vision-impaired users. The above solution scales just fine.
use @media
CSS to choose the right string for the right form factor?
Again, you'll have to know ahead of time how many pixels long each string is, which is impossible on the server side. You can probably get close, but why "get close" when you can be perfect?
Fork This Idea
There are number of directions you might take this concept. For instance, here's a div
that has hover text only if the string inside it has the CSS ellipsis because it doesn't fit:
.under {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 50%;
position: absolute;
top: 0;
right: 0;
z-index: 1;
}
.over {
position: relative;
z-index: 2;
}
the DOM:
<div class="divA">
<div class="invisible_for_height"></div>
<div class="divB">
<div class="under" title="Expectorating">Expectorating</div>
<div class="divC"></div>
<div class="divD over">Expectorating</div>
</div>
</div>
and the demo:
Also, try setting the div
s to all have background colors and remove the overflow hidden. It helps for debugging! Example: http://jsfiddle.net/X3bqx/1/
Post a Comment for "How Do I Show A String In HTML Without Wrapping?"