Last active
November 4, 2025 16:34
-
-
Save marco-prontera/6d9d1a9cead48f44e8dabd8ff5310ecf to your computer and use it in GitHub Desktop.
Check If an Element is Visible in the Viewport with JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function isVisibleInViewport(element) { | |
| const elementStyle = window.getComputedStyle(element); | |
| //Particular cases when the element is not visible at all | |
| if ( | |
| elementStyle.height == '0px' || | |
| elementStyle.display == 'none' || | |
| elementStyle.opacity == '0' || | |
| elementStyle.visibility == 'hidden' || | |
| elementStyle.clipPath == 'circle(0px at 50% 50%)' || | |
| elementStyle.transform == 'scale(0)' || | |
| element.hasAttribute('hidden') | |
| ) { | |
| return false; | |
| } | |
| const rect = element.getBoundingClientRect(); | |
| //Overlapping strict check | |
| const baseElementLeft = rect.left; | |
| const baseElementTop = rect.top; | |
| const elementFromStartingPoint = document.elementFromPoint(baseElementLeft,baseElementTop); | |
| if (elementFromStartingPoint != null && !element.isSameNode(elementFromStartingPoint)) { | |
| const elementZIndex = elementStyle.zIndex; | |
| const elementOverlappingZIndex = window.getComputedStyle(elementFromStartingPoint).zIndex; | |
| if (Number(elementZIndex) < Number(elementOverlappingZIndex)){ | |
| return false; | |
| } | |
| if (elementZIndex === '' && elementOverlappingZIndex === '') { | |
| /** | |
| If two positioned elements overlap without a z-index specified, the element | |
| positioned last in the HTML code will be shown on top | |
| **/ | |
| if (element.compareDocumentPosition(elementFromStartingPoint) & Node.DOCUMENT_POSITION_FOLLOWING) { | |
| return false; | |
| } | |
| } | |
| } | |
| return ( | |
| rect.top >= 0 && | |
| rect.left >= 0 && | |
| rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && | |
| rect.right <= (window.innerWidth || document.documentElement.clientWidth) | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It is not working in all cases.
This is not true:
The element positioned last can be located in a container with
overflow: hiddenand be invisible.Additionally, overlapping element with higher z-index can have transparent background.