Identifying external links with CSS
Inspired by this post on CSS In Real Life, I thought I’d share how I’m styling external links on this site too.
Marking up external links
I’m using Eleventy to generate the site, and have a Markdown plugin that’s borrowed from the Eleventy-Excellent starter (which is a site starter that really does live up to the name). This means that I have the following snippet in my Markdown plugin:
.use(markdownItLinkAttributes, [
{
// match external links
matcher(href) {
return href.match(/^https?:\/\//);
},
attrs: {
target: '_blank',
rel: 'noreferrer noopener'
}
}
])
So all of my external links have target="_blank"
attributes, meaning they’ll open in a new tab/window when clicked. That makes it a bit easier to target them with CSS.
## The selector
a[target="_blank"]::after {
content: " \f08e";
font-family: "font awesome 6 free";
font-style: normal;
font-variant: normal;
text-rendering: auto;
font-weight: 900;
-webkit-font-smoothing: antialiased;
font-size: var(--text-size-xs);
vertical-align: super;
}
I’m lazy and bad at making icons, so I’m just using FontAwesome to place the unicode icon in there. Everything else is just to size it correctly and make it not look weird.
That’s pretty much all I needed, but the CSS In Real Life article had a little section on preventing orphaned icons that I’d have a go at implementing.
Stopping the icons wrapping
The suggestion from the blog, to use position: absolute
with some right-padding on the anchor tag didn’t quite work for me. Instead I had to do all of that, but also make the anchor tags display: inline-block
and position: relative
, and then set right: 0
on the ::after
pseudo-element. On top of that I added a bit of padding to stop things getting too squashed together on smaller displays, so this is what I’ve wound up with:
&[target="_blank"] {
padding-right: 1.5ch;
display: inline-block;
position: relative;
}
&[target="_blank"]::after {
content: " \f08e";
font-family: "font awesome 6 free";
font-style: normal;
font-variant: normal;
text-rendering: auto;
font-weight: 900;
-webkit-font-smoothing: antialiased;
font-size: var(--text-size-xs);
vertical-align: super;
width: 2ch;
padding: 0 .3ch;
display: inline-block;
position: absolute;
right: 0;
}
Seems to work so far; I’m not hugely keen on the .3ch padding, I mostly got there through trying values to see what looked the least-weird. I’ll probably adjust it some more later.