Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 831
Chad Kruse Avatar asked Apr 26 '13 22:04

Chad Kruse


People also ask

How do I make sure my text doesn't wrap?

If you want to prevent the text from wrapping, you can apply white-space: nowrap; Notice in HTML code example at the top of this article, there are actually two line breaks, one before the line of text and one after, which allow the text to be on its own line (in the code).

How do I align text and icon on the same line in HTML?

If you want to make a text appear vertically aligned next to a Font Awesome icon, you can use the CSS vertical-align property set to “middle” and also, specify the line-height property. Change the size of the icon with the font-size property.


2 Answers

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.

like image 92
Troy Alford Avatar answered Sep 18 '22 09:09

Troy Alford


Interestingly enough, I found you only need to change one line of code for this to work. Testing on your .container2 element in jsFiddle, change this

.container2:after {
    font-family: FontAwesome;
    content: "\f111";
    display: inline-block;
}

to

.container2:after {
    font-family: FontAwesome;
    content: "\f111";
    display: inline;
}

It seems to work with any width I set the container to and will stay connected to what ever foo will be.

like image 33
Unmocked Avatar answered Sep 19 '22 09:09

Unmocked