Last Updated: February 25, 2016
·
3.48K
· zaus

Calculate text dimensions of DOM element

Forked from good idea here: https://coderwall.com/p/kdi8ua - see discussion in comments.

Just playing around, but calculates either width or height of multiple elements:

Updated per "other styles" comment

// get width or height
!(function($) {
    var N = function(key) { return 'getTextSize.' + key; },
        fontMapping = function($o, font) {
            //return {"font": font.font || $o.css('font')};
            var result = {}; // don't affect original object
            $.each(font, function(prop, val) {
                result[prop] = (val || $o.css(prop));
            });
            return result;
        }
    ;

    $.fn.getTextSize = function(dimension, text, font) {
        dimension = (dimension || 'width');
        // figure out what font aspects we're concerned with
        if( typeof font === "string" ) {
            font = {"font": font};
        }
        // include other common style properties that affect sizing
        font = $.extend({"font": false, "text-transform": false, "letter-spacing": false}, font);

        // allow multiple calculations
        return $.map($(this), function(o) {
            var $o = $(o), $fake = $o.data(N('fake'));
            console.log($o, $fake);
            if (!$fake) {
                // cloning causes duplication issues on subsequent calls
                // can attach to parent, but may be unnecessary parsing vs. body if updating font each time
                $fake = $('<span>').hide().addClass('placeholder').empty().appendTo(document.body);
                $o.data(N('fake'), $fake);
            }
            return $fake.html(text || $o.val() || $o.text()).css(fontMapping($o, font))[dimension]();
        });    
    };
})(jQuery);

Usage:

$('.multiple-elements').getTextSize().join('px, ')+'px';
$('.single').getTextSize('height')[0];

4 Responses
Add your response

You should also take into account styles like line-height, text-transform, letter-spacing

over 1 year ago ·

Yeah I was thinking about that with the .clone+adjacent idea, now need to do it manually. Good call.

Update font seems to include line-height at least. I've added an option to extend the font value passed to include other properties

over 1 year ago ·

Can you describe the reasons for each change over https://coderwall.com/p/kdi8ua? Is it purely performance (if so, how) or improved in some other way?

over 1 year ago ·

@philfreo -- mostly because i like rewriting stuff; there wasn't anything wrong with your post. i did:

  1. wrap it in a closure because everybody loves closures
  2. allow you to call the plugin on multiple elements (i.e. $('p').getTextSize() would work "correctly" on multiple paragraphs, as they could differ)
  3. get width or height (rather than just width)
  4. or get any font property rather than just 'width' and 'height'

you can kinda see a comparison in the fiddle.

over 1 year ago ·