1

How could one make a line of text fill up the entirety of it's parent container similar specifically to how object-fit: contain; works for images where it does not stretch it but makes sure it fills as much of the space as possible while not getting cut off or stretched.

It should be mentioned the solution I'm looking for should work in React with changing text without much jumping around so it should have all calculations done before firs render.

This question is not SVG specific but is concerned with ANY way of achieving this effect including canvas or other methods.

I'm aware of Pure SVG way to fit text to a box and SVG Scaling Text to fit container but no answer in them has the desired effect. They either calculate the viewBox on mount (and have that flash of incorrect layout) or work by stretching and distorting the text.

Things I've tried thus far:

Thus far the closest I've gotten is by making a component that renders an SVG with a text node inside and on mount inside the useEffect calculates the BBox of the SVG and sets the viewBox accordingly.

The issues with that approach are that there is quite a drastic jump of the test siedways whenever the number of characters changes (like from 0 to 10000 if you're displaying numbers) and in general this problem of jumping around since the bbox changes after the first render so on the first one the viewBox is wrong.

I've tried fixing it by rendering an identical hidden SVG outside of react first and measuring it's bbox and that way being able to have the correct viewBox on the first render but I've not been succesful in that.

The Truth
  • 87
  • 11
  • perhaps your new question should be "how do I avoid a flash of incorrect layout?" when I do... with a suitable example then. – Robert Longson Feb 01 '23 at 12:59
  • @RobertLongson perhaps. I'm interested in the whole package though. Exactly like `object-fit: contain`. As far as I'm aware that does not happen with `object-fit`. As for the question of avoiding flash - i have one for that in SVG specifically. This question is a general question of how this could be done with the flash being a specific issue I've found with most solutions and I haven't been able to get around. I'm hoping someone knows another way of achieving this effect. – The Truth Feb 01 '23 at 13:16
  • In the heydays of jQuery I stumbled upon some plugins that did just that. Maybe it's worth looking into that code... http://danielhoffmann.github.io/jquery-bigtext/ – metatron Feb 07 '23 at 14:36
  • 1
    I took a quick look here: https://github.com/DanielHoffmann/jquery-bigtext/blob/master/jquery-bigtext.js. It seems the text is added to the dom with visibility hidden. Then the dimensions of the bounding box are measured. From the dimensions of the bounding boxes of the element and the parent the appropriate font-size is calculated as a scaling factor to scale up the element. Also some magic is done to align the element in the center. Nowadays I would opt for `display: grid; place-items: center;` After all calculations are done the visibility is switched to visible. A bit finicky but it works. – metatron Feb 07 '23 at 14:46
  • @metatron these are indeed worth looking into. Nice recommendations. – The Truth Feb 07 '23 at 20:26

0 Answers0