External link with an appended icon
Before using this solution, I recommend reviewing the orphan icon problem below. You may not like the look of the icon on a separate line from the link. This occurs occasionally from text wrapping. It is unavoidable.
A common style is to append an icon to an external link. It gives a hint to users that they will be navigating away from the website.
a[href^="http"] {
padding-inline-end: 1rem;
}
a[href^="http"]::after {
content: "";
display: inline-block;
position: absolute;
width: 1.3rem;
height: 1.3rem;
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22currentColor%22%3E%3Cpath%20d%3D%22M16%2016.667H8A.669.669%200%200%201%207.333%2016V8c0-.367.3-.667.667-.667h3.333c.367%200%20.667-.3.667-.666C12%206.3%2011.7%206%2011.333%206h-4C6.593%206%206%206.6%206%207.333v9.334C6%2017.4%206.6%2018%207.333%2018h9.334C17.4%2018%2018%2017.4%2018%2016.667v-4c0-.367-.3-.667-.667-.667-.366%200-.666.3-.666.667V16c0%20.367-.3.667-.667.667zm-2.667-10c0%20.366.3.666.667.666h1.727L9.64%2013.42a.664.664%200%201%200%20.94.94l6.087-6.087V10c0%20.367.3.667.666.667.367%200%20.667-.3.667-.667V6h-4c-.367%200-.667.3-.667.667z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E");
background-size: 100%;
translate: -0.1rem 0.15rem;
} In the code snippet, I am using a data URI of a SVG icon as the image source. This makes the snippet easy to copy-and-paste. You can use your own SVG instead if your prefer. I converted the SVG using this Convert SVG to Data URI tool, in case you are wondering!
Demo
If you use a different SVG, you may have to make adjustments to the spacing and alignment. SVG icons do not use whitespace consistently.
Explanation
You can select elements based on their attributes using the square bracket notation. It is possible to check if an attribute has a particular value. To check if a link (a element) is external, you can check if the href attribute begins with “http”.
/* Appended icon */
a[href^='http']::after {
content: url("img/link-arrow.svg");
display: inline-block;
width: 1rem;
height: 1rem;
} We’ll append an icon by styling the ::after pseudo-element. To add the icon you can provide an image URL or an emoji to the content property. We can add a small margin to the link to give some separation between the text and the icon. And that works quite well.
One gotcha is with the sizing of the image. You may expect to be able to adjust the size of the SVG by adjusting the size of the ::after pseudo-element, but this may not work. When a SVG has the width and height attributes set in the SVG file, it will have an explicit, fixed size.
You can go in one of two ways to get around this.
The first option is to omit the width and height attributes of the SVG element in the SVG file and continue to reference the file using content. Then its size will change relative to the ::after pseudo-element. The SVG must have the viewBox attribute set to display properly.
a[href^='http']::after {
content: url("img/link-arrow.svg");
display: inline-block;
/* If this does not change the size of the SVG, check the markdown of the SVG file
to see if it has width and height on the SVG element.*/
width: 1rem;
height: 1rem;
} The second option is to make the SVG a background image of the pseudo-element. You reference the SVG in background-image and set background-size:100%. This way you do not need to worry about the SVG’s explicit size. We set the content to an empty string to ensure it is displayed.
a[href^="http"]::after {
content: "";
display: inline-block;
width: 1rem;
height: 1rem;
background-image: url("img/external-link.svg");
background-size: 100%;
} The second option is more resilient than the first, so is probably a better default to go with.
Orphan icon problem
Depending on where the line wraps, the icon could break onto a new line on its own. This may confuse people.
I haven’t found a clean way to prevent the orphaning of the icon, which works across all browsers. If you use position: absolute on the pseudo-element, the icon will never wrap by itself in Firefox, but Chrome will let it!
Attribution
Michelle Barker was the one who brought my attention to the orphan icon problem in her article, Styling External Links with Attribute Selectors.