Having fun with link hover effects

A designer I work with was presenting comps at a recent team meeting. She had done a wonderful job piecing together the concept for a design system, from components to patterns and everything in between that would make any front-end developer happy.

But there was a teeny tiny detail in her work that caught my eye: the hover state for links was a squiggle.

Default link (top) and hover effect (bottom)

Huh! Not only had I not seen that before, the idea had never even crossed my mind. Turns out there are plenty of instances of it on live sites, one being The Outline. That was the one that was implementation that inspired the design.

Cool, I figured. We can do something like a linear background gradient or even a background image. But! That wasn’t the end of the design. Turns out it’s animated as well. Again, from The Outline:

Screenshot from The Outline article (source)

Whoa! That’s pretty wild. I wasn’t sure how to approach that, honestly, because animating any of my initial ideas would be difficult, especially for cross-browser support.

So, how did The Outline do it? Turns out, it’s SVG. We can make a squiggly path and animate it pretty easily:

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

But how does that work with a link? Well, we can use SVG on the background-image property:

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

But that’s kinda crappy because we can’t really animate that. We need better values for that. However, we can inline CSS directly on the SVG in the background-image property. We can’t simply copy and paste the SVG code into the property, but we can with some proper encoding:

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

And, since SVG can contain its own styles within the markup, the animation can be tossed right there in the background-image property, the same way we would do it with CSS in an HTML document head or inline CSS in HTML.

See the Pen Squiggle by Geoff Graham (@geoffgraham) on CodePen.

We can style it up a little differently, if we’d like:

See the Pen Link Effectz – Squiggle by Geoff Graham (@geoffgraham) on CodePen.

This is inspiring!

I have no idea if an animated squiggle makes for a good user experience and, frankly, that’s not the point of this post. The point is that The Outline had a fun idea with a slick CSS implementation.

That got me thinking about other non-standard (perhaps even unconventional) hover styling we can do with links. Again, tossing aside usability and have a grand ol’ time with CSS…

The Border to Background Effect

Maybe that same bottom border on the default link can grow and become the full background of the link on hover:

See the Pen Link Effectz – Background on hover by Geoff Graham (@geoffgraham) on CodePen.

Heck, we can even do something similar horizontally:

See the Pen Link Effectz – Horizotonal Background by Geoff Graham (@geoffgraham) on CodePen.

The Outlined Text Effect

Let’s strip out the font color and leave an outline behind.

See the Pen Link Effectz – Outline on hover by Geoff Graham (@geoffgraham) on CodePen.

The Raised Text Effect

Another idea is to raise the text as if it grows out of the page on hover:

See the Pen Link Effectz – Raised text on hover by Geoff Graham (@geoffgraham) on CodePen.

The Font Swapper-oo Effect

This is so impractical that it makes me LOL, but why not:

See the Pen Link Effectz – Swap font on hover by Geoff Graham (@geoffgraham) on CodePen.

The “Turn it Up, Chris” Effect

Sorry, Chris. You know you love it. ❤️

See the Pen Link Effectz – Turn it up, Chris! by Geoff Graham (@geoffgraham) on CodePen.

What can you come up with?

Have ideas? Let me know in the comments and I’ll toss ’em in the CodePen collection I’ve started.

The post Having fun with link hover effects appeared first on CSS-Tricks.

Direction Aware Hover Effects

This is a particular design trick that never fails to catch people’s eye! I don’t know the exact history of who-thought-of-what first and all that, but I know I have seen a number of implementations of it over the years. I figured I’d round a few of them up here.

Noel Delagado

See the Pen Direction-aware 3D hover effect (Concept) by Noel Delgado (@noeldelgado) on CodePen.

The detection here is done by tracking the mouse position on mouseover and mouseout and calculating which side was crossed. It’s a small amount of clever JavaScript, the meat of which is figuring out that direction:

var getDirection = function (ev, obj) { var w = obj.offsetWidth, h = obj.offsetHeight, x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)), y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)), d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4; return d;

Then class names are applied depending on that direction to trigger the directional CSS animations.

Fabrice Weinberg

See the Pen Direction aware hover pure CSS by Fabrice Weinberg (@FWeinb) on CodePen.

Fabrice uses just pure CSS here. They don’t detect the outgoing direction, but they do detect the incoming direction by way of four hidden hoverable boxes, each rotated to cover a triangle. Like this:



