v147 · CSS · Events

Compatibility Lab

Detects event.pseudoTarget on UIEvent, AnimationEvent, and TransitionEvent. Click the cards to test click origin detection — the log shows whether pseudoTarget resolved a CSSPseudoElement or fell back to a null check. Provides the geometry-fallback pattern for non-supporting browsers.

API probes

Live test: click + animation events

Click anywhere on the blue card, trigger the ★ animation, or run the TIP transition. Toggle forced fallback to inspect the unsupported-browser path without changing browsers.

pseudoTarget detection
CLICK
ANIM
TRANS
Detection mode

Auto reads event.pseudoTarget when the browser exposes it.

event log…

Fallback pattern

/* Detect pseudoTarget support */ const HAS_PSEUDO_TARGET = (() => { try { return 'pseudoTarget' in new MouseEvent('click'); } catch { return false; } })(); /* Universal click-origin check */ function isPseudoClick(event, pseudoType) { if (HAS_PSEUDO_TARGET) { return event.pseudoTarget?.type === pseudoType; } // Fallback: geometry check via Element.pseudo() if available const el = event.currentTarget; if (typeof el.pseudo === 'function') { const pseudo = el.pseudo(pseudoType); if (!pseudo) return false; const rect = pseudo.getBoundingClientRect?.(); if (!rect) return false; return event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom; } // Last resort: check if click was within pseudo-element's known region // (requires layout knowledge of the pseudo-element's position) return knownPseudoHit(event, el) === pseudoType; } function knownPseudoHit(event, el) { const rect = el.getBoundingClientRect(); const before = { left: rect.left, top: rect.top, right: rect.left + 28, bottom: rect.top + 28 }; const after = { left: rect.right - 28, top: rect.bottom - 28, right: rect.right, bottom: rect.bottom }; if (event.clientX >= before.left && event.clientX <= before.right && event.clientY >= before.top && event.clientY <= before.bottom) return '::before'; if (event.clientX >= after.left && event.clientX <= after.right && event.clientY >= after.top && event.clientY <= after.bottom) return '::after'; return null; } /* Listen for animation events with pseudo attribution */ function onPseudoAnimationEnd(el, pseudoType, callback) { el.addEventListener('animationend', (e) => { if (HAS_PSEUDO_TARGET) { if (e.pseudoTarget?.type === pseudoType) callback(e); } else { // Fallback: animationName convention if (e.animationName === 'beforeSpin') callback(e); } }); }

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