Many probably faced a problem when some text needs to be displayed in one line. At the same time, the text can be quite long, and the width of the block in which this text is located is usually limited, at least by the same size of the browser window. For these cases, the
text-overflow property was invented, which is included in the
CSS3 recommendation , and was first implemented in IE6 a long time ago. In the case of using this property for a block, if its text is wider than the block itself, the text is cut off and an ellipsis is put at the end. Although it is not so simple, but we will return to this a bit later.
With Internet Explorer, everything is clear, what about other browsers? And although at the moment the text-overflow property is excluded from
the CSS3 specification , Safari supports it (at least in version 3), Opera too (from version 9, though it is called the -o-overflow-text property). And Firefox does not, does not support, and even in the 3rd version will not. Sad but true. But can something be done?
Of course, you can do it. When I searched the Internet for this property, and how with this in Firefox, I came across an
article with a simple solution. The essence of the solution:
- We restrict the block in width through max-width or just width.
- With the help of :: after we create auto-generated content that contains ellipsis (three points).
That's all. Details in the article.
The solution is not bad, but there are problems:
- The text can be cut in the middle (conditionally speaking) of the letter, and we will see its “stump”.
- Ellipsis is always displayed, even when the text is less than the width of the block (that is, it does not fall out of it and ellipses are not needed).
')
Step one
To begin with, we will focus on the second problem, namely, how to avoid displaying ellipses when this is not necessary. Having broken his head and “a little” experimenting, he found some solution. I'll try to explain.
The bottom line is that we need a separate block with ellipsis, which will appear only when the text takes up too much space in width. Then I got the idea of ​​a falling floating block. Although it sounds scary, but here, just, there is a block, which is always there, and pressed to the right, but when the width of the text becomes large, the text pushes the block to the next line.
Let's proceed to practice, otherwise it is difficult to explain. Set the HTML structure:
<div class = "ellipsis">
<div> very long text </ div>
<div> </ div>
</ div>
Not very compact, but I didn’t get any less. So, we have a block-container DIV.ellipsis, a block with our text and another block that will contain ellipsis. Note that the “block with ellipsis” is actually empty, because we don’t need the extra three points when we copy the text. Also, do not be afraid of the lack of additional classes, since this structure is well addressed by CSS selectors. And here is the CSS itself:
.ellipsis
{
overflow: hidden;
white-space: nowrap;
line-height: 1.2em;
height: 1.2em;
border: 1px solid red;
}
.ellipsis> div: first-child
{
float: left;
}
.ellipsis> div + div
{
float: right;
margin-top: -1.2em;
}
.ellipsis> div + div :: after
{
background-color: white;
content: '...';
}
That's all.
We check and make sure that in Firefox, Opera, Safari works as intended. In IE, a very strange, but predictable, result. In IE6, everything went away, but in IE7 it just does not work, as it does not support the generated content. But we’ll go back to IE.

