Mathew Kirmuć
Mathew Kirmuć

Reputation: 107

JS. Detect hidden child with parent overflow:hidden

I'm looking for simple way to detect, if child element of parent with overflow:hidden is visible within parent (it's not hidden by overflow).

I found something like this:

http://www.useallfive.com/thoughts/javascript-tool-detect-if-a-dom-element-is-truly-visible/

but i wonder maybe there is simpler solution.

Thanks in advance!

Upvotes: 5

Views: 4729

Answers (3)

LuizAsFight
LuizAsFight

Reputation: 242

I had a similar requirement, but mine was a bit more complicated because the overflow: hidden element wasn't the first parent, it was like 5 or 6 elements away.

Just spend a whole day trying to do it with solutions from the internet(I've tried the repo you mentioned as well), but nothing worked.

So I've made this repo by myself (only JS, 2kb sized) https://github.com/LuizAsFight/is-element-visible.

It might help you, basically I just get the target element and climb the tree searching if any parent has a overflow:hidden, once I found it I get the parent's rect size, and check if the target element rect is inside the parent (visually, pixels)

for using it you just need to

import isVisible from 'is-element-visible';

const el = document.getElementById('id');
isVisible(el);

I hope it helps you, Best.

Upvotes: 1

Damon
Damon

Reputation: 4346

Assuming you want a vanilla js solution, try this:

function isVisible (parent, child) {
  return !(
    (child.offsetLeft - parent.offsetLeft > parent.offsetWidth) ||
    (child.offsetTop - parent.offsetTop > parent.offsetHeight)
  )
}

Basically "if the difference between the start of the parent element and the start of the child element is greater than the actual width or height of the parent, it's considered not visible"

Run the following snippet for an example:

var parent = document.getElementById('parent');

[].slice.call(document.querySelectorAll('.child')).forEach(function (child, i) {
  console.log(i + ' is visible?', isVisible(parent, child));
});

function isVisible(parent, child) {
  return !(
    (child.offsetLeft - parent.offsetLeft > parent.offsetWidth) ||
    (child.offsetTop - parent.offsetLeft > parent.offsetHeight)
  )
}
* {
  box-sizing: border-box;
}

#parent {
  width: 200px;
  height: 100px;
  white-space: nowrap;
  background: lightblue;
}

.child {
  display: inline-block;
  width: 75px;
  height: 100%;
  border: 1px solid green;
}
<div id="parent">
  <div class="child">0</div>
  <div class="child">1</div>
  <div class="child">2</div>
  <div class="child">3</div>
  <div class="child">4</div>
</div>

Upvotes: 5

margarita
margarita

Reputation: 894

You can do the following things:

  • check if the element has height and width that are bigger than 0px
  • check if the element display CSS property is not "none", preferably "block"
  • check if the element positioning is valid and if so, check if it´s "top" property is not bigger than the parent´s height
  • Same thing for left - if it is not bigger than parent´s width

When checking "width", check offsetWidth and clientWidth, those will show actual numbers as displayed to the client.

Upvotes: 0

Related Questions