Element Visibility trigger in Google Tag Manager
Scroll-depth triggers tell you how far someone scrolled. Element Visibility tells you whether they actually saw the one specific thing you care about - a pricing table, a banner, a specific CTA.
The Element Visibility trigger fires when a targeted element (by CSS selector or ID) enters the viewport at a configurable minimum percentage visible, with a firing-frequency setting of once per page, once per element, or every time. It's the right tool for tracking whether a specific piece of content was seen - a pricing table, an ad unit, a banner - rather than how far down the page someone generically scrolled. It cannot see inside iframes, and it can miss content that isn't in the DOM yet when the check runs, which is the most common setup failure.
What it fires on
You target one element - by its CSS selector or, more reliably, its ID - and set a minimum percentage of that element that must be visible in the viewport before the trigger fires. It's a purpose-built alternative to scroll-depth percentages when what matters is one specific piece of content, not an arbitrary point down the page.
Common uses
- Confirming a specific pricing table or comparison chart was actually seen, not just that the page loaded
- Ad or banner viewability tracking, distinct from a simple impression on page load
- Firing a tag only once a lazy-loaded section has rendered and become visible
- Measuring engagement with a specific CTA block placed mid-page, separate from generic scroll depth
Setup and the gotchas
| Setting | Choice | Note |
|---|---|---|
| Selection method | ID or CSS selector | ID is more reliable if unique and stable; selector needed for repeated components |
| Minimum percent visible | Typically 50-100% | Lower thresholds fire earlier but can count content barely peeking into view |
| Firing frequency | Once per page / once per element / every time | "Once per element" is the common choice for a single viewability event |
Two failure modes account for most Element Visibility problems: the element sits inside an iframe, which the trigger cannot see into at all, or the element is lazy-loaded and not yet in the DOM when GTM's observer starts watching for it - the fix there is usually to combine the visibility trigger with a DOM-ready or custom-event condition that only starts watching after the content actually renders.
Common questions
Should I target the element by CSS selector or by ID?
ID is more reliable if the element has a stable, unique ID that won't be reused elsewhere on the page. CSS selector is more flexible when you need to target an element that only has a class, or the same component appears multiple times and you want every instance to trigger.Why doesn't my Element Visibility trigger fire on a lazy-loaded section?
If the element isn't in the DOM yet at the time GTM evaluates visibility - because it's inserted later by JavaScript, or rendered only once a placeholder is scrolled near - the trigger can miss it entirely. The fix is usually to trigger off a DOM-ready or custom event that fires after the content actually renders, not off the page's initial load.Can Element Visibility fire more than once per page?
Yes - the trigger has a firing-frequency setting: once per page, once per element, or every time the element becomes visible. "Once per element" is the common choice for tracking whether a specific banner or CTA was ever seen, without re-firing every time the user scrolls it in and out of view.
Visibility Trigger Not Firing on a Lazy-Loaded Section?
We trace the actual DOM timing and fix the trigger condition to match how your content really renders.
Get GTM Trigger Help