In the meantime, let's make this done First, we set the line-height and height of the main block, since we need to know the height of the block and the height of the text line. We set the same value for a margin-top block with ellipsis, but with a negative value. Thus, when a block is not “reset” to the next line, it will be above the text line (one line), when it is reset, it will be at its level (in fact, it is lower, we just pull the line up one line). To hide the excess, especially when you do not need to show ellipsis, we do overflow: hidden for the main block, so when the ellipsis is above the line - it will not be shown. This also allows us to remove and, falling outside the block (to the right edge), the text. So that the text is unexpectedly not transferred and does not push the block with lower and lower dots down, we do white-space: nowrap, thereby prohibiting hyphenation - our text will always be in one line. For the block with the text, we set float: left so that it does not immediately dump the block with ellipsis and occupy the minimum width. Since inside the main block (DIV.ellipsis) both blocks are floating (float: left / right), the main block collapses when the block with the text is empty, so for the main block we set a fixed height (height: 1.2em). And finally, we use the pseudo-element :: after to display the ellipsis. For this pseudo-element we also set the background to overlap the text that will be under it. We set the frame for the main unit, only to see the dimensions of the unit, later we will remove it.
If Firefox supported pseudo-elements as Opera and Safari as well in terms of their positioning (setting position / float etc for them), then you could not use a separate block for ellipsis. Try replacing the last 3 rules with the following:
.ellipsis> div: first-child :: after
{
float: right;
content: '...';
margin-top: -1.2em;
background-color: white;
position: relative;
}
Look in Opera and Safari, everything works as before, and without an additional block with ellipsis. But Firefox is disappointing. But it is for him that we make the decision. Well - it is necessary to manage the original HTML structure.
Step Two
As you can see, we got rid of the ellipsis problem when the text fits in a block. However, we still have another problem - the text is cut in the middle of the letters. And besides, it doesn't work in IE. To overcome both, you need to use the native text-overflow rule for browsers, and only use the solution described above for Firefox (there is no alternative). How to make a decision "only for Firefox" we will understand later, and now we will try to make work that is using text-overflow. Correct CSS:
.ellipsis
{
overflow: hidden;
white-space: nowrap;
line-height: 1.2em;
height: 1.2em;
border: 1px solid red;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
width: 100%;
}
.ellipsis *
{
display: inline;
}
/ *
.ellipsis> div: first-child
{
float: left;
}
.ellipsis> div + div
{
float: right;
margin-top: -1.2em;
}
.ellipsis> div + div :: after
{
background-color: white;
content: '...';
}
* /
Edit, as it turned out, not much. Three lines were added to the style of the main block. Two of these include text-overflow. Setting the width: 100% is necessary for IE, so that the text does not push the block to infinity, and the text-overflow property works; in fact, we have limited the width. The idea is that DIV, like all block elements, stretches across the entire width of the container, and width: 100% is useless, and even harmful, but IE has a problem with layout, since the container is always stretched to fit the content, so it cannot be otherwise. We also made all internal elements string (inline), because for some browsers (Safari & Opera) text-overflow would not work otherwise, because inside there are block (block) elements. We commented out the last three rules, because in this case they are not needed and they break everything (conflict). These rules will only be needed for Firefox.
Let's see what we did and continue.

