Ligature Icons via Pseudo Elements and Icon Fonts

Avatar of Jason Jacobson
Jason Jacobson on (Updated on )

The following is a guest post by Jason Jacobson, a senior engineer for Minneapolis based startup LeadPages®. Jason shows off something I didn’t know was possible: turning a string into an icon. This requires an icon font, and I generally refer SVG for icons, but that doesn’t stop this from being a bonafide CSS trick that is certainly worth knowing about!

Pseudo elements (i.e. ::before and ::after) have been a big help to me when creating sites, so I came up with an approach for using them alongside ligature icons to create more readable and maintainable code.

Ligature icons? Yep! That’s how Google’s Material Icons work.

The string “face” here literally turns into an icon of a face.

Rather than use text in the HTML though, you can use a pseudo element. That is, use the content property in CSS to inject the string into any element. Say you have this HTML:

<button data-icon="delete">Remove this item</button>

We can append the string to that (“delete”), like this:

[data-icon]::before {
  content: attr(data-icon);
}

Then we can, through the power of magical ligatures, turn that text into an icon. That happens automatically when the font-family is set to one that does ligature icons, like Material Icons.

First you need that icon font available:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

The full CSS for the psuedo element icons is more like:

[data-icon]::before {
  content: attr(data-icon);
  font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  font-size: 1em;
  display: inline-block;
  vertical-align: middle;
  width: 1em;
  height: 1em;
  line-height: 1;
  text-transform: none;
  letter-spacing: normal;
  word-wrap: normal;
  white-space: nowrap;
  direction: ltr;

  * Support for all WebKit browsers. */
  -webkit-font-smoothing: antialiased;
   
  * Support for Safari and Chrome. */
  text-rendering: optimizeLegibility;

  /* Support for Firefox. */
  -moz-osx-font-smoothing: grayscale;

  /* Support for IE. */
  font-feature-settings: 'liga';
}

Note: we need to use the font-feature-settings property to make this work in Internet Explorer.

How about a list that shows a selected item:

<ul class="list">
  <li>One</li>
  <li data-icon="check">Two</li>
  <li>Three</li>
  <li>Four</li>
</ul>

See the Pen Pen #01 by CSS-Tricks (@css-tricks) on CodePen.

You could also use it for displaying user states with integrations or forms.

<ul class="list">
  <li data-icon="error">Int One</li>
  <li data-icon="check">Int Two</li>
  <li data-icon="error">Int Three</li>
  <li data-icon="error">Int Four</li>
</ul>

See the Pen Ligature Icons – Error Indicators by CSS-Tricks (@css-tricks) on CodePen.

Notice that for all the examples so far, I haven’t added any extra CSS or HTML to get the new icons.

Here is an example of a button that has a :hover and :active state. I’ve added another attribute to handle the success icon. This is something that could be done with JavaScript, but since this is CSS-Tricks, I went for the pure CSS approach.

See the Pen Pen #03 by CSS-Tricks (@css-tricks) on CodePen.