Detect if text has overflowed [duplicate]
Asked Answered
I

4

104

How can you detect if text has overflown? For example, the following text is longer than it's div container allows. How can I detect this in javascript?

<div style="max-width: 100px; white-space:nowrap; overflow: hidden;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit
</div>
Ichnite answered 20/6, 2011 at 4:35 Comment(0)
I
167

If you are using jQuery, you can try comparing the div's width to its scrollWidth.

if ($('#div-id')[0].scrollWidth >  $('#div-id').innerWidth()) {
    //Text has over-flown
}
Interrelated answered 20/6, 2011 at 4:44 Comment(16)
I had to also use innerWidth() instead of width() to account for paddings.Antiar
I use the same technique, but comparing the scrollHeight against innerHeight()Kostival
Edited to use innerWidth() instead of width()Interrelated
AND... It is always better to use "jQuery" instead of "$"... :)Handpick
@TheCuBeMan: The actual best approach is to wrap the jQuery code in a closure taking $ and pass it jQuery as an argument. This is what jQuery Core does. e.g. (function ($) { // code })(jQuery);Injurious
@Injurious but what happens when you have other JS framework(s) on the same page/site and it already uses the $ sign?? I still say that it is best to use the jQuery object name in order to avoid collisions etc.Handpick
@Handpick But that pattern does use jQuery. It aliases it to $ in the closure scope. Collision-free.Injurious
@Injurious Let me ask you this - in this way, does it mean that the $ character will be used to refer to the jQuery object (and functionality)? because if it does, then there's the possibility of the collision. Let's say that there is another framework that is already utilizing this character for its purposes, then this code will override it and create the problem. Even if jQuery is referenced before the other framework, then the latter will be the one to utilize the $ character, therefore the code did nothing. Why not just always rely on "jQuery" as the only reference to its library?...Handpick
@Handpick But only within the IIFE (Immediately-Invoked Function Expression, the pattern I showed above). Outside of the IIFE, if you have called jQuery.noConflict(), there is no problem. The closure receives jQuery as its argument and it takes a parameter called $, so $ within the IIFE points to jQuery. This is compatible with your advice always to use jQuery; it simply aliases it. It doesn't affect the global scope. One can also pass references to other libraries to the IIFE by adding more parameters and arguments.Injurious
@Handpick There are several assumptions I've made in my solution. i.e.: 1) The jQuery object has been assigned to $ in someway, such as being passed into the scope or being set at the global scope. 2) That the selector used returns one and exactly one element. Otherwise the array index used (0) creates problems when the object doesn't exist, or when there are multiple matched elements (this snippet only considers the first element matched). I admit that, in an effort to provide a clear and concise solution to the question, solving these issues are left as an exercise for the reader.Interrelated
doesn't work in ie11Showker
Can you be more specific @ShowkerInterrelated
It worked great in chrome, firefox and iOS but not on ie11. Was a month ago so I don't recall which part of the solution wasn't working. I ended up using the top answer from #144315 instead.Showker
If you can reproduce the problem please provide a jsfiddle and I can update my answerInterrelated
Actually should use .clientWidth. All the rest are not accurate. .width, .innerWidth, etc.. always return a number that is lower than .scrollWidth.Tarah
I second @LiranFunaro's suggestion. In my case innerWidth() returned a float, which deviated 0.072 from scrollWidth, therefore the statement would always evaluate to true.Amboina
C
20

You can detect whether text will fit before you display the element. So you can use this function which doesn't require the element to be on screen.

function textWidth(text, fontProp) {
    var tag = document.createElement('div')
    tag.style.position = 'absolute'
    tag.style.left = '-99in'
    tag.style.whiteSpace = 'nowrap'
    tag.style.font = fontProp
    tag.innerHTML = text

    document.body.appendChild(tag)
    var result = tag.clientWidth
    document.body.removeChild(tag)
    return result;
}

Usage:

if (textWidth('Text', 'bold 13px Verdana') > elementWidth) {
    ...
}
Complected answered 13/9, 2013 at 15:25 Comment(3)
This worked for me when scrollWidth is zero, which seems to happen sometimes (haven't figured out why...)Mischiefmaker
So very helpful! I basically just slapped together my own, simplified version of Fitty.js, to loop through a page's elements and if any are larger than their container, decrease the font 1px at a time until it fits. :-)Rechaba
worked just fine for meHedy
B
6

jQuery plugin for checking if text has overflown, not written very well, but works as it suppose to be working. Posting this because I didn't find a working plugin for this anywhere.

jQuery.fn.hasOverflown = function () {
   var res;
   var cont = $('<div>'+this.text()+'</div>').css("display", "table")
   .css("z-index", "-1").css("position", "absolute")
   .css("font-family", this.css("font-family"))
   .css("font-size", this.css("font-size"))
   .css("font-weight", this.css("font-weight")).appendTo('body');
   res = (cont.width()>this.width());
   cont.remove();
   return res;
}
Botvinnik answered 21/2, 2013 at 11:55 Comment(3)
nice plugin, but the correct past tense of 'overflow' is 'overflowed' =)Pyongyang
This works pretty well! Could you please explain how it works? As far as I can tell, this is better than the isEllipsisActive function you can find here on SO because it works even with some edge cases when the width of the overflowed text is the same as the width of the text without overflow:hidden; and text-overflow: ellipsisCephalalgia
This works, but only for elements that contain single line of text. For elements with a fixed width that span multiple lines, modify this function to test for height instead of width.Homopterous
D
1

For illustrative purposes let's say your div has id="d", then you could do:

var d = document.getElementById('d'),
    dWider;
d.style.maxWidth = '9999em';
d.style.overflow = 'visible';
dWider = d.offsetWidth > 100;
d.style.maxWidth = '100px';
d.style.overflow = 'hidden';

Then the var dWider will be true if the text overflows and false if it doesn't.

Dayledaylight answered 20/6, 2011 at 4:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.