Blog

← All articles

Track Dynamic Elements in GTM: Dropdowns, Tooltips, Popups & More

TL;DR: To track dynamic elements (dropdowns, tooltips, popups) in GTM: freeze the page to inspect them (F8 in DevTools or press F in GTM Event Helper), use Element Visibility triggers with 'Observe DOM changes' enabled for modals and success messages, and use Click triggers with stable CSS selectors for menu items.

Not every element on a page sits there waiting to be clicked. Dropdown menus appear on hover. Tooltips vanish the moment you move your mouse. Modal popups overlay the page and disappear on close. Accordion panels expand and collapse. These dynamic UI elements are some of the most important interactions to track — and some of the hardest to set up in Google Tag Manager.

The core challenge: you can't easily inspect an element that disappears when you try to examine it. And GTM's standard click trigger doesn't capture the nuance of elements that appear and disappear dynamically. This guide covers practical strategies for each type.

Why are dynamic elements hard to track in GTM?

When you right-click a dropdown menu item to "Inspect Element" in Chrome DevTools, the dropdown closes. When you try to use GTM's Preview mode to click a tooltip, it vanishes before you can interact with it. The standard approach of "find the element, copy the selector, create a trigger" breaks down because you can't find the element long enough to get a selector.

There are three strategies to solve this:

  1. Freeze the page to keep dynamic elements visible
  2. Use Element Visibility triggers instead of Click triggers
  3. Use the DOM inspector with keyboard shortcuts to pause rendering

How do I freeze the page to inspect dynamic elements?

You can freeze JavaScript execution in Chrome to prevent elements from disappearing:

  1. Open Chrome DevTools (F12)
  2. Hover over the dynamic element to make it appear
  3. While it's visible, press F8 (or Ctrl+\\) to pause script execution
  4. The page is now frozen — the element stays visible
  5. Switch to the Elements tab and inspect the element
  6. Copy the CSS selector
  7. Press F8 again to resume

This works for most JavaScript-driven UI elements. However, pure CSS hover effects (like :hover-based dropdowns) may not be captured this way since no JavaScript is involved.

Alternative: setTimeout in Console

For CSS-only hover effects, use a delayed debugger statement:

setTimeout(() => { debugger; }, 3000);

Run this in the console, then hover over the element within 3 seconds. The debugger pauses execution with the element still visible.

GTM Event Helper has a built-in Freeze Page feature. Press F while in Select Mode to freeze the entire page state. Dynamic elements stay visible, and you can click them to get a CSS selector with stability analysis. No DevTools required.

How do I use Element Visibility triggers for dynamic content?

Instead of tracking the click on a dynamic element, track when it appears. GTM's Element Visibility trigger fires when a specified element becomes visible in the viewport.

When to Use This

