Normal text wrapping can leave big gaps in your container, which can become even more exaggerated with the new-ish CSS values of text-wrap: balance and text-wrap: pretty. You almost certainly want to use balance or pretty because they do a great job preventing “dangling” lines in your text, even with icons.
But what can we do about all that leftover space around the wrapped text?
You’d think inline-size: fit-content or inline-size: min-content would be the ticket, but those don’t size to wrapped text or awkwardly squish to the longest word.
Look at the chat bubbles in iOS. They conform nicely to the text, whether it’s a short line or wrapped.
Surely we can accomplish that with CSS, right? Right???

Roman Komarov’s experimental technique involving animation timelines felt a bit too complicated. I couldn’t find any other passable techniques, but I had an idea…
Anchors Away!
CSS’s new position-anchor opens all kinds of doors. Developers like Temani Afif are constantly using anchors for great effects such as connecting nodes on a page. Anchors allow us to reference position and size values from one element in other elements. With that in mind, we can add an anchor to a display: inline text element and use that to create a background sized exactly to the wrapped text.
To accomplish the shrink-wrapping, we add a simple span around the text.
<div class="message">
<span class="text">
Why can't we simply "shrink wrap" the background to match the text?
</span>
</div>Code language: HTML, XML (xml)
Span elements are display: inline by default, so they’ll adhere to the actual size of the text even with it wrapped! Adding a background directly to the span doesn’t give the right effect, though, because it only applies on the actual lines of text and you can’t add any padding.
However, if we add anchor-name: --text to the span, we can get the exact size of the text and create an appropriate background with a psuedo-element on the parent.
.text {
/* Add an anchor so we can position a background around it */
anchor-name: --text;
display: inline;
}
.message::before {
content: "";
/* Position and size based on the text element anchor */
position: absolute;
z-index: -1;
position-anchor: --text;
place-self: anchor-center;
height: anchor-size(height);
width: anchor-size(width);
}Code language: CSS (css)
By placing it in the center of our text anchor, then giving it the width and height of the anchor, we can add additional padding, backgrounds, borders, etc.
A few additional styles for good appearances and little improvements results in this:
It’s definitely more code than I’d like for what should be a simple one-liner in CSS ( inline-size: text-content anyone? ), but there’s no real hackery going on here. The approach works in most browsers and degrades nicely.
Real Chat Bubbles
Since we’re trying to create that iOS Chat Bubble look, here’s a more fleshed out demo that shows how we can use more complex backgrounds, borders and box-shadows on the psuedo-element background
Next time you need the background to trim down to text size, don’t forget your best friend position-anchor! Happy wrapping.