[selectors] Proposal: :near(<length>) pseudo-class for pointer proximity (“pre-hover” styling)

4 min read Original article ↗

Introduction

Designers often want “pre-hover” affordances: reveal controls, brighten icons, or show hints when a pointing device approaches an interactive target—common in physical UIs. On the web, doing this robustly typically requires JS (pointermove) and custom hit-testing/geometry, which is heavy for a simple threshold effect and hard to integrate with the cascade.

Examples / use cases

  • Reveal a toolbar when the pointer approaches a container (without requiring the container to be hovered yet).
  • Increase contrast/brightness of small icon buttons as the pointer nears them, improving discoverability.
  • Display contextual hints (“Drag to reorder”) when approaching a handle.

Add a functional pseudo-class that matches elements when the active pointing device* is within a given distance of the element. On devices without hover-capable pointers, :near() never matches.

*In this proposal, "active pointing device" is the UA’s primary hover-capable pointing device (if any).

Syntax

button:near(200px) { outline: 1px solid; }

This is intended as a boolean threshold (“inside/outside”) rather than exposing continuous pointer coordinates.

Open question: Is the argument exactly <length> (including calc()), and are negative lengths invalid? What about 0?

Considerations

Non-goals (to keep scope contained)

  • Not a general “distance between two elements” selector.
  • Not a replacement for :hover / :focus and should not imply activation.
  • Not exposing pointer coordinates or requiring JS.

Suggested initial semantics (strawman, for discussion)

An element matches :near(<length>) when:

  • The UA has an active pointing device (see “Which pointer / modality” below).
  • The distance between the pointer hotspot and the element’s “proximity shape” is ≤ <length>.
  • The “proximity shape” is intentionally left to define (see questions below), but likely should align with existing UA hit-testing / painted geometry rather than author-defined shapes.

Key semantics questions to resolve

1. Distance & geometry

  • Distance from pointer hotspot to the nearest point on what geometry?
    • border box / padding box / visual border edge
    • UA hit-test region
    • post-transform painted geometry (transforms, border-radius)
  • How should overflow: clip/hidden, masks, and clip-path affect the geometry?

2. Which pointer / modality

  • Should this instead use any-pointer semantics (match if any hover-capable pointer is within range), rather than primary-only?
  • What about pen hover (where supported) vs mouse?

3. Update model

  • When does matching update?
    • pointer movement
    • scroll
    • layout/transform changes
  • Can UAs throttle updates for performance (similar to how they handle other high-frequency input-driven effects)?
  • What happens when the pointer is outside the viewport, or in a different browsing context (iframes)? How should this interact with Shadow DOM (closed trees, retargeting)?

4. Hit-testing & stacking context

  • Should :near() consider the element even if it is not the topmost hit-test target at that point (covered by another element)?
  • Interaction with pointer-events: none: should such elements ever match?

5. Opt-in / performance gating

  • Should :near() itself be the opt-in gate (UA only needs to track proximity for elements that participate in selectors containing :near())?
  • Are additional restrictions needed to prevent “global proximity listeners” (e.g., *:near(999999px)) from forcing continuous evaluation?
    • UAs may impose implementation-defined throttling and may clamp extremely large radii for performance/privacy.

Privacy / fingerprinting considerations

This introduces a new CSS-driven state that can change styling based on pointer approach earlier than :hover. Even without JS, that can potentially be observed via conditional resource loads (e.g., background-image changes) and timing.

Potential mitigations to discuss:

  • Consider restricting evaluation to the document/viewport (no cross-document or OS-level proximity semantics).
  • Document and/or constrain observable side effects (if the group considers it necessary).

Why a boolean proximity selector (vs pointer coordinates)

A threshold pseudo-class supports common “approach” affordances while keeping the feature smaller than exposing continuous coordinates. It may be easier to constrain for privacy and performance and provides a CSS-native alternative to JS pointermove patterns.

Prior art / related CSSWG discussions