webdevpuneet.com

Direction-Aware Hover — Free HTML CSS JS Reveal Snippet

Direction-Aware Hover · Cards · Plain HTML, CSS & JS · Live preview

CategoryCards

Copy & paste

Source Code

<div class="da-grid" id="daGrid">
  <article class="da-card" style="--bg:linear-gradient(135deg,#6366f1,#0a0a18)"><div class="da-overlay"><h3>Aurora</h3><p>View set →</p></div></article>
  <article class="da-card" style="--bg:linear-gradient(135deg,#ec4899,#0a0a18)"><div class="da-overlay"><h3>Ember</h3><p>View set →</p></div></article>
  <article class="da-card" style="--bg:linear-gradient(135deg,#22d3ee,#0a0a18)"><div class="da-overlay"><h3>Tide</h3><p>View set →</p></div></article>
  <article class="da-card" style="--bg:linear-gradient(135deg,#34d399,#0a0a18)"><div class="da-overlay"><h3>Fern</h3><p>View set →</p></div></article>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Edge detection
A dominant-axis test classifies entry direction.
Trig-free and fast
Compares offsets, no angle math.
Variable-driven slide
--tx/--ty set the start offset per edge.
Single CSS animation
One transform transition does the reveal.
Next-frame trigger
rAF ensures the slide animates from off-screen.
Symmetric exit
Overlay leaves toward the exit edge.
Reusable handlers
One loop wires every card in the grid.
Responsive grid
Two columns collapse to one on mobile.

About this UI Snippet

Direction-Aware Hover — Overlays That Enter From the Cursor Edge

Screenshot of the Direction-Aware Hover snippet rendered live

Direction-aware hover is the refined gallery effect where a card's caption overlay slides in from the precise edge your cursor crossed — enter from the left and it comes from the left, enter from the bottom and it rises up — and then slides back out toward whichever edge you leave by. This snippet implements that classic interaction with plain HTML, CSS, and a small vanilla JavaScript edge detector.

Detecting the entry edge

The whole effect hinges on knowing which side the pointer crossed. On pointerenter, the edge() function reads the cursor's position relative to the card center as -0.5…0.5 fractions on each axis, then asks which magnitude dominates: if the horizontal offset is larger, the pointer came from the left or right; otherwise from the top or bottom. The sign picks the specific edge. This dominant-axis test is a fast, trig-free way to classify entry into one of four directions accurately.

Driving the slide with two variables

The overlay's start position is two CSS custom properties, --tx and --ty. setStart() maps the detected edge to an off-screen offset — (-100%, 0) for left, (0, 100%) for bottom, and so on — so the overlay is parked just outside the matching edge. The CSS transitions transform: translate(var(--tx), var(--ty)) to translate(0, 0) when the .show class is added, sliding the overlay in from exactly that side. Passing the geometry through variables keeps the animation itself a single CSS rule.

The next-frame trigger

After setting the start offset, the code adds .show inside a requestAnimationFrame callback. That one-frame gap lets the browser register the overlay at its off-screen start before the transition target is applied, so the slide animates rather than jumping straight to visible. It's the same double-frame technique used for any "set start, then animate" CSS transition.

Exiting toward the leaving edge

On pointerleave, the code removes .show and recomputes the edge from the exit point, setting --tx/--ty to that side. Because .show is gone, the overlay transitions back to its start offset — which now points at the edge you left through — so it slides out the way you exited. This symmetry (in from entry, out toward exit) is what makes the effect feel physically correct rather than scripted.

A reusable grid

Each card is a simple gradient tile with an overlay containing a title and a call-to-action, set up identically, so the same handlers apply to every card in the grid via a shared loop. The background is themed per card through an inline --bg variable, and the grid collapses to a single column on narrow screens.

Customizing it

Swap the gradient tiles for real images, change the overlay content and its background scrim, adjust the .35s transition for a faster or slower slide, or change the easing. Because the direction logic is generic, you can apply it to any hoverable element. Pair it with a focus cards grid or an Instagram gallery for a polished media section.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA grid of four gradient cards renders with hidden overlays.
  2. 2
    Enter a card from the leftThe caption overlay slides in from the left.
  3. 3
    Enter from the bottomThe overlay rises up from the bottom edge instead.
  4. 4
    Leave the cardThe overlay slides out toward the edge you exit by.
  5. 5
    Swap in imagesReplace the gradient tiles with real photos.
  6. 6
    Tune the slideAdjust the transition duration and easing.

Real-world uses

Common Use Cases

Portfolio gallery captions
Reveal project captions from the edge the cursor crossed, as an alternative to the dimming effect of focus cards.
Image collection grids
Pair with an Instagram gallery of images, with a dominant-axis test classifying entry direction without any trigonometry.
Team role overlays
Slide in a role description over a team card layout, entering from the side the visitor approached.
Product tile calls to action
Surface a CTA over a product card, with --tx and --ty variables setting the starting offset per edge.
Category navigation labels
Animate category labels over a bento grid of navigation tiles, where a single transform transition handles every reveal.
Related: Motion One Spring Cards
See the Motion One Spring Cards for a related cards pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

On pointerenter, the edge() function reads the cursor's position relative to the card center as -0.5 to 0.5 on each axis and checks which magnitude is larger. If horizontal dominates, entry was left or right; otherwise top or bottom, with the sign choosing the exact edge. This dominant-axis comparison classifies the direction without any trigonometry.

The detected edge maps to an off-screen offset stored in two CSS variables, --tx and --ty, so the overlay is parked just outside that edge. The CSS transitions translate(var(--tx), var(--ty)) to translate(0,0) when the show class is added, animating the overlay in from exactly the side the cursor crossed.

On pointerleave the code removes the show class and recomputes the edge from the exit point, setting --tx/--ty to that side. With show gone, the overlay transitions back to its start offset — now pointing at the exit edge — so it leaves the way you went out. That in-from-entry, out-toward-exit symmetry makes it feel physically correct.

After setting the off-screen start offset, the browser needs to paint that start state before the animation target is applied, or it would jump straight to visible. Deferring the class to the next frame with requestAnimationFrame guarantees the start position is registered first, so the slide actually animates.

Render the cards from data and attach pointerenter and pointerleave handlers that compute the edge and set the --tx/--ty inline style and a show state per card. Use refs to measure each card. The transition CSS stays the same. In Tailwind, drive the overlay with translate utilities and arbitrary inline variables, toggling a data attribute for the shown state.