Hajime, the duck guy

UX and graphics kata
On this page
Level: Essential

Create an icon font

Create a icon webfont using provided SVG files

The way of kata

Kata is an exercise for muscle memory. It's not intended to fill your brain with information but train your fingers to react. The information is there to give you the why, but your fingers need to learn the how.

The material on this page is presented in a specific order — from least specific to highly technical. You will learn the most by jumping in as soon as you have some idea of what you should do. Once you're done, read the rest of the material and check your solution.

All katas are designed to be doable without using 3rd party libraries (and, in fact, the point is to also learn how to do what these libraries do).

To make the best of katas, observe the following rules.

  • Don't rush.
  • When stuck, take a break and do something unrelated.
  • Do not copy/paste code. Always retype everything.
  • Do not use AI tools to generate code.
  • Try to do something that wasn't in the instructions, experiment.
  • Repeat the kata from time to time, even if you think you've got it.
  • You have mastered the kata once you are able to complete it without thinking too much.

Remember, the goal is not to get it done, but to get some practice.

Introduction

In this exercise, you will create a webfont for displaying icons on the page.

Skills you will acquire

  • Creating icon webfonts
  • Adding icons to the page
  • Providing text fallback for icons

Objective

  • Create a webfont from the provided SVG files
  • Create elements on the page that showcase all of the icons
  • Create a button with a 'plus' icon with "Add" as a label
  • Create a button with a 'minus' icon and no visible text
  • When the page is read by a screenreader, icons are spoken as their content
  • When the plus button is read by a screen reader, it is read as "Add"
  • When the minus button is read by a screen reader, it is read as "Remove"

Check your solution

  • One of each icon is shown on the page
  • When the page is read using a screen reader the icons are spoken as their names
  • A button with the 'plus' icon and 'Add' label is shown on the page
  • A button with the 'minus' icon and no text label is shown on the page
  • When the plus button is read by the screen reader, it is spoken as just 'Add' (the icon is not spoken)
  • When the minus button is read by the screen reader, it is spoken as 'Remove'

Materials

Tools

Keep in mind

There are several ways to add icons to your page. Of these methods, the icon font is the most efficient in terms of the overall payload size because fonts compress vector graphics better than text-based formats such as SVG. The advantage of using icon fonts lies also in the fact that the icon can be controlled through CSS rather than from the HTML side as with various SVG-based methods. The primary disadvantage of the icon font is that when a user replaces the fonts on the page for accessibility purposes, they will see boxes where the icons should be and lose context. For this, SVG-based approaches are much better.

In this exercise, you are expected to use two tools to create an icon font. One is the Icomoon app, which is used to create the icon font itself. The other tool is the Transfonter app which is used to further optimize the font. When using Transfonter, pay attention to the difference in payload size between the the files created by Icomoon and the files created by Transfonter.

By default, Icomoon will generate a stylesheet that contains classes for each icon. Adding the classes to the elements will cause the icon to be rendered as the ::before pseudo-class. While this is the dfault, it is not strictly necessary to use those classes. We can also apply icons to elements by directly selecting them. Here is an example from this website:

:is(
#home-link,
#hero h1
)::before {
     font-family: 'icons' !important;
     font-style: normal;
     font-weight: normal;
     font-variant: normal;
     text-transform: none;
     line-height: 1;
     -webkit-font-smoothing: antialiased;
     -moz-osx-font-smoothing: grayscale;
 }

:is(
#home-link,
#hero h1
)::before {
    content: '\e901';
}

Although this sounds a bit more involved than simply applying icon classes, the advantage of doing it this way is that it gives CSS full control over which icon appears where. In other words, to change the icon of some element, we do not need to modify the HTML. The disadvantage is that it results in a bit more code and is a bit harder to maintain. This website uses a custom preprocessor to make the work easier. Try both approaches and make note of the differences.

Generally speaking, we use icons in two ways. We use them either to augment some text content, or we use them to replace the text content. In either case, you should make sure that the screen reader is able to announce the intended information. For instance, if a button only shows a single icon, you should ensure that the meaning visually able people get from the icon is also conveyed to those who cannot (clearly) see the icon. Text alternatives are provided in order to achieve this. You can think of text alternatives as the alt attribute on the <img> tag.

Since not all elements have a built-in equivalent of an alt attribute, we have several approaches to provide text alternative. For practice, you should try different approaches as some work better than others in different scenarios.

The two most common approaches are using aria-label, and visual hiding.

The easiest way to provide a text alternative for an element is to use the aria-label attribute. For example:

<button class="icon icon-plus" aria-label="plus"></button>

The downside of using aria-label is that it does not work on all elements. There are other rules about using aria-label which may not be immediately obvious. Be sure to read up on the attribute and learn how to use it properly. As is generally the case with anything ARIA-related, when in doubt, avoid using.

The second approach is to include the text label in the element. This has the advantage of being supported by virtually all accessibility tools. On the other hand it requires us to remove the text using CSS in a way that doesn't circumvent those tools. We commonly use a technique called 'visual hiding' for this.

.text-alt {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

The reason properties like visibility are not used for this is that accessibility tools generally try to honor CSS as much as possible to account for pages that aren't designed with accessibility in mind.

In case of icons, we would make the text visually hidden by wrapping it in a span and hiding the span:

<span class="icon icon-plus"><span class="text-alt">plus</span></span>

With the example markup would apply the visual hiding CSS to the inner span only.

Reading list

Want more?

Back to top