Html – Attach font icon to last word in text string and prevent from wrapping

cssfont-awesomehtmlpseudo-elementword-wrap

I want to attach a Font Awesome icon to the last word in a text string:

foo bar●

But if a line wrap is required, I want the icon to attach to the last word and have them wrap together:

foo
bar●

My problem is very similar to:
Prevent :after element from wrapping to next line

However, the solution assumes I have access to the last word. In my case, the text will be generated dynamically. Is there a css/html-only way to ensure the icon wraps with the last word?

Here's a jsfiddle.

Best Solution

I just wanted to point out why the change that @Unmocked provided actually works, and it has to do with the difference between display: inline and display: inline-block.

To explain, here's a little background on the difference between block display and inline display.

Block Display

block elements, in general, are elements which cause layout. They receive their own bounding box, and have the ability to push other elements around to some degree in order to fit into the space available within the browser's rendering area. Examples of block items include: h1, p, ul, and table. Note that each of these items, by default, starts a new line and also ends its own line when closed. In other words - they fit into a block of text by creating their own paragraph-level section.

Inline Display

inline elements, in general, are displayed in-line with the text. In other words, they are designed to display with-in the line of text. Examples include i, b, or span. Note that each of these items, by default, continues with the flow of its surrounding text, without forcing a newline before or after itself.

Enter the mid-way case...

Inline-Block Display

inline-block is a hybrid of the above two. In essence, an inline-block element starts wherever its preceding text leaves off, and attempts to fit into the flow of the document inline. However, if it reaches a point where it needs to wrap, it will drop to a new line, as if it were a block element. Subsequent text will then continue immediately following the inline-block element, and continue wrapping as normal. This can lead to some strange situations.

Here is an example, to show what I mean. To see it in action, check out this cssdesk snippet.

enter image description here

In your example, you were setting the :after pseudo-element to be display: inline-block - which meant that when it happened to extend past the right-most boundary of the wrapping display, it acted like the light-blue text in the example - and wrapped, as a block. When you instead change the :after element to display: inline, it causes it to act just like any other text - and without whitespace between it and the preceding letters, the word-wrap acts as you wanted it to.

I hope this helps!

Note: The other thing which changed between your original fiddle and the updated one is the elimination of white-space around the text.

In the first fiddle, your HTML looks like:

<div class="container2">
    foo bar
</div>

While the browser doesn't display the spaces before and after the text, it does contain the spaces, and when the :after element is rendered, it is as if this is happening:

<div class="container2"> foo bar :after</div>

The browser compresses the multiple spaces into single spaces, but still puts a space between the word "bar" and the :after element. Just like a space between any other words, this will cause the wrap to occur after "bar" but before :after at a certain width.

In the second fiddle, you are using:

<div class="container-wide">foo bar</div>
<div class="container-narrow">foo bar</div>

In this case, because there are no spaces trailing the "foo bar" strings, the browser renders the :after element displayed immediately following the end of the content string. It is as if this is happening:

<div class="container-narrow">foo bar:after</div>

No break in inline-rendered text means no break.

For an example demonstrating this, please see this update to your jsFiddle.

Related Question