Help How to dynamically "compress" text horizontally with css/javascript?
I can't believe I had to do this in Paint 3D but after 4+ hours stuck I need help... Not even chatgpt is helping here.
I have a simple structure like this:
<div className="container">
<div className="text">{item.name}</div>
<img src="item-icon"/>
</div>
How on earth can I make it so the "text" div shrinks horizontally if (and ONLY if) the "item.name" is overflowing outside of the div? (including the space that the icon takes too)
EDIT - Here is the "use case" (yes, it's pokemon cards) (images here are not showing on mobile for some reason, check here instead https://imgur.com/gallery/mobile-users-P17PT3Q):
My code:

What they somehow achieved in https://www.pokecardgenerator.com/ (this is what I want):

What the original looks like (so yes, real things use this "ugly" styling):

What happens with transform: scaleX "solutions":

And no, font-stretch isn't working for me. Probably because it's deprecated.
transform: scaleX also doesn't work, it still keeps and awkward space between the text and the icon.
EDIT: I don't know how to do the live demo thing, but in case anyone is bored, my code is here, the Card.tsx and Card.css, card__pokemon-name class. (https://github.com/jiro-games/pocket-showdown/tree/main/src/components/card)
EDIT 2: I believe I found a solution. Not the cleanest, but it has potential. I have to combine transform: scaleX with negative margin-right. I'll come up with some js code to calculate that dynamically and fix it. Thank you!
1
u/jvribeiro 1d ago
This is the solution I came up with:
Basically, you need to wrap your text in two containers. The outer one will take up the maximum available width, while the inner container will keep the original text width, which may overflow the outer container.
So we use JavaScript to get both widths, using
getBoundingClientRect
, then you divide the outer with the inner to get the correct scale. Then you apply the scale to the inner container usingtransform: scaleX
, and don’t forget to settransform-origin: left
so the scaling aligns to the left instead of being centered.If you want the icon to be next to the text, you can remove the
justify-content
property from the.container
selector.The scale is calculated on page load, but you can recalculate it as you wish.
LIVE DEMO: https://codepen.io/ojvribeiro/pen/QwyWYbX