将字体图标附加到文本字符串中的最后一个单词并防止换行

时间:2022-04-26 00:45:47

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

我想将一个Font Awesome图标附加到文本字符串中的最后一个单词:

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?

但是,解决方案假设我可以访问最后一个单词。在我的例子中,文本将动态生成。是否有一种css / html唯一的方法来确保图标包含最后一个单词?

Here's a jsfiddle.

这是一个jsfiddle。

3 个解决方案

#1


5  

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

有趣的是,我发现你只需要改变一行代码即可。在jsFiddle中测试你的.container2元素,改变它

.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.

它似乎适用于我设置容器的任何宽度,并将保持连接到foo将会是什么。

#2


10  

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.

我只是想指出为什么@Unmocked提供的更改实际上有效,并且它与display:inline和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.

通常,块元素是导致布局的元素。它们接收自己的边界框,并且能够在某种程度上推动其他元素,以适应浏览器渲染区域内的可用空间。块项的示例包括:h1,p,ul和table。请注意,默认情况下,每个项都会启动一个新行,并在关闭时结束自己的行。换句话说 - 它们通过创建自己的段落级别部分而适合文本块。

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.

通常,内联元素与文本一起显示。换句话说,它们被设计为与文本行一起显示。示例包括i,b或span。请注意,默认情况下,这些项目中的每一项都会继续其周围文本的流程,而不会在其自身之前或之后强制换行。

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.

内联块是上述两者的混合体。本质上,内联块元素从其前一文本离开的任何地方开始,并尝试内联地适应文档流。但是,如果它到达需要换行的点,它将下降到一个新行,就好像它是一个块元素。然后,后续文本将紧跟在inline-block元素之后继续,并继续正常包装。这可能会导致一些奇怪的情况。

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

这是一个例子,以显示我的意思。要查看它的实际效果,请查看此cssdesk代码段。

将字体图标附加到文本字符串中的最后一个单词并防止换行

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.

在您的示例中,您设置了:after伪元素显示:inline-block - 这意味着当它恰好延伸到包装显示的最右边界时,它的作用就像是在包装显示中的浅蓝色文本示例 - 并作为一个块包装。当你改变:after元素来显示:inline时,它会使它像任何其他文本一样动作 - 并且它与前面的字母之间没有空格,自动换行按你的意愿行事。

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:

在第一个小提琴中,您的HTML看起来像:

<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:

虽然浏览器不显示文本前后的空格,但它确实包含空格,当渲染:after元素时,就好像这样:

<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.

浏览器将多个空格压缩为单个空格,但仍然在单词“bar”和:after元素之间放置一个空格。就像任何其他单词之间的空格一样,这将导致在“bar”之后但在之前:在某个宽度之后发生换行。

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:

在这种情况下,因为没有空格跟踪“foo bar”字符串,浏览器会在内容字符串结束后立即显示:after元素。好像发生这种情况:

<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.

有关演示此示例的示例,请参阅此jsFiddle的更新。

#3


2  

You can use negative margin the width of the icon and css transform. Here a fiddle how to do :

您可以使用负边距图标和css变换的宽度。这里有一个小提琴怎么办:

    .container {
        width: 50px;
    }
    .icon-circle {
        background:black;
        height:10px;
        width:10px;
        display: inline-block;   
        margin-left:5px;
    }
    .ANSWER{
        display:block;
        padding-right:15px; /* width of the icon */
    }
    .ANSWER .icon-circle{
        margin-left:-10px;
        transform:translate(15px);
    }
    <h4>What we want</h4>
    <div class="this-is-how-it-should-wrap">
        foo bar<i class="icon-circle"></i>
    </div>

    <div style="margin-top:25px"></div>

    <h4>What happenned</h4>
    <div class="container NORMAL">
        foo bar<i class="icon-circle"></i>
    </div>

    <div style="margin-top:25px"></div>

    <h3>The answer</h3>
    <div class="container ANSWER">
        foo bar<i class="icon-circle"></i>
    </div>

Have a nice day!

祝你今天愉快!

#1


5  

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

有趣的是,我发现你只需要改变一行代码即可。在jsFiddle中测试你的.container2元素,改变它

.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.

它似乎适用于我设置容器的任何宽度,并将保持连接到foo将会是什么。

#2


10  

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.

我只是想指出为什么@Unmocked提供的更改实际上有效,并且它与display:inline和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.

通常,块元素是导致布局的元素。它们接收自己的边界框,并且能够在某种程度上推动其他元素,以适应浏览器渲染区域内的可用空间。块项的示例包括:h1,p,ul和table。请注意,默认情况下,每个项都会启动一个新行,并在关闭时结束自己的行。换句话说 - 它们通过创建自己的段落级别部分而适合文本块。

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.

通常,内联元素与文本一起显示。换句话说,它们被设计为与文本行一起显示。示例包括i,b或span。请注意,默认情况下,这些项目中的每一项都会继续其周围文本的流程,而不会在其自身之前或之后强制换行。

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.

内联块是上述两者的混合体。本质上,内联块元素从其前一文本离开的任何地方开始,并尝试内联地适应文档流。但是,如果它到达需要换行的点,它将下降到一个新行,就好像它是一个块元素。然后,后续文本将紧跟在inline-block元素之后继续,并继续正常包装。这可能会导致一些奇怪的情况。

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

这是一个例子,以显示我的意思。要查看它的实际效果,请查看此cssdesk代码段。

将字体图标附加到文本字符串中的最后一个单词并防止换行

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.

在您的示例中,您设置了:after伪元素显示:inline-block - 这意味着当它恰好延伸到包装显示的最右边界时,它的作用就像是在包装显示中的浅蓝色文本示例 - 并作为一个块包装。当你改变:after元素来显示:inline时,它会使它像任何其他文本一样动作 - 并且它与前面的字母之间没有空格,自动换行按你的意愿行事。

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:

在第一个小提琴中,您的HTML看起来像:

<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:

虽然浏览器不显示文本前后的空格,但它确实包含空格,当渲染:after元素时,就好像这样:

<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.

浏览器将多个空格压缩为单个空格,但仍然在单词“bar”和:after元素之间放置一个空格。就像任何其他单词之间的空格一样,这将导致在“bar”之后但在之前:在某个宽度之后发生换行。

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:

在这种情况下,因为没有空格跟踪“foo bar”字符串,浏览器会在内容字符串结束后立即显示:after元素。好像发生这种情况:

<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.

有关演示此示例的示例,请参阅此jsFiddle的更新。

#3


2  

You can use negative margin the width of the icon and css transform. Here a fiddle how to do :

您可以使用负边距图标和css变换的宽度。这里有一个小提琴怎么办:

    .container {
        width: 50px;
    }
    .icon-circle {
        background:black;
        height:10px;
        width:10px;
        display: inline-block;   
        margin-left:5px;
    }
    .ANSWER{
        display:block;
        padding-right:15px; /* width of the icon */
    }
    .ANSWER .icon-circle{
        margin-left:-10px;
        transform:translate(15px);
    }
    <h4>What we want</h4>
    <div class="this-is-how-it-should-wrap">
        foo bar<i class="icon-circle"></i>
    </div>

    <div style="margin-top:25px"></div>

    <h4>What happenned</h4>
    <div class="container NORMAL">
        foo bar<i class="icon-circle"></i>
    </div>

    <div style="margin-top:25px"></div>

    <h3>The answer</h3>
    <div class="container ANSWER">
        foo bar<i class="icon-circle"></i>
    </div>

Have a nice day!

祝你今天愉快!