Our solution was to use couple things to determine whether the element is visible and not behind any other elements. Here's the methods we used.
- window.getComputedStyle to check visibility:hiddenanddisplay:none
- document.elementFromPoint from multiple points. Most common cases could probably be handled by checking all the corners. Though we needed more points to get more robust results. Corner coordinates can be easily checked with Element.getBoundingClientRect()
https://jsfiddle.net/k591Lbwu/27/
HTML
<div id="covering-element"></div>
<div>
  <div id="hidden-element"></div>
</div>
<button style="margin-top:100px">Check visibility</button>
CSS
#covering-element {
  position: absolute;
  width: 100px;
  height: 100px;
  background: darksalmon;
  text-align: center;
}
#hidden-element {
  width: 25px;
  height: 25px;
  background: deeppink;
}
JavaScript
document.querySelector('button').addEventListener('click', function() {
    const element = document.getElementById('hidden-element')
  alert('Visible = '+isVisible(element))
})
function isVisible(element) {
  if(!isVisibleByStyles(element)) return false
  if(isBehindOtherElement(element)) return false
  return true
}
function isVisibleByStyles(element) {
    const styles = window.getComputedStyle(element)
  return styles.visibility !== 'hidden' && styles.display !== 'none'
}
function isBehindOtherElement(element) {
  const boundingRect = element.getBoundingClientRect()
  // adjust coordinates to get more accurate results
  const left = boundingRect.left + 1
  const right = boundingRect.right - 1
  const top = boundingRect.top + 1
  const bottom = boundingRect.bottom - 1
  if(document.elementFromPoint(left, top) !== element) return true
  if(document.elementFromPoint(right, top) !== element) return true
  if(document.elementFromPoint(left, bottom) !== element) return true
  if(document.elementFromPoint(right, bottom) !== element) return true
  return false
}