Step Three
When I once again looked at the page (before I was going to write this article), mentioned at the very beginning, then, for the sake of interest, I looked through the comments on the subject of clever related ideas. And I found an
interesting link in the comments, where it was said about another solution that works in Firefox and IE (for this person, as well as for the author of the first article, there are apparently no other browsers). So, in this decision, the author is somewhat differently struggling with this phenomenon (lack of text-overflow), hanging handlers on overflow and underflow events to elements for which it was necessary to put ellipsis if necessary. Not bad, but it seems to me this solution is very expensive (in terms of resources), especially since it is a little tinged with it. However, figuring out how he achieved this, he came across an interesting thing, namely the CSS -moz-binding property. As I understand it, this is an analogue of behavior in IE, only under a different sauce and more abruptly. But we will not go into details, let us just say that in this way you can hang a JavaScript handler on an element using CSS. It sounds weird, but it works. What are we doing:
.ellipsis
{
overflow: hidden;
white-space: nowrap;
line-height: 1.2em;
height: 1.2em;
border: 1px solid red;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
width: 100%;
-moz-binding: url (moz_fix.xml # ellipsis);
zoom: 1;
}
.ellipsis *
{
display: inline;
}
.moz-ellipsis> DIV: first-child
{
float: left;
display: block;
}
.moz-ellipsis> div + div
{
float: right;
margin-top: -1.2em;
display: block;
}
.moz-ellipsis> DIV + DIV :: after
{
background-color: white;
content: '...';
}
As you can see, we again made few changes. At this step, a strange glitch is observed in IE7, everything is skewed if you do not set the zoom: 1 for the main unit (the easiest option). If you remove (delete, comment out) the rule .ellipsis * or .moz-ellipsis> DIV + DIV (which doesn’t touch IE7 at all), the glitch disappears. Strange all this, if anyone knows what's the matter, let me know. For now, let's zoom: 1 and go to Firefox.
The -moz-binding property connects the moz_fix.xml instruction file with the identifier ellipsis. The contents of this xml file are as follows:
<? xml version = "1.0"?>
<bindings xmlns = "http://www.mozilla.org/xbl" xmlns: html = "http://www.w3.org/1999/xhtml">
<binding id = "ellipsis" applyauthorstyles = "false">
<implementation>
<constructor> <! [CDATA [
this.style.mozBinding = '';
this.className = this.className + 'moz-ellipsis';
]]> </ constructor>
</ implementation>
</ binding>
</ bindings>
All that this constructor does is add the moz-ellipsis class to the element for which the selector worked. This will only work in Firefox (gecko browsers?), So only in it will the moz-ellipsis class be added to the elements, and we can add additional rules for this class. What and sought. Not quite sure about the need for this.style.mozBinding = ", but from experience with expression, it is better to be safe (generally I have little knowledge of this side of Firefox, so I can be mistaken).
You may be alerted that this technique uses an external file and, in general, JavaScript. Do not be afraid. First of all, if the file does not load and / or JavaScript is disabled and does not work, no problem, the user simply will not see the dots at the end, the text will be cut off at the end of the block. That is, in this case we get an “unobtrusive” solution. You can
see for yourself.

Thus, we got the style for the Big Four browsers, which implements text-overflow for Opera, Safari & IE, and for Firefox it emulates, not so hot, but it's better than nothing.
Step Four
At this point, it would be possible to put an end, but I would like to slightly improve our solution. Since we can hang a constructor on any block and, accordingly, gain control over it, why not take advantage of it. Simplify our structure:
<div class = "ellipsis"> very long text </ div>
Oh yeah! I think you will agree with me - this is what you need!
Now remove all unnecessary from the style:
.ellipsis
{
overflow: hidden;
white-space: nowrap;
line-height: 1.2em;
height: 1.2em;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
width: 100%;
-moz-binding: url (moz_fix.xml # ellipsis);
}
.moz-ellipsis> DIV: first-child
{
float: left;
}
.moz-ellipsis> div + div
{
float: right;
margin-top: -1.2em;
}
.moz-ellipsis> DIV + DIV :: after
{
background-color: white;
content: '...';
}
We finally removed the red frame :)
And now, let's finish our moz_fix.xml a bit:
<? xml version = "1.0"?>
<bindings xmlns = "http://www.mozilla.org/xbl" xmlns: html = "http://www.w3.org/1999/xhtml">
<binding id = "ellipsis" applyauthorstyles = "false">
<implementation>
<constructor> <! [CDATA [
(function (block) {
setTimeout (function () {
block.style.mozBinding = '';
var t = document.createElement ('DIV');
while (block.firstChild)
t.appendChild (block.firstChild);
block.appendChild (t);
block.appendChild (document.createElement ('DIV'));
block.className = block.className + 'moz-ellipsis';
}, 0);
}) (this);
]]> </ constructor>
</ implementation>
</ binding>
</ bindings>
What's going on here? We recreate our initial HTML structure. That is, those difficulties with blocks are made automatically, and only in Firefox. JavaScript code is written in the best traditions :)
Unfortunately, we can’t avoid the situation when the text is cut off in the middle of the letter (although, perhaps temporarily, since my solution is still very raw, and it may work out in the future). But we can smooth out this effect a little. To do this, we need an image (white background with a transparent gradient), and some changes to the style:
.moz-ellipsis> DIV: first-child
{
float: left;
margin-right: -26px;
}
.moz-ellipsis> div + div
{
float: right;
margin-top: -1.2em;
background: url (ellipsis.png) repeat-y;
padding-left: 26px;
}
We look and enjoy life.

On this and put an end.
Conclusion
I will
give a small example for third-party layout. I took the table of contents of one of the
pages of Wikipedia (the first thing that turned up), and applied the method described above to it.
In general, this solution can be called universal only with a stretch. It all depends on your layout and its complexity. You may need a file, and maybe a tambourine. Although in most cases, I think it will work. And then, you now have a starting point;)
I hope you learned something interesting and useful from the article;) Learn, experiment, share.
Good luck!