Follow this how-to guide by an Atlassian designer to make a single icon font for the Atlassian products.

The Atlassian design team has been making some big changes to our products over the last 12 months. We’re achieving this with the help of the Atlassian Design Guidelines (ADG). In a separate post I’ve elaborated on how we made the ADG, which has been instrumental in establishing experience design at Atlassian.

One part of the design evolution was finding a scalable solution for handling large sets of icon assets. We needed a technique that works on our supported browsers, looks crisp on HiDPI displays and is easily maintainable. The solution I eventually came to was to create an icon font containing all these icons.

Key reasons for using an icon font at Atlassian:

  • A single source of truth so we never have two versions of the same icon
  • It can be included in the Atlassian User Interface (AUI), the UI library for all Atlassian product, for easy consumption for all our product teams
  • It works all the way back to IE7
  • Scales up and down so you don’t have to manage normal resolution and @2x resolution assets
  • Image sprites can be removed for your code base
  • Less resources to load and a lighter page weight

Our new icons

Part of the icon font roll out was to overhaul their visual style. The old icons were starting to look a little tired, and with the ADG moving into our products we needed an icon style that would match our design principles.

01-new-icons

Designing icons is not an easy task. You have 16 pixels to convey a clear metaphor which can be quite challenging. There’s one main topic around icon design that I want to discuss. The conceptual metaphors around icons is a huge topic but for this post I will be focusing on the craft and production side of icon design for an icon font (optimized for 16px) step-by-step.

Step 1: Make your icons sharp

Before we get into this I wanted to point out the tools I will be using along the way. I’ve got Photoshop and Illustrator CS6 installed along with Glyphs for Mac and for the coding part you can us whatever IDE you prefer. I’ve been using the TextMate 2 alpha version and is my IDE of choice right now.

The first and most important thing is to make sure that your anchors snap to a pixel grid. Sometimes, snapping to pixels is not good but generally speaking, your icons will look much sharper if they do. In Photoshop (or Illustrator) this is easy to do: go to the Preferences and turn pixel snapping on/off. I ended up recording an action for it to make the switching a simple click of the mouse.

02-snap-pixels

You might consider taking one of the existing icon sets out there like Pictos or Glyphicons instead of creating your own icons. Just be careful when you resize them down to 16px.

Designing icons can be very time consuming. The best results will only come from being obsessive with the details. That’s what makes the difference between good icons and great icons.

Step 2: Moving from Photoshop/Illustrator to Glyphs

I like to make my icons in Photoshop as vector shapes because I feel it gives me more control in a tool I’m familiar with but it’s just a personal preference. Once an icon is created in Photoshop, I then open up the PSD in Illustrator and then copy the shape over to a new Illustrator document that is 1024pts x 1024pts. I’ve left Illustrator to render values at points and not pixels, changing it didn’t make a difference.

In Illustrator, your 16px icon is going to look amazing at any size. Make sure you change your viewing mode in Illustrator by going to View > Pixel Preview. This will make Illustrator view your vector like a rasterised image even though it isn’t. Resize the icon up to fill the 1024pts x 1024pts and centre it on the canvas with the x,y co-ordinates at 512pts (assuming you have a 16×16 icon). This shape is what you’ll be copying into Glyphs so make sure that it looks awesome and all your paths are still behaving. If they aren’t, Glyphs will render exactly what you have on screen at 1024pts.

03-icon-canvas

Once you’re happy with how the icon looks, copy the shape and head over to Glyphs.

Step 3: Setting up Glyphs

If you haven’t installed Glyphs yet, you can grab it from the Mac App Store or get a trial from the Glyphs website. Unfortunately it’s only for Mac, but I’m sure there is a Windows equivalent out there.

First, create a new font file and then remove all the alphabet characters they pre-fill the font with. We don’t need alphanumeric characters because this is a symbol font. We’ll be using the private use unicode character ranges. If you have a small set of icons that can fit into a normal alphabet then you can use that instead of the unicode ranges. The major advantage of the unicode ranges is that it holds 6,400 possible icons in the private use range which is more than enough for all our products combined.

