Styling External Links with an Icon in CSS
For technical docs, blogs and articles it’s often a good idea to differentiate between links within the site (internal) and links to another site (external) as it can be jarring to be reading a blog or technical docs, clicking on a link and getting kicked to an external site unexpectedly.
A nice UX pattern is to display an ’external link’ icon next to external links. A simple way to implement this is using a CSS pseudo selector targeting only links which begin with http://
or https://
.
article a[href^="http"]::after,
article a[href^="https://"]::after
{
content: "";
width: 11px;
height: 11px;
margin-left: 4px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z'/%3E%3Cpath fill-rule='evenodd' d='M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
background-size: contain;
display: inline-block;
}
If you’d like to exclude certain domains from displaying the icon (for example subdomains) you can set the icon to be hidden with something like:
article a[href^="https://example.com"]::after
{
display: none !important;
}
The CSS examples above are to be used within the <article>
section of a page, and isn’t intended for navbars, footers or elsewhere where the font size and colors may differ - where automating the appearance of these links may not be appropriate.
The icon used in the example above is Bootstrap’s ‘box arrow up-right’ icon, but feel free to switch to something else such as Font Awesome’s External-Link-Alt’ icon.
I used the neat URL-encoder for SVG service to convert the SVG code.
One gotcha is that images which are links have the icon appended which isn’t ideal. Unfortunately I don’t have an easy CSS-only fix for that. The :has()
CSS relational pseudo-class would be perfect, but browser support is unfortunately nonexistent.