javascripthtmllayoutresponsiveness

Automatic font size - js


How do you make font size automatically adjust so that the text doesn't overflow?

const h1 = document.getElementsByTagName('h1')[0];
const content = document.getElementById('content');
let size = parseInt(window.getComputedStyle(h1).getPropertyValue('font-size'));
while (checkIfOverflows(h1, content)){
    size--;
    h1.style.fontSize = size + 'px';
}

function checkIfOverflows(element, parent){
    const oldWidth = element.style.width;
    element.style.width = 'fit-content';
    const parentRect = parent.getBoundingClientRect();
    const elementRect = element.getBoundingClientRect();
    const overflows = (parentRect.right - elementRect.right < 0);
    element.style.width = oldWidth;
    console.log(overflows);
    return overflows;
}

The h1 has a stable left edge and nowrap, checkIfOverflows works when checking once, but not in this loop, where if it overflows at first it loops forever, meaning it's most likely a timing thing or some other weird stuff like that


Solution

  • You can create a virtual ruler that measures text width, like this...

    function GetTextWidth(Str,Font,Size){
    
    let Ruler=document.createElement('div');
    
    Ruler.style.cssText='visibility:hidden;position:absolute;top:0;left:0;wdth:auto;height:auto;padding:0;margin:0;font:normal 400 '+Size+'px "'+Font+'";';
    
    Ruler.textContent=Str;
    
    document.body.appendChild(Ruler);
    
    let Width=Ruler.offsetWidth;
    
    Ruler.remove();
    
    return Width;
    
    }
    

    NB: If you're gonna be doing a lot of measuring then you might want to not remove the ruler from the document so you'll have to modify this function a bit.

    Also, it’s probably tempting to use display:none and maybe modify some other CSS properties of the ruler, but keep in mind that doing so may render it useless.

    ie: Firefox doesn’t consider a container to exist when display:none so be careful with any changes.