3

https://jsfiddle.net/basickarl/apts370w/1/

I'm expecting the checkOverflow function to return true in this case.

HTML:

<div style="float:right;">
  <div id="z">
    <div id="txt">
      345345345345345345345345345345345
    </div>
  </div>
</div>

Javascript:

console.log(checkOverflow(document.getElementById('z')));

function checkOverflow(el) {

  var curOverflow = el.style.overflow;

  if (!curOverflow || curOverflow === 'visible')
    el.style.overflow = 'hidden';

  var isOverflowing = el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;

  el.style.overflow = curOverflow;

  return isOverflowing;
};

CSS:

div#z {
  position: relative;
  background: red;
  width: 50px;
  height: 50px;
  overflow: auto;
}

div#txt {
  background: lightblue;
  float: right;
}

Any idea why the console.log of the function returns true here?

David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
basickarl
  • 37,187
  • 64
  • 214
  • 335

3 Answers3

2

scrollHeight and scrollWidth correspond to the actual clientHeight and clientWdith + the hidden height or width. Since div#txt is floated to the right, it doesn't overflow.

You should have a look at the box model and at this answer as well.

Community
  • 1
  • 1
jeerbl
  • 7,537
  • 5
  • 25
  • 39
1

The problem is that #txt is floated to the right, so it overflows towards the left.

But with the default left-to-right direction it's not possible to scroll towards the left.

However, you can if you use a right-to-left direction

#z { direction: rtl; }

function checkOverflow(el) {
  var curOverflow = el.style.overflow;
  if (!curOverflow || curOverflow === 'visible')
    el.style.overflow = 'hidden';
  var isOverflowing = el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;
  el.style.overflow = curOverflow;
  return isOverflowing;
}
console.log(checkOverflow(document.getElementById('z')));
div#z {
  position: relative;
  background: red;
  width: 50px;
  height: 50px;
  overflow: auto;
  direction: rtl;
}
div#txt {
  background: lightblue;
  float: right;
}
<div style="float:right;">
  <div id="z">
    <div id="txt">
      345345345345345345345345345345345
    </div>
  </div>
</div>

Of course, if then content overflows towards the right (e.g. you change to float: left), you will have the same problem.

If you want a more general approach, you can use getBoundingClientRect:

var rect = el.getBoundingClientRect();
var isOverflowing = [].every.call(el.children, function(child) {
  var childRect = child.getBoundingClientRect();
  return childRect.left < rect.left
    || childRect.right > rect.right
    || childRect.top < rect.top
    || childRect.bottom > rect.bottom;
});

function checkOverflow(el) {
  var curOverflow = getComputedStyle(el).overflow;
  if (!curOverflow || curOverflow === 'visible')
    el.style.overflow = 'hidden';
  var rect = el.getBoundingClientRect();
  var isOverflowing = [].every.call(el.children, function(child) {
    var childRect = child.getBoundingClientRect();
    return childRect.left < rect.left
      || childRect.right > rect.right
      || childRect.top < rect.top
      || childRect.bottom > rect.bottom;
  });
  el.style.overflow = curOverflow;
  return isOverflowing;
}
console.log(checkOverflow(document.getElementById('z')));
div#z {
  position: relative;
  background: red;
  width: 50px;
  height: 50px;
  overflow: auto;
}
div#txt {
  background: lightblue;
  float: right;
}
<div style="float:right;">
  <div id="z">
    <div id="txt">
      345345345345345345345345345345345
    </div>
  </div>
</div>
Oriol
  • 274,082
  • 63
  • 437
  • 513
0

This is my solution

https://jsfiddle.net/apts370w/3/

The problem is that is not a inline element, if you change to span tag it works

I change this too

el.offsetWidth //instead of clientWidth
Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69