134

I have a div with a fixed height and overflow:hidden;

I want to check with jQuery if the div has elements that are overflowing past the fixed height of the div. How can I do this?

Justin Meltzer
  • 13,318
  • 32
  • 117
  • 182
  • I could be wrong, but I don't think there is a magical jQuery way to check if an element is outside another element. You would probably have to check the height and position of the elements inside your div and do some calculations to see if they overflow. – adeneo Oct 05 '11 at 22:50
  • 1
    Yeah, I was thinking to check if the difference between the position of the top of the div and the position of the bottom of last child element inside the div was greater than the height of the div – Justin Meltzer Oct 05 '11 at 22:52
  • Possible duplicate of [detect elements overflow using jquery](http://stackoverflow.com/questions/2059743/detect-elements-overflow-using-jquery) – Noyo Oct 23 '15 at 17:11

9 Answers9

287

You actually don't need any jQuery to check if there is an overflow happening or not. Using element.offsetHeight, element.offsetWidth , element.scrollHeight and element.scrollWidth you can determine if your element have content bigger than it's size:

if (element.offsetHeight < element.scrollHeight ||
    element.offsetWidth < element.scrollWidth) {
    // your element have overflow
} else {
    // your element doesn't have overflow
}

See example in action: Fiddle

But if you want to know what element inside your element is visible or not then you need to do more calculation. There is three states for a child element in terms of visibility:

enter image description here

If you want to count semi-visible items it would be the script you need:

var invisibleItems = [];
for(var i=0; i<element.childElementCount; i++){
  if (element.children[i].offsetTop + element.children[i].offsetHeight >
      element.offsetTop + element.offsetHeight ||
      element.children[i].offsetLeft + element.children[i].offsetWidth >
      element.offsetLeft + element.offsetWidth ){

        invisibleItems.push(element.children[i]);
    }

}

And if you don't want to count semi-visible you can calculate with a little difference.

Ivan Akulov
  • 4,323
  • 5
  • 37
  • 64
Mohsen
  • 64,437
  • 34
  • 159
  • 186
  • Correct me if I'm wrong but this doesn't appear to be working any more Chrome V.20.0.1132.57 . If you change the text inside the div, the background colour stays yellow, http://jsbin.com/ujiwah/25/edit#javascript,html,live – Robbie Jul 16 '12 at 14:40
  • 4
    @Robbie `

    ` is a block level element and takes 100% width. If you want to try this with amount of text inside the p just make `p{display:inline}`. This way text inside determines width of `p`.

    – Mohsen Jul 16 '12 at 16:49
  • I read "You actually don't need any jQuery" and immediately went "duh, it's simple math." – Michael J. Calkins Mar 23 '13 at 00:50
  • 1
    Works for most cases but won't cover up scenario with CSS tables (display table-cell, table-rwo, table) - – User18165 Jul 01 '14 at 13:55
  • 1
    I understand offsetHeight includes borders, which do not count towards scrollable area. Just a note. (correct me if I'm wrong) – Lodewijk Aug 06 '15 at 17:35
  • 1
    @Lodewijk I am seeing the same thing. Maybe the correct property is clientHeight? – Pete Aug 21 '15 at 23:27
  • This is not a good answer. I have a jquery object and I need a full jquery solution, something like $(obj).offset().left – Jonathan Simas Nov 23 '16 at 12:47
  • This doesn't take into account the current `scroll[Top/Left]` of the container. – Kaiido Jun 11 '17 at 06:10
  • I agree with @Lodewijk and @Pete, use [client](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight) values instead of [offset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight) values, when comparing with [scroll](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight) values: `div.clientHeight < div.scrollHeight || div.clientWidth < div.scrollWidth` – Tamás Bolvári Jan 18 '21 at 13:31
41

I had the same question as the OP, and none of those answers fitted my needs. I needed a simple condition, for a simple need.

Here's my answer:

if ($("#myoverflowingelement").prop('scrollWidth') > $("#myoverflowingelement").width() ) {
  alert("this element is overflowing !!");
}
else {
 alert("this element is not overflowing!!");
}

Also, you can change scrollWidth by scrollHeight if you need to test the either case.

sidney
  • 2,704
  • 3
  • 28
  • 44
  • 1
    Thanks, that worked for me. just needed a simple example in jquery but not in plain js. – mikhail-t Jul 29 '14 at 20:37
  • 4
    doesn't work for elements with padding/margin. use outerWidth(true) instread of width – Vladimir Shmidt Aug 31 '16 at 20:16
  • Does not work in ie, works fine in mozilla and chrome. – Sushil Kumar Sep 21 '16 at 13:47
  • I have some weird effects with this script. Testing in Chrome. I rewrote it to check height (using OuterHeight) and if I use F5 to reload a page to check the script, or navigate to it from another page, it always come back as overflow = true, but if I use ctrl-F5 it comes back as overflow = false. This is when testing a situation that is supposed to come back false. When it's supposed to be true it always works. – Dennis Jun 28 '18 at 06:42
  • Ok I figured it out myself. I have my script tags wrapped in window.addEventListener('DOMContentLoaded') so they will work with my asynchronously loaded jquery and other files. But running this script at that stage returns apparently false readings, so for this script I replaced DOMContentLoaded with just 'load' to delay the execution of the script further. Now it returns correct results every time. And for my purposes it's perfectly fine that it waits to run it until after the page is loaded, then I can even add an animation to highlight the users attention to a "read more" button. – Dennis Jun 28 '18 at 06:47
4

Partially based on Mohsen's answer (the added first condition covers the case where the child is hidden before the parent):

jQuery.fn.isChildOverflowing = function (child) {
  var p = jQuery(this).get(0);
  var el = jQuery(child).get(0);
  return (el.offsetTop < p.offsetTop || el.offsetLeft < p.offsetLeft) ||
    (el.offsetTop + el.offsetHeight > p.offsetTop + p.offsetHeight || el.offsetLeft + el.offsetWidth > p.offsetLeft + p.offsetWidth);
};

Then just do:

jQuery('#parent').isChildOverflowing('#child');
brauliobo
  • 5,843
  • 4
  • 29
  • 34
3

So I used the overflowing jquery library: https://github.com/kevinmarx/overflowing

After installing the library, if you want to assign the class overflowing to all overflowing elements, you simply run:

$('.targetElement').overflowing('.parentElement')

This will then give the class overflowing, as in <div class="targetElement overflowing"> to all elements that are overflowing. You could then add this to some event handler(click, mouseover) or other function that will run the above code so that it updates dynamically.

maudulus
  • 10,627
  • 10
  • 78
  • 117
2

I fixed this by adding another div in the one that overflows. Then you compare the heights of the 2 divs.

<div class="AAAA overflow-hidden" style="height: 20px;" >
    <div class="BBBB" >
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </div>
</div>

and the js

    if ($('.AAAA').height() < $('.BBBB').height()) {
        console.log('we have overflow')
    } else {
        console.log('NO overflow')
    }

This looks easier...

alex toader
  • 2,300
  • 1
  • 17
  • 20
2

One method is to check scrollTop against itself. Give the content a scroll value larger than its size and then check to see if its scrollTop is 0 or not (if it is not 0, it has overflow.)

http://jsfiddle.net/ukvBf/

Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
1

This is the jQuery solution that worked for me. offsetWidth etc. didn't work.

function is_overflowing(element, extra_width) {
    return element.position().left + element.width() + extra_width > element.parent().width();
}

If this doesn't work, ensure that elements' parent has the desired width (personally, I had to use parent().parent()). position is relative to the parent. I've also included extra_width because my elements ("tags") contain images which take small time to load, but during the function call they have zero width, spoiling the calculation. To get around that, I use the following calling code:

var extra_width = 0;
$(".tag:visible").each(function() {
    if (!$(this).find("img:visible").width()) {
        // tag image might not be visible at this point,
        // so we add its future width to the overflow calculation
        // the goal is to hide tags that do not fit one line
        extra_width += 28;
    }
    if (is_overflowing($(this), extra_width)) {
        $(this).hide();
    }
});

Hope this helps.

Dennis Golomazov
  • 16,269
  • 5
  • 73
  • 81
1

In plain English: Get the parent element. Check it's height, and save that value. Then loop through all the child elements and check their individual heights.

This is dirty, but you might get the basic idea: http://jsfiddle.net/VgDgz/

Doozer Blake
  • 7,677
  • 2
  • 29
  • 40
  • 1
    It's a good example, but what about the position. If an element is positioned absolute all the way at the top of the parent it could overflow even if the height is lower then the parent. – adeneo Oct 05 '11 at 23:07
  • Absolutely, there are likely quite a few different cases that could cause it. Just a quick example of where to maybe start. Op's specific case will probably define what needs to be checked for – Doozer Blake Oct 05 '11 at 23:25
0

Here's a pure jQuery solution, but it's rather messy:

var div_height = $(this).height();
var vertical_div_top_position = $(this).offset().top;
var lastchild_height = $(this).children('p:last-child').height();
var vertical_lastchild_top_position = $(this).children('p:last-child').offset().top;
var vertical_lastchild_bottom_position = lastchild_height + vertical_lastchild_top_position;
var real_height = vertical_lastchild_bottom_position - vertical_div_top_position;

if (real_height > div_height){
    //overflow div
}
Justin Meltzer
  • 13,318
  • 32
  • 117
  • 182