You Might Also Like
Direction-Aware Hover — Free HTML CSS JS Reveal Snippet
Direction-Aware Hover · Cards · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Direction-Aware Hover — Overlays That Enter From the Cursor Edge

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.
Build with AI
Build, Understand, Optimize, and Extend It With AI
Instead of working through the geometry in your head, paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the edge() function's dominant-axis comparison classifies a pointer position into one of four directions without any trigonometry, and why setStart() must run again on pointerleave rather than only on pointerenter. The same assistant can help optimize it, for instance checking whether getBoundingClientRect() being called on every single pointerenter and pointerleave event is worth caching for a grid with many cards. It is also useful for extending the effect: ask it to add a fifth diagonal-corner direction for finer entry detection, apply the same edge-aware slide to a full-bleed image gallery instead of gradient tiles, or combine it with a subtle scale transform on the underlying image. Treat the code less like a finished artifact and more like a starting point for a conversation.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a direction-aware hover reveal for a grid of cards in plain HTML, CSS, and JavaScript with no library.
Requirements:
- A grid of cards, each containing a caption overlay that starts fully translated off-screen using two CSS custom properties for its X and Y offset, transitioning to translate(0,0) via a single CSS transition rule.
- On pointerenter, compute which of the four edges (top, right, bottom, left) the pointer crossed by comparing the entry point's position relative to the card's center as normalized -0.5 to 0.5 fractions on each axis, and picking whichever axis has the larger absolute magnitude to decide between a horizontal or vertical edge, then using the sign to choose the specific side.
- Map the detected edge to an off-screen start offset for the two CSS custom properties (e.g. left edge means the overlay starts fully translated to -100% on the X axis) before adding a class that triggers the transition to (0,0).
- Defer adding that triggering class by one requestAnimationFrame after setting the start offset, so the browser registers the off-screen position before the transition target is applied, guaranteeing the slide actually animates instead of snapping.
- On pointerleave, remove the triggering class and immediately recompute the edge from the exit point, setting the same two custom properties so the overlay animates back out toward whichever edge the cursor left through, not just the edge it entered from.
- Wire the same two event handlers to every card in the grid from a single loop, and make the grid responsive by collapsing to one column on narrow viewports.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Step by step
How to Use
- 1Paste HTML, CSS, and JSA grid of four gradient cards renders with hidden overlays.
- 2Enter a card from the leftThe caption overlay slides in from the left.
- 3Enter from the bottomThe overlay rises up from the bottom edge instead.
- 4Leave the cardThe overlay slides out toward the edge you exit by.
- 5Swap in imagesReplace the gradient tiles with real photos.
- 6Tune the slideAdjust the transition duration and easing.
Real-world uses
Common Use Cases
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.