A lightweight, zero-dependency JavaScript library for measuring element visibility in the browser viewport. Perfect for ad viewability tracking, lazy loading, scroll animations, and analytics.
- Zero dependencies - Lightweight and fast
- Precise measurements - Returns exact percentage (0-1) of element visibility
- Flexible API - Check vertical, horizontal, or combined visibility
- Detailed state information - Know exactly why an element is not visible
- CommonJS & CDN support - Use with any build system or directly in the browser
var vertical = require("viewability/vertical");
var result = vertical(document.getElementById("blue-box"));
// Returns: {value: 1, state: "EL_IS_WITHIN_VERTICAL_VIEW"}
// value: 1 means 100% visible vertically
// value: 0.5 means 50% visible vertically
// value: 0 means not visible at allSee live examples of viewability in action:
- Draggable-based example - Drag elements around to see real-time viewability
- Timer-based example - Automatic scrolling demonstration
Source code for demos is in the gh-pages branch.
npm install --save viewability<script src="https://cdn.jsdelivr.net/npm/viewability@latest/dist/viewability.min.js"></script>Or specify a version:
<script src="https://cdn.jsdelivr.net/npm/viewability@1.3.4/dist/viewability.min.js"></script>Download the latest version from GitHub Releases
Check if an element is visible on screen:
var v = require("viewability");
var el = document.getElementById("blue-box");
// Check if any part is visible
if (v.isElementOnScreen(el)) {
console.log("Element is at least partially visible");
}
// Check if element is 100% visible
if (v.isElementOnScreen(el, true)) {
console.log("Element is completely visible");
}Get detailed vertical visibility information:
var vertical = require('viewability/vertical');
var result = vertical(document.getElementById('blue-box'));
console.log(result);
// {value: 1, state: "EL_IS_WITHIN_VERTICAL_VIEW"}
// value: 0-1 (percentage visible)
// state: describes position relative to viewportPossible vertical states:
EL_IS_WITHIN_VERTICAL_VIEW- Fully visible verticallyEL_IS_ABOVE_VIEW- Element is above the viewportEL_IS_BELOW_VIEW- Element is below the viewportEL_TOP_TRUNCATED- Top portion is cut offEL_BOTTOM_TRUNCATED- Bottom portion is cut offEL_BOTTOM_AND_TOP_TRUNCATED- Both top and bottom are cut offEL_IS_NOT_WITHIN_VIEW- Generic not visible state
Get detailed horizontal visibility information:
var horizontal = require('viewability/horizontal');
var result = horizontal(document.getElementById('blue-box'));
console.log(result);
// {value: 1, state: "EL_IS_WITHIN_HORIZONTAL_VIEW"}Possible horizontal states:
EL_IS_WITHIN_HORIZONTAL_VIEW- Fully visible horizontallyEL_IS_TOO_LEFT- Element is to the left of the viewportEL_IS_TOO_RIGHT- Element is to the right of the viewportEL_LEFT_TRUNCATED- Left portion is cut offEL_RIGHT_TRUNCATED- Right portion is cut offEL_LEFT_AND_RIGHT_TRUNCATED- Both left and right are cut offEL_IS_NOT_WITHIN_VIEW- Generic not visible state
When using the CDN, the library is exposed globally as viewability:
<script src="https://cdn.jsdelivr.net/npm/viewability@latest/dist/viewability.min.js"></script>
<script>
var element = document.getElementById('my-element');
// Check vertical visibility
var v = viewability.vertical(element);
console.log('Vertical visibility:', v.value * 100 + '%');
// Check horizontal visibility
var h = viewability.horizontal(element);
console.log('Horizontal visibility:', h.value * 100 + '%');
// Quick boolean check
if (viewability.isElementOnScreen(element)) {
console.log('Element is visible!');
}
</script>Track when advertisements are actually viewable according to IAB standards:
var vertical = require('viewability/vertical');
var horizontal = require('viewability/horizontal');
function trackAdViewability(adElement) {
var v = vertical(adElement);
var h = horizontal(adElement);
var visiblePercentage = v.value * h.value;
// IAB standard: 50% visible for 1 second
if (visiblePercentage >= 0.5) {
console.log('Ad is viewable:', (visiblePercentage * 100).toFixed(1) + '%');
}
}Load images only when they're about to enter the viewport:
var vertical = require('viewability/vertical');
function checkLazyLoad() {
document.querySelectorAll('img[data-src]').forEach(function(img) {
var v = vertical(img);
// Start loading when element is close to viewport
if (v.value > 0 || v.state === 'EL_IS_BELOW_VIEW') {
var rect = img.getBoundingClientRect();
if (rect.top < window.innerHeight + 200) { // 200px threshold
img.src = img.getAttribute('data-src');
img.removeAttribute('data-src');
}
}
});
}
window.addEventListener('scroll', checkLazyLoad);Trigger animations when elements become visible:
var viewability = require('viewability');
function checkAnimations() {
document.querySelectorAll('.animate-on-scroll').forEach(function(el) {
if (viewability.isElementOnScreen(el)) {
el.classList.add('animated');
}
});
}
window.addEventListener('scroll', checkAnimations);Returns vertical viewability information for an element.
- Parameters:
element(HTMLElement): The DOM element to check
- Returns: Object with:
value(number): Visibility percentage from 0 to 1state(string): Description of element position
Returns horizontal viewability information for an element.
- Parameters:
element(HTMLElement): The DOM element to check
- Returns: Object with:
value(number): Visibility percentage from 0 to 1state(string): Description of element position
Boolean check for element visibility.
- Parameters:
element(HTMLElement): The DOM element to checkfull(boolean, optional): If true, checks for 100% visibility. If false/omitted, checks for any visibility
- Returns: boolean
This library uses getBoundingClientRect() and window.innerWidth/window.innerHeight, which are supported in all modern browsers and IE9+.
npm install
npm testnpm run buildnpm run lintContributions are welcome! Please feel free to submit a Pull Request.
ISC