Secondly, make sure the settings under the hood are correct. Go to File > Font Info and you’ll see the settings for the font. Make note of the keyboard short-cut (cmd + i), you’ll be coming back to this settings pane a lot.

On the font screen, make sure you fill out:

  • Font family name
  • Designer
  • Date
  • Set the ‘units per Em’ to 1024 (default is 1000)

04-glyphs-settings

I hadn’t worked with type design before so I had to research a little and play with the values in Glyphs to get the icons to sit on the right baseline.

05-font-anatomy

The values that I have used in Glyphs don’t match the diagram exactly, I think this may just be because of the way Glyphs is calculating it. It doesn’t seem to matter though, the icons render correctly anyway.

  • Ascender: 832
  • Cap height: 768
  • X-height: 576
  • Descender: -192

06-type-settings

We’re using the 1024pts as the direct representation of 16px in the browser. Think of 1px in the browser as 64pts in Glyphs. I found it handy to write out the corresponding pixel amounts for easy math when pushing lots of these icons into the font.

07-size-note

In the settings pane is the ‘Other Settings’ tab which has the important grid spacing field. That should be set to 1 to start with. Later on you’ll want to change this value to 64 so you can see the grid that will represent the 16px displayed in the browser. Remember, 1px in the browser is 64pts in Glyphs. Keep using the keyboard shortcut to get back to this window (cmd + i), it saves a lot of time clicking around.

The last thing to do in the settings pane is to make sure you’ve checked the checkbox ‘Don’t use nice names’. You won’t be able to enter unicode values for your icons without having this confusing label checked.

Step 4: Creating icons in Glyphs

Once you’ve followed these steps you can start turning your lovely vectors from Photoshop/Illustrator into unicode mapped icons.

Move back to your 1024pt icon in Illustrator that we first resized and copy the whole shape. Move over to Glyphs and add your first character by clicking the ‘+’ button at the bottom of the app.

Once the new glyph is selected, change the value of the width in the sidebar from 600 to 1024 and make sure the padding on both sides is set to 0. Now double-click on the new glyph to edit it. Paste (cmd + v) in your copied icon shape from Illustrator. Glyphs will probably prompt you to reset the bounding box, accept the changes.

08-new-glyph

Your icon should now be in Glyphs but not in the position you want. Make sure the whole icon is selected (cmd + a) and then change the x,y coordinates accordingly. This is where that 64pts = 1px post-it note comes in handy. The majority of the time I set the anchor to be in the middle, the Y axis to be 320 and the X axis to be 512. For icons that are 16px x 14px or some other shape, you will need to use the 64pts increments to make it sit where you want. Keep in mind that the whole 16px box will be displayed in the browser. For example, if you have a 12px high icon and position it at the top of the 16px container, it will be 2px off centre when displayed in the browser.

09-icon-not-16

If you need to nudge the icon into position, make sure you change the grid spacing back to 1 (cmd + i to view settings). If you leave it at 64 to see the overlay grid and then nudge your icon into position, Glyphs will grab hold of the anchors and your icon will look like the one below. Unfortunately, Glyphs has some pretty bad undo (cmd + z) capabilities so this disaster will not be recoverable with a simple undo. To fix your icon, you’ll have to re-paste the shape in but before you do, set the grid spacing back to 1.

10-fucked-icon

Step 5: Maintaining and organising your font

Atlassian has several products that have specific icons and we needed a way to organise the font accordingly. The easy way to do it was to namespace the icons and set up filters in the sidebar.

11-table-view

The convention I’m using is to separate global, Confluence, JIRA and Dev Tools (Stash, Bitbucket, FishEye, Crucible and Bamboo) icons. For example, the help icon is named ‘aui-global-help’. With the filters set up in the sidebar, viewing a specific set of icons is easy.

Unicode ranges

Private use unicode ranges from UTF+E001 – U+F8FF which is 6,400 characters so I don’t think we’re going to run out of characters any time soon.

