When text gets in two lines

I am always running into this problem. Lets say i have a button which is display: inline-block (or flex, or inline-flex) and max-width: fit-content; As long as the inner text does not break into two lines it looks good. The width of the button is defined by its text. When the text breaks in two lines the button gets width 100%. I want it to fit the content. Any ideas what to do? I cannot use max-width because its a cms and i dont know what text will be inside.
41 Replies
LachsDuJour
LachsDuJourOP2w ago
After research it seems there is no css solution for this. The text behaviour is really weird. It should not become block-element when becoming multi-lines. So the only solution seems to be via JS: I check the height and inject a <br> inbetween. That is so stupid
Jochem
Jochem5d ago
it has to do with text-wrap: balance; Apparently, for Reasons™️, the element isn't shrink wrapped when you use balance: https://developer.chrome.com/docs/css-ui/css-text-wrap-balance
Balancing won’t change the inline-size of the element There's an advantage to some of the JavaScript solutions for balanced text wrapping, as they change the max-width of the containing element itself. This has an added bonus of being "shrink wrapped" to the balanced block. text-wrap: balance does not have this effect and can be seen in this example:
No description
Jochem
Jochem5d ago
See how the width shown from DevTools has a bunch of extra space at the end? That's because it's a wrapping style only, not a size changing style. Because of this, there's a few scenarios where text-wrap: balance isn't that great, at least in my opinion. For example, headings inside of a card (or any container with borders or shadows).
LachsDuJour
LachsDuJourOP5d ago
Turning text-wrap:balance off does not change the behaviour:
No description
LachsDuJour
LachsDuJourOP5d ago
the button still is 100% width
LachsDuJour
LachsDuJourOP5d ago
No description
Jochem
Jochem5d ago
balance doesn't recalculate the width after balancing the text. The top one is full width because there's room for the text. With balance on, it's still pretending the text is there, but it's moving the words nonetheless Basically I'm just saying you're right, there's no css solution
LachsDuJour
LachsDuJourOP5d ago
lol 🙂
Jochem
Jochem5d ago
The article just explains why
LachsDuJour
LachsDuJourOP5d ago
that is really sad ty
Jochem
Jochem5d ago
Np, I learned something too
Zempai
Zempai5d ago
Indeed an interesting case. I was dealing with content sensitive demands here and there, mostly realizing that it may not be a job for CSS but needs to be solved either by design or actual programming. Limiting the label's inline-space with magic numbers (20ch) would be the "best" CSS can do, other than that I am clueless aswell. That balance renders a block is unfortunate ...lol Thanks for sharing 🙆
LachsDuJour
LachsDuJourOP5d ago
That is something that should be implemented in future css!
Jochem
Jochem5d ago
To clarify, it's not changing the rendering mode of the element, it's simply determining the size of the element before it balances the text, and not recalculating after balancing. I'm sure there's some kind of valid reason for this, either performance wise (this is apparently an expensive computation) or logistically, but the display property is untouched in this case.
LachsDuJour
LachsDuJourOP4d ago
Not sure if we are really talking about the same. I removed text-wrap: balance. To emphasize i changed the wording. Why does the first button behaves like a block element when the inner text is too long for one line?
No description
Jochem
Jochem4d ago
It's not behaving like a block element because of balance. Balance just isn't shrinking the container when it does the balancing. This has nothing to do with the display value and it doesn't change at all
Simon
Simon4d ago
It's how flexbox operates, innit?
Jochem
Jochem4d ago
This isn't due to flex box either. It's just a quirk of text wrap balance
LachsDuJour
LachsDuJourOP4d ago
but there is no text-wrap: balance!
Jochem
Jochem4d ago
In this one?
LachsDuJour
LachsDuJourOP4d ago
yes. i updated the codepen and made a second Button-Set below. No text-wrap:balance, no flexbox. Why does the button gets 100% width?
Simon
Simon4d ago
The pen got updated. – But doesn't flex fill up the hypothetical space to push the children apart and/or do flexy stuff? I do see that comparing it to block is not correct 🥲 imo in any case as for now you may be forced to limit the parent element's max-width to let the children act on it (this should also allow text-wrap to do its job?). Maybe with rules applied by javascript if there is a need for different stylings between single-and multi-line buttons. But I could be wrong ofc.
LachsDuJour
LachsDuJourOP4d ago
I think it is just a strange behaviour of multiline text. IDK. My problem is that i am developing CMS Systems and the content is entered by the editors. And i am always asked to resolve this problem. Here is a nice live-example:
No description
LachsDuJour
LachsDuJourOP4d ago
They ask me why the 3rd button is so wide...
LachsDuJour
LachsDuJourOP4d ago
The html is div > span. Div has no css properties, Span is set to inline-block. If i set it to inline it looks really weird:
No description
LachsDuJour
LachsDuJourOP4d ago
Same here. Just a Textbox with an arrow:
No description
LachsDuJour
LachsDuJourOP4d ago
If text gets multiline:
No description
LachsDuJour
LachsDuJourOP4d ago
They ask me to move the arrow next to the text In this case i could use display inline / inline-block but loose the positioning features of flexbox
Simon
Simon4d ago
Well, thats a design issue imo ... It would be strange if the multi-line click area is more narrow than the others, given these are listed vertically, no? Moving the arrow next to the text would either cause a large white-space clickable area on it's right that is not visible, or the design to be inconsitent. This could perhaps be solved by adding background and/or borders to make the click-area more obvious. In the case of buttons maybe centering them horizontally would make it look more coherent
LachsDuJour
LachsDuJourOP4d ago
In the second case there is always just one Button with arrow. The problem only gets visible on mobile. People dont see the arrow (because it is too far from the text, they say) I can live with that 🙂 The Orange-Button: The design is not made by myself. I am not allowed to center them
Jochem
Jochem4d ago
I'm pretty sure that's just how fit-content works. It wraps the content as best as possible, but at the same time with inline text content it'll take as much room as it can
LachsDuJour
LachsDuJourOP4d ago
yes. I thought there maybe is a solution for this. But maybe not
Jochem
Jochem4d ago
the only way to accomplish this with CSS, is with text-wrap: balance; and that has the issue described earlier
LachsDuJour
LachsDuJourOP4d ago
yes. so i have to tell them the internet (browsers) have no solution for this (seemingly easy) problem Maybe Kevin has an idea 😉
Simon
Simon4d ago
-# Edit 20241115: caution, calculation fails with box-sizing: border-box I have stolen a thing https://jsfiddle.net/d63Lpshg/ _
LachsDuJour
LachsDuJourOP4d ago
I just looked at the link you provided. https://jsfiddle.net/d63Lpshg/ That is a neat way to resolve this problem with JS. Gonna try that Many thanks!
Edit fiddle - JSFiddle - Code Playground
JSFiddle - Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle.
LachsDuJour
LachsDuJourOP4d ago
I never worked with createRange()
Simon
Simon4d ago
not sure if it targets the right thing, but eventually you can use bits of it ... lol
LachsDuJour
LachsDuJourOP4d ago
yes think so. Also: Many thanks for your patience guys 😉
LachsDuJour
LachsDuJourOP4d ago
I modified the JS a little bit and it works 🙂
No description
Want results from more Discord servers?
Add your server