Sainthood.xyz

Link ::before Effects

Some fun little things you can do with links using ::before.

Table of Contents

HTML

I'll be using this HTML structure for all of the examples on this page.

<ul class="className">
    <li><a href="#">Link #1</a></li>
    <li><a href="#">Link #2</a></li>
    <li><a href="#">Link #3</a></li>
</ul>

CSS

ul.className a::before {
    content: url("heartspin.gif");
    margin-right: 0.5em; /* Optional, extra spacing so it looks nicer */
}

ul.className {
    list-style: none; /* removes list bullets */
}

A pretty basic, but fun way to customize links. Best suited for links in simple lists or navigation menus, not in the main content.

Animate Sprite on Hover

Single Sprite Type

ul.className a::before {
    content: url("mascot.gif"); /* This is your default/still sprite */
    margin-right: 0.5em; /* Optional, extra spacing so it looks nicer */
}

ul.className a:hover::before, ul.className a:focus::before {
    content: url("mascot-animated.gif"); /* This is your animated sprite */
}

ul.className {
    list-style: none; /* removes list bullets */
}

I really like this one. It gives the impression that we've "paused" and "played" the GIF without any fancy scripting! All you have to do is save your regular animated GIF and a still frame from that GIF separately. Set the still one as your default sprite and the animated one for when the link is hovered over or focused on.

You can get the first frame of the GIF by using Ezgif, or any image editor that supports animation. Why save the still image as a GIF? I noticed that saving it as a PNG made the colors a little off. If you want it to seamlessly transition, you'll want the colors to match.

Multiple Sprite Types

ul.className li a::before {
    content: url("mascot1.gif"); /* First still sprite */
    margin-right: 0.5em; /* Optional, extra spacing so it looks nicer */
}

ul.className li a:hover::before, ul.className li a:focus::before {
    content: url("mascot1-animated.gif"); /* First animated sprite */
}

ul.className li:nth-of-type(3n-1) a::before {
    content: url("mascot2.gif"); /* Second still sprite */
}

ul.className li:nth-of-type(3n-1) a:hover::before, ul.className li:nth-of-type(3n-1) a:focus::before {
    content: url("mascot2-animated.gif"); /* Second animated sprite */
}

ul.className li:nth-of-type(3n) a::before {
    content: url("mascot3.gif"); /* Third still sprite */
}

ul.className li:nth-of-type(3n) a:hover::before, ul.className li:nth-of-type(3n-1) a:focus::before {
    content: url("mascot3-animated.gif"); /* Third animated sprite */
}

ul.className {
    list-style: none; /* removes list bullets */
}

Here's a little snippet I made for myself that uses multiple images before the links. I was originally going to use it for a project I'm working on, but I didn't like how it looked with the rest of the layout I designed. Still, I thought it was cute and some people might find it useful, so I'm sharing it with you guys now!

I used the :nth-of-type pseudo-class to select the second and third links and define them separately from the default link. Note that the second sprite doesn't use :nth-of-type(2n). That would select every second link. Instead it uses :nth-of-type(3n-1), which selects the link before every third link. This also creates a repeating pattern, so if I added more links it'd just repeat the pattern of the sprites before them indefinitely.

Show Sprite on Hover

nav ul a::before {
    content: url("heart.png");
    margin-right: 0.4em; /* Optional, extra spacing so it looks nicer */
    visibility: hidden; /* Hides our sprite without collapsing the space it takes up */
}

nav ul a:hover::before, nav ul a:focus::before {
    visibility: visible; /* Shows our sprite */
}

Take note that the visibility property is different from the display property. display: none; treats the element as if it's been completely removed, removing all the space that element takes up. visibility: hidden; just makes the element invisible. Our sprite still takes up space, it just isn't shown. This is done to avoid the text shifting around, which can be very annoying.