The unicode ranges are hexadecimal. The sequence always starts with numbers ’1′ through ’9′ and then the letters ‘a’ through ‘f’ (e000, e001, e002, … e009, e00a, e00b, … e00f, e010, e011, etc).

In Glyphs you’ll need to specify the unicode values for every icon you add. Do this by selecting the icon and then changing its value in the sidebar. You don’t need to specify the ‘UTF+’ part in Glyphs, only the hexadecimal part.

Now that you’ve completed one icon, you can repeat these same steps for all your remaining icons.

Step 6: Exporting

When you’re happy with your icons in Glyphs you’ll need to export the saved file (cmd + e). Choose OTF from the menu pane, select a location to export to and click ‘Next…’. Glyphs tends to crash every now and then when it runs exports so make sure you’ve saved all your progress.

12-export

Once the export is successful, navigate to the folder Glyphs has export the font into to convert this OTF file into a web font to use in your application.

Making the web font

Font Squirrel is a great free service for turning OTF files into web fonts. Go to the web font generator and add your font file.

The configuration I used is below:

Mode: Expert
Formats: ttf, woff, eot, svg
Truetype Hinting: Keep existing
Subsetting: Custom
Unicode ranges: E000-E3FF, EC00-EFFF

Make sure you adjust your unicode range to the unicodes you actually use and tick the ‘Remember my settings’ checkbox. Convert the font and then download it to your desktop and you’re ready to put the final touches on it to make your icon font perfect.

Step 7: Subpixel rendering of icons

The last bit of tuning comes in the browser to make the new icons extra crisp.

Using -webkit-font-smoothing: antialiased; on the font makes a big difference. You might not be able to tell on standard screens when you’re entering this in the CSS but have a closer look on an Apple screen to see the difference in Safari and Chrome.

13-css-antialiasing

The CSS

The basic CSS for the small and large icon sizes we have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@font-face {
    font-family: "Atlassian Icons";
    src: url(atlassian-icons.eot);
    src: url(atlassian-icons.eot?#iefix) format("embedded-opentype"),
    url(atlassian-icons.woff) format("woff"),
    url(atlassian-icons.ttf) format("truetype"),
    url(atlassian-icons.svg#atlassian-icons) format("svg");
    font-weight: normal;
    font-style: normal;
}
.aui-icon-small,
.aui-icon-large {
    line-height: 0;
    position: relative;
    vertical-align: text-top;
}
.aui-icon-small {
    height: 16px;
    width: 16px;
}
.aui-icon-large {
    height: 32px;
    width: 32px;
}
.aui-icon-small:before,
.aui-icon-large:before {
    color: inherit;
    font-family: "Atlassian Icons";
    font-weight: normal;
    -webkit-font-smoothing: antialiased; /* Improves the rendering of icons */
    font-style: normal;
    left: 0;
    line-height: 1;
    position: absolute;
    text-indent: 0;
    speak: none; /* This prevents screen readers from pronouncing the pseudo element text content used to trigger the icon font */
    top: 50%;
}
.aui-icon-small:before {
    font-size: 16px;
    margin-top: -8px; /* (font-size/2) */
}
.aui-icon-large:before {
    font-size: 32px;
    margin-top: -16px; /* (font-size/2) */
}

When coding up the classes for the individual icons you’ll need to remember those unicodes from Glyphs that you entered earlier and put the values in as the content.

1
2
3
.aui-iconfont-configure:before {
    content: "\e001";
}

The HTML markup is specific to Atlassian so feel free to use your own pattern. The text inside of the span is inserted for screen readers but is not displayed on the page.

1
<span class="aui-icon aui-icon-small aui-iconfont-configure">Configure</span>

You’re all done

It may have seemed like a lot of work but after doing a couple of icons it gets much faster. The real time-saver will be in the developer speed when the icons are reused. I’ve already seen big improvements for the Stash team from using the icon font everywhere in our UI.

We’ll be adding more icons to the Atlassian icon font as we convert the old icons over for all our products.

Check out the ADG