Setup Steps

  1. Create a new trigger → Element Visibility
  2. Selection Method: CSS Selector (more reliable than ID for dynamic elements)
  3. Element Selector: Enter the CSS selector of the element you want to track (e.g., .modal-success, #thank-you-message)
  4. When to fire:
    • "Once per page" — for elements that appear once (success messages)
    • "Once per element" — for elements that can re-appear (repeated popups)
    • "Every time an element appears on screen" — for elements that toggle visibility
  5. Observe DOM changes: Check this box. It tells GTM to watch for elements that are dynamically added to the page, not just elements that exist on page load.

The "Observe DOM Changes" Setting

This is the key setting. Without it, GTM only checks for the element once on page load. If the element doesn't exist yet (because it's a popup that hasn't opened), the trigger never fires. With "Observe DOM changes" enabled, GTM uses a MutationObserver to watch for new elements matching your selector.

Performance note: MutationObserver watches every DOM change on the page. For most sites this is fine, but on pages with heavy DOM manipulation (real-time dashboards, infinite scroll feeds), it can impact performance. Use specific selectors to minimize the cost.

How do I track specific dynamic UI elements?

Dropdown Menus

Dropdown menu items are usually inside a container that appears on hover or click.

Approach: Use a Click trigger with a selector targeting the menu items, not the menu container.

/* Target individual menu items */
.dropdown-menu a
nav .submenu li a
[role="menu"] [role="menuitem"]

The click on the menu item fires before the menu closes, so standard Click triggers work here. The tricky part is getting the right selector — which requires freezing the page first to inspect the menu while it's open.

Tooltips

Tooltips appear on hover and disappear when the mouse moves away.

Approach: Don't track the tooltip itself — track the element that triggers the tooltip. Users hover over (or click) something to see the tooltip, so the trigger should fire on that interaction.

/* Track the trigger element, not the tooltip */
[data-tooltip]
.has-tooltip
[aria-describedby]

If you need to know which tooltip was shown, use the Click Text or a data-* attribute as an event parameter.

Modal Popups

Modals overlay the page and usually contain important conversion actions (signup forms, pricing details, video players).

Track modal open: Use an Element Visibility trigger on the modal container with "Observe DOM changes" enabled.

.modal.is-open
[role="dialog"]:not([aria-hidden="true"])
.popup-overlay.visible

Track actions inside the modal: Use standard Click triggers. Once the modal is open, its contents are regular DOM elements that can be clicked.

Accordion / Expandable Panels

Accordion panels expand to show content and collapse to hide it.

Approach: Track the click on the accordion header (the toggle element).

/* Accordion toggles */
.accordion-header
[data-toggle="collapse"]
details > summary
button[aria-expanded]

To distinguish open from close, check the aria-expanded attribute. If aria-expanded="false" at click time, the user is opening the panel. Create a Custom JavaScript variable that reads this attribute.

Mega Menus

Mega menus are large dropdown panels that contain multiple columns, links, and sometimes images.

Approach: Track individual link clicks within the mega menu. Freeze the page to inspect the menu structure, then use a selector targeting the links inside:

.mega-menu a
nav .mega-menu-panel a
.mega-menu [role="menuitem"]

Use Click Text and Click URL as event parameters to differentiate which menu item was clicked.

How do I track tab switching and carousel interactions?

Tabs and carousels are among the most common interactive elements on the web, yet they're frequently untracked. Understanding which tabs users click and which carousel slides they engage with can reveal content preferences and inform page layout decisions.

Tab Panels

Well-built tab interfaces use ARIA roles. The tab buttons have [role="tab"] and the content panels have [role="tabpanel"]. Track the tab button click:

/* CSS selectors for tab clicks */
[role="tab"]
.nav-tabs button
.tab-list [aria-selected]

Pass the tab label as an event parameter using GTM's built-in Click Text variable, or read a data-tab-name attribute with a Custom JavaScript variable:

// GTM Custom JavaScript Variable: "Tab Name"
function() {
  var el = {{Click Element}};
  return el.getAttribute('data-tab-name') || el.textContent.trim();
}

Carousels and Sliders

Carousels present a unique challenge: they often auto-rotate, and you only want to track manual interactions — the user intentionally clicking "Next" or a slide indicator.

To track which slide the user navigated to, read the active slide index from the DOM after the click:

// GTM Custom JavaScript Variable: "Carousel Slide Index"
function() {
  var active = document.querySelector('.carousel-item.active, .slick-current');
  return active ? active.getAttribute('data-slide-index') || 'unknown' : 'unknown';
}

How do I track notification badges and toast messages?

Notifications, toast messages, and transient UI elements are among the trickiest to track because they appear briefly and often don't require user interaction.

Toast and Snackbar Messages

Toast notifications slide in from a corner, display a message for a few seconds, and auto-dismiss. Use an Element Visibility trigger with "Observe DOM changes" enabled:

To capture the toast content as an event parameter, create a Custom JavaScript variable:

// GTM Custom JavaScript Variable: "Toast Message Text"
function() {
  var toast = document.querySelector('.toast.show, .snackbar.visible, [role="alert"]');
  return toast ? toast.textContent.trim().substring(0, 100) : '(not set)';
}

Cookie Consent Banners

Consent banners are critical to track because they affect your data collection. Track both the banner appearance and the user's choice:

Chat Widget Interactions

Live chat widgets (Intercom, Drift, Zendesk) load in iframes, so GTM can't track clicks inside them. However, you can track the open/close toggle button, which lives on your page:

How do I debug Element Visibility triggers that don't fire?

Element Visibility triggers are powerful but can be frustrating when they silently fail. Here's a systematic debugging checklist:

Check 1: Is "Observe DOM Changes" Enabled?

This is the most common cause. Without this setting, GTM only checks for the element on page load. If the element is added dynamically (which is the case for modals, toasts, success messages), the trigger never fires. Go to the trigger configuration and verify the checkbox is checked.

Check 2: Does the Selector Actually Match?

Open the browser console and run:

// Test your selector — trigger the dynamic element first, then run this:
document.querySelectorAll('.your-selector-here')

If the result is an empty NodeList, your selector doesn't match anything. Common causes: a typo in the class name, the element is inside a shadow DOM, or the selector worked on a different page.

Check 3: Is the Element Actually Visible?

GTM's Element Visibility trigger checks whether the element is in the viewport and visually rendered. Elements with these CSS properties will not trigger it:

Check 4: Is the Element Inside an Iframe?

GTM cannot observe DOM changes inside cross-origin iframes. If your dynamic element lives in an iframe (common with embedded forms, payment widgets, chat tools), the Element Visibility trigger won't detect it. You'll need to track a wrapper element on the parent page or use a different approach entirely.

Check 5: Are Other Trigger Conditions Blocking It?

If your trigger has additional conditions (like Page Path or custom variable filters), verify each condition is met. In GTM Preview mode, check the "Tags Not Fired" section — it shows which conditions passed and which failed for each trigger evaluation.

GTM Event Helper's Select Mode shows real-time selector validation. When you click an element, it tests the CSS selector against the live DOM and warns you if the selector is unstable, matches multiple elements, or targets content inside an iframe.

How do I combine Click and Visibility triggers for complex interactions?

Some tracking requirements involve two events happening in sequence — for example, tracking that a user opened a product quickview modal and then clicked "Add to Cart" inside it. There are three approaches, each suited to different complexity levels.

Approach 1: Two Separate Events (Recommended)

Fire independent events for each interaction and analyze the sequence in GA4:

In GA4, use a Path Exploration report to see how many users who triggered modal_open went on to trigger modal_cta_click. This is the simplest implementation and gives you the most analytical flexibility.

Approach 2: Trigger Groups

GTM Trigger Groups fire a tag only when all specified triggers have fired during the same page view. Create a trigger group containing both the Element Visibility trigger (modal open) and the Click trigger (CTA click). The associated tag fires only when both conditions are met.

Limitation: Trigger groups don't enforce order. If the user clicks the CTA first (unlikely but possible in edge cases) and then the modal appears, the group still fires. For most modal workflows, this isn't a problem because the CTA only exists inside the modal.

Approach 3: Custom JavaScript State Tracking

For truly complex sequences, use a Custom HTML tag to set a JavaScript variable when the first event occurs, then check that variable in the second trigger's conditions:

<script>
// Custom HTML tag fired on modal_open trigger
window._gtm_modal_open = true;
window._gtm_modal_name = '{{Click Text}}';
</script>

Then create a Custom JavaScript variable that reads window._gtm_modal_open and use it as a condition on your CTA click trigger. This gives you full control over sequencing but adds complexity — use it only when Approaches 1 and 2 fall short.

When to Use Each

ScenarioApproachWhy
General analytics (funnel analysis)Two separate eventsSimplest, most flexible in GA4
Fire a tag only after both interactionsTrigger groupBuilt-in GTM feature, no code
Strict sequencing with stateCustom JS stateFull control, handles edge cases

What CSS selectors work best for dynamic elements?

Dynamic elements often have generated class names that change between builds. Stable selectors for dynamic elements:

Selector TypeExampleStability
ARIA role[role="dialog"]High
ARIA attribute[aria-expanded="true"]High
Data attribute[data-modal="signup"]High
Semantic HTMLdetails > summaryHigh
Stable class.modal-successMedium
Generated class.css-1a2b3cLow — avoid

Is there a faster way to track dynamic elements?

The manual process for dynamic elements is: freeze the page in DevTools, find the element, manually copy the selector, switch to GTM, create the trigger, hope the selector is stable. GTM Event Helper combines it all:

  1. Enter Select Mode (Ctrl+Shift+E)
  2. Press F to freeze the page with the dynamic element visible
  3. Click the element — the extension generates a stable CSS selector
  4. Choose your event name and tag type
  5. Click "Create in GTM" — trigger and tag are created via the API

The Freeze Page feature is purpose-built for this problem. No DevTools, no console commands, no guessing at selectors.

Track dropdowns, tooltips, and popups — without the struggle.

Install GTM Event Helper

External Resources

Related Articles

← All articles · Home · Privacy Policy · Contact