Determine Pixel Length of String in Javascript/jQuery?

JavascriptJquery

Javascript Problem Overview


Is there any way to determine the pixel length of a string in jQuery/JavaScript?

Javascript Solutions


Solution 1 - Javascript

Wrap text in a span and use jquery width()

Solution 2 - Javascript

The contexts used for HTML Canvases have a built-in method for checking the size of a font. This method returns a TextMetrics object, which has a width property that contains the width of the text.

function getWidthOfText(txt, fontname, fontsize){
    if(getWidthOfText.c === undefined){
        getWidthOfText.c=document.createElement('canvas');
        getWidthOfText.ctx=getWidthOfText.c.getContext('2d');
    }
    var fontspec = fontsize + ' ' + fontname;
    if(getWidthOfText.ctx.font !== fontspec)
        getWidthOfText.ctx.font = fontspec;
    return getWidthOfText.ctx.measureText(txt).width;
}

Or, as some of the other users have suggested, you can wrap it in a span element:

function getWidthOfText(txt, fontname, fontsize){
    if(getWidthOfText.e === undefined){
        getWidthOfText.e = document.createElement('span');
        getWidthOfText.e.style.display = "none";
        document.body.appendChild(getWidthOfText.e);
    }
    if(getWidthOfText.e.style.fontSize !== fontsize)
        getWidthOfText.e.style.fontSize = fontsize;
    if(getWidthOfText.e.style.fontFamily !== fontname)
        getWidthOfText.e.style.fontFamily = fontname;
    getWidthOfText.e.innerText = txt;
    return getWidthOfText.e.offsetWidth;
}

EDIT 2020: added font name+size caching at Igor Okorokov's suggestion.

Solution 3 - Javascript

I don't believe you can do just a string, but if you put the string inside of a <span> with the correct attributes (size, font-weight, etc); you should then be able to use jQuery to get the width of the span.

<span id='string_span' style='font-weight: bold; font-size: 12'>Here is my string</span>
<script>
  $('#string_span').width();
</script>

Solution 4 - Javascript

Put it in an absolutely-positioned div then use clientWidth to get the displayed width of the tag. You can even set the visibility to "hidden" to hide the div:

<div id="text" style="position:absolute;visibility:hidden" >This is some text</div>
<input type="button" onclick="getWidth()" value="Go" />
<script type="text/javascript" >
	function getWidth() {
		var width = document.getElementById("text").clientWidth;
		alert(" Width :"+  width);
	}
</script>

Solution 5 - Javascript

Based on vSync's answer, the pure javascript method is lightning fast for large amount of objects. Here is the Fiddle: https://jsfiddle.net/xeyq2d5r/8/

[1]: https://jsfiddle.net/xeyq2d5r/8/ "JSFiddle"

I received favorable tests for the 3rd method proposed, that uses the native javascript vs HTML Canvas

Google was pretty competive for option 1 and 3, 2 bombed.

FireFox 48:
Method 1 took 938.895 milliseconds.
Method 2 took 1536.355 milliseconds.
Method 3 took 135.91499999999996 milliseconds.

Edge 11 Method 1 took 4895.262839793865 milliseconds.
Method 2 took 6746.622271896686 milliseconds.
Method 3 took 1020.0315412885484 milliseconds.

Google Chrome: 52
Method 1 took 336.4399999999998 milliseconds.
Method 2 took 2271.71 milliseconds.
Method 3 took 333.30499999999984 milliseconds.

Solution 6 - Javascript

First replicate the location and styling of the text and then use Jquery width() function. This will make the measurements accurate. For example you have css styling with a selector of:

.style-head span
{
  //Some style set
}

You would need to do this with Jquery already included above this script:

var measuringSpan = document.createElement("span");
measuringSpan.innerText = 'text to measure';
measuringSpan.style.display = 'none'; /*so you don't show that you are measuring*/
$('.style-head')[0].appendChild(measuringSpan);
var theWidthYouWant = $(measuringSpan).width();

Needless to say

> theWidthYouWant

will hold the pixel length. Then remove the created elements after you are done or you will get several if this is done a several times. Or add an ID to reference instead.

Solution 7 - Javascript

Maybe it will useful for some

const getMaxPixelsOfStrings = ({ strings, styles = {} }) => {
  const spans = strings.map(str => {
    const span = document.createElement('span')
    span.append(str)
    Object.assign(span.style, {
      position: 'absolute',
      ...styles,
    })

    return span
  })

  document.querySelector('html').prepend(...spans)
  const maxPixels = Math.max(...spans.map(span => span.getBoundingClientRect().width))

  spans.forEach(span => span.remove())

  return maxPixels
}

usage

getMaxPixelsOfStrings({
            strings: ['One', 'Two', 'Three', 'Four', 'Five'],
            styles: {
              fontSize: '18px',
              letterSpacing: '1px',
            },
          })

Solution 8 - Javascript

If you use Snap.svg, the following works:

var tPaper = Snap(300, 300);
var tLabelText = tPaper.text(100, 100, "label text");
var tWidth = tLabelText.getBBox().width;  // the width of the text in pixels.
tLabelText.attr({ x : 150 - (tWidth/2)});   // now it's centered in x

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGStoView Question on Stackoverflow
Solution 1 - JavascriptNatriumView Answer on Stackoverflow
Solution 2 - JavascriptLuxView Answer on Stackoverflow
Solution 3 - JavascriptTopher FangioView Answer on Stackoverflow
Solution 4 - JavascriptGrinnView Answer on Stackoverflow
Solution 5 - JavascriptRJ KellyView Answer on Stackoverflow
Solution 6 - JavascriptAndrew MaraisView Answer on Stackoverflow
Solution 7 - JavascriptDandgersonView Answer on Stackoverflow
Solution 8 - JavascriptTim EricksonView Answer on Stackoverflow