I use ::before
to generate a pseudo-element to display a small image left of the anchor text of links. However, when re-sizing the browser window's width, the line may become wrapped between the small image and the first word of the link anchor text, which is undesired.
I want to keep the small image and the first word of the link anchor text together on the same line.
I keep display: inline
on the a-tag because the link anchor text shall be able to wrap line, not as a whole atomic box, but so that its first word(s) fill up the current line and any remaining words continue on the next line.
Also, the text after the link shall continue on the same line as the last word of the link anchor text (provided there is space for its first word of course).
Note 1) If I would use display:inline-block
on the a-tag, the entire link anchor text would wrap as a whole, which I do not want.
Note 2) I use display:inline-block
on the pseudo-element because I need to set its width and height.
Note 3) I have tried with setting white-space: pre
on the pseudo-element, but that did not solve the problem.
Thanks!
The code is at JSFiddle and repeated below for completeness.
My HTML:
<p>
Text text <a class="pre-icon" href="#">FirstWord word2 word3</a> text after link.
</p>
My CSS:
.pre-icon::before {
content: "";
display: inline-block;
width: 6px;
height: 10px;
background-color: transparent;
background-image: url(data:image/gif;base64,R0lGODlhBgAKAJEAADM2Zv///////wAAACH5BAUUAAIALAAAAAAGAAoAAAINBIRimdvHFETOUWglKwA7);
background-repeat: no-repeat;
margin-left: .13em;
margin-right: .25em;
white-space: nowrap;
}
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).
::before (:before) In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default.
Definition and Usage The ::before selector inserts something before the content of each selected element(s). Use the content property to specify the content to insert. Use the ::after selector to insert something after the content.
The content CSS property is used in conjunction with these pseudo-elements, to insert the generated content.
The problem is that the line break happens between the pseudo-element and the content, so you can't avoid it by setting white-space
only to the pseudo-element.
Instead, you can wrap the content of the anchor inside a span, set white-space: nowrap
to the entire anchor, and restore the initial white-space: normal
in the span.
.pre-icon {
white-space: nowrap;
}
.pre-icon > span {
white-space: normal;
}
.pre-icon::before {
content: "";
display: inline-block;
width: 6px;
height: 10px;
background-color: transparent;
background-image: url(data:image/gif;base64,R0lGODlhBgAKAJEAADM2Zv///////wAAACH5BAUUAAIALAAAAAAGAAoAAAINBIRimdvHFETOUWglKwA7);
background-repeat: no-repeat;
margin-left: .13em;
margin-right: .25em;
}
.pre-icon {
white-space: nowrap;
}
.pre-icon > span {
white-space: normal;
}
Text text <a class="pre-icon" href="#"><span>FirstWord word2 word3</span></a> text after link.
While it would be really cool if we could finally get a :first-word selector (Great post by Chris Coyier about that: https://css-tricks.com/a-call-for-nth-everything/), you probably need an extra span to do this. Here's a fork on your fiddle that looks to be doing what you described:
https://jsfiddle.net/0hrn2Lao/
HTML:
<p>Text text <a class="pre-icon" href="#">
<span>FirstWord</span> word2 word3</a> text after link.
</p>
CSS:
.pre-icon span {
display:inline-block;
text-decoration:underline;}
.pre-icon span::before {
content:"";
display:inline-block;
width:6px;
height:10px;
background-color:transparent;
background-image:url(data:image/gif;base64,R0lGODlhBgAKAJEAADM2Zv///////wAAACH5BAUUAAIALAAAAAAGAAoAAAINBIRimdvHFETOUWglKwA7);
background-repeat:no-repeat;
margin-left:.13em;
margin-right:.25em;
white-space:nowrap;
}
Basically, put the pseudo element with the image on the span containing the first word, then let the span be inline-block
, without having to put the inline-block
rule on the <a>
element itself.
If you wanted, you could probably use some jQuery to insert the span around the first word of <a class="pre-icon">
throughout the document - but if you're specifically adding that class, maybe it's not a lot of effort to just drop the span in manually too...depends on your pain tolerance, I guess :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With