It is necessary that the text fills the svg as much as possible as with bacground-size: contain
. The svg parent can be resized dynamically. The text is always single line. Now such a solution is used using js, but it is desirable to do it using the svg itself.
const $svg = document.querySelector(`svg`);
const $text = $svg.querySelector('text');
const $input = document.querySelector('input');
$input.addEventListener('input', e => {
$text.textContent = e.target.value;
const box = $text.getBBox();
$svg.setAttribute('viewBox', `${box.x} ${box.y} ${box.width} ${box.height}`);
});
$input.dispatchEvent(new Event('input'))
svg {
border: 1px solid red;
height: 10em;
width: 100%;
}
<svg preserveAspectRatio="xMaxYMid meet">
<text alignment-baseline="baseline" dominant-baseline="middle" text-anchor="middle" fill="black"></text>
</svg>
<input type='text' value='Random single line text'>