In an article by Mary Lou on Codrops from 2012, Direction-Aware Hover Effect with CSS3 and jQuery, the detection is also done in JavaScript. Here’s that part of the plugin:

_getDir: function (coordinates) { // the width and height of the current div var w = this.$el.width(), h = this.$el.height(), // calculate the x and y to get an angle to the center of the div from that x and y. // gets the x value relative to the center of the DIV and "normalize" it x = (coordinates.x - this.$el.offset().left - (w / 2)) * (w > h ? (h / w) : 1), y = (coordinates.y - this.$el.offset().top - (h / 2)) * (h > w ? (w / h) : 1), // the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123); // first calculate the angle of the point, // add 180 deg to get rid of the negative values // divide by 90 to get the quadrant // add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/ direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4; return direction;

It’s technically CSS doing the animation though, as inline styles are applied as needed to the elements.

John Stewart

See the Pen Direction Aware Hover Goodness by John Stewart (@johnstew) on CodePen.

John leaned on Greensock to do all the detection and animation work here. Like all the examples, it has its own homegrown geometric math to calculate the direction in which the elements were hovered.

// Detect Closest Edge
function closestEdge(x,y,w,h) { var topEdgeDist = distMetric(x,y,w/2,0); var bottomEdgeDist = distMetric(x,y,w/2,h); var leftEdgeDist = distMetric(x,y,0,h/2); var rightEdgeDist = distMetric(x,y,w,h/2); var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist); switch (min) { case leftEdgeDist: return "left"; case rightEdgeDist: return "right"; case topEdgeDist: return "top"; case bottomEdgeDist: return "bottom"; }
} // Distance Formula
function distMetric(x,y,x2,y2) { var xDiff = x - x2; var yDiff = y - y2; return (xDiff * xDiff) + (yDiff * yDiff);

Gabrielle Wee

See the Pen CSS-Only Direction-Aware Cube Links by Gabrielle Wee ✨ (@gabriellewee) on CodePen.

Gabrielle gets it done entirely in CSS by positioning four hoverable child elements which trigger the animation on a sibling element (the cube) depending on which one was hovered. There is some tricky stuff here involving clip-path and transforms that I admit I don’t fully understand. The hoverable areas don’t appear to be triangular like you might expect, but rectangles covering half the area. It seems like they would overlap ineffectively, but they don’t seem to. I think it might be that they hang off the edges slightly giving a hover area that allows each edge full edge coverage.

Elmer Balbin

See the Pen Direction Aware Tiles using clip-path Pure CSS by Elmer Balbin (@elmzarnsi) on CodePen.

Elmer is also using clip-path here, but the four hoverable elements are clipped into triangles. You can see how each of them has a point at 50% 50%, the center of the square, and has two other corner points.

clip-path: polygon(0 0, 100% 0, 50% 50%)
clip-path: polygon(100% 0, 100% 100%, 50% 50%);
clip-path: polygon(0 100%, 50% 50%, 100% 100%);
clip-path: polygon(0 0, 50% 50%, 0 100%);

Nigel O Toole


Raw JavaScript powers Nigel’s demo here, which is all modernized to work with npm and modules and all that. It’s familiar calculations though:

const _getDirection = function (e, item) { // Width and height of current item let w = item.offsetWidth; let h = item.offsetHeight; let position = _getPosition(item); // Calculate the x/y value of the pointer entering/exiting, relative to the center of the item. let x = (e.pageX - position.x - (w / 2) * (w > h ? (h / w) : 1)); let y = (e.pageY - position.y - (h / 2) * (h > w ? (w / h) : 1)); // Calculate the angle the pointer entered/exited and convert to clockwise format (top/right/bottom/left = 0/1/2/3). See https://stackoverflow.com/a/3647634 for a full explanation. let d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4; // console.table([x, y, w, h, e.pageX, e.pageY, item.offsetLeft, item.offsetTop, position.x, position.y]); return d;

The JavaScript ultimately applies classes, which are animated in CSS based on some fancy Sass-generated animations.


A CSS-only take that handles the outgoing direction nicely!

See the Pen CSS-only directionally aware hover by Giana (@giana) on CodePen.

Seen any others out there? Ever used this on something you’ve built?

Direction Aware Hover Effects is a post from CSS-Tricks