Overflowing HTML line text before it gets obscured by right aligned content

Question!

I've got some text that is displayed on a single line in a container that has a fixed width. If the text can't be contained within the width of the container the overflow is hidden. Any combination of three status icons may appear positioned from the right hand side of the container. If any of these icons appear I'd like the text overflow to be hidden before the first icon appears so the text does not appear obscured behind the icons.

How can I overflow the text so it doesn't flow under the icons (ideally using only CSS and not needing to resort to JavaScript)?

An example of the CSS and HTML I've started from (neither of which are set in concrete) follows. Here's a live example of the code which also illustrates the desired result (note it has an background image inlined in the CSS using the data URI scheme so won't work in versions of Internet Explorer earlier than 8).

CSS:

.line {
  position: relative;
  width: 200px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.star, .circle, .flag {
  position: absolute;
  top: 3px;
  height: 23px;
  width: 15px;
  background-image: url(icons.png);
}

.star {
  right: 30px;
}

.circle {
  right: 15px;
  background-position: -17px 0;
}

.flag {
  right: 0;
  background-position: -32px 0;
}

HTML:

<div class="line">This is some text that should have overflow that is hidden.</div>
<div class="line">
	This is some text that should have overflow that is hidden.
	<div class="flag"></div>
</div>
<div class="line">
	This is some text that should have overflow that is hidden.
	<div class="circle"></div><div class="flag"></div>
</div>
<div class="line">
	This is some text that should have overflow that is hidden.
	<div class="star"></div><div class="circle"></div><div class="flag"></div>
</div>
<div class="line">
	This is some text that should have overflow that is hidden.
	<div class="star"></div><div class="flag"></div>
</div>
<div class="line">
	This is some text that should have overflow that is hidden.
	<div class="circle"></div>
</div>


Answers

Your problem is that you want to affect the rendering of a parent tag based on the number of its children of a particular type. That's just not possible without some programmatic intervention.

If you're programmatically generating these lists, I'd suggests just adding three classes which specify the width of the line to the outer div:

.line {
  position: relative;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.noicon {
   width: 200px
}

.oneicon {
   width: 183px
}

.twoicon {
   width: 168px
}

.threeicon {
   width: 154px
}

<div class="line noicon">This is some text that should have overflow that is hidden.</div>
<div class="line oneicon">
        This is some text that should have overflow that is hidden.
        <div class="flag"></div>
</div>
<div class="line twoicon">
        This is some text that should have overflow that is hidden.
        <div class="star"></div><div class="flag"></div>
</div>
<div class="line threeicon">
        This is some text that should have overflow that is hidden.
        <div class="star"></div><div class="circle"></div><div class="flag"></div>
</div>

Otherwise, your best option might be to use Javascript to dynamically shrink the boxes.



The easiest way to be able to let those icons affect the width of the text is to have them precede it (they're absolutely positioned anyway), and to give text itself a container as well (I'm pretty sure you need that, whichever way you do it). So you end up with this:

<div class="line">This is some text that should have overflow that is hidden.</div>
<div class="line">
    <div class="flag"></div>
    <div class="text">This is some text that should have overflow that is hidden.</div>
</div>
<div class="line">
    <div class="circle"></div>
    <div class="flag"></div>
    <div class="text">This is some text that should have overflow that is hidden.</div>
</div>

Here's the only new CSS you need to make that work (in addition to the CSS in the question):

.text {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.flag   ~ .text { width: 183px; }
.circle ~ .text { width: 168px; }
.star   ~ .text { width: 154px; }

The .text rule is the same as the .line div you used for your own working example. The real "magic" happens in those last rules, and they're the reason I moved the image divs up. That allows you to use the CSS3 sibling selector to set the width of the .text div based on the presence of the icons. You can simply let the CSS cascade take care of the width by listing the icon classes in right-to-left order.

As a side note, I do have to say that there are rather a lot of divs here, so there's no indication of what it actually means. Your first concern should always be to create semantic HTML.

I'd probably want to put the text in paragraph tags and the icons in a list, and give each list item a textual description as well (hiding it with CSS). Then again, maybe that's not actually appropriate (and maybe the icon divs should really come after the text); I can't tell. And if the icons go in a list, the sibling selector will need some help...

By : mercator


I can't comment on Merkuro's answer and your response (too few points), so I'm adding this here: You could just use a placeholder image of the line covered by the opaque img so that, once placed, it'll cover the text and the line, but the background line is seemingly uninterrupted as the image has a line that aligns up neatly with the real line behind it. And you could use hover: to switch images when the line changes colour, etc. (best I could think of at the moment)

Also if you use seperate images with just one symbol (star, circle, flag) and pad the images to the right with opaque whitespace upto the width you want to cover, you'd have something like this (I did my best to encode the base64 images, but it only works in FF. The CSS should work correctly with proper linked images).

CSS:

.line {
  position: relative;
  width: 200px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.star,
.circle,
.flag {
  position: absolute;
  top: 3px;
  height: 23px;
  right: 0px;
}

.star {
  width: 45px;
  background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAQCAMAAABeF73YAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFAAAA%2F%2F%2F%2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ3bsYwAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjM2qefiJQAAAE5JREFUKFOd0jEOACAIA8Dy%2F0%2BLDQY3WlhcDlIJCKtQ%2Br1D844D2vhSOk%2FZNf07pxs6GKYaptFX0tALesXNMAwipfmg4sn1u5H20Tsz%2BQHT4AKfEabvTAAAAABJRU5ErkJggg%3D%3D');
  //background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAAQCAIAAADBBVtVAAAAfUlEQVR4nNVVQQrAIAyz4v%2B%2F3B0K%0AzuEYth0p6UmF1hiSKKraOKvnR4hIfkigfoBeVVnoRnkJ8cSsi9emhwQD3O9m%2FQQTJrXcrN%2Bdb%2FQj%0Aozau9R0l%2BIsgtmkc%2Bi4YcESOZP8UCT7au926Xvy9nYftKW5bIx9AbNN4OJYXccJcMFQtIo2LoIEA%0AAAAASUVORK5CYII%3D');
}

.circle {
  width: 30px;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAQCAMAAABeF73YAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFAAAA%2F%2F%2F%2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ3bsYwAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjM2qefiJQAAAENJREFUKFO10UEOACAIA8Hy%2F08rSPC6NZHzpBCqsEaWjieuHLKnUGnkk7cm3ucTDuJ3usn%2F3u4%2Bsj2uicBjUPU3zuQLvrYCj5S%2FhI4AAAAASUVORK5CYII%3D');
  //background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAQCAIAAADmq9q9AAAAaUlEQVR4nO1VQQ7AIAhrjf%2F%2FMjuO%0AGOVAF8VkvWFiKAUKzQw10E4TeFGISlc%2Bk%2FSh2Ou8KgOP6csOKqusCptCs5KhEpeeFuZyVeJNSe%2FR%0A5apgXbpiLQ0AST9rcRhkFS1OcttvTyn%2FyzzBA%2B9YHizbV3zJAAAAAElFTkSuQmCC');
}

.flag {
  width: 15px;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAQCAMAAABeF73YAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAwBQTFRFAAAA%2F%2F%2F%2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ3bsYwAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjM2qefiJQAAAExJREFUKFO10LECACAERVH%2B%2F6dTJJtryNB06CE6KhlpPVyyumbjD%2FdfVd6N3jleFqALJzpXRdjD2LJQO48X9ASn48NNOfSX%2FeXgKpssziECqaokJE4AAAAASUVORK5CYII%3D');
  //background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAQCAIAAABhmjO7AAAAbElEQVR4nLWSUQ7AIAhDqdn9r8w%2B%0ASJyJ2pki%2FVPio0Lh7lamVoc2s0d%2BCYBUYyQKnXM7WqSfcEPK3HdBmO%2BvbXXZEnIi%2B%2FQJIeudm9Pp%0AJ5%2FOeufpTNF%2F7bfoP1rgx1mkWrtVPZEfAlvIBTrRC7wOMBc8CAoqAAAAAElFTkSuQmCC');
}
By : facepalmd


This video can help you solving your question :)
By: admin