---
title: "Identifying external links with CSS"
date: 2023-10-25T07:33:53
slug: identifying-external-links-with-css
tags: [code, css, eleventy]
---
Inspired by [this post on CSS In Real Life](https://css-irl.info/styling-external-links-with-attribute-selectors/), I thought I'd share how I'm styling external links on this site too.

## Marking up external links

I'm using [Eleventy](https://11ty.dev) to generate the site, and have a Markdown plugin that's borrowed from [the Eleventy-Excellent starter](https://github.com/madrilene/eleventy-excellent) (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:

```javascript
.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

```css
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:

```css
&[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.
