CSS-Tricks has this pretty cool way of styling hovered links. By default, the text is a fairly common blue. But hover of the links, and they’re filled with a linear gradient.
Pretty neat, right? And the trick isn’t all that complicated. On hover…
- give the link a linear gradient background,
- clip the background to the text, and
- give the text a transparent fill so the background shows through.
It looks like this in CSS:
a {
color: #007db5;
}
a:hover {
background: linear-gradient(90deg,#ff8a00,#e52e71);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
Notice the -webkit-
prefix, which is required for now. There’s a little more to the actual implementation here on CSS-Tricks, but this little bit gets us what we’re looking for.
But that’s not the point here. Just the other day, Brad Westfall phoned in to let us know that this technique also takes effect on emojis which, like any other text, gets a transparent fill on hover.
He noticed it happening on a link in one of our posts.
Not the worst thing. And it totally makes sense. I mean, an emoji is a glyph like any other text in a font file, right? They just happen to be a color font and take on the form of an image. Of course they would be treated like any other glyph in a situation like this where we’re hallowing out the fill color.
But if keeping the color in tact on emojis is a requirement, that can be resolved by wrapping the emoji in a span and setting its fill back to its initial state.
But who wants to write a span every time an emoji happens to pop up in a link? 👎
If you’re looking for a CSS solution, we’re kinda out of luck. That said, the CSS Fonts Module Level 4 specification includes a definition for a proposed font-variation-emoji
property. However, there’s not much on it (that I can find) at the moment and it doesn’t appear to be designed for this sort of thing, A quick skim of some discussion related to the proposal suggests it’s more about the way some browsers or systems automatically convert Unicode to emoji and how to control that behavior.
There’s also the proposed definition of font-palette
in the same draft spec which seems like a way to control color fonts — that’s what emojis are at the end of the day. But this isn’t the solution, either.
It seems the only way to prevent an emoji’s fill from being changed without a span is some sort of JavaScript solution. Look at services like WordPress, Dropbox, Facebook and Twitter. They all implement their own custom emoji sets. And what do they use? Images.
That would be one way to do it. If the emoji is replaced with an image (an SVG in this specific example), then that would certainly exclude it from being filled along with the link text.
Or, hey, why not prevent ourselves from getting into the situation at all and place that dang thing outside of the link?
That’s probably the route we should have taken all along. But an emoji might not come at the beginning or end of a link, but somewhere in the middle. It just underscores the point that there are cases where having some sort of control here could come in handy.
The Codepen examples don’t show any gradients in Firefox. Are emojis overfilled here to? Would it be very laborious to make the examples work in non-Chrome browsers, too?
Wrapping the emoji(s) in a span seems like the simplest solution. If JavaScript is already being considered as a possible fix, maybe there could simply be a line or two that wraps all emojis that are inside links with spans when the page renders.
This is considered good.
With transparent text stroke
‘-webkit-text-stroke: 1px rgb(0 0 0 / 0);’
we can get this working in Firefox.
As Alex Berkowitz says, you could put all your emoji into spans robotically using JS. BUT:
Searching for emoji in a string using regex turns out to be kind of complicated, but people have made stuff to do it. I found this one by satans17 on GitHub:
`var unified_emoji_ranges = [
‘\ud83c[\udf00-\udfff]’, // U+1F300 to U+1F3FF
‘\ud83d[\udc00-\ude4f]’, // U+1F400 to U+1F64F
‘\ud83d[\ude80-\udeff]’ // U+1F680 to U+1F6FF
];
var reg = new RegExp(unified_emoji_ranges.join(‘|’), ‘g’);`
An interesting topic that I hadn’t considered before! It seems the span solution is best if you absolutely must include the emoji within the link itself, and shouldn’t be hard to automate.