I've madeRewritten my answer from scratch (thanks for that minus). Now function accepts a tiny ES6 moduletext and css rules to be applied (usesand doesn't use jQuery anymore):. So it will respect paddings too. Resulting values are being rounded (you can see Math.round there, remove if you want more that precise values)
import $ from 'jquery'; const $span=$('<span>'); $span.css({ position: 'absolute', display: 'none' }).appendTo('body'); export default function(str, css){ $span[0].style = ''; // resetting the styles being previously set $span.text(str).css(css || {}); return $span.innerWidth(); } Easy to use:
import stringWidth from './string_width'; const w = stringWidth('1-3', {fontSize: 12, padding: 5}); function getSpan(){ const span = document.createElement('span') span.style.position = 'fixed'; span.style.visibility = 'hidden'; document.body.appendChild(span); return span; } function textWidth(str, css) { const span = getSpan(); Object.assign(span.style, css || {}); span.innerText = str; const w = Math.round(span.getBoundingClientRect().width); span.remove(); return w; } const testStyles = [ {fontSize: '10px'}, {fontSize: '12px'}, {fontSize: '60px'}, {fontSize: '120px'}, {fontSize: '120px', padding: '10px'}, {fontSize: '120px', fontFamily: 'arial'}, {fontSize: '120px', fontFamily: 'tahoma'}, {fontSize: '120px', fontFamily: 'tahoma', padding: '5px'}, ]; const ul = document.getElementById('output'); testStyles.forEach(style => { const li = document.createElement('li'); li.innerText = `${JSON.stringify(style)} > ${textWidth('abc', style)}`; ul.appendChild(li); }); <ul id="output"></ul> Cool thing you might notice - it allows to take into account any CSS attributes, even paddings!